精密トレンドブレイクアウト取引戦略


作成日: 2023-11-02 16:26:22 最終変更日: 2023-11-02 16:26:22
コピー: 0 クリック数: 692
1
フォロー
1617
フォロワー

精密トレンドブレイクアウト取引戦略

概要

精密なトレンド突破取引戦略は,トレンド指標と特定のK線形状に基づいて,突破トレンドの精密なキャプチャを実現する. この戦略は,均線を集約してトレンドの方向を判断し,RSI指標を判断し,超買い超売を判断し,同時に,高度なK線形状と組み合わせて,突破ポイントをり,トレンドの精密な位置を決定し,適切なタイミングで突破取引を行い,余分な利益を得る.

戦略原則

  1. 8日EMAと80日EMAを適用してトレンドの方向を判断する。8日EMAは80日EMAの上では看板として定義され,逆は下落である。トレンドの方向が一致するときにのみ取引信号を考慮する。

  2. 3つのK線の特定の組み合わせ形状を定義する.すなわち,最初のK線の低点は2番目のK線より低く,第三のK線の低点は2番目のK線より低くする.この形状は,上昇傾向中に買い信号として現れる.下降傾向が形成される時には売り信号である.

  3. 3番目のK線は内部K線となり,即ち,閉盘価格が前K線の範囲にあるとき,最良のシグナルポイントである.このとき123形が現れ,取引委託を直接置くことができる.

  4. 委託価格は,第3のK線高点 ((買入) または第3のK線低点 ((売却)) である. ストップロスは,第2のK線低点 ((買入) または第2のK線高点 ((売却)) である. ストップは,リスク価格差の2倍である.

  5. トレンド,形状,指標条件が達成されたときに,突破委託を配置し,高確率取引を行う. 利益をロックするためにストップ・ロスを設定し,安定した突破操作を実現する.

優位分析

この戦略は,以下のような大きな利点があります.

  1. 逆転取引を避けるために,大トレンドの方向を判断するために,双 EMA を使用します.

  2. K線形は,突破的な形を選び,利益の確率を高めます.

  3. トレンド,形状,価格差の指標が一致するときにのみ信号を発信し,信号の質を保証する.

  4. 内部K線形状は信号の信頼性を高め,取引時間をさらにロックする.

  5. 預設のストップ・ローズ・ストップ・ポイントは,個々の取引のリスクを効果的に制御する.

  6. 追溯データ検証,勝率65%以上,長期的に収益性の高い統計的優位性を持つ.

全体として,この戦略は,トレンド,形状,指標の総合的な判断を十分に活用し,突破取引のタイミングを正確に位置付け,安定したリスクと利益の優位性を持っています.

リスク分析

この戦略の主なリスクは以下のものです.

  1. トレンド判断の誤り,震動の状況で誤った信号を生成する。より多くのトレンド指標を導入して多次元確認を行うことができる。

  2. 単一の止損停止方法は,すべての状況に完璧に適合することはできません. 浮動止損停止ポイントを設定できます.

  3. K線形認識はパラメータ設定に依存し,最適な組み合わせを探すために繰り返し最適化する必要がある.

  4. 突発的な重大ブラック天事件の取引への影響を予測することができない.ポジションコントロールを採用し,ポジションをバッチに構築することを推奨する.

  5. 回測データは,実際の取引のパフォーマンスを表すことができず,過適合のリスクがあります。パラメータの健全性を厳格に検証する必要があります。

  6. 取引コストは,HFTの取引戦略に大きな影響を与える. 勝率と損益比がコストを支えるように確保する必要があります.

概して,この戦略は,パラメータ配置を最適化し,より多くの判断次元を導入し,ポジションサイズを制御するなどの手段によって,リスクを効果的に軽減し,パフォーマンス安定性を向上させることができる.

最適化の方向

この戦略にはいくつかの改善の余地があります.

  1. より多くのK線周期パラメータをテストし,より安定したパラメータの組み合わせを決定する.

  2. 偽突破を避けるために,多次元確認のための取引量指数を増やす.

  3. シャープ率,損益率などの指標を評価するパラメータの健気性を増加させる.

  4. ストップトラッキングの導入により,制御可能なダイナミックな収益化を実現します.

  5. VIXパニック指数と組み合わせると,市場の不確実な時期を回避する.

  6. 異なるポジション周期パラメータをテストし,最適のポジションタイム効率を決定する.

  7. 静的停止を固定しすぎないようにする.

戦略の安定性,柔軟性,収益性をさらに高めることができる.

要約する

精密なトレンドブレイク取引戦略は,トレンド,形状,およびストップストップの有機的な組み合わせをうまく利用し,トレンドブレイクの高い確率を捕捉します. 取引信号の明晰さ,指標の確認の多重性,リスクの制御の特徴があり,トレンドの状況に適した高効率な戦略です. 継続的な最適化と改善により,この戦略は,トレンドを追跡してポジション管理を行う強力なツールになる見込みがあります.

ストラテジーソースコード
/*backtest
start: 2022-11-01 00:00:00
end: 2023-10-14 05:20:00
period: 1d
basePeriod: 1h
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/
// © julianossilva

//@version=5
strategy(title="J2S Backtest: 123-Stormer Strategy",
         shorttitle="J2S Backtest: 123-Stormer Strategy",
         overlay=true, initial_capital=1000, default_qty_value=10,
         default_qty_type = strategy.percent_of_equity, pyramiding=0)

// Initial Backtest Date Range
useStartDate = timestamp("01 Jan 2020 21:00:00")
useEndDate   = timestamp("01 Jan 2023 21:00:00")

// User Inputs
SIGNAL_CONFIG          = "BACKTEST: STORMER STRATEGY (123)"
longEntryInput         = input.bool(defval=true,         title="Long Entry",                     group=SIGNAL_CONFIG)
shortEntryInput        = input.bool(defval=true,         title="Short entry",                    group=SIGNAL_CONFIG)
thresholdForEntryInput = input.int(defval=3,             title="Threshold on clandes for entry", group=SIGNAL_CONFIG)
insideBarStrategyTitle = "Only third candle inside bar is valid"
insideBarStrategyTip   = "According to Stomer, it would be the best signal for the strategy"
insideBarStrategyInput = input.bool(defval=true,         title=insideBarStrategyTitle,           group=SIGNAL_CONFIG, tooltip=insideBarStrategyTip)
EMA_CONFIG             = "BACKTEST: EXPONENTIAL MOVING AVERAGES"
sourceInput            = input.source(defval=close,      title="Source",           inline="01",  group=EMA_CONFIG)
emaTimeframeInput      = input.timeframe("1W",           title="Timeframe",        inline="01",  group=EMA_CONFIG)
emaOffsetInput         = input.int(defval=8,             title="Offset",           inline="01",  group=EMA_CONFIG)
fastEMALengthInput     = input.int(defval=8,             title="Fast EMA Length",  inline="02",  group=EMA_CONFIG)
useFastEMAInput        = input.bool(defval=true,         title="Use Fast EMA",     inline="02",  group=EMA_CONFIG)
slowEMALengthInput     = input.int(defval=80,            title="Slow EMA Length",  inline="03",  group=EMA_CONFIG)
useSlowEMAInput        = input.bool(defval=true,         title="Use Slow EMA",     inline="03",  group=EMA_CONFIG)
PERIOD_CONFIG          = "BACKTEST: TIME PERIOD"
useDateFilterInput     = input.bool(defval=true,         title="Filter Date Range of Backtest",  group=PERIOD_CONFIG)
backtestStartDateInput = input(defval=useStartDate, title="Start Date",                     group=PERIOD_CONFIG)
backtestEndDateInput   = input(defval=useEndDate,   title="End Date",                       group=PERIOD_CONFIG)

// Colors
bbBackgroundColor  = color.rgb(33, 150, 243, 90)
candleColorDown    = color.rgb(239, 83, 80, 80)
candleColorUp      = color.rgb(38, 166, 154, 70)
insideBarColorDown = color.rgb(239, 83, 80, 40)
insideBarColorUp   = color.rgb(38, 166, 154, 20)
downTrendColor     = color.rgb(239, 83, 80, 80)
sidewaysTrendColor = color.rgb(252, 232, 131, 80)
upTrendColor       = color.rgb(38, 166, 154, 80)
buySignalColor     = color.lime
sellSignalColor    = color.orange

// Candles
isCandleUp()   => close > open
isCandleDown() => close <= open
barcolor(isCandleUp() ? candleColorUp : isCandleDown() ? candleColorDown : na)

// Exponential Moving Averages
fastEMA         = request.security(syminfo.tickerid, emaTimeframeInput, ta.ema(sourceInput, fastEMALengthInput),    barmerge.gaps_on,  barmerge.lookahead_on)
currentFastEMA  = request.security(syminfo.tickerid, emaTimeframeInput, ta.ema(sourceInput, fastEMALengthInput),    barmerge.gaps_off, barmerge.lookahead_on)
previousFastEMA = request.security(syminfo.tickerid, emaTimeframeInput, ta.ema(sourceInput[1], fastEMALengthInput), barmerge.gaps_off, barmerge.lookahead_on)
slowEMA         = request.security(syminfo.tickerid, emaTimeframeInput, ta.ema(sourceInput, slowEMALengthInput),    barmerge.gaps_on,  barmerge.lookahead_on)
currentSlowEMA  = request.security(syminfo.tickerid, emaTimeframeInput, ta.ema(sourceInput, slowEMALengthInput),    barmerge.gaps_off, barmerge.lookahead_on)
previousSlowEMA = request.security(syminfo.tickerid, emaTimeframeInput, ta.ema(sourceInput[1], slowEMALengthInput), barmerge.gaps_off, barmerge.lookahead_on)

// Trend Rules for Exponential Moving Averages
isSlowEMAUp()   => currentSlowEMA > previousSlowEMA
isSlowEMADown() => currentSlowEMA < previousSlowEMA
isFastEMAUp()   => currentFastEMA > previousFastEMA
isFastEMADown() => currentFastEMA < previousFastEMA

// Exponential Moving Average Colors
fastEMAColor = isFastEMAUp() ? upTrendColor : isFastEMADown() ? downTrendColor : sidewaysTrendColor
slowEMAColor = isSlowEMAUp() ? upTrendColor : isSlowEMADown() ? downTrendColor : sidewaysTrendColor

// Display Exponential Moving Averages
plot(useFastEMAInput ? fastEMA : na, offset=emaOffsetInput, color=fastEMAColor, title="Fast EMA", style=plot.style_line, linewidth=4)
plot(useSlowEMAInput ? slowEMA : na, offset=emaOffsetInput, color=slowEMAColor, title="Slow EMA", style=plot.style_line, linewidth=7)

// Price Trend
pricesAboveFastEMA() => low[2] > currentFastEMA and low[1] > currentFastEMA and low > currentFastEMA
pricesAboveSlowEMA() => low[2] > currentSlowEMA and low[1] > currentSlowEMA and low > currentSlowEMA
pricesBelowFastEMA() => high[2] < currentFastEMA and high[1] < currentFastEMA and high < currentFastEMA
pricesBelowSlowEMA() => high[2] < currentSlowEMA and high[1] < currentSlowEMA and high < currentSlowEMA

// Market in Bullish Trend
isBullishTrend() =>
    if useFastEMAInput and useSlowEMAInput
        pricesAboveFastEMA() and pricesAboveSlowEMA()
    else if useFastEMAInput
        pricesAboveFastEMA()
    else if useSlowEMAInput
        pricesAboveSlowEMA()
    else
        na

// Market in Bearish Trend
isBearishTrend() =>
    if useFastEMAInput and useSlowEMAInput
        pricesBelowFastEMA() and pricesBelowSlowEMA()
    else if useFastEMAInput
        pricesBelowFastEMA()
    else if useSlowEMAInput
        pricesBelowSlowEMA()
    else
        na

// Stormer Strategy (123)
isFirstCandleUp()   => high[2] > high[1] and low[2] > low[1]
isFirstCandleDown() => high[2] < high[1] and low[2] < low[1]
isThirdCandleUp()   => low > low[1]
isThirdCandleDown() => high < high[1]
isThirdCandleInsideBar() => high < high[1] and low > low[1]

// Buy Signal
isStormer123Buy() =>
    if insideBarStrategyInput
        longEntryInput and isFirstCandleUp() and isThirdCandleInsideBar() and isBullishTrend()
    else
        longEntryInput and isFirstCandleUp() and isThirdCandleUp() and isBullishTrend()

// Sell Signal
isStormer123Sell() =>
    if insideBarStrategyInput
        shortEntryInput and isFirstCandleDown() and isThirdCandleInsideBar() and isBearishTrend()
    else
        shortEntryInput and isFirstCandleDown() and isThirdCandleDown() and isBearishTrend()

// Backtest Time Period
inTradeWindow             = true
isInTradeWindow()         => inTradeWindow
isBacktestDateRangeOver() => not inTradeWindow and inTradeWindow[1]

// Backtest Price Parameters
highestPrice = ta.highest(high, 3)
lowestPrice  = ta.lowest(low,3)
priceRange   = highestPrice - lowestPrice

// Stormer Strategy (123): LONG
var myLongOrders = array.new_int(0)
longtEntryID     = "Long Entry:\n" + str.tostring(bar_index)
longExitID       = "Long Exit:\n" + str.tostring(bar_index)
stopLossInLong   = lowestPrice + 0.01
takeProfitInLong = priceRange + high

longEntryHasBeenMet = isInTradeWindow() and isBullishTrend() and isStormer123Buy()

// Scheduling LONG entry
if longEntryHasBeenMet
    array.push(myLongOrders, bar_index)
    strategy.order(longtEntryID, strategy.long, stop=high)
    strategy.exit(longExitID, longtEntryID, stop=stopLossInLong, limit=takeProfitInLong)

// In pine script, any order scheduled but not yet filled can be canceled.
// Once a order is filled, the trade is only finished with use of close or exit functions.
// As scheduled orders are not stored in the strategy.opentrades array, manual control is required.
for myOrderIndex = 0 to (array.size(myLongOrders) == 0 ? na : array.size(myLongOrders) - 1)
    myLongOrder = array.get(myLongOrders, myOrderIndex)
    if bar_index - myLongOrder == thresholdForEntryInput
        longEntryID = "Long Entry:\n" + str.tostring(myLongOrder)
        strategy.cancel(longEntryID)

// Stormer Strategy (123): SHORT
var myShortOrders = array.new_int(0)
shortEntryID      = "Short Entry:\n" + str.tostring(bar_index)
shortExitID       = "Short Exit:\n" + str.tostring(bar_index)
stopLossInShort   = highestPrice + 0.01
takeProfitInShort = low - priceRange

shortEntryHasBeenMet = isInTradeWindow() and isBearishTrend() and isStormer123Sell()

// Scheduling SHORT entry
if shortEntryHasBeenMet
    array.push(myShortOrders, bar_index)
    strategy.order(shortEntryID, strategy.short, stop=low)
    strategy.exit(shortExitID, shortEntryID, stop=stopLossInShort, limit=takeProfitInShort)

// In pine script, any order scheduled but not yet filled can be canceled.
// Once a order is filled, the trade is only finished with use of close or exit functions.
// As scheduled orders are not stored in the strategy.opentrades array, manual control is required.
for myOrderIndex = 0 to (array.size(myShortOrders) == 0 ? na : array.size(myShortOrders) - 1)
    myShortOrder = array.get(myShortOrders, myOrderIndex)
    if bar_index - myShortOrder == thresholdForEntryInput
        shortEntryID := "Short Entry:\n" + str.tostring(myShortOrder)
        strategy.cancel(shortEntryID)

// Close all positions at the end of the backtest period
if isBacktestDateRangeOver()
    strategy.cancel_all()
    strategy.close_all(comment="Date Range Exit")

// Display Signals
plotshape(series=longEntryHasBeenMet,  title="123 Buy",  style=shape.triangleup,   location=location.belowbar, color=buySignalColor,  text="123", textcolor=buySignalColor)
plotshape(series=shortEntryHasBeenMet, title="123 Sell", style=shape.triangledown, location=location.abovebar, color=sellSignalColor, text="123", textcolor=sellSignalColor)