2つの移動平均逆転戦略

作者: リン・ハーンチャオチャン, 日付: 2023-12-25 13:24:14
タグ:

img

概要

ダブル・ムービング・平均逆転戦略 (Dual Moving Average Reversal Strategy) は,短期的および長期的トレンドを特定するためにダブル・ムービング・平均を使用する定量的な取引戦略である.この戦略は,10日間のシンプル・ムービング・平均値 (SMA) と200日間の SMAを組み合わせて,長期的上昇傾向内の短期的な引き下げをキャピタライズする.また,トレンドフォローおよびリスク管理メカニズムも備えている.

戦略の論理

二重移動平均逆転戦略は,以下の仮定に基づいています.

  1. 200日SMAは,市場の長期トレンドを特定します.価格が200日線を超えると,市場は長期上昇傾向にあることを示します.

  2. 10日間のSMAは,価格の短期的な引き下げを特定します.価格が10日間の線を下回ると,一時的な引き下げが起きたことを示します.

  3. 進行中の牛市上昇傾向において 短期的な引き下げは 上昇傾向を効果的に捉えるための 購入機会と見なすことができます

上記の仮定に基づいて,取引シグナルは次のように生成されます.

  1. 閉じる価格が200日SMAを上回り,10日SMAを下回ると,長期トレンドがポジティブのままだが短期的な引き下がりが起きたことを示しているので,買い信号が発信されます.

  2. ロングポジションの価格が10日SMAを上回る場合は,短期トレンドが逆転したため,ポジションは直ちに閉鎖されます.また,ストップ・ロスの違反につながる市場が大幅に下落した場合,ポジションは閉鎖されます.

  3. 大きく下落する (前もって定義された値を超えた) 時は,反発信号として下落を購う機会を提示します.

この設計により,戦略は持続的な上昇傾向の際に上昇したスナップバックを効率的に資本化することを目指し,ストップ損失を使用してリスクを制御します.

利点

二重移動平均の逆転戦略には以下の主要な利点があります.

  1. 戦略の論理は単純で分かりやすいです
  2. 移動平均の2つのフィルターは,短期と長期のトレンドを効果的に識別します.
  3. 短期的な逆転から利益を得ることで 良い時間効率を提供します
  4. ストップ・ロスのメカニズムは 個々のポジションのリスクを厳格に制御します
  5. 柔軟なパラメータ化により,この戦略はインデックスや株式に広く適用可能になります.

リスク

一般的に効果的ですが,この戦略には以下のような制限があります.

  1. 市場が範囲に限定されている場合,ウィップソーや誤った信号が発生する可能性があります. 戦略は延長 konsolidiation 時に無効にする必要があります.
  2. 移動平均値のみに頼ることは,信号の精度に制限がある.より多くの指標がパフォーマンスを向上させる可能性がある.
  3. 固定ストップロスの方法論は柔軟性がない.他のストップロスのテクニックはテストできる.
  4. 適正なパラメータは,異なる市場のために校正する必要があります. 適正でない設定は信頼性を低下させます.

増進 の 機会

この戦略のさらなる改善には,以下が含まれます.

  1. 適正な組み合わせを見つけるために他の移動平均長さをテストします
  2. より信頼性の高いシグナルを生成するために,サポート指標を追加します.例えば,ボリューム,変動指標.
  3. ストップ・ロスの追跡や タイムベースストップ・ロスのような ストップ・ロスの他のテクニックを探っています
  4. 市場ダイナミクスの変化に適応できるように,エントリールールとストップロスのパラメータに適応能力を構築する.
  5. 機械学習アルゴリズムを組み込み より多くの歴史的データを活用して パラメータをさらに最適化します

結論

概要すると,ダブル・ムービング・平均逆転戦略は,非常に実践的なアプローチである.ストップ損失と組み合わせた移動平均分析を使用して,持続的な上昇傾向中に収益性の高いプルバックが消えるようにする.また,市場体制検出機能とリスク制御も提供する.継続的な改善により,戦略は差別化されたパフォーマンスを提供する強力な可能性を提示する.


/*backtest
start: 2023-11-24 00:00:00
end: 2023-12-24 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Gold_D_Roger
//note: spreading 1 statement over multiple lines needs 1 apce + 1 tab | multi line function is 1 tab
//Recommended tickers: SPY (D), QQQ (D) and big indexes, AAPL (4H)

//@version=5
strategy("Davin's 10/200MA Pullback on SPY Strategy v2.0",
     overlay=true,
     initial_capital=10000,
     default_qty_type=strategy.percent_of_equity,
     default_qty_value=10, // 10% of equity on each trade
     commission_type=strategy.commission.cash_per_contract, 
     commission_value=0.1) //Insert your broker's rate, IB is 0.005USD or tiered

//Best parameters
// SPY D
// Stop loss 0.15
// commission of 0.005 USD using Interactive brokers
// Exit on lower close 
// Buy more when x% down --> 14%
// DO NOT include stop condition using MA crossover

// Get User Input
i_ma1           = input.int(title="MA Length 1", defval=200, step=10, group="Strategy Parameters", tooltip="Long-term MA 200")
i_ma2           = input.int(title="MA Length 2", defval=10, step=10, group="Strategy Parameters", tooltip="Short-term MA 10")
i_ma3           = input.int(title="MA Length 3", defval=50, step=1, group="Strategy Parameters", tooltip="MA for crossover signals`")
i_stopPercent   = input.float(title="Stop Loss Percent", defval=0.15, step=0.01, group="Strategy Parameters", tooltip="Hard stop loss of 10%")
i_startTime     = input(title="Start filter", defval=timestamp("01 Jan 2013 13:30 +0000"), group="Time filter", tooltip="Start date and time to begin")
i_endTime       = input(title="End filter", defval=timestamp("01 Jan 2099 19:30 +0000"), group="Time filter", tooltip="End date and time to stop")
i_lowerClose    = input.bool(title="Exit on lower close", defval=true, group="Strategy Parameters", tooltip="Wait for lower close after above 10SMA before exiting") // optimise exit strat, boolean type creates tickbox type inputs
i_contrarianBuyTheDip = input.bool(title="Buy whenever more than x% drawdown", defval=true, group="Strategy Parameters", tooltip="Buy the dip! Whenever x% or more drawdown on SPY")
i_contrarianTrigger = input.int(title="Trigger % drop to buy the dip", defval=14, step=1, group="Strategy Parameters", tooltip="% drop to trigger contrarian Buy the Dip!") 
//14% to be best for SPY 1D
//20% best for AMZN 1D
i_stopByCrossover_MA2_3 = input.bool(title="Include stop condition using MA crossover", defval=false, group="Strategy Parameters", tooltip="Sell when crossover of MA2/1 happens")

// Get indicator values
ma1 = ta.sma(close,i_ma1) //param 1
ma2 = ta.sma(close,i_ma2) //param 2
ma3 = ta.sma(close,i_ma3) //param 3
ma_9 = ta.ema(close,9) //param 2
ma_20 = ta.ema(close,20) //param 3

// Check filter(s)
f_dateFilter = true //make sure date entries are within acceptable range

// Highest price of the prev 52 days: https://www.tradingcode.net/tradingview/largest-maximum-value/#:~:text=()%20versus%20ta.-,highest(),max()%20and%20ta.
highest52 = ta.highest(high,52)
overall_change = ((highest52 - close[0]) / highest52) * 100

// Check buy/sell conditions
var float buyPrice = 0 //intialise buyPrice, this will change when we enter a trade ; float = decimal number data type 0.0
buyCondition  = (close > ma1 and close < ma2 and strategy.position_size == 0 and f_dateFilter) or (strategy.position_size == 0 and i_contrarianBuyTheDip==true and overall_change > i_contrarianTrigger and f_dateFilter) // higher than 200sma, lower than short term ma (pullback) + avoid pyramiding positions
sellCondition = close > ma2 and strategy.position_size > 0 and (not i_lowerClose or close < low[1])  //check if we already in trade + close above 10MA; 
// third condition: EITHER i_lowerClose not turned on OR closing price has to be < previous candle's LOW [1]

stopDistance  = strategy.position_size > 0 ? ((buyPrice - close)/close) : na // check if in trade > calc % drop dist from entry, if not na
stopPrice     = strategy.position_size > 0 ? (buyPrice - (buyPrice * i_stopPercent)) : na // calc SL price if in trade, if not, na
stopCondition = (strategy.position_size > 0 and stopDistance > i_stopPercent) or (strategy.position_size > 0 and (i_stopByCrossover_MA2_3==true and ma3 < ma1))


// Enter positions
if buyCondition 
    strategy.entry(id="Long", direction=strategy.long) //long only

    
if buyCondition[1] // if buyCondition is true prev candle
    buyPrice := open // entry price = current bar opening price

// Exit position
if sellCondition or stopCondition 
    strategy.close(id="Long", comment = "Exit" + (stopCondition ? "Stop loss=true" : "")) // if condition? "Value for true" : "value for false"
    buyPrice := na //reset buyPrice

// Plot
plot(buyPrice, color=color.lime, style=plot.style_linebr)
plot(stopPrice, color=color.red, style=plot.style_linebr, offset = -1)
plot(ma1, color=color.blue) //defval=200
plot(ma2, color=color.white) //defval=10
plot(ma3, color=color.yellow) // defval=50






もっと