価格格差に基づくストップ損失戦略

作者: リン・ハーンチャオチャン, 日付: 2023-11-28 13:53:16
タグ:

img

概要

この戦略は,価格が最近の低値を突破したとき,価格格差原則を採用し,ストップ・ロストと収益の取扱いを,最も低い価格を追いかけるようにしています.

戦略の論理

価格が過去N時間間の最低価格を下回ったときのギャップを特定し,設定したパーセントに基づいてストップ・ロストとテイク・プロフィートオーダーでロングします.ストップ・ロストラインとテイク・プロフィートラインは価格アクションに応じて動きます.論理は:

  1. 最低価格を拘束価格として過去N時間内で計算する
  2. リアルタイム価格が拘束価格*購入パーセントより低いときにロングに行く
  3. 入場価格 * 販売パーセントに基づいて利益を取ること
  4. ストップ・ロスの設定は,エントリー価格 - エントリー価格 * ストップ・ロスの割合をベースにします.
  5. ポジションサイズは,戦略資本のパーセントです.
  6. 最低価格のトレイルストップ損失線
  7. 負債の負債の負債と負債の負債の負債の負債の負債の負債

利点分析

この戦略の利点は

  1. 価格格差の概念を活用し,勝率を向上させる
  2. トレーリングストップ損失の自動化により,ほとんどの利益が確保されます.
  3. 異なる市場におけるストップ・ロストと得益率の調整可能
  4. 明らかにリバウンドを持つ楽器にうまく機能します
  5. シンプルな論理と実行が簡単

リスク分析

リスクもあります:

  1. ギャップの突破は,低い底値で失敗する可能性があります
  2. 誤ったストップ・ロースまたはテイク・プロフィートの設定は,早期離脱を引き起こす可能性があります.
  3. 市場の変化に定期的なパラメータ調整を要求する
  4. 制限された適用可能な手段は,いくつかの場合,機能しない可能性があります
  5. 時々 手作業 が 必要

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

戦略は以下の点で改善できる:

  1. 自動パラメータ調整のための機械学習モデルを追加する
  2. Stop loss/take profit の種類を追加する.例えば,ストップ損失を後押しする,ブラクレットオーダー
  3. スマートな出口のためにストップ・ロスト/テイク・プロフィートのロジックを最適化
  4. 誤った信号をフィルタリングするためにより多くの指標を組み込む
  5. 普遍性を向上させるためのより多くの手段に拡大する

結論

結論として,これは価格ギャップに基づいたシンプルで効果的なストップ損失戦略です.それは誤ったエントリと利益のロックを効果的に削減します.パラメータチューニングとシグナルフィルタリングの改善にはまだ多くの余地があります.さらなる研究と精製に値します.


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

//@version=4

strategy(title="Squeeze Backtest by Shaqi v1.0", overlay=true, pyramiding=0, currency="USD", process_orders_on_close=true, commission_type=strategy.commission.percent, commission_value=0.075, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=100, backtest_fill_limits_assumption=0)
strategy.risk.allow_entry_in(strategy.direction.long)

R0 = "6 Hours"
R1 = "12 Hours"
R2 = "24 Hours"
R3 = "48 Hours"
R4 = "1 Week"
R5 = "2 Weeks"
R6 = "1 Month"
R7 = "Maximum"


buyPercent = input( title="Buy, %",         type=input.float,   defval=3,       minval=0.01,                        step=0.01,  inline="Percents",  group="Squeeze Settings") * 0.01
sellPercent = input(title="Sell, %",        type=input.float,   defval=1,       minval=0.01,                        step=0.01,  inline="Percents",  group="Squeeze Settings") * 0.01
stopPercent = input(title="Stop Loss, %",   type=input.float,   defval=1,       minval=0.01,        maxval=100,     step=0.01,  inline="Percents",  group="Squeeze Settings") * 0.01
isMaxBars = input(  title="Max Bars To Sell",               type=input.bool,    defval=true ,                                   inline="MaxBars",   group="Squeeze Settings")
maxBars = input(    title="",       type=input.integer, defval=2,     minval=0,           maxval=1000, step=1,                  inline="MaxBars",   group="Squeeze Settings")
bind = input(       title="Bind",           type=input.source,  defval=close,                                                                       group="Squeeze Settings")
isRange = input(    title="Fixed Range",               type=input.bool,    defval=true,                                         inline="Range",     group="Backtesting Period")
rangeStart = input( title="",                       defval=R4,      options=[R0, R1, R2, R3, R4, R5, R6, R7],                   inline="Range",     group="Backtesting Period")
periodStart = input(title="Backtesting Start", type=input.time,    defval=timestamp("01 Aug 2021 00:00 +0000"),                                     group="Backtesting Period")
periodEnd = input(  title="Backtesting End",   type=input.time,    defval=timestamp("01 Aug 2022 00:00 +0000"),                                     group="Backtesting Period")

int startDate = na
int endDate = na
if isRange
    if rangeStart == R0
        startDate := timenow - 21600000
        endDate := timenow
    else if rangeStart == R1
        startDate := timenow - 43200000
        endDate := timenow
    else if rangeStart == R2
        startDate := timenow - 86400000
        endDate := timenow
    else if rangeStart == R3
        startDate := timenow - 172800000
        endDate := timenow
    else if rangeStart == R4
        startDate := timenow - 604800000
        endDate := timenow
    else if rangeStart == R5
        startDate := timenow - 1209600000
        endDate := timenow
    else if rangeStart == R6
        startDate := timenow - 2592000000
        endDate := timenow
    else if rangeStart == R7
        startDate := time
        endDate := timenow
else 
    startDate := periodStart
    endDate := periodEnd

afterStartDate = (time >= startDate)
beforeEndDate = (time <= endDate)
notInTrade = strategy.position_size == 0
inTrade = strategy.position_size > 0

barsFromEntry = barssince(strategy.position_size[0] > strategy.position_size[1])
entry = strategy.position_size[0] > strategy.position_size[1]
entryBar = barsFromEntry == 0
notEntryBar = barsFromEntry != 0
buyLimitPrice = bind - bind * buyPercent
buyLimitFilled = low <= buyLimitPrice
sellLimitPriceEntry = buyLimitPrice * (1 + sellPercent)
sellLimitPrice = strategy.position_avg_price * (1 + sellPercent)

stopLimitPriceEntry = buyLimitPrice - buyLimitPrice * stopPercent
stopLimitPrice = strategy.position_avg_price - strategy.position_avg_price * stopPercent

if afterStartDate and beforeEndDate and notInTrade
    strategy.entry("BUY", true, limit = buyLimitPrice)
    strategy.exit("INSTANT", limit = sellLimitPriceEntry, stop = stopLimitPriceEntry)
strategy.cancel("INSTANT", when = inTrade)
if isMaxBars
    strategy.close("BUY", when = barsFromEntry >= maxBars, comment = "Don't Sell")
strategy.exit("SELL", limit = sellLimitPrice, stop = stopLimitPrice)

showStop = stopPercent <= 0.03

plot(showStop ? stopLimitPrice : na, title="Stop Loss Limit Order", style=plot.style_linebr, color=color.red, linewidth=1)
plot(sellLimitPrice, title="Take Profit Limit Order", style=plot.style_linebr, color=color.purple, linewidth=1)
plot(strategy.position_avg_price, title="Buy Order Filled Price", style=plot.style_linebr, color=color.blue, linewidth=1)
plot(buyLimitPrice, title="Trailing Buy Limit Order", style=plot.style_stepline, color=color.new(color.blue, 30), offset=1)



もっと