
이동 평균 크로스 전략 (영어: Moving average cross strategy) 은 쌍 이동 평균의 교차 신호를 사용하여 트렌드 방향을 판단하여 구매 및 판매 신호를 생성하는 모멘텀 전략이다. 이 전략은 2개의 간단한 이동 평균과 1개의 지수 이동 평균을 사용하여, 그들의 교차 상황에 따라 다리가 있다고 판단하며, 중단기 거래 전략에 속한다.
이 전략은 3가지 이동 평균을 사용합니다.
전략은 EMA1, SMA1, SMA2의 크기와 관계를 통해 트렌드를 판단합니다.
입력 신호:
출구 신호:
이 전략은 여러 가지 변수 구성을 제공하며, 진입과 퇴출을 판단하기 위해 다른 이동 평균을 선택할 수 있습니다.
이 전략은 다음과 같은 장점을 가지고 있습니다.
이 전략에는 다음과 같은 위험도 있습니다.
위프사우스 위험에는 이동 평균 주기를 적절하게 조정할 수 있습니다. 매개 변수에 민감한 위험에는 매개 변수를 최적화 할 수 있습니다. 지연 위험에는 다른 선행 지표와 함께 최적화 할 수 있습니다.
이 전략은 다음과 같은 부분에서 최적화될 수 있습니다.
이동 평균 경로 전략은 전반적으로 간단하고 직접적이며, 빠른 속도 평균 경로의 경로로 트렌드 방향과 참여 시간을 결정한다. 이 전략의 장점은 Momentum를 잡을 수 있고, 유연한 구성 파라미터를 사용할 수 있지만, 특정 휘파람 위험, 지연 위험 등의 문제가 있습니다. 다른 지표를 도입하여 필터링 최적화를 수행하면 이 전략은 매우 실용적인 정량 거래 전략이 될 수 있습니다.
/*backtest
start: 2023-09-26 00:00:00
end: 2023-10-26 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/
// © Decam9
//@version=5
strategy(title = "Moving Average Crossover", shorttitle = "MA Crossover Strategy", overlay=true,
initial_capital = 100000,default_qty_type = strategy.percent_of_equity, default_qty_value = 10)
//Moving Average Inputs
EMA1 = input.int(title="Fast EMA", group = "Moving Averages:",
inline = "EMAs", defval=5, minval = 1)
isDynamicEMA = input.bool(title = "Dynamic Exponential Moving Average?", defval = true,
inline = "EMAs", group = "Moving Averages:", tooltip = "Changes the source of the MA based on trend")
SMA1 = input.int(title = "Slow SMA", group = "Moving Averages:",
inline = "SMAs", defval = 10, minval = 1)
isDynamicSMA = input.bool(title = "Dynamic Simple Moving Average?", defval = false,
inline = "SMAs", group = "Moving Averages:", tooltip = "Changes the source of the MA based on trend")
SMA2 = input.int(title="Trend Determining SMA", group = "Moving Averages:",
inline = "MAs", defval=13, minval = 1)
//Moving Averages
Trend = ta.sma(close, SMA2)
Fast = ta.ema(isDynamicEMA ? (close > Trend ? low : high) : close, EMA1)
Slow = ta.sma(isDynamicSMA ? (close > Trend ? low : high) : close, SMA1)
//Allowed Entries
islong = input.bool(title = "Long", group = "Allowed Entries:",
inline = "Entries",defval = true)
isshort = input.bool(title = "Short", group = "Allowed Entries:",
inline = "Entries", defval= true)
//Entry Long Conditions
buycond = input.string(title="Buy when", group = "Entry Conditions:",
inline = "Conditions",defval="Fast-Slow Crossing",
options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
intrendbuy = input.bool(title = "In trend", defval = true, group = "Entry Conditions:",
inline = "Conditions", tooltip = "In trend if price is above SMA 2")
//Entry Short Conditions
sellcond = input.string(title="Sell when", group = "Entry Conditions:",
inline = "Conditions2",defval="Fast-Slow Crossing",
options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
intrendsell = input.bool(title = "In trend",defval = true, group = "Entry Conditions:",
inline = "Conditions2", tooltip = "In trend if price is below SMA 2?")
//Exit Long Conditions
closebuy = input.string(title="Close long when", group = "Exit Conditions:",
defval="Fast-Slow Crossing", options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
//Exit Short Conditions
closeshort = input.string(title="Close short when", group = "Exit Conditions:",
defval="Fast-Slow Crossing", options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
//Filters
filterlong =input.bool(title = "Long Entries", inline = 'linefilt', group = 'Apply Filters to',
defval = true)
filtershort =input.bool(title = "Short Entries", inline = 'linefilt', group = 'Apply Filters to',
defval = true)
filterend =input.bool(title = "Exits", inline = 'linefilt', group = 'Apply Filters to',
defval = true)
usevol =input.bool(title = "", inline = 'linefiltvol', group = 'Relative Volume Filter:',
defval = false)
rvol = input.int(title = "Volume >", inline = 'linefiltvol', group = 'Relative Volume Filter:',
defval = 1)
len_vol = input.int(title = "Avg. Volume Over Period", inline = 'linefiltvol', group = 'Relative Volume Filter:',
defval = 30, minval = 1,
tooltip="The current volume must be greater than N times the M-period average volume.")
useatr =input.bool(title = "", inline = 'linefiltatr', group = 'Volatility Filter:',
defval = false)
len_atr1 = input.int(title = "ATR", inline = 'linefiltatr', group = 'Volatility Filter:',
defval = 5, minval = 1)
len_atr2 = input.int(title = "> ATR", inline = 'linefiltatr', group = 'Volatility Filter:',
defval = 30, minval = 1,
tooltip="The N-period ATR must be greater than the M-period ATR.")
usersi =input.bool(title = "", inline = 'linersi', group = 'Overbought/Oversold Filter:',
defval = false)
rsitrhs1 = input.int(title = "", inline = 'linersi', group = 'Overbought/Oversold Filter:',
defval = 0, minval=0, maxval=100)
rsitrhs2 = input.int(title = "< RSI (14) <", inline = 'linersi', group = 'Overbought/Oversold Filter:',
defval = 100, minval=0, maxval=100,
tooltip="RSI(14) must be in the range between N and M.")
issl = input.bool(title = "SL", inline = 'linesl1', group = 'Stop Loss / Take Profit:',
defval = false)
slpercent = input.float(title = ", %", inline = 'linesl1', group = 'Stop Loss / Take Profit:',
defval = 10, minval=0.0)
istrailing = input.bool(title = "Trailing", inline = 'linesl1', group = 'Stop Loss / Take Profit:',
defval = false)
istp = input.bool(title = "TP", inline = 'linetp1', group = 'Stop Loss / Take Profit:',
defval = false)
tppercent = input.float(title = ", %", inline = 'linetp1', group = 'Stop Loss / Take Profit:',
defval = 20)
//Conditions for Crossing
fscrossup = ta.crossover(Fast,Slow)
fscrossdw = ta.crossunder(Fast,Slow)
ftcrossup = ta.crossover(Fast,Trend)
ftcrossdw = ta.crossunder(Fast,Trend)
stcrossup = ta.crossover(Slow,Trend)
stcrossdw = ta.crossunder(Slow,Trend)
//Defining in trend
uptrend = Fast >= Slow and Slow >= Trend
downtrend = Fast <= Slow and Slow <= Trend
justCrossed = ta.cross(Fast,Slow) or ta.cross(Slow,Trend)
//Entry Signals
crosslong = if intrendbuy
(buycond =="Fast-Slow Crossing" and uptrend ? fscrossup:(buycond =="Fast-Trend Crossing" and uptrend ? ftcrossup:(buycond == "Slow-Trend Crossing" and uptrend ? stcrossup : na)))
else
(buycond =="Fast-Slow Crossing"?fscrossup:(buycond=="Fast-Trend Crossing"?ftcrossup:stcrossup))
crossshort = if intrendsell
(sellcond =="Fast-Slow Crossing" and downtrend ? fscrossdw:(sellcond =="Fast-Trend Crossing" and downtrend ? ftcrossdw:(sellcond == "Slow-Trend Crossing" and downtrend ? stcrossdw : na)))
else
(sellcond =="Fast-Slow Crossing"?fscrossdw:(buycond=="Fast-Trend Crossing"?ftcrossdw:stcrossdw))
crossexitlong = (closebuy =="Fast-Slow Crossing"?fscrossdw:(closebuy=="Fast-Trend Crossing"?ftcrossdw:stcrossdw))
crossexitshort = (closeshort =="Fast-Slow Crossing"?fscrossup:(closeshort=="Fast-Trend Crossing"?ftcrossup:stcrossup))
// Filters
rsifilter = usersi?(ta.rsi(close,14) > rsitrhs1 and ta.rsi(close,14) < rsitrhs2):true
volatilityfilter = useatr?(ta.atr(len_atr1) > ta.atr(len_atr2)):true
volumefilter = usevol?(volume > rvol*ta.sma(volume,len_vol)):true
totalfilter = volatilityfilter and volumefilter and rsifilter
//Filtered signals
golong = crosslong and islong and (filterlong?totalfilter:true)
goshort = crossshort and isshort and (filtershort?totalfilter:true)
endlong = crossexitlong and (filterend?totalfilter:true)
endshort = crossexitshort and (filterend?totalfilter:true)
// Entry price and TP
startprice = ta.valuewhen(condition=golong or goshort, source=close, occurrence=0)
pm = golong?1:goshort?-1:1/math.sign(strategy.position_size)
takeprofit = startprice*(1+pm*tppercent*0.01)
// fixed stop loss
stoploss = startprice * (1-pm*slpercent*0.01)
// trailing stop loss
if istrailing and strategy.position_size>0
stoploss := math.max(close*(1 - slpercent*0.01),stoploss[1])
else if istrailing and strategy.position_size<0
stoploss := math.min(close*(1 + slpercent*0.01),stoploss[1])
if golong and islong
strategy.entry("long", strategy.long )
if goshort and isshort
strategy.entry("short", strategy.short)
if endlong
strategy.close("long")
if endshort
strategy.close("short")
// Exit via SL or TP
strategy.exit(id="sl/tp long", from_entry="long", stop=issl?stoploss:na,
limit=istp?takeprofit:na)
strategy.exit(id="sl/tp short",from_entry="short",stop=issl?stoploss:na,
limit=istp?takeprofit:na)