ダブルインクルージョンとトレンド戦略


作成日: 2024-01-30 15:11:48 最終変更日: 2024-01-30 15:11:48
コピー: 1 クリック数: 705
1
フォロー
1617
フォロワー

ダブルインクルージョンとトレンド戦略

概要

双内含とトレンド戦略は,双内含形態と移動平均を用いてトレンドを判断する量化取引戦略である.この戦略は,双内含形態を組み合わせて,高い確率の取引信号を提供し,同時に移動平均を用いて市場トレンドを判断し,トレンドの方向に空白を多めに行う.

戦略原則

  1. Hull移動平均をトレンドの判断指標として計算する.
  2. 二次含有形が現れたとき,これはより高い確率の取引信号であると考えます.含有形は前2つのK線の最高値であり,最低価格も第3のK線に含まれている形です.
  3. 収束価格が移動平均線上から多頭内含形成された場合,内含形状高点の近くで買取停止令状を設定する.収束価格が移動平均線の下から空頭内含形成された場合,内含形状低点の近くで売出停止令状を設定する.
  4. 停止券がトリガーされた後,預定の止損幅と停止比率に応じて止損と停止券を設定します.

優位分析

  1. 含有形は,より高い確率で反転シグナルを提供する. 二重含有形の出現は,短期間の価格反転を予兆する可能性がある.
  2. 移動平均と組み合わせると,大きなトレンドの方向に操作し,利益の確率を高めます.
  3. トレンド期間中に突破点の近くでストップ単体倉庫を建設することで,より良い入場時間を獲得できます.

リスク分析

  1. 震動の状況では,内在形態で提供される取引信号は,しばしば損失が発生する可能性があります.
  2. 移動平均はトレンドを判断する指標として誤った信号を発し,逆行取引の損失を引き起こす可能性があります.
  3. ストップポイントの設定が小さすぎると,価格の小さな滑落によってストップが引き起こす可能性があります.

最適化の方向

  1. 異なるパラメータの移動平均をトレンド判断の指標としてテストできます.
  2. 他の指標と組み合わせて,波動をフィルタリングすることで,明確なトレンドがない場合の盲目取引を回避できます.
  3. 移動平均周期,ストップダスト倍数,ストップストップ比率などのパラメータのより優れた組み合わせをビッグデータ分析で得ることができる.
  4. 取引時間と品種のフィルタリング条件を追加して,異なる時間周期と異なる品種の特性を適合させることができます.

要約する

双内含とトレンド戦略は,双内含形態を利用して高い確率の取引信号を提供し,移動平均が大きなトレンドの方向を判断するのに補助し,トレンドの方向で空白を多く行う,比較的安定した突破型の戦略である.パラメータ最適化とルール最適化により,この戦略は,市場への適応性が向上し,高い確率の利益を得ることができる.

ストラテジーソースコード
/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
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/
// © Kaspricci

//@version=5
strategy(
     title = "Double Inside Bar & Trend Strategy - Kaspricci", 
     shorttitle = "Double Inside Bar & Trend", 
     overlay=true, 
     initial_capital = 100000, 
     currency = currency.USD, 
     default_qty_type = strategy.percent_of_equity, 
     default_qty_value = 100, 
     calc_on_every_tick = true, 
     close_entries_rule = "ANY")

// ================================================ Entry Inputs ======================================================================
headlineEntry   = "Entry Seettings"

maSource        = input.source(defval = close,             group = headlineEntry, title = "MA Source")
maType          = input.string(defval = "HMA",             group = headlineEntry, title = "MA Type", options = ["EMA", "HMA", "SMA", "SWMA", "VWMA", "WMA"])
maLength        = input.int(   defval = 45,    minval = 1, group = headlineEntry, title = "HMA Length")

float ma = switch maType 
    "EMA"  => ta.ema(maSource,  maLength)
    "HMA"  => ta.hma(maSource,  maLength)
    "SMA"  => ta.sma(maSource,  maLength)
    "SWMA" => ta.swma(maSource)
    "VWMA" => ta.vwma(maSource, maLength)
    "WMA"  => ta.wma(maSource,  maLength)

plot(ma, "Trend MA", color.purple)

// ================================================ Trade Inputs ======================================================================
headlineTrade   = "Trade Seettings"

stopLossType    = input.string(defval = "ATR",                         group = headlineTrade,                 title = "Stop Loss Type",            options = ["ATR", "FIX"])
atrLength       = input.int(   defval = 50,   minval = 1,              group = headlineTrade, inline = "ATR", title = "   ATR: Length                 ")
atrFactor       = input.float( defval =  2.5, minval = 0, step = 0.05, group = headlineTrade, inline = "ATR", title = "Factor       ",             tooltip = "multiplier for ATR value")
takeProfitRatio = input.float( defval =  2.0, minval = 0, step = 0.05, group = headlineTrade,                 title = "            TP Ration",     tooltip = "Multiplier for Take Profit calculation")
fixStopLoss     = input.float( defval = 10.0, minval = 0, step = 0.5,  group = headlineTrade, inline = "FIX", title = "   FIX: Stop Loss             ") * 10 // need this in ticks
fixTakeProfit   = input.float( defval = 20.0, minval = 0, step = 0.5,  group = headlineTrade, inline = "FIX", title = "Take Profit",               tooltip = "in pips") * 10 // need this in ticks
useRiskMagmt    = input.bool(  defval = true,                          group = headlineTrade, inline = "RM",  title = "")
riskPercent     = input.float( defval = 1.0,  minval = 0., step = 0.5, group = headlineTrade, inline = "RM",  title = "Risk in %                ", tooltip = "This will overwrite quantity from startegy settings and calculate the trade size based on stop loss and risk percent") / 100

// ================================================ Filter Inputs =====================================================================
headlineFilter  = "Filter Setings"

// date filter
filterDates     = input.bool(defval = false,                                 group = headlineFilter, title = "Filter trades by dates")
startDateTime   = input(defval = timestamp("2022-01-01T00:00:00+0000"), group = headlineFilter, title = "       Start Date & Time")
endDateTime     = input(defval = timestamp("2099-12-31T23:59:00+0000"), group = headlineFilter, title = "       End Date & Time  ")

dateFilter      = not filterDates or (time >= startDateTime and time <= endDateTime)

// session filter
filterSession   = input.bool(title = "Filter trades by session", defval = false, group = headlineFilter)
session         = input(title = "       Session", defval = "0045-2245", group = headlineFilter)

sessionFilter   = not filterSession or time(timeframe.period, session, timezone = "CET")

// ================================================ Trade Entries and Exits =====================================================================

// calculate stop loss
stopLoss        = switch stopLossType
    "ATR" => nz(math.round(ta.atr(atrLength) * atrFactor / syminfo.mintick, 0), 0)
    "FIX" => fixStopLoss

// calculate take profit
takeProfit      = switch stopLossType
    "ATR" => math.round(stopLoss * takeProfitRatio, 0)
    "FIX" => fixTakeProfit


doubleInsideBar = high[2] > high[1] and high[2] > high[0] and low[2] < low[1] and low[2] < low[0]

// highlight mother candel and inside bar candles
bgcolor(doubleInsideBar ? color.rgb(33, 149, 243, 80) : na)
bgcolor(doubleInsideBar ? color.rgb(33, 149, 243, 80) : na, offset = -1)
bgcolor(doubleInsideBar ? color.rgb(33, 149, 243, 80) : na, offset = -2)

var float buyStopPrice  = na
var float sellStopPrice = na

if (strategy.opentrades == 0 and doubleInsideBar and barstate.isconfirmed)
    buyStopPrice  := high[0] // high of recent candle (second inside bar)
    sellStopPrice := low[0] // low of recent candle (second inside bar)

    tradeID = str.tostring(strategy.closedtrades + strategy.opentrades + 1)

    quantity = useRiskMagmt ? math.round(strategy.equity * riskPercent / stopLoss, 2) / syminfo.mintick : na

    commentTemplate = "{0} QTY: {1,number,#.##} SL: {2} TP: {3}"

    if (close > ma)
        longComment = str.format(commentTemplate, tradeID + "L", quantity, stopLoss / 10, takeProfit / 10)
        strategy.entry(tradeID + "L", strategy.long, qty = quantity, stop = buyStopPrice, comment = longComment)
        strategy.exit(tradeID + "SL", tradeID + "L", profit = takeProfit, loss = stopLoss, comment_loss = "SL", comment_profit = "TP")

    if (close < ma)
        shortComment = str.format(commentTemplate, tradeID + "S", quantity, stopLoss / 10, takeProfit / 10)
        strategy.entry(tradeID + "S", strategy.short, qty = quantity, stop = sellStopPrice, comment = shortComment)
        strategy.exit(tradeID + "SL", tradeID + "S", profit = takeProfit, loss = stopLoss, comment_loss = "SL", comment_profit = "TP")

// as soon as the first pending order has been entered the remaing pending order shall be cancelled 
if strategy.opentrades > 0
    currentTradeID = str.tostring(strategy.closedtrades + strategy.opentrades)
    strategy.cancel(currentTradeID + "S")
    strategy.cancel(currentTradeID + "L")