2つの移動平均のクロスオーバーアルゴリズム取引戦略

作者: リン・ハーンチャオチャン開催日:2023年10月30日 (月) 15:27:34
タグ:

img

概要

この戦略は,主に移動平均クロスオーバー原理を活用し,RSI指標逆転信号とカスタムダブル移動平均クロスオーバーアルゴリズムを組み合わせてトレンドトレードを実装する.この戦略は,異なる期間の移動平均を2つ追跡し,短期のトレンドを追跡するMAが速く,長期のトレンドを追跡するMAが遅い.高速MAが緩やかなMAを上向きに越えると,上向きのトレンドと購入のチャンスが示される.高速MAが緩やかなMAを下回ると,短期トレンドの終わりとポジションを閉じるチャンスが示される.

戦略の論理

  1. 異なるパラメータを持つVWAP移動平均の2つのグループを計算し,それぞれ長期的な傾向と短期的な傾向を表します.

    • スロー・テンカンセンとキジョンセンが長期的傾向を計算する
    • ファスト・テンカンセンとキジュンセンが 短期的な傾向を計算する
  2. テンカンセンとキジュンセンの平均を ゆっくりと速く動く平均としましょう

  3. ボリンジャー帯を計算して 統合とブレイクを特定します

    • 中間線は,速いMAsと遅いMAsの平均値です.
    • 上部と下部帯は突破を検出するために使用されます
  4. 容量エネルギーを決定するためにTSVを計算する

    • 0以上のTSVは,上昇傾向のボリュームを示す.
    • TSV が EMA を上回るということは,勢いが強まることを示しています.
  5. RSI を計算し,過剰購入と過剰販売の条件を特定する

    • RSIが30未満なら,買い物のために過剰販売区域です.
    • RSIが70を超えると,売り場が過剰に買いすぎます.
  6. 入国条件:

    • 速度のMAが遅さのMAを横切る
    • 上部ボリンジャー帯の横断を閉じる
    • TSVは0以上で EMAは0以上
    • RSI 30以下
  7. 出口条件:

    • 速度のMAは,ゆっくりしたMAを下回る
    • RSI 70以上

利点分析

  1. 二重移動平均系は,長期および短期間のトレンドの両方を把握する

  2. RSIは過買い区分を買ったり過売り区分を売ったりしない

  3. TSVは,トレンドを支える十分な量を確保する

  4. ボリンジャー・バンドは主要なブレイクポイントを特定します

  5. インディケーターの組み合わせは,偽のブレイクをフィルタリングするのに役立ちます

リスク分析

  1. 誤った信号に敏感なMAシステム,他の指標でフィルタリングする必要がある

  2. RSI パラメータは最適化が必要で,そうでなければ買い/売点を見逃す可能性があります.

  3. TSVもパラメータに敏感で 慎重に検査する必要があります

  4. BB上部バンドを壊すのは,偽の突破かもしれない,検証が必要です

  5. 多くの指標を最適化するのは困難で,過剰なフィットメントのリスクがあります

  6. 列車/試験データが不十分である場合,曲線の固定が起こる

オプティマイゼーションの方向性

  1. 最適なパラメータ組み合わせを見つけるためにより多くの期間をテストする

  2. MACD,KDなどの他の指標をRSIと置き換えたり組み合わせたりしてください.

  3. パラメータ最適化のためにウォーク・フォワード分析を使用する

  4. 単一の取引損失を制御するためにストップロスを追加する

  5. 信号予測を助ける機械学習モデルを検討する

  6. 異なる市場のためのパラメータを調整し,単一のパラメータセットに過剰に適合しないでください

結論

この戦略は,二重移動平均値を使用して,長期および短期間のトレンドを捕捉し,RSI,TSV,ボリンジャーバンドなどでシグナルをフィルタリングする.利点は長期上向きのモメンタムに沿って取引することです.しかし,リスクを減らすためにさらなるパラメータ調整とストップ損失を必要とする偽信号リスクも伴います.全体として,トレンドフォローと平均逆転を組み合わせることで,長期上向きのトレンドで良い結果が得られますが,パラメータは異なる市場のために調整する必要があります.


/*backtest
start: 2022-10-23 00:00:00
end: 2023-10-29 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// @version=4

// Credits

// "Vwap with period" code which used in this strategy to calculate the leadLine was written by "neolao" active on https://tr.tradingview.com/u/neolao/
// "TSV" code which used in this strategy was written by "liw0" active on https://www.tradingview.com/u/liw0. The code is corrected by "vitelot" December 2018.
// "Vidya" code which used in this strategy was written by "everget" active on https://tr.tradingview.com/u/everget/

strategy("HYE Combo Market [Strategy] (Vwap Mean Reversion + Trend Hunter)", overlay = true, initial_capital = 1000, default_qty_value = 100, default_qty_type = strategy.percent_of_equity, commission_value = 0.025)
  
//Strategy inputs

source = input(title = "Source", defval = close, group = "Mean Reversion Strategy Inputs")
smallcumulativePeriod = input(title = "Small VWAP", defval = 8, group = "Mean Reversion Strategy Inputs")
bigcumulativePeriod = input(title = "Big VWAP", defval = 10, group = "Mean Reversion Strategy Inputs")
meancumulativePeriod = input(title = "Mean VWAP", defval = 50, group = "Mean Reversion Strategy Inputs")
percentBelowToBuy = input(title = "Percent below to buy %", defval = 2, group = "Mean Reversion Strategy Inputs")
rsiPeriod = input(title = "Rsi Period", defval = 2, group = "Mean Reversion Strategy Inputs")
rsiEmaPeriod = input(title = "Rsi Ema Period", defval = 5, group = "Mean Reversion Strategy Inputs") 
rsiLevelforBuy = input(title = "Maximum Rsi Level for Buy", defval = 30, group = "Mean Reversion Strategy Inputs")
slowtenkansenPeriod = input(9, minval=1, title="Slow Tenkan Sen VWAP Line Length", group = "Trend Hunter Strategy Inputs")
slowkijunsenPeriod = input(13, minval=1, title="Slow Kijun Sen VWAP Line Length", group = "Trend Hunter Strategy Inputs")
fasttenkansenPeriod = input(3, minval=1, title="Fast Tenkan Sen VWAP Line Length", group = "Trend Hunter Strategy Inputs")
fastkijunsenPeriod = input(7, minval=1, title="Fast Kijun Sen VWAP Line Length", group = "Trend Hunter Strategy Inputs")
BBlength = input(20, minval=1, title= "Bollinger Band Length", group = "Trend Hunter Strategy Inputs")
BBmult = input(2.0, minval=0.001, maxval=50, title="Bollinger Band StdDev", group = "Trend Hunter Strategy Inputs")
tsvlength  = input(20, minval=1, title="TSV Length", group = "Trend Hunter Strategy Inputs")
tsvemaperiod = input(7, minval=1, title="TSV Ema Length", group = "Trend Hunter Strategy Inputs")
length = input(title="Vidya Length", type=input.integer, defval=20, group = "Trend Hunter Strategy Inputs") 
src = input(title="Vidya Source", type=input.source, defval= hl2 , group = "Trend Hunter Strategy Inputs")

// Vidya Calculation 

getCMO(src, length) =>
    mom = change(src)
    upSum = sum(max(mom, 0), length)
    downSum = sum(-min(mom, 0), length)
    out = (upSum - downSum) / (upSum + downSum)
    out

cmo = abs(getCMO(src, length))

alpha = 2 / (length + 1)

vidya = 0.0
vidya := src * alpha * cmo + nz(vidya[1]) * (1 - alpha * cmo)

// Make input options that configure backtest date range 

startDate = input(title="Start Date", type=input.integer,
     defval=1, minval=1, maxval=31, group = "Strategy Date Range")
startMonth = input(title="Start Month", type=input.integer,
     defval=1, minval=1, maxval=12, group = "Strategy Date Range")
startYear = input(title="Start Year", type=input.integer,
     defval=2000, minval=1800, maxval=2100, group = "Strategy Date Range")

endDate = input(title="End Date", type=input.integer, 
     defval=31, minval=1, maxval=31, group = "Strategy Date Range")
endMonth = input(title="End Month", type=input.integer,
     defval=12, minval=1, maxval=12, group = "Strategy Date Range") 
endYear = input(title="End Year", type=input.integer,
     defval=2021, minval=1800, maxval=2100, group = "Strategy Date Range")
     
inDateRange = true
// Mean Reversion Strategy Calculation 

typicalPriceS = (high + low + close) / 3
typicalPriceVolumeS = typicalPriceS * volume
cumulativeTypicalPriceVolumeS = sum(typicalPriceVolumeS, smallcumulativePeriod)
cumulativeVolumeS = sum(volume, smallcumulativePeriod)
smallvwapValue = cumulativeTypicalPriceVolumeS / cumulativeVolumeS

typicalPriceB = (high + low + close) / 3
typicalPriceVolumeB = typicalPriceB * volume
cumulativeTypicalPriceVolumeB = sum(typicalPriceVolumeB, bigcumulativePeriod)
cumulativeVolumeB = sum(volume, bigcumulativePeriod)
bigvwapValue = cumulativeTypicalPriceVolumeB / cumulativeVolumeB 

typicalPriceM = (high + low + close) / 3
typicalPriceVolumeM = typicalPriceM * volume
cumulativeTypicalPriceVolumeM = sum(typicalPriceVolumeM, meancumulativePeriod)
cumulativeVolumeM = sum(volume, meancumulativePeriod)
meanvwapValue = cumulativeTypicalPriceVolumeM / cumulativeVolumeM

rsiValue = rsi(source, rsiPeriod)
rsiEMA   = ema(rsiValue, rsiEmaPeriod)
buyMA = ((100 - percentBelowToBuy) / 100) * bigvwapValue[0]

inTrade = strategy.position_size > 0
notInTrade = strategy.position_size <= 0

if(crossunder(smallvwapValue, buyMA) and rsiEMA < rsiLevelforBuy and close < meanvwapValue and inDateRange and notInTrade)
    strategy.entry("BUY-M", strategy.long)

if(close > meanvwapValue or not inDateRange)
    strategy.close("BUY-M")
    
// Trend Hunter Strategy Calculation

// Slow Tenkan Sen Calculation

typicalPriceTS = (high + low + close) / 3
typicalPriceVolumeTS = typicalPriceTS * volume
cumulativeTypicalPriceVolumeTS = sum(typicalPriceVolumeTS, slowtenkansenPeriod)
cumulativeVolumeTS = sum(volume, slowtenkansenPeriod)
slowtenkansenvwapValue = cumulativeTypicalPriceVolumeTS / cumulativeVolumeTS

// Slow Kijun Sen Calculation

typicalPriceKS = (high + low + close) / 3
typicalPriceVolumeKS = typicalPriceKS * volume
cumulativeTypicalPriceVolumeKS = sum(typicalPriceVolumeKS, slowkijunsenPeriod)
cumulativeVolumeKS = sum(volume, slowkijunsenPeriod)
slowkijunsenvwapValue = cumulativeTypicalPriceVolumeKS / cumulativeVolumeKS

// Fast Tenkan Sen Calculation

typicalPriceTF = (high + low + close) / 3
typicalPriceVolumeTF = typicalPriceTF * volume
cumulativeTypicalPriceVolumeTF = sum(typicalPriceVolumeTF, fasttenkansenPeriod)
cumulativeVolumeTF = sum(volume, fasttenkansenPeriod)
fasttenkansenvwapValue = cumulativeTypicalPriceVolumeTF / cumulativeVolumeTF

// Fast Kijun Sen Calculation

typicalPriceKF = (high + low + close) / 3
typicalPriceVolumeKF = typicalPriceKS * volume
cumulativeTypicalPriceVolumeKF = sum(typicalPriceVolumeKF, fastkijunsenPeriod)
cumulativeVolumeKF = sum(volume, fastkijunsenPeriod)
fastkijunsenvwapValue = cumulativeTypicalPriceVolumeKF / cumulativeVolumeKF

// Slow LeadLine Calculation
 
lowesttenkansen_s = lowest(slowtenkansenvwapValue, slowtenkansenPeriod)
highesttenkansen_s = highest(slowtenkansenvwapValue, slowtenkansenPeriod)

lowestkijunsen_s = lowest(slowkijunsenvwapValue, slowkijunsenPeriod)
highestkijunsen_s = highest(slowkijunsenvwapValue, slowkijunsenPeriod)

slowtenkansen = avg(lowesttenkansen_s, highesttenkansen_s)
slowkijunsen = avg(lowestkijunsen_s, highestkijunsen_s)
slowleadLine = avg(slowtenkansen, slowkijunsen)

// Fast LeadLine Calculation 
 
lowesttenkansen_f = lowest(fasttenkansenvwapValue, fasttenkansenPeriod)
highesttenkansen_f = highest(fasttenkansenvwapValue, fasttenkansenPeriod)

lowestkijunsen_f = lowest(fastkijunsenvwapValue, fastkijunsenPeriod)
highestkijunsen_f = highest(fastkijunsenvwapValue, fastkijunsenPeriod) 

fasttenkansen = avg(lowesttenkansen_f, highesttenkansen_f)
fastkijunsen = avg(lowestkijunsen_f, highestkijunsen_f)
fastleadLine = avg(fasttenkansen, fastkijunsen)

// BBleadLine Calculation
 
BBleadLine = avg(fastleadLine, slowleadLine)

// Bollinger Band Calculation
 
basis = sma(BBleadLine, BBlength)
dev = BBmult * stdev(BBleadLine, BBlength)
upper = basis + dev  
lower = basis - dev 

// TSV Calculation

tsv = sum(close>close[1]?volume*(close-close[1]):close<close[1]?volume*(close-close[1]):0,tsvlength)
tsvema = ema(tsv, tsvemaperiod)

// Rules for Entry & Exit  

if(fastleadLine > fastleadLine[1] and slowleadLine > slowleadLine[1] and tsv > 0 and tsv > tsvema and close > upper and close > vidya and inDateRange and notInTrade)
    strategy.entry("BUY-T", strategy.long)
 
if((fastleadLine < fastleadLine[1] and slowleadLine < slowleadLine[1]) or not inDateRange)
    strategy.close("BUY-T")

// Plots 

plot(meanvwapValue, title="MEAN VWAP", linewidth=2, color=color.yellow)

//plot(vidya, title="VIDYA", linewidth=2, color=color.green)

//colorsettingS = input(title="Solid Color Slow Leadline", defval=false, type=input.bool)
//plot(slowleadLine, title = "Slow LeadLine", color = colorsettingS ? color.aqua : slowleadLine > slowleadLine[1] ? color.green : color.red, linewidth=3)

//colorsettingF = input(title="Solid Color Fast Leadline", defval=false, type=input.bool)
//plot(fastleadLine, title = "Fast LeadLine", color = colorsettingF ? color.orange : fastleadLine > fastleadLine[1] ? color.green : color.red, linewidth=3)

//p1 = plot(upper, "Upper BB", color=#2962FF)
//p2 = plot(lower, "Lower BB", color=#2962FF)
//fill(p1, p2, title = "Background", color=color.blue)

//plot(smallvwapValue, color=#13C425, linewidth=2)
//plot(bigvwapValue, color=#CA1435, linewidth=2)


もっと