超トレンドに基づくビットコイン量化取引戦略

作者: リン・ハーンチャオチャン開催日: 2024-02-06 12:09:09
タグ:

基于超级趋势的比特币量化交易策略

概要

この戦略は,スーパートレンド指標に基づいたビットコインの自動量化取引戦略である.これはスーパートレンド指標を用いて市場傾向を判断し,ATRストップ損失原理と組み合わせてリスクを制御し,長期間の双方向取引を実現する.この戦略の最大の利点は,リスクと利益の比率が良好であり,ストップ損失戦略は信頼性があり,中長期の保有に適している.この戦略は,Coinbase Proなどの主流取引所で4時間レベルで使用できる.

戦略の原理

この戦略は,スーパートレンド指標が市場傾向の方向を判断する.スーパートレンド指標が下落傾向から上落傾向へと転換するときに多頭入場する.スーパートレンド指標が上落傾向から上落傾向へと転換するときに空頭入場する.

具体的には,この戦略では,まずATR指標の長さを14サイクルに計算し,ATR停止損失倍数 (例えば1.5倍) で1回の停止損失距離を決定する.その後,超傾向指標を計算し,指標パラメータはデフォルト値 (ATRサイクル9,超傾向因数2.5) を使用します.超傾向指標が方向転換するときに取引信号を発します.

入場後,ストップロスの位はATRのストップロスの上または下に固定される.最初のストップロスはリスクリターン比率に基づいて計算され,デフォルトでは0.75で,ストップロスの距離はストップロスの距離の0.75倍である.価格が最初のストップロスを到達すると,50%のポジションを平衡し,ストップロスを開場価格に移動し,そのポジションを利潤にロックする.第二のストップロスは0.75のリスクリターン比率で計算され,価格がストップロスを触ると,残りのストップロスの位はすべて出場する.

このように,この戦略は,停止損失リスクが制御可能なことを保証する前提で,部分的な停止で利益を確保し,中期・長期間の保有投資戦略に適している.

優位性分析

この戦略の最大の利点は,中長期にわたって維持できるリスク利回りである. 具体的な利点は以下の通りである.

  1. 超トレンドで市場トレンドを判断し,市場のノイズをフィルタリングし,主要なトレンドを見逃すのを避ける.

  2. ATRは動的ストップ損失を追跡し,単発損失を信頼的に制御する.

  3. リスクは,利益と利益の相関性が高い.

  4. 価格が停止値1に達すると,停止損失を開始価格に調整し,利益を確保し,戦略の安定性を強化します.

  5. 超シンプルな取引論理,理解しやすい実装,パラメータ調整スペースが大きい.

  6. 主要な取引所の昼間または高周波データに適用可能で,柔軟性があります.

リスク分析

この戦略には,いくつかのリスクがあり,主に以下の点に焦点を当てています.

  1. 市場突発事件がギャップや空飛ぶことを引き起こし,停止できない損失と大きな損失に直面します. ATR停止損失倍数を合理的に調整することでリスクを減らすことができます.

  2. スーパートレンド指標判定が失敗し,取引信号の誤差を引き起こします. ATRとスーパートレンドパラメータの組み合わせを適切に調整して最適化できます.

  3. 部分平衡比率が高く設定され,十分なトレンド利益を得ることができない.異なる市場に応じて部分平衡比率を調整する必要があります.

  4. 取引頻度は高すぎたり低すぎたりする. 超トレンドパラメータを調整して最適なバランスを取るべきである.

優化方向

この戦略には,以下のような分野に焦点を当てて,最適化できる余地があります.

  1. 標準ATR,モーターストップ,ブリンベルトストップなど,さまざまなATRストップ方法を試し,ストップ戦略を最適化します.

  2. 異なるパラメータのスーパートレンド指標をテストし,最適なパラメータ組み合わせを見つけます. 段階的な最適化または遺伝アルゴリズムを使用して多次元パラメータ最適化することができます.

  3. ストップをより信頼性のあるものにするために,ドンチアン通道のような2階ストップ指標をストップ上に重ねてみる.

  4. 様々な部分平衡比率をテストし,最適の利得回帰とリスク平衡を見つけます.部分平衡比率は動的に調整することもできます.

  5. 機械学習に基づく動的停止,動的位置調整などの戦略を探求する.

概要

この戦略は,超傾向判断傾向,ATR動的停止損失,部分的な停止利益に基づく量化戦略である.これはリスク・利益のバランスが良好で,自動取引に適している.この戦略は,超傾向,停止損失,収益方法などを大幅に最適化できる.これは長期にわたって調整し実行する価値のある量化戦略である.


/*backtest
start: 2024-01-06 00:00:00
end: 2024-02-05 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/
// Developed by © StrategiesForEveryone
//@version=5

strategy("SuperTrend Strategy for BTCUSD 4H", overlay=true, process_orders_on_close = true, initial_capital = 100, default_qty_type = strategy.cash, precision = 2, slippage = 50, commission_value = 0.03, backtest_fill_limits_assumption = 50)

// ------ Date filter (obtained from ZenAndTheArtOfTrading) ---------

initial_date = input(title="Initial date", defval=timestamp("10 Feb 2014 13:30 +0000"), group="Time filter", tooltip="Enter the start date and time of the strategy")
final_date   = input(title="Final date", defval=timestamp("01 Jan 2030 19:30 +0000"), group="Time filter", tooltip="Enter the end date and time of the strategy")
dateFilter(int st, int et) => time >= st and time <= et
colorDate = input.bool(defval=false, title="Date background", tooltip = "Add color to the period of time of the strategy tester")
bgcolor(colorDate and dateFilter(initial_date, final_date) ? color.new(color.blue, transp=90) : na)

// ------------ Super Trend ----------

atrPeriod = input(9, "ATR Length SuperTrend")
factor = input.float(2.5, "Factor SuperTrend", step = 0.05)
[supertrend, direction] = ta.supertrend(factor, atrPeriod)
show_supertrend = input.bool(defval = false, title="Show supertrend ?", group = "Appearance")
bodyMiddle = plot(show_supertrend ? ((open + close) / 2) : na, display=display.none)
upTrend = plot(show_supertrend and direction < 0 ? supertrend : na, "Up Trend", color = color.green, style=plot.style_linebr)
downTrend = plot(show_supertrend and direction > 0 ? supertrend : na, "Down Trend", color = color.red, style=plot.style_linebr)
fill(bodyMiddle, upTrend, color.new(color.green, 90), fillgaps=false)
fill(bodyMiddle, downTrend, color.new(color.red, 90), fillgaps=false)

// ---------- Atr stop loss (obtained from garethyeo)

source_atr = input(close, title='Source', group = "Atr stop loss", inline = "A")
length_atr = input.int(14, minval=1, title='Period', group = "Atr stop loss" , inline = "A")
multiplier = input.float(1.5, minval=0.1, step=0.1, title='Atr multiplier', group = "Atr stop loss", inline = "A", tooltip = "Defines the stop loss distance based on the Atr stop loss indicator")
shortStopLoss = source_atr + ta.atr(length_atr) * multiplier
longStopLoss = source_atr - ta.atr(length_atr) * multiplier
show_atr_stoploss = input.bool(defval=false, title="Show Atr stop loss ?", group = "Appearance")
plot(show_atr_stoploss ? longStopLoss : na, color=color.white, style = plot.style_circles)
plot(show_atr_stoploss ? shortStopLoss : na, color=color.white, style = plot.style_circles)

// ------------- Money management --------------

strategy_contracts = strategy.equity / close
distance_sl_atr_long = -1 * (longStopLoss - close) / close
distance_sl_atr_short = (shortStopLoss - close) / close
risk = input.float(2.5, '% Account risk per trade', step=1, group = "Risk management for trades", tooltip = "Percentage of total account to risk per trade")
long_amount = strategy_contracts * (risk / 100) / distance_sl_atr_long
short_amount = strategy_contracts * (risk / 100) / distance_sl_atr_short

// ---------- Risk management ---------------

risk_reward_breakeven_long= input.float(title="Risk/reward for breakeven long", defval=0.75, step=0.05, group = "Risk management for trades")
risk_reward_take_profit_long= input.float(title="Risk/reward for take profit long", defval=0.75, step=0.05, group = "Risk management for trades")
risk_reward_breakeven_short= input.float(title="Risk/reward for break even short", defval=0.75, step=0.05, group = "Risk management for trades")
risk_reward_take_profit_short= input.float(title="Risk/reward for take profit short", defval=0.75, step=0.05, group = "Risk management for trades")
tp_percent=input.float(title="% of trade for first take profit", defval=50, step=5, group = "Risk management for trades", tooltip = "Closing percentage of the current position when the first take profit is reached.")

// ------------ Trade conditions ---------------

bought = strategy.position_size > 0
sold = strategy.position_size < 0
long_supertrend=ta.crossover(close, supertrend)
short_supertrend=ta.crossunder(close, supertrend)
var float sl_long = na
var float sl_short = na 
var float be_long = na
var float be_short = na
var float tp_long = na
var float tp_short = na
if not bought
    sl_long:=na
if not sold
    sl_short:=na

// ---------- Strategy -----------

// Long position 

if not bought and long_supertrend
    sl_long:=longStopLoss           
    long_stoploss_distance = close - longStopLoss
    be_long := close + long_stoploss_distance * risk_reward_breakeven_long
    tp_long:=close+(long_stoploss_distance*risk_reward_take_profit_long)
    strategy.entry('L', strategy.long, long_amount, alert_message = "Long")
    strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
    strategy.exit('Exit', 'L', stop=sl_long)
if high > be_long
    sl_long := strategy.position_avg_price
    strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
    strategy.exit('Exit', 'L', stop=sl_long)
if bought and short_supertrend
    strategy.close("L", comment="CL")

// Short position

if not sold and short_supertrend
    sl_short:=shortStopLoss
    short_stoploss_distance=shortStopLoss - close  
    be_short:=((short_stoploss_distance*risk_reward_breakeven_short)-close)*-1
    tp_short:=((short_stoploss_distance*risk_reward_take_profit_short)-close)*-1
    strategy.entry("S", strategy.short, short_amount, alert_message = "Short")
    strategy.exit("Tp", "S", stop=sl_short, limit=tp_short, qty_percent=tp_percent)
    strategy.exit("Exit", "S", stop=sl_short)
if low < be_short
    sl_short:=strategy.position_avg_price
    strategy.exit("Tp", "S", stop=sl_short, limit=tp_short, qty_percent=tp_percent)
    strategy.exit("Exit", "S", stop=sl_short)    
if sold and long_supertrend
    strategy.close("S", comment="CS") 

// ---------- Draw position on chart -------------

if high>tp_long
    tp_long:=na
if low<tp_short
    tp_short:=na
if high>be_long
    be_long:=na
if low<be_short
    be_short:=na

show_position_on_chart = input.bool(defval=true, title="Draw position on chart ?", group = "Appearance", tooltip = "Activate to graphically display profit, stop loss and break even")
position_price = plot(show_position_on_chart? strategy.position_avg_price : na, style=plot.style_linebr, color = color.new(#ffffff, 10), linewidth = 1)

sl_long_price = plot(show_position_on_chart and bought ? sl_long : na, style = plot.style_linebr, color = color.new(color.red, 10), linewidth = 1)
sl_short_price = plot(show_position_on_chart and sold ? sl_short : na, style = plot.style_linebr, color = color.new(color.red, 10), linewidth = 1)

tp_long_price = plot(strategy.position_size>0 and show_position_on_chart? tp_long : na, style = plot.style_linebr, color = color.new(#11eb47, 10), linewidth = 1)
tp_short_price = plot(strategy.position_size<0 and show_position_on_chart? tp_short : na, style = plot.style_linebr, color = color.new(#11eb47, 10), linewidth = 1)

breakeven_long = plot(strategy.position_size>0 and high<be_long and show_position_on_chart ? be_long : na , style = plot.style_linebr, color = color.new(#00ff40, 60), linewidth = 1)
breakeven_short = plot(strategy.position_size<0 and low>be_short and show_position_on_chart ? be_short : na , style = plot.style_linebr, color = color.new(#00ff40, 60), linewidth = 1)

position_profit_long = plot(bought and show_position_on_chart and strategy.openprofit>0 ? close : na, style = plot.style_linebr, color = color.new(#4cd350, 10), linewidth = 1)
position_profit_short = plot(sold and show_position_on_chart and strategy.openprofit>0 ? close : na, style = plot.style_linebr, color = color.new(#4cd350, 10), linewidth = 1)

fill(plot1 = position_price, plot2 = position_profit_long, color = color.new(color.green,90))
fill(plot1 = position_price, plot2 = position_profit_short, color = color.new(color.green,90))

fill(plot1 = position_price, plot2 = sl_long_price, color = color.new(color.red,90))
fill(plot1 = position_price, plot2 = sl_short_price, color = color.new(color.red,90))

fill(plot1 = position_price, plot2 = tp_long_price, color = color.new(color.green,90))
fill(plot1 = position_price, plot2 = tp_short_price, color = color.new(color.green,90))


もっと見る