9가지 이동평균 교차 전략


생성 날짜: 2024-01-02 10:37:21 마지막으로 수정됨: 2024-01-02 10:37:21
복사: 0 클릭수: 767
avatar of ChaoZhang ChaoZhang
1
집중하다
1621
수행원

9가지 이동평균 교차 전략

개요

이 전략은 두 가지 다른 변수 설정의 이동 평균을 사용하여 교차 작업을 수행합니다. 교차 신호에 따라 트렌드 방향을 판단하여 포지션을 개시하고 닫습니다. 이 전략은 간단한 이동 평균 ((SMA), 지수 이동 평균 ((EMA), 가중 이동 평균 ((WMA), 알모 이동 평균 ((ALMA), 수량 가치 이동 평균 ((VWMA) 등 9 가지 다른 유형의 이동 평균을 선택할 수 있습니다.

전략 원칙

이 전략의 핵심 논리는 두 개의 이동 평균의 수치를 비교하여 두 개의 이동 평균의 교차 상황에 따라 시장의 경향 방향을 판단하는 것입니다. 구체적으로, 우리는 빠른 선과 느린 선의 두 개의 이동 평균을 설정합니다. 빠른 선에서 느린 선을 통과하면 시장이 상승 추세에 들어간다고 생각하며, 더 많은 것을합니다. 빠른 선에서 느린 선을 통과하면 시장이 하향 추세에 들어간다고 생각하며, 공백을 만듭니다.

포지션에 들어간 후, 가격이 스톱로스 라인 (stop loss line) 에 닿으면 손실이 발생하면 포지션을 종료한다. 가격이 스톱 라인 (stop loss line) 에 닿으면 수익이 예상에 도달하면 포지션을 종료한다. 이렇게하면 수익을 잠금하고 손실이 확대되는 것을 막을 수 있다.

코드의 논리적으로 보면, 전략은 크게 4가지로 나니다.

  1. 이동 평균을 계산한다. 사용자가 선택한 이동 평균 유형에 따라 빠른 선과 느린 선의 이동 평균을 계산한다.

  2. 거래 신호를 생성한다. 빠른 선과 느린 선의 교차 상황에 따라 더 많은 것을 하고, 부족한 것을 하는 신호를 생성한다.

  3. 스톱로스트를 설정한다. 입점 가격과 세팅된 스톱로스트의 비율에 따라 실시간으로 스톱로스트 라인과 스톱로스트 라인의 가격을 계산한다.

  4. 진입 및 퇴출 ᅳ ᅳ ᅳ ᅳ ᅳ ᅳ ᅳ ᅳ

우위 분석

이 전략의 가장 큰 장점은 여러 종류의 이동 평균을 자유롭게 선택할 수 있다는 것입니다. 다양한 유형의 이동 평균은 가격에 대한 민감성이 다르기 때문에 사용자는 자신의 필요에 따라 적절한 이동 평균을 선택할 수 있습니다. 또한 이동 평균의 길이를 사용자 정의 할 수 있습니다.

또 다른 장점은 스톱로스 스톱 메커니즘을 설정하는 것이다. 이것은 손실이 더 확장되는 것을 효과적으로 방지하고, 수익을 잠금하는 것이다. 전반적으로, 이 전략은 유연하고, 사용자 정의가 높으며, 다양한 사용자의 요구에 적합하다.

위험 분석

이 전략의 주요 위험은 이동 평균이 지연성이 있다는 것이다. 가격이 갑자기 큰 변동이 있을 때 이동 평균이 적시에 대응하지 못하여 최적의 진입 또는 출구 시기를 놓칠 수 있다. 이 때 큰 손실이 발생할 수 있다.

또 다른 위험은 손해 막기 포지션의 설정이다. 설정된 폭이 너무 작다면, 중매될 수 있다. 너무 크면, 이익이 적당히 잠금되지 않게 될 수 있다. 따라서 실전에서는 시장 상황에 따라 손해 막기 파라미터를 최적화한다.

전체적으로, 이 전략은 주로 이동 평균에 의존하여 트렌드 방향을 결정하기 때문에 갑작스러운 사건이 가격의 큰 변동으로 인해 효과가 적당하다. 또한, 매개 변수 설정은 전략의 수익에 큰 영향을 미칩니다.

최적화 방향

이 전략은 다음과 같은 부분에서 최적화될 수 있습니다.

  1. 이동 평균의 종류를 최적화하십시오. 다른 시장 환경과 거래 유형에 따라 더 적합한 이동 평균을 선택하십시오.

  2. 이동 평균의 최적화 파라미터. 이동 평균의 기간을 조정하여 시장 특성에 더 적합하도록 한다.

  3. 다른 지표 필터를 추가하십시오. MACD, RSI 등 다른 지표가 추가 될 수 있으므로 추세가없는 시장에서 자주 거래하지 마십시오.

  4. 최적화된 스톱 스톱 비율. 역사적 데이터에 따라 최적의 스톱 스톱 파라미터를 계산한다.

  5. 기계 학습 모델을 추가한다. LSTM, Random Forest 등의 알고리즘을 사용하여 가격 움직임을 예측하고, 거래 신호를 보조적으로 생성한다.

  6. 스톱 트래킹 알고리즘을 사용한다. 스톱 라인이 가격 움직임에 따라 점진적으로 이동할 수 있도록 하며, 스톱 손실이 유발되는 확률을 감소시킨다.

요약하다

이 전략은 전체적으로 간단하고 직접적이며, 트렌드 방향을 교차 판단하여 전형적인 트렌드 추적 전략에 속한다. 장점은 간단하고 이해하기 쉽고, 유연성이 높으며, 이동 평균 유형과 파라미터를 스스로 선택할 수 있다. 단점은 갑작스러운 사건에 대한 반응이 느리고, 어느 정도 지연이 있다.

전략 소스 코드
/*backtest
start: 2022-12-26 00:00:00
end: 2024-01-01 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=3
strategy("Kozlod - Yet Another Moving Average Cross Strategy", shorttitle="kozlod_yamacs", overlay = true)

// 
// author: Kozlod
// date: 2018-03-06
// 

////////////
// INPUTS //
////////////

ma_type      = input(title = "MA Type",          defval = "SMA", options = ['SMA', 'EMA', 'WMA', 'ALMA', 'VWMA', 'HMA', 'LSMA', 'SMMA', 'DEMA'])
short_ma_len = input(title = "Short MA Length",  defval = 5,     minval = 1)
short_ma_src = input(title = "Short MA Source",   defval = close)
long_ma_len  = input(title = "Long MA Length",   defval = 15,    minval = 2)
long_ma_src  = input(title = "Long MA Source",    defval = close)
alma_offset  = input(title = "ALMA Offset",     type = float,   defval = 0.85,  step = 0.01, minval = 0, maxval = 1)
alma_sigma   = input(title = "ALMA Sigma",      type = float,   defval = 6,     step = 0.01)
lsma_offset  = input(title = "LSMA Offset",      defval = 0,     step = 1)

sl_lev_perc  = input(title = "SL Level % (0 - Off)", type = float,   defval = 0,  minval = 0, step = 0.01)
pt_lev_perc  = input(title = "PT Level % (0 - Off)", type = float,   defval = 0,  minval = 0, step = 0.01)

// Set initial values to 0
short_ma = 0.0
long_ma  = 0.0

// Simple Moving Average (SMA)
if ma_type == 'SMA' 
    short_ma := sma(short_ma_src, short_ma_len)
    long_ma  := sma(long_ma_src,  long_ma_len)

// Exponential Moving Average (EMA)
if ma_type == 'EMA'
    short_ma := ema(short_ma_src, short_ma_len)
    long_ma  := ema(long_ma_src,  long_ma_len)

// Weighted Moving Average (WMA)
if ma_type == 'WMA'
    short_ma := wma(short_ma_src, short_ma_len)
    long_ma  := wma(long_ma_src,  long_ma_len)

// Arnaud Legoux Moving Average (ALMA)
if ma_type == 'ALMA'
    short_ma := alma(short_ma_src, short_ma_len,  alma_offset, alma_sigma)
    long_ma  := alma(long_ma_src,  long_ma_len,   alma_offset, alma_sigma)

// Hull Moving Average (HMA)
if ma_type == 'HMA'
    short_ma := wma(2*wma(short_ma_src, short_ma_len/2)-wma(short_ma_src, short_ma_len), round(sqrt(short_ma_len)))
    long_ma  := wma(2*wma(long_ma_src,  long_ma_len /2)-wma(long_ma_src,  long_ma_len),  round(sqrt(long_ma_len)))

// Volume-weighted Moving Average (VWMA)
if ma_type == 'VWMA'
    short_ma := vwma(short_ma_src, short_ma_len)
    long_ma  := vwma(long_ma_src,  long_ma_len)

// Least Square Moving Average (LSMA)
if ma_type == 'LSMA'
    short_ma := linreg(short_ma_src, short_ma_len, lsma_offset)
    long_ma  := linreg(long_ma_src,  long_ma_len,  lsma_offset)

// Smoothed Moving Average (SMMA)    
if ma_type == 'SMMA'
    short_ma := na(short_ma[1]) ? sma(short_ma_src, short_ma_len) : (short_ma[1] * (short_ma_len - 1) + short_ma_src) / short_ma_len
    long_ma  := na(long_ma[1])  ? sma(long_ma_src,  long_ma_len)  : (long_ma[1]  * (long_ma_len  - 1) + long_ma_src)  / long_ma_len

// Double Exponential Moving Average (DEMA)
if ma_type == 'DEMA'
    e1_short = ema(short_ma_src, short_ma_len)
    e1_long  = ema(long_ma_src,  long_ma_len)
    
    short_ma := 2 * e1_short - ema(e1_short, short_ma_len)
    long_ma  := 2 * e1_long  - ema(e1_long,  long_ma_len)

/////////////
// SIGNALS //
/////////////

long_signal  = crossover( short_ma, long_ma)
short_signal = crossunder(short_ma, long_ma)

// Calculate PT/SL levels 
// Initial values 
last_signal    = 0
prev_tr_price  = 0.0
pt_level       = 0.0
sl_level       = 0.0

// Calculate previous trade price
prev_tr_price := long_signal[1] or short_signal[1] ? open : nz(last_signal[1]) != 0 ? prev_tr_price[1] : na

// Calculate SL/PT levels 
pt_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 + pt_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 - pt_lev_perc / 100)  : na
sl_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 - sl_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 + sl_lev_perc / 100)  : na

// Calculate if price hit sl/pt 
long_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) ==  1 and close >= pt_level
long_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) ==  1 and close <= sl_level

short_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) ==  -1 and close <= pt_level
short_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) ==  -1 and close >= sl_level

// What is last active trade? 
last_signal := long_signal ? 1 : short_signal ? -1 : long_hit_pt or long_hit_sl or short_hit_pt or short_hit_sl ? 0 : nz(last_signal[1])

//////////////
// PLOTTING //
//////////////

// Plot MAs
plot(short_ma, color = red,   linewidth = 2)
plot(long_ma,  color = green, linewidth = 2)


// Plot Levels 
plotshape(prev_tr_price, style = shape.cross, color = gray, location  = location.absolute, size = size.small)


plotshape(sl_lev_perc > 0 ? sl_level : na, style = shape.cross, color = red,   location  = location.absolute, size = size.small)
plotshape(pt_lev_perc > 0 ? pt_level : na, style = shape.cross, color = green, location  = location.absolute, size = size.small)

//////////////
// STRATEGY //
//////////////

strategy.entry("long",  true,  when = long_signal)
strategy.entry("short", false, when = short_signal)

strategy.close("long",  when = long_hit_pt  or long_hit_sl)
strategy.close("short", when = short_hit_pt or short_hit_sl)