이 전략은 MACD 지표의 황금 십자 및 죽은 십자 신호, 폐쇄 가격과 중간선과의 관계 및 가격 변동성 특성을 결합하여 입점과 출점을 결정합니다. 또한 위험을 제어하고 안정적인 수익을 창출하면서 더 많은 거래 기회를 얻기 위해 재입구 및 수정 입구 메커니즘을 설정합니다.
이 전략은 주로 다음과 같은 원칙에 기초합니다.
MACD 빠른 라인과 느린 라인 황금 십자 및 죽은 십자 를 사용하여 황소와 곰 시장 및 특정 입구 지점을 결정합니다.
트렌드의 끝과 출구점을 결정하기 위해 닫기 가격과 중간 선의 관계를 사용하십시오.
현재 MACD 트렌드가 끝나면 같은 방향으로 시장에 다시 진입하는 재진입 메커니즘을 설정하여 수익을 높입니다.
트렌드 내에서 부분 가격 수정 중 포지션을 추가하기 위해 수정 입시 메커니즘을 설정합니다.
위와 같이 위치를 동적으로 조정하여 트렌드 내에서 수익을 극대화하고 트렌드가 끝나면 빠르게 종료합니다.
구체적으로, 전략은 먼저 MACD 빠른 라인과 느린 라인 사이에서 금색 십자 또는 죽은 십자 발생 여부를 확인하여 긴 또는 짧은 것을 확인합니다. 그 다음 폐쇄 가격이 트렌드의 끝을 결정하고 포지션을 닫는 중간 라인을 만지는지 확인합니다.
또한, 전략은 초기 트렌드가 종료된 후 MACD가 동일한 방향으로 신호를 계속 표시하는 경우 원래 방향으로 포지션을 다시 여는 재입구 메커니즘을 갖추고 있습니다. 또한 완전한 반전 전에 작은 인하 동안 포지션을 적당하게 추가 할 수 있는 수정 입구 메커니즘이 있습니다.
이러한 설정을 통해 전략은 역동적으로 포지션을 조정하고, 진입 및 출구 주파수를 증가시키고, 트렌드 내에서 위험을 제어하면서 수익을 극대화 할 수 있습니다.
이 다중 지표 전략의 주요 장점은 다음과 같습니다.
MACD는 진입의 경향과 전환점을 식별합니다.
마감 가격과 중간선 관계는 트렌드 끝을 정확하게 결정합니다.
재입구는 자본 활용 효율을 높여줍니다.
보정 항목은 트렌드를 파악하기 위해 순서를 추가합니다.
통제 가능한 위험과 함께 높은 거래 빈도는 높은 수익 요인을 제공합니다.
제품과 시장에서 최적화를 위해 사용자 정의 가능한 매개 변수.
명확한 논리와 간결한 코드는 실시간 거래에 용이합니다.
충분한 백테스트 데이터가 신뢰성을 보장합니다.
주요 위험은 다음과 같습니다.
잘못된 MACD 신호의 확률은 다른 지표로 확인되어야 합니다.
너무 단단한 스톱은 변동적인 움직임에 의해 멈출 수 있습니다.
무역의 빈도가 높아지면 자본 사용량을 통제해야 합니다.
수정 항목은 철수 중에 손실을 일으킬 수 있습니다.
다양한 제품과 시장에 최적화가 필요합니다.
지속적인 백테스팅과 최적화를 요구합니다.
실전 거래에 있어 슬리퍼 비용도 고려해야 합니다.
리스크 관리 조치에는 손실을 제한하기 위해 스톱을 사용하는 것, 자본 활용을 평가하는 것, 백테스팅을 통해 제품별 매개 변수를 최적화하는 것, 매개 변수를 정제하기 위해 시장 역학을 모니터링하는 것, 테스트에서 미끄러지는 것을 회계하는 것이 포함됩니다.
개선 가능성:
신호를 확인하기 위해 다른 지표를 추가합니다. 예를 들어 KDJ.
적응적인 동적 정지를 구현합니다.
다시 입력하고 수정 입력 논리를 최적화
제품별 매개 변수 최적화
입시에 대한 자본 활용을 최적화합니다.
부수 지표를 포함해서 회수 출입으로 인한 손실을 피합니다.
출구 메커니즘을 추가합니다.
자동 거래 로봇을 만들자
미끄러짐과 같은 현실적인 요소를 고려합니다.
이들은 안정성, 적응력, 자동화 및 라이브 성능을 더욱 향상시킬 수 있습니다.
이 전략은 MACD 신호, 폐쇄 가격 분석 및 여러 입구 메커니즘을 통합하여 위험을 제어하는 동시에 트렌드를 극대화합니다. 높은 자본 효율성과 구현 용이성이 있지만 위험 통제 및 최적화가 필요합니다. 자동화는 강력한 양적 거래 시스템으로 만들 수 있습니다.
/*backtest start: 2023-09-29 00:00:00 end: 2023-10-29 00:00:00 period: 2h 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/ // © Puckapao //@version=4 // strategy(title="MACD", shorttitle="MACD", overlay=true, initial_capital=10000.00, currency="USD", default_qty_type=strategy.cash, default_qty_value=10000.00) // Getting inputs reenter_delay = input(title="Re-enter Delay", type=input.integer, defval=2) sculp_delay = input(title="Sculp Delay", type=input.integer, defval=4) fast_length = input(title="Fast Length", type=input.integer, defval=12) slow_length = input(title="Slow Length", type=input.integer, defval=26) src = input(title="Source", type=input.source, defval=close) signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9) sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false) sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=true) ema_period = input(title="EMA Period", type=input.integer, defval=21) // Get date startDate = input(title="Start Date", type=input.integer, defval=19, minval=1, maxval=31) startMonth = input(title="Start Month", type=input.integer, defval=09, minval=1, maxval=12) startYear = input(title="Start Year", type=input.integer, defval=2017, minval=1800, maxval=2100) endDate = input(title="End Date", type=input.integer, defval=31, minval=1, maxval=31) endMonth = input(title="End Month", type=input.integer, defval=3, minval=1, maxval=12) endYear = input(title="End Year", type=input.integer, defval=2021, minval=1800, maxval=2100) // STEP 2: // Look if the close time of the current bar // falls inside the date range inDateRange = true reenter_cnt = 0 reenter_cnt := nz(reenter_cnt[1]) sculp_cnt = 0 sculp_cnt := nz(sculp_cnt[1]) close_cnt = 0 close_cnt := nz(close_cnt[1]) on_long = false on_long := nz(on_long[1]) on_short = false on_short := nz(on_short[1]) sculp = false reenter = false slowdown = false ema = ema(close, ema_period) // Plot colors col_grow_above = #26A69A col_grow_below = #FFCDD2 col_fall_above = #B2DFDB col_fall_below = #EF5350 col_macd = #0094ff col_signal = #ff6a00 // Calculating 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 // plot(hist, title="Histogram", style=plot.style_columns, color=(hist>=0 ? (hist[1] < hist ? col_grow_above : col_fall_above) : (hist[1] < hist ? col_grow_below : col_fall_below) ), transp=0 ) // plot(macd, title="MACD", color=col_macd, transp=0) // plot(signal, title="Signal", color=col_signal, transp=0) cross_up = crossover(macd, signal) cross_down = crossunder(macd, signal) if (inDateRange) over_macd = macd > 0 and signal > 0 ? true : false under_macd = macd < 0 and signal < 0 ? true : false over_water = close > ema ? true : false under_water = close < ema ? true : false slowdown := hist >= 0 ? (hist[1] > hist ? true : false) : (hist[1] > hist ? false : true) reenter := hist >= 0 ? (hist[1] < hist ? true : false) : (hist[1] > hist ? true : false) sculp := (hist >= 0 ? (hist[1] > hist ? true : false) : (hist[1] < hist ? true : false)) if(reenter == true) if(reenter_cnt < reenter_delay) reenter_cnt := reenter_cnt + 1 else if(reenter_cnt > 0) reenter_cnt := reenter_cnt - 1 if(sculp == true) if(sculp_cnt < sculp_delay) sculp_cnt := sculp_cnt + 1 else if(sculp_cnt > 0) sculp_cnt := sculp_cnt - 1 if(slowdown == false) if(close_cnt < 2) close_cnt := close_cnt + 1 else close_cnt := 0 // plotchar(fork_cnt, "fork count", "") // plotchar(spoon_cnt, "spoon count", "") // Entry if (cross_up == true) strategy.entry("long", strategy.long, comment = "long", alert_message = "long") on_long := true on_short := false if (cross_down == true) strategy.entry("short", strategy.short, comment = "short", alert_message = "short") on_short := true on_long := false // Sculp bottom / top if (sculp == true and sculp_cnt >= sculp_delay) if (hist >= 0) strategy.entry("sculp-short", strategy.short, comment = "sculp-short", alert_message = "sculp-short") else strategy.entry("sculp-long", strategy.long, comment = "sculp-long", alert_message = "sculp-long") sculp_cnt := 0 sculp := false // Re-Entry if (reenter == true and reenter_cnt >= reenter_delay) if (hist >= 0) strategy.entry("re-long", strategy.long, comment = "re-long", alert_message = "re-long") else strategy.entry("re-short", strategy.short, comment = "re-short", alert_message = "re-short") reenter_cnt := 0 reenter := false // Close strategy.close("long", when = slowdown, comment = "close long", alert_message = "close long") strategy.close("short", when = slowdown, comment = "close short", alert_message = "close short") strategy.close("re-long", when = slowdown, comment = "close re-long", alert_message = "close re-long") strategy.close("re-short", when = slowdown, comment = "close re-short", alert_message = "close re-short") strategy.close("sculp-long", when = slowdown, comment = "close sculp-long", alert_message = "close sculp-long") strategy.close("sculp-short", when = slowdown, comment = "close sculp-short", alert_message = "close sculp-short") if (slowdown) if (hist >= 0) on_long := false else on_short := false plotchar(slowdown, "close", "") plotchar(reenter, "reenter", "") plotchar(reenter_cnt, "reenter count", "") plotchar(sculp, "sculp", "") plotchar(sculp_cnt, "sculp count", "")