이동평균의 9가지 유형의 크로스오버 전략

저자:차오장, 날짜: 2024-01-02 10:37:21
태그:

img

전반적인 설명

이 전략은 트렌드 방향과 오픈/클로즈 포지션을 결정하기 위해 크로스오버 거래에 다른 매개 변수 설정을 가진 두 개의 이동 평균을 사용합니다. 전략은 간단한 이동 평균 (SMA), 기하급수적인 이동 평균 (EMA), 가중 이동 평균 (WMA), 아르노 레고 이동 평균 (ALMA), 볼륨 가중 이동 평균 (VWMA) 등 9 가지 다른 유형의 이동 평균 중에서 선택할 수 있습니다. 전략은 또한 스톱 손실 및 수익 수준을 설정합니다.

전략 논리

이 전략의 핵심 논리는 두 개의 이동 평균 라인의 값을 비교하고 그 교차에 따라 시장 트렌드 방향을 결정하는 것입니다. 구체적으로 두 개의 이동 평균을 사용하여 빠른 라인과 느린 라인을 설정합니다. 빠른 라인이 느린 라인을 넘을 때 시장이 상승 추세에 있으며 길게 갈 것이라고 믿습니다. 빠른 라인이 느린 라인을 넘을 때 시장이 하락 추세에 있으며 짧게 갈 것이라고 믿습니다.

포지션에 진입한 후, 가격이 스톱 로스 라인을 만지면 손실을 줄이기 위해 포지션을 종료합니다. 가격이 수익 라인을 만지면 예상대로 이익을 잠금하기 위해 포지션을 종료합니다. 이로 인해 이익을 잠금하고 손실이 더 확장되는 것을 방지 할 수 있습니다.

코드 논리에서 전략은 네 부분으로 나눌 수 있습니다.

  1. 이동평균을 계산합니다. 이동평균 유형의 사용자 선택에 따라 빠른 라인 및 느린 라인 이동평균을 계산합니다.

  2. 트레이딩 신호를 생성합니다. 빠른 라인과 느린 라인의 교차 상황을 기반으로 긴 신호와 짧은 신호를 생성합니다.

  3. 스톱 로스 및 취리 레벨을 설정합니다. 입력 가격과 설정된 스톱 로스/ 취리 비율을 기반으로 실시간으로 스톱 로스 및 취리 가격 수준을 계산합니다.

  4. 엔트리 및 엑스포트, 롱/쇼트 신호를 기반으로 엔트리, 스톱/로스/프로프트 신호를 기반으로 엑스포트

이점 분석

이 전략의 가장 큰 장점은 여러 종류의 이동 평균에서 자유롭게 선택할 수 있다는 것입니다. 다른 유형의 이동 평균은 가격에 대한 다른 민감성을 가지고 있습니다. 사용자는 자신의 필요에 따라 적절한 이동 평균을 선택할 수 있습니다. 또한 이동 평균의 길이는 시간 차원을 최적화하기 위해 사용자 정의 될 수 있습니다.

또 다른 장점은 스톱 로스 및 영업 메커니즘이 설정되어 있다는 것입니다. 이것은 추가 손실을 효과적으로 방지하고 수익을 잠금 할 수 있습니다. 전반적으로이 전략은 높은 사용자 정의성으로 매우 유연하며 다른 필요를 가진 사용자에게 적합합니다.

위험 분석

이 전략의 주요 위험은 이동 평균이 뒤떨어지는 것입니다. 가격이 갑자기 격렬하게 변동하면 이동 평균은 시간에 대응할 수 없으며, 최고의 입출시기를 놓칠 수 있습니다. 이것은 큰 손실로 이어질 수 있습니다.

또 다른 위험은 스톱 로스 및 영업 수익 수준을 설정하는 것입니다. 범위가 너무 작다면 스칼퍼에게 취약할 수 있습니다. 너무 크면 적시에 이익을 잠금하지 못하는 것이 쉽습니다. 따라서 라이브 거래 중 시장 조건에 따라 스톱 로스 / 영업 수익 매개 변수를 최적화해야합니다.

일반적으로 이 전략은 주로 트렌드 방향을 결정하기 위해 이동 평균에 의존한다. 따라서 갑작스러운 사건이 큰 가격 변동을 유발할 때 그 효과는 손상될 수 있다. 또한, 매개 변수 설정은 전략 수익에도 큰 영향을 줄 수 있다.

최적화 방향

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

  1. 이동 평균 유형을 최적화합니다. 다른 시장 환경과 거래 제품을 기반으로 더 적합한 이동 평균을 선택하십시오.

  2. 이동 평균 매개 변수를 최적화합니다. 이동 평균 길이를 조정하여 시장 특성에 더 잘 맞게하십시오.

  3. 필터링을 위해 다른 지표를 추가하십시오. MACD, RSI 및 다른 지표가 명확한 추세가 없을 때 빈번한 거래를 피하기 위해 추가 될 수 있습니다.

  4. 스톱 로스/트랙 이윤 비율을 최적화 합니다. 역사적 데이터에 기초하여 최적의 스톱 로스/트랙 이윤 매개 변수를 계산합니다.

  5. 기계 학습 모델을 추가합니다. LSTM, 무작위 숲 알고리즘을 사용하여 가격 움직임을 예측하고 거래 신호를 생성하는 데 도움이됩니다.

  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)

더 많은