동적 회귀 채널 전략


생성 날짜: 2024-02-23 12:14:49 마지막으로 수정됨: 2024-02-23 12:14:49
복사: 0 클릭수: 667
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

동적 회귀 채널 전략

개요

동적 회귀 통로 전략 (Dynamic Regression Channel Strategy) 은 선형 회귀를 이용한 가격 트렌드를 분석하고 동적 스톱로스를 결합하여 트렌드 추적을 가능하게 하는 양적 거래 전략이다. 이 전략은 선형 회귀를 사용하여 가격 통로를 그리며, 가격의 통로 돌파 신호를 판단하고, 구매 및 판매 명령을 발령한다. 동시에, 전략은 가격을 실시간으로 최신 스톱로스 위치를 추적하고, 수익을 잠금한다.

전략 원칙

이 전략은 우선 가격의 선형 회귀 곡선을 계산하여 가격이 상향 또는 하향 회귀 통로를 뚫었는지 판단합니다. 가격이 통로 상향 궤도를 초과하면 구매 신호가 발생하며, 가격이 통로 하향 궤도를 넘어지면 판매 신호가 발생합니다.

시장에 진입한 후, 전략은 실시간으로 가격의 스톱로스 평균선을 깨는 상황을 추적한다. 다수의 주문을 하면, 가격이 스톱로스 평균선을 떨어뜨리면, 스톱로스 판매 명령을 발령한다. 빈 주문을 하면, 가격이 스톱로스 평균선을 초과하면, 스톱로스 구매 명령을 발령한다. 이렇게 수익을 잠금하고 위험을 제어할 수 있다.

주의할 점은, 만약 가격이 다시 통로를 돌파하고 역작업을 실행한다면, 전략은 즉시 상장된 위치를 반전 거래로 변경할 것이다.

우위 분석

이 전략은 추세와 역전 거래 사고방식을 결합하여 가격의 전반적인 움직임에 부응하면서도 단기 조정 기회를 잡을 수 있습니다. 실시간으로 업데이트 된 중지 손실 전략은 위험을 효과적으로 제어 할 수 있으며, 균형 잡힌 거래 방법입니다.

간단한 이동 평균 전략에 비해, 동적 회귀 통로 전략은 가격 변화에 더 민감하여 잘못된 거래를 줄일 수 있다. 또한, 이 전략은 가격이 통로를 뚫고 오르락 내리락 할 때만 실행되며, 무질서한 급진적 거래를 피하는 데 도움이 된다.

위험 분석

이 전략은 주로 회귀 곡선의 부적절한 적합성으로 인한 위험에 직면합니다. 회귀 통로의 범위가 부적절하게 설정되어 너무 넓으면 유효하지 않은 거래의 확률이 증가합니다. 너무 좁은 통로는 거래 기회를 놓치게됩니다.

또한, 스톱 포지션의 설정도 중요합니다. 스톱 포지션은 너무 가깝고, 단기 가격 변동에 의해 촉발 될 수 있습니다. 너무 느슨한 스톱 포지션은 위험 통제의 효과를 발휘할 수 없습니다.

최적화 방향

다른 주기 또는 품종에 따라 자동으로 최적화 된 파라미터를 고려하여 회귀 통로와 스톱 라인을 가격 추세에 더 적합하게 만들 수 있습니다. 예를 들어, 기계 학습 알고리즘과 결합하여 최적의 파라미터를 훈련 할 수 있습니다.

다른 한편으로, 복소수 회귀, 지역 중화 회귀 등과 같은 다른 유형의 회귀 방법을 시도하여 더 나은 적합성을 얻을 수 있습니다. 또는 여러 회귀 지표를 결합하여 거래 규칙을 구축하여 전략의 안정성을 높일 수 있습니다.

요약하다

동적 회귀 통로 전략은 종합적으로 트렌드 및 역전 분석 방법을 적용하여 가격의 전반적인 움직임에 부응하면서 단기 조정 기회를 포착하여 거래를합니다. 중요한 회귀 통로 및 중단 위치 설정은 전략 효과에 중요한 영향을 미칩니다. 매개 변수 최적화 및 모델 반복을 통해 거래 전략을 더 개선 할 수 있습니다.

전략 소스 코드
/*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")