이중 이동 평균 크로스오버 트렌드 전략

저자:차오장, 날짜: 2023-12-06 11:52:10
태그:

img

전반적인 설명

이중 이동 평균 크로스오버 트렌드 전략은 이동 평균에 기반한 거래 전략이다. 빠른 EMA와 느린 SMA 라인의 크로스오버를 구매 및 판매 신호로 사용하고 MACD 지표의 분리를 필터 신호로 결합합니다. 전략은 가격, 트렌드 및 추진력과 같은 여러 요인을 고려하여 비교적 완전한 거래 시스템을 형성합니다.

전략 원칙

이 전략은 200일 길이의 EMA와 100일 길이의 SMA라는 두 개의 이동평균을 사용합니다. 가격이 양쪽 라인을 상향으로 돌파할 때 구매 신호가 생성됩니다. 가격이 양쪽 라인을 상향으로 돌파할 때 판매 신호가 생성됩니다. 이것은 오스실레이션 트렌드와 단기적 인퇴를 효과적으로 필터링 할 수 있습니다.

신호의 신뢰성을 더욱 향상시키기 위해 MACD 지표도 도입된다. 가격이 EMA와 SMA를 뚫고 신호를 형성할 때, MACD의 빠른 선은 아래에서 느린 선을 뚫고 MACD 히스토그램은 실제 구매 신호를 유발하기 위해 0 축 위에 있어야 한다. 반대로, MACD의 빠른 선이 위에서 느린 선을 뚫고 MACD 히스토그램이 0 축 아래에 있으면 실제 판매 신호를 유발한다.

또한 전략에는 스톱 로스 및 트레이드 노프트가 설정되어 있습니다. 전략이 포지션을 열면 사용자에 의해 설정된 비율에 따라 스톱 로스 포인트와 트레이드 노프트 포인트가 계산되고 설정됩니다. 이것은 단일 거래의 위험을 효과적으로 제어 할 수 있습니다.

요약하자면 이 전략은 여러 지표를 종합적으로 고려하고, 구매 및 판매 신호에 대한 엄격한 필터링 조건을 설정하고, 위험을 관리하기 위해 스톱 로스 및 수익을 채택하여 비교적 엄격하고 완전한 거래 시스템을 형성합니다.

이점 분석

이중 이동 평균 크로스오버 트렌드 전략은 다음과 같은 장점을 가지고 있습니다.

  1. 여러 가지 지표를 결합하고 가격, 트렌드 및 모멘텀을 포괄적으로 고려하고 신호에 대한 엄격한 필터링 조건을 설정하면 잘못된 신호를 효과적으로 방지하고 신호 신뢰성을 향상시킬 수 있습니다.

  2. 서로 다른 매개 변수를 가진 두 개의 이동 평균을 사용하면 시장 트렌드를 더 잘 식별하고 오스실레이션 시장을 필터 할 수 있습니다. 빠른 EMA 라인은 가격 변화를 적시에 추적하는 데 사용됩니다. 느린 SMA 라인은 장기 트렌드를 결정하는 데 사용됩니다. 두 라인의 조합은 더 잘 작동합니다.

  3. MACD 지표는 다양한 시장의 특성에 따라 조정할 수 있는 사용자 정의 가능한 매개 변수를 도입하고 높은 유연성을 가지고 있습니다. MACD의 설정은 거래 신호가 가격, 트렌드 및 동력으로 동시에 지원되도록 보장하므로 매우 강력한 응용 가치를 가지고 있습니다.

  4. 스톱 로스 및 영업점 설정은 단일 거래 손실에 대한 통제를 극대화하고 과도한 손실을 피할 수 있습니다. 수익을 취하기 위한 합리적인 비율 설정은 부분 수익을 차단하고 수익을 얻은 후 시장 위험 노출을 줄일 수 있습니다.

  5. 이 전략의 매개 변수는 유연하게 설정 될 수 있으며 최적화 결과에 따라 전략을 조정 할 수 있습니다. 이는 매우 실용적입니다. 다양한 시장과 매개 변수를 테스트하고 최적화 할 수있는 충분한 공간이 있습니다.

위험 분석

이중 이동 평균 크로스오버 트렌드 전략은 또한 다음과 같은 영역에서 몇 가지 위험을 가지고 있습니다.

  1. 주식 가격이 급격한 변동을 보이는 경우, EMA와 SMA는 여러 번 거짓으로 교차할 수 있으며, 이로 인해 거래 신호가 자주 열리고 닫히게 됩니다. 이것은 거래 빈도와 수수료 지출을 증가시킵니다.

  2. MACD 지표는 잘못된 브레이크가있을 수 있습니다. 특히 이 운동이 아직 명확하지 않은 과정에서. 이 경우 신호도 신뢰할 수 없으며 불필요한 손실을 초래할 수 있습니다.

  3. 스톱 로스 설정의 위치와 비율은 이익과 손실 결과에 큰 영향을 미칩니다. 스톱 로스가 너무 작게 설정되면 잡힐 위험이 있습니다. 스톱 로스가 너무 커 설정되면 단일 손실이 너무 커질 수 있습니다. 최적의 매개 변수를 찾기 위해 충분한 테스트가 필요합니다.

  4. 트렌드 추적 지표로서, 이동 평균의 효과는 가격이 빠르게 반전될 때 할인됩니다. 전략은 가격 반전으로 인해 더 큰 손실이 발생하기 전에 손실을 멈출 시간이 없을 수 있습니다.

이에 대응하는 해결책은 다음과 같습니다.

  1. 변동성 시장의 경우 크로스오버 빈도를 줄이기 위해 낮은 매개 변수 EMA와 SMA를 사용하여 이동 평균의 매개 변수를 적절히 조정합니다.

  2. MACD가 0선 이상과 아래로 돌파하는 것과 같은 필터링 조건을 높여서 거짓 돌파를 어느 정도 줄일 수 있습니다. KDJ와 BOLL과 같은 다른 지표를 결합하는 것도 고려할 수 있습니다.

  3. 스톱 로스 위치와 비율의 설정은 최적의 매개 변수를 찾기 위해 충분한 백테스팅과 최적화를 필요로 합니다. 이러한 기초에 따라 지속적인 모니터링과 동적 조정도 고려되어야 합니다.

  4. 급격한 가격 전환을 식별하기 위한 메커니즘을 설정할 수 있습니다. 비정상적인 전환이 발견되면 위험 노출을 제어하기 위해 포지션을 줄이거나 거래 전략을 중단하는 등 긴급 조치를 취할 수 있습니다.

최적화 방향

이중 이동 평균의 크로스오버 트렌드 전략을 더 이상 최적화 할 수있는 여지가 여전히 있습니다. 주로 다음 측면에서:

  1. 더 나은 매개 변수를 찾기 위해 더 많은 지표를 조합하여 테스트하십시오. 예를 들어 BOLL 채널을 통합하고 변동성의 영향을 고려하십시오.

  2. 이동 평균 길이의 매개 변수를 최적화하여 다른 시장 조건에서 최상의 매개 변수 조합을 찾습니다. 롤링 매개 변수 최적화 또한 옵션입니다.

  3. 보다 과학적이고 합리적인 스톱 로스 및 수익 전략을 수립하십시오. 예를 들어 후속 스톱 로스 도입 또는 역사적 통계 결과를 기반으로 동적 리스크 보상 비율을 설정하십시오. 이것은 전략의 안정성을 더욱 향상시킬 수 있습니다.

  4. 비정상적인 가격 전환을 자동으로 식별하고 긴급 대응하는 메커니즘을 구축합니다. 극단적인 시장 조건에서 엄청난 손실을 피하기 위해 적극적으로 포지션을 줄이거나 전략을 중단하십시오.

  5. 외환, 암호화폐 및 기타 종류와 같은 거래 품종을 확장하십시오. 전략의 적용 가능성을 확장하기 위해 다른 품종에 대한 매개 변수 안정성을 테스트하십시오.

  6. 고정 금액 거래, 고정 위치 비율 등 전략의 자본 관리 전략을 최적화하십시오. 단일 거래 손실 위험을 제어하여 전체 자본 곡선을 더 안정화하십시오.

결론

이중 이동 평균 크로스오버 트렌드 전략은 여러 요인을 포괄적으로 고려합니다. 거래 신호를 생성 할 때 신호 신뢰성을 보장하기 위해 가격, 트렌드 및 추진력과 같은 여러 지표의 지원이 필요합니다. 이 전략은 또한 개별 거래의 위험을 효과적으로 제어하기 위해 이동 스톱 손실과 수익을 채택합니다. 전략의 유연한 매개 변수 설정은 자동 거래에 매우 실용적입니다.

그러나 어떤 전략도 완벽할 수 없다. 이 전략은 또한 빈번한 거래, 잘못된 브레이크, 스톱 로스 포지셔닝 등과 같은 응용에 있어서 몇 가지 어려움을 겪을 것이다. 전략의 견고성과 수익성을 더욱 향상시키기 위해서는 매개 변수 포트폴리오를 최적화하고, 새로운 기술적 지표를 도입하고, 스톱 로스 메커니즘을 개선하는 등 여러 측면에서 노력이 필요하다.

요약하자면, 이중 이동 평균 크로스오버 트렌드 전략은 비교적 완전하고 엄격한 거래 시스템을 형성합니다. 미래 연구 및 응용 분야에서 지속적인 최적화와 개선을 통해 전략은 더 큰 실용적 가치를 얻을 수 있습니다.


/*backtest
start: 2023-11-01 00:00:00
end: 2023-11-30 23:59:59
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// Hi,
// This is my first strategy made by myself(except for the MACD indicator). I'm publishing this to get myself out there and for some newer people to see how a basic strategy works. All credits go to Zen&TheArtofTrading, for teaching me almost everything I know about Pinescript
// The strategy is basically an MACD crossover trend strategy. If the MACD line crosses the signal line upward, above the zero point of the histogram, while the price is above 200 EMA and 100 SMA it's a buy signal
// If the MACD line crosses the signal line downward, while below zero point of the histogram, as well as the price being below 200 EMA and 100 SMA it's a sell signal
// I used the 200 EMA and 100 SMA because I wanted to filter weak signals as much as possible when the market is ranging, if you have any suggestions to go around this better, please let me know, still learning everyday

// If you have any suggestions, tips or tricks please let me know. I'm still new to Pinescript, but having a lot of fun trying stuff out. If you see something in my code that you don't understand, feel free to ask, I'll try to answer as best as I can

// I opened the strategy with predetermined backtesting pyramiding, currency etc. This made the progress of backtesting multiple TP and SL easier. Also the commission value is from Binance Futures, I just left it in there for anyone who wants to just copy this strategy
strategy("MACD Crossover Trend Strategy Template", overlay = true )

// Determining inputs and values, I just copied the built-in MACD strategy and removed everything I didn't need, just needed the barebone indicator and added EMA + SMA inputs
fast_length = input(title = "Fast Length", type = input.integer, defval = 12, group = "MACD Values")
slow_length = input(title = "Slow Length", type = input.integer, defval = 26, group = "MACD Values")
src = input(title = "Source", type = input.source, defval = close, group = "MACD Values")
signal_length = input(title = "Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9, group = "MACD Values")
sma_source = input(title = "Simple MA (Oscillator)", type = input.bool, defval = false, group = "MACD Values")
sma_signal = input(title = "Simple MA (Signal Line)", type = input.bool, defval = false, group = "MACD Values")
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length)
hist = macd - signal
emaLength = input(title = "EMA", type = input.integer, defval = 200, step = 10, group = "Moving Averages")
smaLength = input(title = "SMA", type = input.integer, defval = 100, step = 10, group = "Moving Averages")

// Input backtest range, you can adjust this here or in the input options
fromMonth = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12, group = "Backtest Date Range")
fromDay   = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31, group = "Backtest Date Range")
fromYear  = input(defval = 2000, title = "From Year",       type = input.integer, minval = 1970, group = "Backtest Date Range")
thruMonth = input(defval = 1,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12, group = "Backtest Date Range")
thruDay   = input(defval = 1,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31, group = "Backtest Date Range")
thruYear  = input(defval = 2099, title = "Thru Year",       type = input.integer, minval = 1970, group = "Backtest Date Range")

// Inputs for EMA, SMA and to adjust your take profit and stop losses in the input options while backtesting, it's result of your input is calculated back to percentages
ema = ema(close, emaLength)
sma = sma(close, smaLength)
profitlong = input(title = "Profit Long %", type = input.float, defval = 2, minval = 0.1, maxval = 100, step = 0.1, group = "TP / SL %") * 0.01
losslong = input(title = "Loss Long %", type = input.float, defval = 1, minval = 0.1, maxval = 100, step = 0.1, group = "TP / SL %") * 0.01
profitshort = input(title = "Profit Short %", type = input.float, defval = 2, minval = 0.1, maxval = 100, step = 0.1, group = "TP / SL %") * 0.01
lossshort = input(title = "Loss Short %", type = input.float, defval = 1, minval = 0.1, maxval = 100, step = 0.1, group = "TP / SL %") * 0.01

// Check EMA and SMA also check the backtest range. inDataRange is a true or false statement, true if the date right now is between the parameters that's filled at the corresponding inputs
// (for example 1-1-2020 till 12-12-2020, if that specific bar is between these dates, statement is true and trade will be executed)
// If the date is not in between the given parameters, statement turns to false and it won't allow new trades and closes all current trades as seen with the strategy.close_all function
inDataRange = (time >= timestamp(syminfo.timezone, fromYear, fromMonth, fromDay, 0, 0)) and (time < timestamp(syminfo.timezone, thruYear, thruMonth, thruDay, 0, 0))
long = close > ema and close > sma and inDataRange
short = close < ema and close < sma and inDataRange

// Entry and exit signals + checking backtest date range, what the signals are supposed to do is noted at the beginning of the code
// I want a way to filter out weak signals that are ranging around the zero point of the histogram. 
// So far couldn't think of a decent way to do this over multiple symbols since the range of the histogram changes with every symbol, sometimes ranging between 0 and 1 or sometimes ranging between 0 and 1000
// I could probably use a cofficiency or something, but that's beyond my grasp at the moment
// Also I wanted a way to let my strategy determine a stop loss based on the pullback and having a 1.5 risk/reward TP on top of that. Couldn't really figure out a way to determine the pullback
if (crossover(macd, signal) and macd > 0)
    strategy.entry("Long", long = strategy.long,
     comment = "Long Buy",
     when = long)

strategy.exit("Exit Long", "Long", profit = close * profitlong / syminfo.mintick, loss = close * losslong / syminfo.mintick)


if (crossunder(macd, signal) and macd < 0)
    strategy.entry("Short", long = strategy.short,
     comment = "Short Buy",
     when = short)

strategy.exit("Exit Short", "Short", profit = close * profitshort / syminfo.mintick, loss = close * lossshort / syminfo.mintick)

// To make sure the backtesting doesn't leave a position open beyond, or before, our applied dates
if (not inDataRange)
    strategy.close_all()

// plot(strategy.equity, title="equity", color=color.red, linewidth=2, style=plot.style_areabr)

더 많은