[PYTHON] [Introduction to Systre] Fibonacci Retracement ♬

This time, as an application of learning functions and classes, I created a class that calculates the Fibonacci sequence and played with it. Also, apply the Fx and stock price app created in the previous introduction to Pandas. I will put the created application as a bonus.

I put the code below

MuAuan/FibonacciRetracement

First of all, have you seen the following sequence of numbers?

Fibonacci sequence

F_n

1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 ...

This sequence of numbers has the following properties.

Ratio of adjacent numbers

F_n/F_{n+1}

1.00000 1.00000 0.50000 0.66667 0.60000 0.62500 0.61538 0.61905 0.61765 0.61818 0.61798 0.61806 0.61803 0.61804 0.61803 0.61803 ...

F_{n+1}/F_n

1.00000 1.00000 2.00000 1.50000 1.66667 1.60000 1.62500 1.61538 1.61905 1.61765 1.61818 1.61798 1.61806 1.61803 1.61804 1.61803 ...

Golden ratio

That is, the above convergence values have the following relationship.

\begin{align}
\frac{F_{n+1}}{F_n} &=& 1 + \frac{F_n}{F_{n+1}} \\
(\frac{F_{n+1}}{F_n})^2 &=& \frac{F_{n+1}}{F_n} + 1
\end{align}

That is, this ratio is the solution of the quadratic equation $ x ^ 2-x-1 = 0 $.

x=\frac{1\pm\sqrt5}{2}

Of these two solutions, the positive solution is the above ratio, called the golden ratio $ \ phi = \ frac {1 + \ sqrt5} {2} = 1.618 ... $, in many situations in nature. Encounter. Also, the reciprocal is the solution of $ x ^ 2 + x-1 = 0 $, $ x = \ frac {-1 + \ sqrt5} {2} = \ phi -1 $, and $ = \ phi'$. If you put it, you can see that the above relationship is satisfied. For reference, there are examples such as sunflowers.

【reference】 [Fibonacci number](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3% 83% 81% E6% 95% B0)

Fibonacci retracement

In the world of systole, Fibonacci retracement is used as an index to judge the target price of a squeeze in the rising market or a temporary return in the falling market, as shown in the reference commentary. From Reference (2) "Retracement is so-called" retracement "and" retracement ". In other words, it is a temporary price retrograde in the formed trend. " 【reference】 ① Fibonacci RetracementRetracement presser knowledge four points @ This time, I would like to consciously verify "3/4, 2/3, 1/2, 1/3, 1/4" in Reference ②.

Verification

The target was ZARJPY = X in South Africa, which is rumored to be generally difficult in Forex. ① First, in the Fibonacci sequence, look at the retracement between the upside and downside as usual for the appropriate period. As a result, it seems that the return after 2020.5 after hitting the lower price is on the forecast line properly. fx_ZARJPY=X_ema_df_decompose_2018-01-01_2020-08-14ex0.875.png It should be noted here that even though we started from a sloppy place, we almost reproduced the return, and it seems that many of the peaks on the left side of the lower price are also returning near the drawn line.

The retracement between the upper price and the lower price is calculated by the following function. In the label m618d, d means n = 2, t means 3 ... Also, m50 is the 50% line.

def M618_(x, n):
    #Find the retracement between the lower and upper limits
    f = 1
    for i in range(0,n,1):
        f *= f_ratio
    m618 = pd.Series(x).min() + f*(pd.Series(x).max()-pd.Series(x).min())
    return m618

(2) Set the period to 2020.1.1-2020.8.14, and draw a clear upper and lower price so that it will be entered in half the period. Also, I will add a Fibonacci retracement near the upper price. The results show that it has been moving on the forecast line since mid-2020.4. Moreover, it seems that the retracement of the period to the left of the lower price is reproduced here as well. fx_ZARJPY=X_ema_df_decompose_2020-01-01_2020-08-14ex0.5.png

Here, in addition to the above, the line near the upper price is added by the following function. The label m618_3 means n = 3.

def M618_1(x, n):
    #Find the retracement near the upper limit
    f = 1
    for i in range(0,n,1):
        f *= f_ratio
    m618 = pd.Series(x).max() - f*(pd.Series(x).max()-pd.Series(x).min())
    return m618

③ Now, let's draw the period as 2019.4.1-2020.8.14. In this figure, the upper price of 2019.4 and the lower price of 2019.9 are used to predict the subsequent transition. In this case as well, the behavior of this price range range in the next period can be predicted. Furthermore, although it broke below the lower price in 2020.3, the subsequent transition has been able to reproduce a large return and rebound. In particular, it is good to be able to predict m618_20 (next bottom price), and if the lower price changes, if the next prediction is made again, the subsequent transition can be predicted more accurately as shown in the graph above. However, it is almost impossible to predict the subsequent return, such as m618_23. fx_ZARJPY=X_ema_df_decompose_2019-04-01_2020-08-14ex0.5.png The forecast below the lower price is carried out by the following function. The label is m618_23, where 23 means n = 3.

def M618_2(x, n):
    #Find retracement below the lower limit
    f = 1
    for i in range(0,n,1):
        f *= f_ratio
    m618 = pd.Series(x).min() - f*(pd.Series(x).max()-pd.Series(x).min())
    return m618

Stock price

As shown below, the stock prices and retracements are in good agreement. fx_7201.T_ema_df_decompose_2020-01-01_2020-08-14ex0.8.png

Try rational numbers

Comparing the Fibonacci sequence and the rational (fraction ratio) sequence, we can find them at almost the corresponding positions as shown below. So, since there is also the story of reference (2), I will calculate the retracement in the same way with the fraction ratio and compare it.

- Fibonacci Fibonacci Rational Rational
1 91.0 1-\phi'^5 93.8 15/16
2 85.4 1-\phi'^4 87.5 7/8
3 76.4 1-\phi'^3 75 3/4
4 61.8 \phi'=1-\phi'^2 66.6 2/3
5 50 1/2 50 1/2
6 38.2 \phi '^2=1-\phi' 33.3 1/3
7 23.6 \phi '^3 25 1/4
8 14.6 \phi '^4 16.7 1/6
9 9.0 \phi '^5 12.5 1/8
10 5.57 \phi '^6 6.25 1/16
- - - -

The rational number is an intuitive number (on the chart), although there are other rational numbers.

The result is as follows (1) Period and conditions corresponding to (1) of verification The result shows that the retracement lines are well aligned again. fx_ZARJPY=X_ema_df_decompose_2018-01-01_2020-08-14ratio0.875.png ③ Period and conditions corresponding to ③ of verification As shown below, the position of the return is reproduced considerably. It seems that there is almost no superiority or inferiority. The reason why -50% and -100% when the price breaks out of the lower price may be that they are in the same position in the first place, but as mentioned above, the original cause is that there are numerical values in similar positions. I think that fx_ZARJPY=X_ema_df_decompose_2019-04-01_2020-08-14ratio0.5.png The numerical comparison of the positions below the lower price is as follows. Some lines do not correspond to rational numbers, but as seen in ①, if you try to make it, you can make it.

Fibonacci Rational Remarks
6.8236 6.8236 Lower price
6.749006
6.64947 6.674412 almost the same
6.541853 6.525225 almost the same
6.367723 2020.3 Down line
6.22685 6.22685 -50%
6.085976 Return after rebound from lower price
5.630099 5.630099 -100%

Discussion

The interesting part of this story is that this ups and downs exist even if it expands or contracts, and there seems to be one index represented by the golden ratio in the infinite upper and lower prices. It is in the place. That is, there is a possibility of one of the so-called fractal phenomena. This story is not about predicting whether it will rise, whether it is Forex or stock prices. However, if retracement occurs in the trend, it means that it returns or repels around the value calculated by this coefficient. In the past, you would have invested in your eyes or mental arithmetic, so you would have done it with a rational number, but now that you are doing it with Systre, you naturally think that you are introducing this Fibonacci sequence. Can be judged to be good. I think that incorporating this kind of knowledge and making even a small amount of scientific investment is a shortcut to success.

Summary

・ Created a class to calculate Fibonacci sequence at high speed ・ As an application, we verified Fibonacci retracement. ・ Fibonacci retracement is established for both fx and stock prices. ・ As a result of verifying similar retracements with rational numbers, it was found that almost the same prediction lines can be calculated.

・ In order to introduce it to Systre, it is necessary to calculate an appropriate Fibonacci retracement from the ever-changing time series numbers.

bonus

fibonacci

class_fibonacci.py


import numpy as np

class MyFibonacciClass:
    f_const = 0.6180339887498949 #514229/832040 #0.6180
    def __init__(self,x=1,y=0,n=10):
        self.x = x
        self.y = y
        self.n = n
                
    def calc_1(self,n):
        const = 1
        for i in range(1,n):
            const *= MyFibonacciClass.f_const
        return const, self.y + const*(self.x - self.y), self.x - const*(self.x - self.y)
    def calc_1_(self,n):
        const = 1
        for i in range(1,n):
            const *= MyFibonacciClass.f_const
        return self.y + (1-const)*(self.x - self.y)
    
    def calc_fib(self,m, sb1,sb2):
            if m ==1 or m== 2:
                return 1
            else:
                return sb1 + sb2
    def calc_fib2(self,m):
            if m ==1 or m== 2:
                return 1
            else:
                return MyFibonacciClass.calc_fib2(self,m-1) + MyFibonacciClass.calc_fib2(self,m-2)
            
    def calc_fib3(self, m): 
        # fastest m=100000;108 ms ± 4.01 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
        a, b = 1, 1
        for _ in range(m-2):
            a, b = b, a + b
        return b
    
    def calc_fib4(self,m): # m =< 70
        return round((((1 + 5 ** 0.5) / 2) ** m - ((1 - 5 ** 0.5) / 2) ** m) / 5 ** 0.5)
  
    def calc_print(self):
        sb1 = 1
        sb2 = 1
        for n0 in range(1,self.n+1):
            s = MyFibonacciClass.calc_fib(self,n0, sb1, sb2)
            print(n0, s,end=' ')
            #print(s,end=' ')
            rs = np.float64(sb1/s)
            rs1 = np.float64(s/sb1)
            print(rs, rs1)
            #print('{0:5,.5f}'.format(rs1), end=' ')
            sb2 = sb1
            sb1 = s
            
if __name__ == '__main__':
    fibonacci1 = MyFibonacciClass(1604.5,834.6,10)
    for i in range(1,11,1):
        c,a,b = fibonacci1.calc_1(i)
        print('{0:5,.3f}_{1:5,.3f}_{2:5,.3f}'.format(c,a,b))

    fibonacci2 = MyFibonacciClass(1604.5,834.6,10000)
    fibonacci2.calc_print()
    print(fibonacci2.calc_fib3(1000000))

fx_plot.py

fx_plot.py


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import datetime as dt
import statsmodels.api as sm
from statsmodels.tsa.seasonal import STL
import pandas_datareader.data as DataReader

stock0='ZARJPY=X'  #'USDJPY=X' #'EURJPY=X' #AUDJPY=X JPYAUD=X ZARJPY=X GBPJPY=X JPYUSD=X
bunseki = "trend"
start = dt.date(2018,1,1)
end = dt.date(2020,8,14)

df=DataReader.get_data_yahoo("{}".format(stock0),start,end) 
print(df)

series=df['Close']
cycle, trend = sm.tsa.filters.hpfilter(series, 144)
df['trend']=  trend
f_ratio = 0.6180339887498949

def MAX_(x):
    return pd.Series(x).max()
def MIN_(x):
    return pd.Series(x).min()
def M618_(x, n):
    #Find the retracement between the lower and upper limits
    f = 1
    for i in range(0,n,1):
        f *= f_ratio
    m618 = pd.Series(x).min() + f*(pd.Series(x).max()-pd.Series(x).min())
    return m618
def M618_2(x, n):
    #Find retracement below the lower limit
    f = 1
    for i in range(0,n,1):
        f *= f_ratio
    m618 = pd.Series(x).min() - f*(pd.Series(x).max()-pd.Series(x).min())
    return m618
def M618_1(x, n):
    #Find the retracement near the upper limit
    f = 1
    for i in range(0,n,1):
        f *= f_ratio
    m618 = pd.Series(x).max() - f*(pd.Series(x).max()-pd.Series(x).min())
    return m618
def M50_(x, n):
    #Seeking 50% retracement
    f = 1
    for i in range(0,n,1):
        f *= 0.5
    m618 = pd.Series(x).max() - f*(pd.Series(x).max()-pd.Series(x).min())
    return m618
def M50_1(x, n):
    #Find an additional 50% retracement below the lower limit
    f = 1
    for i in range(0,n,1):
        f *= 0.5
    m618 = pd.Series(x).min() - f*(pd.Series(x).max()-pd.Series(x).min())
    return m618


series2 = df['trend'].values.tolist()
print(series2[len(series2)-10:len(series2)])
m = 1/5 #Data range for finding upper and lower limits; percentage of all data
df['Close']=series  #series" #cycle" #trend
df['Close2']=series2
df['max'] = MAX_(df['Close'][:int(len(series)*m)])
df['min'] = MIN_(df['Close'][:int(len(series)*m)])
df['m50'] = M50_(df['Close'][:int(len(series)*m)],1)
df['m50_1'] = M50_1(df['Close'][:int(len(series)*m)],1)
#Find the retracement near the upper limit
df['m618_3'] = M618_1(df['Close'][:int(len(series)*m)],3)
df['m618_4'] = M618_1(df['Close'][:int(len(series)*m)],4)
df['m618_5'] = M618_1(df['Close'][:int(len(series)*m)],5)
#Find retracement below the lower limit
df['m618_20'] = M618_2(df['Close'][:int(len(series)*m)],0)
df['m618_21'] = M618_2(df['Close'][:int(len(series)*m)],1)
df['m618_22'] = M618_2(df['Close'][:int(len(series)*m)],2)
df['m618_23'] = M618_2(df['Close'][:int(len(series)*m)],3)
df['m618_24'] = M618_2(df['Close'][:int(len(series)*m)],4)
#Find the retracement between the lower and upper limits
df['m618'] = M618_(df['Close'][:int(len(series)*m)],1)
df['m618d'] = M618_(df['Close'][:int(len(series)*m)],2)
df['m618t'] = M618_(df['Close'][:int(len(series)*m)],3)
df['m618q'] = M618_(df['Close'][:int(len(series)*m)],4)
df['m618q5'] = M618_(df['Close'][:int(len(series)*m)],5)
df['m618q6'] = M618_(df['Close'][:int(len(series)*m)],6)

date_df=df['Close'].index.tolist()
print(df[len(series)-10:len(series)])

fig, ax1 = plt.subplots(1,1,figsize=(1.6180 * 8, 8*1),dpi=200)
ax1.plot(df['Close'],label="series")
ax1.plot(df['Close2'],label="series2")
ax1.plot(df['max'],label="max")
ax1.plot(df['min'],'black',label="min")
ax1.plot(df['m50'],'blue',label="m50")
ax1.plot(df['m50_1'],'blue',label="m50_1")
ax1.plot(df['m618_3'],label="m618_3")
ax1.plot(df['m618_4'],label="m618_4")
ax1.plot(df['m618_5'],label="m618_5")
ax1.plot(df['m618_20'],label="m618_20")
ax1.plot(df['m618_21'],label="m618_21")
ax1.plot(df['m618_22'],label="m618_22")
ax1.plot(df['m618_23'],label="m618_23")
ax1.plot(df['m618_24'],label="m618_24")
ax1.plot(df['m618'],label="m618")
ax1.plot(df['m618d'],label="m618d")
ax1.plot(df['m618t'],label="m618t")
ax1.plot(df['m618q'],label="m618q")
ax1.plot(df['m618q5'],label="m618q5")
ax1.plot(df['m618q6'],label="m618q6")

ax1.set_title("{}".format(stock0))
ax1.legend()
#ax1.grid()
plt.savefig("./fx/fx_{}_ema_df_decompose_{}_{}ex{}.png ".format(stock0,start,end,m))
plt.pause(1)
plt.close()

Recommended Posts

[Introduction to Systre] Fibonacci Retracement ♬
Introduction to MQTT (Introduction)
Introduction to Scrapy (1)
Introduction to Scrapy (3)
Introduction to Supervisor
Introduction to Tkinter 1: Introduction
Introduction to PyQt
Introduction to Scrapy (2)
[Linux] Introduction to Linux
Introduction to Scrapy (4)
Introduction to discord.py (2)
Introduction to discord.py
Introduction to Lightning pytorch
Introduction to Web Scraping
Introduction to Nonparametric Bayes
Introduction to EV3 / MicroPython
Introduction to Python language
Introduction to OpenCV (python)-(2)
Introduction to PyQt4 Part 1
Introduction to Dependency Injection
Introduction to Private Chainer
Introduction to machine learning
AOJ Introduction to Programming Topic # 1, Topic # 2, Topic # 3, Topic # 4
Introduction to electronic paper modules
A quick introduction to pytest-mock
Introduction to dictionary lookup algorithm
Introduction to Monte Carlo Method
[Learning memorandum] Introduction to vim
Introduction to PyTorch (1) Automatic differentiation
opencv-python Introduction to image processing
Introduction to Python Django (2) Win
Introduction to Cython Writing [Notes]
An introduction to private TensorFlow
Kubernetes Scheduler Introduction to Homebrew
An introduction to machine learning
[Introduction to cx_Oracle] Overview of cx_Oracle
A super introduction to Linux
AOJ Introduction to Programming Topic # 7, Topic # 8
[Introduction to pytorch-lightning] First Lit ♬
[Introduction to Systre] Stock price forecast; Monday is weak m (__) m
Introduction to Anomaly Detection 1 Basics
Introduction to RDB with sqlalchemy Ⅰ
Introduction to Nonlinear Optimization (I)
Introduction to serial communication [Python]
AOJ Introduction to Programming Topic # 5, Topic # 6
Introduction to Deep Learning ~ Learning Rules ~
[Introduction to Python] <list> [edit: 2020/02/22]
Introduction to Python (Python version APG4b)
An introduction to Python Programming
[Introduction to cx_Oracle] (8th) cx_Oracle 8.0 release
Introduction to discord.py (3) Using voice
An introduction to Bayesian optimization
Deep Reinforcement Learning 1 Introduction to Reinforcement Learning
Super introduction to machine learning
Introduction to Ansible Part ③'Inventory'
Series: Introduction to cx_Oracle Contents
[Introduction] How to use open3d
Introduction to Python For, While
Introduction to Deep Learning ~ Backpropagation ~
Introduction to Ansible Part ④'Variable'
Introduction to vi command (memorandum)