ダイナミック回帰チャネル戦略

作者: リン・ハーンチャオチャン, 日付: 2024-02-23 12:14:49
タグ:

img

概要

ダイナミックリグレッションチャネル戦略は,定量取引におけるトレンドフォローを実装するために,動的ストップ損失と組み合わせた価格動向の線形リグレッション分析を使用する. 戦略は,線形リグレッションを使用して価格チャネルをプロットし,価格がチャネルを突破すると購入・販売信号を生成する. 同時に,ストップ損失レベルを更新し,利益をロックするためにリアルタイムで価格を追跡する.

戦略の論理

この戦略は,まず価格の線形回帰曲線を計算し,価格が回帰チャネルの上または下を突破するかどうかを決定する.価格がチャネルの上部レールの上に上昇すると,購入信号が生成される.価格が下部レールの下に落ちると,販売信号が誘発される.

ストップ・ロスの移動平均線を破った場合,ストラテジーは追跡を続けます.ロングオーダーでは,価格がストップ・ロスのラインを下回るとストップ・ロスの販売オーダーが発行されます.ショートオーダーでは,価格がストップ・ロスのラインを超えるとストップ・ロスの購入オーダーが起動します.これは利益をロックし,リスクを制御します.

もし価格が再びチャネルを突破して方向を逆転させると,戦略はすぐに元の位置を平ら化し,反対方向の取引に切り替える.

利点分析

この戦略は,トレンドフォローと平均リバースの両方の概念を組み合わせ,短期的な逆転を捉えながら全体的な価格トレンドに乗っています. ダイナミックストップロスはリスクも効果的に制御します. したがって,バランスの取れた取引アプローチです.

ダイナミック・リグレッション・チャネル・戦略は,単純な移動平均戦略と比較して,価格変動により敏感で,マスタードを減らすことができます.また,この戦略は,制限のない攻撃的な取引を避け,チャネルのブレイクで取引するだけです.

リスク分析

主なリスクは回帰曲線の不正確なフィットメントにあります.チャネル範囲があまりにも幅広くまたは狭すぎると,不正な取引を増やしたり,取引機会を逃したりします.

また,適切なストップロスのポジショニングは極めて重要です.ストップロスは市場価格に近いので,短期波動により早期清算になりやすいが,ストップロスは遠すぎるとリスク管理の目的を果たすことはできません.さまざまな製品で細かな調整が必要です.

最適化

価格動向により適した回帰チャネルとストップ・ロスのラインを作るために,異なる期間や製品のための自動最適化パラメータを検討します.例えば,機械学習アルゴリズムは最適なパラメータを訓練するために潜在的に活用することができます.

代替として,多項式回帰およびローカル重量回帰などの異なる種類の回帰を試験することで,フィッティングを改善することができる.複数の回帰指標を組み合わせて取引規則を構築することで,戦略の安定性も向上する.

結論

ダイナミックリグレッションチャネル戦略は,トレンドフォローと平均リバース技術の両方を巧みに活用し,短期的な逆転を捕捉しながら全体的な価格トレンドを走行する.キーリグレッションチャネルとストップ損失パラメータの適切なチューニングは戦略のパフォーマンスに不可欠である.パラメータ最適化とモデルの繰り返しを通してさらなる改良を行うことができます.


/*backtest
start: 2024-01-01 00:00:00
end: 2024-01-31 23:59:59
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy("Estratégia de Regressão Linear", shorttitle="Regressão Linear Estratégia", overlay=true, initial_capital = 100, default_qty_value = 10, default_qty_type = strategy.percent_of_equity)

// média móvel exponencial para definição de regressao linear
var SlopeEMASize = input.int(defval = 21, title = "Slope EMA" )
// ema_length = 21
slope_ema = ta.ema(close, SlopeEMASize)

// média móvel exponencial para definição de nivel de stop
var StopEMASize = input.int(defval = 13, title = "Stop EMA" )
stop_ema = ta.ema(close, StopEMASize)

// Variáveis para controle de posição
var float long_stop_level = na
var float long_entry_level = na
var bool long_signal = false
var bool long_order_open = false
var int long_order_id = 0


var float short_stop_level = na
var float short_entry_level = na
var bool short_signal = false
var bool short_order_open = false
var int short_order_id = 0

// Regressão linear para uso como sinal de entrada 
var SlopeLenght = input.int(defval = 21, title = "Slope Lenght" )
entry_signal = ta.linreg(slope_ema, SlopeLenght, 0)

//Variaveis com a indicação do pivot da regressao
long_entry_signal = ta.crossover(entry_signal, entry_signal[1])
short_entry_signal = ta.crossunder(entry_signal, entry_signal[1])

// Condição de entrada (reversão da regressão)
if long_entry_signal
    long_signal := true
    short_signal := false
    long_entry_level := high
    long_stop_level := low

if short_entry_signal
    short_signal := true
    long_signal := false
    short_entry_level := low
    short_stop_level := high


// Indica quando o preço cruzou o nível de stop 
price_cross_stop_ema_up = ta.crossover(close, stop_ema)
price_cross_stop_ema_down = ta.crossunder(close, stop_ema)

// Mover o stop quando o preço cruzar a nível stop e operação long ativa
if long_signal and long_order_open and price_cross_stop_ema_down
    if low > long_entry_level
        long_stop_level := high

// Mover o stop quando o preço cruzar a nível stop e operação short ativa
if short_signal and short_order_open and price_cross_stop_ema_up
    if high < short_stop_level
        short_stop_level := low

// Sair da posição se houver nova reversão da regressão
if long_order_open or short_order_open
    if long_entry_signal //and short_order_open
        strategy.close(str.tostring(short_order_id), comment ="Inversão Sinal("+str.tostring(short_order_id)+")")
        short_order_open:= false
    if short_entry_signal //and long_order_open
        strategy.close(str.tostring(long_order_id), comment = "Inversão Sinal("+str.tostring(long_order_id)+")")
        long_order_open:=false

// Sinais de compra e venda com base no stop
if long_signal and close > long_entry_level and not long_order_open
    if strategy.opentrades != 0
        strategy.cancel_all()

    long_order_id+=1
    // strategy.order(str.tostring(long_order_id), strategy.long, comment="Open Long("+str.tostring(long_order_id)+")", limit = long_entry_level) 
    strategy.entry(str.tostring(long_order_id), strategy.long, comment="Open Long("+str.tostring(long_order_id)+")", limit = long_entry_level)
    long_order_open := true
    // log.info("Open Long:"+str.tostring(long_order_id))

if short_signal and close < short_entry_level and not short_order_open
    if strategy.opentrades != 0
        strategy.cancel_all()

    short_order_id+=1
    // strategy.order(str.tostring(short_order_id), strategy.short, comment="Open Short("+str.tostring(short_order_id)+")", limit = short_entry_level)
    strategy.entry(str.tostring(short_order_id), strategy.short, comment="Open Short("+str.tostring(short_order_id)+")", limit = short_entry_level)
    short_order_open := true
    // log.info("Open Short:"+str.tostring(short_order_id))

// Sinais de compra e venda com base no stop
if long_signal and close < long_stop_level and long_order_open
    strategy.close(str.tostring(long_order_id), comment = "Stop Atingido("+str.tostring(long_order_id)+")", immediately = true)
    long_order_open := false

if short_signal and close > short_stop_level and short_order_open
    strategy.close(str.tostring(short_order_id),comment = "Stop Atingido("+str.tostring(short_order_id)+")", immediately = true)
    short_order_open := false

// Plotagem da regressão e do stop

plot(stop_ema, title="Stop Signal", color=color.red)
plot(entry_signal,"Entry Signal", linewidth = 5, color = color.rgb(155, 0, 140))

plotshape(long_order_open?long_stop_level:na, title = "Long Stop Level", color = color.green, location = location.absolute)
plotshape(long_order_open?long_entry_level:na, title="Long Entry Value",location=location.absolute, color = color.green, style = shape.circle)
plotshape(series=long_entry_signal, title="Long Signal", location=location.abovebar, color=color.green, style=shape.triangleup, size=size.small, text = "Long Signal")

plotshape(short_order_open?short_stop_level:na, title = "Short Stop Level", color = color.red, location = location.absolute)
plotshape(short_order_open?short_entry_level:na, title="Short Entry Value",location=location.absolute, color = color.red, style = shape.circle)

plotshape(series=short_entry_signal, title="Short Signal", location=location.belowbar, color=color.red, style=shape.triangledown, size=size.small, text="Short Signal")



もっと