良き友人であるラン氏は この指標を長い間観察し 新年明け前には 定量化できるかどうか 議論するために 私に勧めました 延ばし屋がそんな願いを叶えるのを 今までに遅らせてしまったのは残念です 実際,最近 アルゴリズムについての私の理解は急速に改善しました いつの日か私はパインの言語の翻訳者を書こうと推定されています.何でもパイソンでできます. 冗談を言わずに 伝説的なスーパートレンドラインを紹介しましょう
CMC Marketsの新しい世代のインテリジェント・トレーディング・システムでは,使用するテクニカル・インジケーターから"スーパー・トレンド・ライン"を選択できます. 増幅信号と減少信号の色と厚さを 自分の好みに応じて調整できます スーパートレンドインジケーターの公式を理解する前に,ATRを理解する必要があります. スーパートレンドはATR値を採用して指標値を計算します. 主なアルゴリズムは次の図で説明されています.
HL2 (k線平均価格) + ATRの n 倍. トレンド突破をします. 詳細なアルゴリズムはありません. そこで私は最も素晴らしいコミュニティを考えました, TradingView. 実に,それは確かにそこにあります.
グラフを見ると 傾向に合致しています 残念なことに これはアラーム信号に過ぎません
コードが長くないので 翻訳してみましょう!
パインコードは上記のように
FMZで新しい戦略を作り出し,それをスーパートレンドと名付けます
2つのパラメータを設定します.
Pythonの高度なデータ拡張パッケージ Pandas を使用する必要があります (https://pandas.pydata.org/) について FMZは今この図書館をサポートしています.
import pandas as pd
import time
def main():
exchange.SetContractType("quarter")
preTime = 0
Log(exchange.GetAccount())
while True:
records = exchange.GetRecords(PERIOD_M15)
if records and records[-2].Time > preTime:
preTime = records[-2].Time
doTicker(records[:-1])
Sleep(1000 *60)
def doTicker(records):
M15 = pd.DataFrame(records)
M15.columns = ['time','open','high','low','close','volume','OpenInterest']
#HL2
M15['hl2']=(M15['high']+M15['low'])/2
次にMyLanguageのマニュアルを参照し,ATRの実際の変動幅の平均値のアルゴリズムステップは以下のとおりです. TR: MAX (MAX) (MAX) (HIGH (HIGH) (Low) (ABS (REF) (CLOSE,1) (HIGH) (ABS (REF) (CLOSE,1) (Low)) ATR: RMA (TR,N)
TR値は,次の3つの差の最大値である.
Python の計算では
M15['prev_close']=M15['close'].shift(1)
前の行で,つまり,新しいパラメータを形成するために1グリッドで右に移動
ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]
次に,TRの対照値3つの配列を記録する中間変数を定義します. (HIGH-LOW) (high-prev_close) (low-prev_close)
M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)
TR の値は,関数 abs () と max () を使って,中間変数の最大絶対値です.
alpha = (1.0 / length) if length > 0 else 0.5
M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()
ATR:RMA (TR,N) の値を計算する必要があります. RMAアルゴリズムは EMAアルゴリズムの固定値変数であることが判明しました. 標準パラメータは 14 です. ここで,アルファ=長さの対数をインポートします.
===
EMAを計算するために使用されます. ATRの計算の完全な手順は次のとおりです.
#ATR(PD)
length=Pd
M15['prev_close']=M15['close'].shift(1)
ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]
M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)
alpha = (1.0 / length) if length > 0 else 0.5
M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()
9 アップとDnを計算する
M15['Up']=M15['hl2']-(Factor*M15['atr'])
M15['Dn']=M15['hl2']+(Factor*M15['atr'])
Up=hl2 - (因数*atr) Dn=hl2 +(因数 * atr) 簡単じゃないですか?
これはTVの 15-21行のコアコードセクションです
TrendUp=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn
Trend = close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl = Trend==1? TrendUp: TrendDown
linecolor = Trend == 1 ? green : red
この段落の主なポイントは, 上昇段階にある場合 (下の線) トレンドアップ=最大 (上昇,トレンドアップ [1]) 落ちている場合 (上行) TrendDown=min (Dn,TrendDown [1]) つまり,ATR値が動いている傾向は,Bandit Bollinger戦略に似た技術を使っているということです. 運河の反対側を絞り続ける
この場合は,TrendUpとTrendDownの各計算は自己繰り返しを必要とします. つまり,各ステップは前のステップに従って計算されるべきです. したがって,データセットはループで繰り返されるべきです.
初期値を与えます. 初期値が,最初の値に等しくなります. 0 で計算した結果の0でゼロ値でデータを埋めます.
M15['TrendUp']=0.0
M15['TrendDown']=0.0
M15['Trend']=1
M15['Tsl']=0.0
M15['linecolor']='Homily'
M15 = M15.fillna(0)
forループを有効にする python のループ内の三重演算を使用する
for x in range(len(M15)):
トレンドアップを計算する トレンドアップ = MAX(アップ,トレンドアップ[-1]) 近い場合[-1]>トレンドアップ[-1] 前回の Close>前回の TrendUp が true ならば,Up と前回の TrendUp の間の最大値が取られ,そうでなければ,Up 値が取られ,現在の TrendUp に渡されます.
M15['TrendUp'].values[x] = max(M15['Up'].values[x],M15['TrendUp'].values[x-1]) if (M15['close'].values[x-1]>M15['TrendUp'].values[x-1]) else M15['Up'].values[x]
同じように,トレンドダウンを計算します. トレンドダウン=min(Dn,TrendDown[-1]) が接近している場合[-1]
M15['TrendDown'].values[x] = min(M15['Dn'].values[x],M15['TrendDown'].values[x-1]) if (M15['close'].values[x-1]<M15['TrendDown'].values[x-1]) else M15['Dn'].values[x]
制御方向を計算するためのフラグです.私は偽コードを簡素化しました トレンド= 1 if (close > TrendDown[-1]) else (x) x = -1 もし (close
値が1 (上昇) ならば,値を取ります. そうでない場合は,値を取ります. 閉じる価格が前回のトレンドアップより低い場合は, -1 (下落) の値を取ります.そうでなければ,前回のトレンド (変化なし) を取ります. 画像言語に翻訳すると,上線トレイル移行フラグのブレイクが上昇し,下線トレイル移行フラグのブレイクが下線トレイル移行フラグのブレイクです.
M15['Tsl'].values[x] = M15['TrendUp'].values[x] if (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
Tsl と Linecolor を計算する
Tsl=RendUp if (トレンド==1) else トレンドダウン
Tsl は,画像上のスーパートレンドを表すのに使用される値です. これは,上昇傾向にある画像のダウントラックをマークし,下落傾向にある画像の上部トラックをマークすることを意味します.
linecolor=
M15['Tsl'].values[x] = M15['TrendUp'].values[x] if (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
M15['linecolor'].values[x]= 'green' if ( M15['Trend'].values[x]==1) else 'red'
次の 23-30 行のコードは主にグラフ図で,ここでは説明されていません.
購入と販売の信号を制御する 2 行のコードがあります Tradeviewでは,信号がフラグを逆転した後で与えられていることを意味します 条件文を python に変換します 最後のトレンドフラグが -1 から 1 に変化すると,上位レジスタンスが超えられ,ロングポジションが開けることを意味します. 最後のトレンドフラグが 1 から -1 に変化すると,ダウンサポートが超えられ,ショートポジションが開きます.
if(M15['Trend'].values[-1] == 1 and M15['Trend'].values[-2] == -1):
Log('SuperTrend V.1 Alert Long',"Create Order Buy)
if(M15['Trend'].values[-1] == -1 and M15['Trend'].values[-2] == 1):
Log('SuperTrend V.1 Alert Long',"Create Order Sell)
完全なコードは以下のとおりです
M15['TrendUp']=0.0
M15['TrendDown']=0.0
M15['Trend']=1
M15['Tsl']=0.0
M15['linecolor']='Homily'
M15 = M15.fillna(0)
for x in range(len(M15)):
M15['TrendUp'].values[x] = max(M15['Up'].values[x],M15['TrendUp'].values[x-1]) if (M15['close'].values[x-1]>M15['TrendUp'].values[x-1]) else M15['Up'].values[x]
M15['TrendDown'].values[x] = min(M15['Dn'].values[x],M15['TrendDown'].values[x-1]) if (M15['close'].values[x-1]<M15['TrendDown'].values[x-1]) else M15['Dn'].values[x]
M15['Trend'].values[x] = 1 if (M15['close'].values[x] > M15['TrendDown'].values[x-1]) else ( -1 if (M15['close'].values[x]< M15['TrendUp'].values[x-1])else M15['Trend'].values[x-1] )
M15['Tsl'].values[x] = M15['TrendUp'].values[x] if (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
M15['linecolor'].values[x]= 'green' if ( M15['Trend'].values[x]==1) else 'red'
if(M15['Trend'].values[-1] == 1 and M15['Trend'].values[-2] == -1):
Log('SuperTrend V.1 Alert Long',"Create Order Buy)
Log('Tsl=',Tsl)
if(M15['Trend'].values[-1] == -1 and M15['Trend'].values[-2] == 1):
Log('SuperTrend V.1 Alert Long',"Create Order Sell)
Log('Tsl=',Tsl)
全体のコード構造を調整した ストラテジーに組み込みました ストラテジーは 完全なコードはこうです
'''backtest
start: 2019-05-01 00:00:00
end: 2020-04-21 00:00:00
period: 15m
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
'''
import pandas as pd
import time
def main():
exchange.SetContractType("quarter")
preTime = 0
Log(exchange.GetAccount())
while True:
records = exchange.GetRecords(PERIOD_M15)
if records and records[-2].Time > preTime:
preTime = records[-2].Time
doTicker(records[:-1])
Sleep(1000 *60)
def doTicker(records):
#Log('onTick',exchange.GetTicker())
M15 = pd.DataFrame(records)
#Factor=3
#Pd=7
M15.columns = ['time','open','high','low','close','volume','OpenInterest']
#HL2
M15['hl2']=(M15['high']+M15['low'])/2
#ATR(PD)
length=Pd
M15['prev_close']=M15['close'].shift(1)
ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]
M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)
alpha = (1.0 / length) if length > 0 else 0.5
M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()
M15['Up']=M15['hl2']-(Factor*M15['atr'])
M15['Dn']=M15['hl2']+(Factor*M15['atr'])
M15['TrendUp']=0.0
M15['TrendDown']=0.0
M15['Trend']=1
M15['Tsl']=0.0
M15['linecolor']='Homily'
M15 = M15.fillna(0)
for x in range(len(M15)):
M15['TrendUp'].values[x] = max(M15['Up'].values[x],M15['TrendUp'].values[x-1]) if (M15['close'].values[x-1]>M15['TrendUp'].values[x-1]) else M15['Up'].values[x]
M15['TrendDown'].values[x] = min(M15['Dn'].values[x],M15['TrendDown'].values[x-1]) if (M15['close'].values[x-1]<M15['TrendDown'].values[x-1]) else M15['Dn'].values[x]
M15['Trend'].values[x] = 1 if (M15['close'].values[x] > M15['TrendDown'].values[x-1]) else ( -1 if (M15['close'].values[x]< M15['TrendUp'].values[x-1])else M15['Trend'].values[x-1] )
M15['Tsl'].values[x] = M15['TrendUp'].values[x] if (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
M15['linecolor'].values[x]= 'Long' if ( M15['Trend'].values[x]==1) else 'Short'
linecolor=M15['linecolor'].values[-2]
close=M15['close'].values[-2]
Tsl=M15['Tsl'].values[-2]
if(M15['Trend'].values[-1] == 1 and M15['Trend'].values[-2] == -1):
Log('SuperTrend V.1 Alert Long','Create Order Buy')
Log('Tsl=',Tsl)
position = exchange.GetPosition()
if len(position) > 0:
Amount=position[0]["Amount"]
exchange.SetDirection("closesell")
exchange.Buy(_C(exchange.GetTicker).Sell*1.01, Amount);
exchange.SetDirection("buy")
exchange.Buy(_C(exchange.GetTicker).Sell*1.01, vol);
if(M15['Trend'].values[-1] == -1 and M15['Trend'].values[-2] == 1):
Log('SuperTrend V.1 Alert Long','Create Order Sell')
Log('Tsl=',Tsl)
position = exchange.GetPosition()
if len(position) > 0:
Amount=position[0]["Amount"]
exchange.SetDirection("closebuy")
exchange.Sell(_C(exchange.GetTicker).Buy*0.99,Amount);
exchange.SetDirection("sell")
exchange.Sell(_C(exchange.GetTicker).Buy*0.99, vol*2);
公共戦略の住所:https://www.fmz.com/strategy/200625
過去1年のデータを バックテストに利用しました 15分間の期間で OKEXの四半期契約を使います 設定されたパラメータは: 要素=3 Pd=45 Vol=100 (各注文につき100契約) 年間収益率は約33%です 一般的に,抽出はあまり多くありません 312 の急激な減少は,システムに比較的大きな影響を与えた. 312がないなら 返金はもっと良いはずです
スーパートレンドは非常に良い取引システムです
スーパートレンドシステムの主な原則は,ATRチャンネル突破戦略を採用することです (ケントチャンネルに似ている) しかし,その変化は主にバンディット・ボリンガー (Bandit Bollinger) の絞り込み戦略,またはドンチアン原理の逆の使用によるものです. 市場操作では 上下のチャネルが絶えず狭くなっています (チャネルを突破すると,上部と下部の軌跡は元の値に戻る)
TradeViewで TrendUpとTrendDnを別々にグラフ化します 戦略をよりよく理解できるようにします 一目でわかるように
js のバージョンが github にあります. js は苦手ですが,if ステートメントに何か問題があるようです. アドレス:https://github.com/Dodo33/gekko-supertrend-strategy/blob/master/Supertrend.js
最終的にはオリジナルのバージョンを 追跡しました 2013年5月29日に掲載されました 著者はラジャンドラン R C++コードは Mt4 フォーラムで公開されました:https://www.mql5.com/en/code/viewcode/10851/128437/Non_Repainting_SuperTrend.mq4C++の意味を大まかに理解し,機会があったら書き直します.
精髓を学べるといいな 難しい!