问题
I would like to create a zigzag indicator for stocks in Python. I have this Metastock Formula. I dicided to publish this problem here because I don't know any other foro. I saw 2 stackoverflow posts with something like this but they are wrong. As you can see, the indicator tooks the close prices. Thanks for your help.
Python code:
from __future__ import division
import matplotlib.pyplot as plt
import numpy as np
def islocalmax(x):
"""Both neighbors are lower,
assumes a centered window of size 3"""
return (x[0] < x[1]) & (x[2] < x[1])
def islocalmin(x):
"""Both neighbors are higher,
assumes a centered window of size 3"""
return (x[0] > x[1]) & (x[2] > x[1])
def isextrema(x):
return islocalmax(x) or islocalmin(x)
def create_zigzag(col, p=0.05):
# Find the local min/max
# converting to bool converts NaN to True, which makes it include the endpoints
ext_loc = col.rolling(3, center=True).apply(isextrema, raw=False).astype(np.bool_)
# extract values at local min/max
ext_val = col[ext_loc]
# filter locations based on threshold
thres_ext_loc = (ext_val.diff().abs() > (ext_val.shift(-1).abs() * p))
# Keep the endpoints
thres_ext_loc.iloc[0] = True
thres_ext_loc.iloc[-1] = True
thres_ext_loc = thres_ext_loc[thres_ext_loc]
# extract values at filtered locations
thres_ext_val = col.loc[thres_ext_loc.index]
# again search the extrema to force the zigzag to always go from high > low or vice versa,
# never low > low, or high > high
ext_loc = thres_ext_val.rolling(3, center=True).apply(isextrema, raw=False).astype(np.bool_)
thres_ext_val =thres_ext_val[ext_loc]
return thres_ext_val
from pandas_datareader import data
# Only get the adjusted close.
serie = data.DataReader(
"AAPL", start='2018-1-1', end='2020-12-31', data_source='yahoo'
)
dfzigzag = serie.apply(create_zigzag)
data1_zigzag = dfzigzag['Close'].dropna()
fig, axs = plt.subplots(figsize=(10, 3))
axs.plot(serie.Close, '-', ms=4, label='original')
axs.plot(data1_zigzag, 'ro-', ms=4, label='zigzag')
axs.legend()
plt.show()
Python code Plot: The indicator:
Metastock Formula:
{ Copyright (c) 2004, John Bruns and Financial Trading Inc. }
reversal:=Input("Reversal",0,100,5);
pc:=Input("Use Percentage?",0,1,1);
z:=If(pc,Zig(CLOSE,reversal,%),Zig(CLOSE,reversal,$));
peakbar:=LastValue(BarsSince((z>Ref(z,-1)AND Ref(Z,-1)<Ref(Z,-2)) OR (z<Ref(z,-1))AND Ref(Z,-1)>Ref(Z,-2)))+1;
lastpeak:=LastValue(Ref(z,-peakbar));
lastend:=LastValue(z);
bars:=Cum(1);
invalid:=If(pc,If(Abs(lastend-lastpeak)*100/lastpeak<reversal,1,0),If(Abs(lastend-lastpeak)<reversal,1,0));
If(bars>=LastValue(bars)-peakbar AND invalid,lastpeak,z);
来源:https://stackoverflow.com/questions/63164124/zigzag-indicator-metastock-formula-to-python