동적 회귀 채널 전략

저자:차오장, 날짜: 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")



더 많은