이중 이동 평균선 교차 전략은 서로 다른 주기의 이동 평균선을 계산하여 가격 경향 방향을 판단하여 트렌드 추적을 구현한다. 짧은 주기 평균선 상에 긴 주기 평균선 을 통과할 때 더 많이 하고, 짧은 주기 평균선 아래에 긴 주기 평균선 을 통과할 때 공백을 하는 것이 전형적인 트렌드 추적 전략이다.
이 전략은 9주기, 21주기 및 50주기 지수 이동 평균 (EMA) 을 기반으로 한다. 이 중 9주기 EMA는 단기 경향을, 21주기 EMA는 중기 경향을, 50주기 EMA는 장기 경향을 나타낸다.
9주기 EMA 위에 21주기 EMA를 통과하면, 단기 경향이 상승으로 바뀌는 것을 나타냅니다. 9주기 EMA 아래에 21주기 EMA를 통과하면, 단기 경향이 하락으로 바뀌는 것을 나타냅니다.
코드에는 장고와 빈고의 개장, 중지, 중지 논리가 설정되어 있다. 개장 조건은 평선 상 또는 아래로 뚫린다. 다중 머리 막은 진입 가격 × ((1+ 입력의 중지 비율), 빈머리 막은 진입 가격 × ((1- 입력의 중지 비율) 이다. 다중 머리 막은 진입 가격 × ((1- 입력의 중지 비율), 빈머리 막은 진입 가격 × ((1+ 입력의 중지 비율) 이다.
또한, 코드는 추세적 필터링과 같은 몇 가지 필터링 조건을 추가했습니다. K 선이 평평선 상하로 통과하기 전에 흔들리지 않도록 요구합니다. 그리고 자본 사용률 필터링은 전략 적당이 N 일 평평선보다 낮아지지 않도록 요구합니다. 손실을 피하기 위해 너무 많은 시간 동안 여전히 거래합니다. 이러한 필터링 조건은 거짓 신호를 어느 정도 방지 할 수 있습니다.
전체적으로 이 전략은 가격 트렌드 방향을 판단하기 위해 쌍 EMA 교차와 합리적인 스톱 스톱 로직을 사용하여 중장선 트렌드를 잡을 수 있습니다. 그러나 단일 요소 전략으로 신호는 충분히 안정적이지 않을 수 있으며 추가적으로 최적화 할 수 있습니다.
어떻게 대처해야 할까요?
이 전략은 다음과 같은 측면에서 최적화될 수 있습니다.
이동 평균선의 주기 변수를 최적화하여 최적의 주기 조합을 찾는다. 자기 적응 최적화 기술을 도입할 수 있으며, 동적으로 최적의 주기이다.
다른 기술 지표 필터링 신호를 추가하여 신호 품질을 향상 시키거나 기계 학습을 도입하여 자동으로 가짜 신호를 필터링합니다.
거래량 분석과 함께. 평균선을 돌파하지만 거래량이 부족하면 신호를 받지 않는다.
돌파가 발생했을 때, 진동권에서의 돌파와 같은 전기의 변동 상황을 조사하여 가짜 돌파가 될 수 있다.
동적 스톱 메커니즘을 구축하십시오. 추적형 스톱, Chandelier Exit 등으로 스톱 거리를 줄이면서도 스톱을 효과적으로 보장하십시오.
포지션 관리를 최적화하여 고정 포지션, 동적 포지션, 레버리지 포지션 등으로 수익률을 합리화한다.
거래 비용, 슬라이드 포인트 영향을 전체적으로 고려하십시오. 스톱 스톱 손실 비율을 최적화하여 전략이 실전에서 여전히 수익성이 있는지 확인하십시오.
이 전략의 전체 구조는 합리적이고, 원칙은 간단하며, 트렌드 방향을 쌍 EMA 교차로 판단하고, 스톱 스톱 로직을 설정하여 트렌드를 잡을 수 있다. 그러나 단일 요소 전략으로, 파라미터 설정, 신호 필터 등을 추가로 최적화하여 전략을 더 안정화 할 수 있다. 스톱 스톱 및 포지션 관리와 같은 메커니즘을 추가하면 위험을 추가로 줄일 수 있다.
/*backtest
start: 2023-10-16 00:00:00
end: 2023-11-15 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © TradingMentalist
//@version=4
strategy("Initial template",initial_capital=1000, overlay=true, pyramiding=0, commission_type=strategy.commission.percent, commission_value=0.04, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, currency = currency.USD)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////inputs
//turn on/off longs/shorts / extraneous conditions
longinc=input(true, title="include longs?")
lConSw2=input(true, title="condition two?")
lConSw3=input(true, title="condition three?")
shotinc=input(true, title="include shorts?")
sConSw2=input(true, title="condition two?")
sConSw3=input(true, title="condition three?")
//turn on/off / adjust trade filters (average range/average equity)
sidein2 = input(200, step=10, title='lookback for average range (bars)')
sidein = input(1, title='filter trades if range is less than (%)')/100
equityIn = input(40, title='filter trades if equity is below ema()')
sidewayssw = input(true, title='sideways filter?')
equitysw = input(true, title='equity filter?')
longtpin = input(1,step=0.1, title='long TP %')/100
longslin = input(0.4,step=0.1, title='long SL %')/100
shorttpin = input(1,step=0.1, title='short TP %')/100
shortslin = input(0.4,step=0.1, title='short SL %')/100
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////filters
//(leave as is)
side1 = (close[1] + close[sidein2]) / 2
side2 = close[1] - close[sidein2]
side3 = side2 / side1
notsideways = side3 > sidein
equityMa = equitysw ? ema(strategy.equity, equityIn) : 0
equityCon = strategy.equity >= equityMa
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////indicators
ma1 = ema(close, 9)
ma2 = ema(close, 21)
ma3 = ema(close, 50)
plot(ma1, color=color.new(#E8B6B0,50))
plot(ma2, color=color.new(#B0E8BE,50))
plot(ma3, color=color.new(#00EEFF,50))
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////conditions
//adjust conditions
//-------------------------------------------
longCondition1 = crossover(ma2,ma3)
longCondition2 = close[5] > close[10]
longCondition3 = close[1] > close[2]
shortCondition1 = crossover(ma3,ma2)
shortCondition2 = close[5] < close[10]
shortCondition3 = close[1] < close[2]
closelong = shortCondition1
closeshort = longCondition1
//-------------------------------------------
//(leave as is)
longCondition1in = longCondition1
longCondition2in = lConSw2 ? longCondition2 : true
longCondition3in = lConSw3 ? longCondition3 : true
shortCondition1in = shortCondition1
shortCondition2in = sConSw2 ? shortCondition2: true
shortCondition3in = sConSw3 ? shortCondition3: true
longConditions = longCondition1in and longCondition2in and longCondition3in
shortConditions = shortCondition1in and shortCondition2in and shortCondition3in
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////execution
//(leave as is)
long = sidewayssw ? notsideways and equityCon and longConditions : equityCon and longConditions
short = sidewayssw ? notsideways and equityCon and shortConditions : equityCon and shortConditions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////risk
//(leave as is)
longtplevel = strategy.position_avg_price * (1 + longtpin)
longsllevel = strategy.position_avg_price * (1 - longslin)
shorttplevel = strategy.position_avg_price * (1 - shorttpin)
shortsllevel = strategy.position_avg_price * (1 + shortslin)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////timeframe
//adjust timeframe
//-------------------------------------------
startyear = 2000
startmonth = 1
startday = 1
stopyear = 9999
stopmonth = 12
stopday = 31
//-------------------------------------------
//(leave as is)
startperiod = timestamp(startyear,startmonth,startday,0,0)
periodstop = timestamp(stopyear,stopmonth,stopday,0,0)
timeframe() =>
time >= startperiod and time <= periodstop ? true : false
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////orders
//comments are empty characters for clear chart
if timeframe()
if longinc
if strategy.position_size == 0 or strategy.position_size > 0
strategy.entry(id="long", long=true, when=long, comment=" ")
strategy.exit("stop","long", limit=longtplevel, stop=longsllevel,comment=" ")
strategy.close(id="long", when=closelong, comment = " ")
if shotinc
if strategy.position_size == 0 or strategy.position_size < 0
strategy.entry(id="short", long=false, when=short, comment = " ")
strategy.exit("stop","short", limit=shorttplevel, stop=shortsllevel,comment = " ")
strategy.close(id="short", when=closeshort, comment = " ")