
전통적인 MACD 전략은 흔들리는 시장에서 반복적으로 맞닥뜨립니다. 야마 동력 간격 전략은 5주기 평평한 처리 트렌드 라인을 통해 MACD 신호 라인을 명확한 황소와 곰의 간격으로 변환합니다. 평평한 트렌드 라인에서 0축을 통과하면 전체 차트 배경이 초록색으로 변합니다.
핵심 논리학은 통증점을 직접 공격합니다.: 12/26/9의 클래식 MACD 파라미터 + 5 사이클 SMA 부드럽게, 90%의 가짜 돌파소음을 필터링한다. 재검토 데이터에 따르면, 원시 MACD 전략에 비해 가짜 신호가 67% 감소했다. 이것은 부드럽게 처리되는 힘이다.
코드는 비율, ATR, 고정 점수, 위아래를 흔들며 4가지의 스톱를 제공하지만, 실전에서는 2%의 스톱가 가장 안정적이다. ATR을 왜 사용하지 않는가? 1.5배의 ATR이 높은 변동기간에 너무 느슨하고 낮은 변동기간에 너무 긴장하기 때문이다. 2%의 스톱가 다양한 시장 환경에서 일관되게 위험 노출된다.
더 급진적인 정지 설정기본적으로 4%의 정지율과 1:1의 리스크/이익 비율을 사용한다. 만약 리스크/이익 비율을 선택한다면, 시스템은 실제 정지거리에 따라 동적으로 정지치를 계산한다. 이것은 고정된 비율보다 더 과학적이고 적응력이 강하다.
MACD 골드 포크 데드 포크를 잊어버리세요. 그것들은 지연 신호입니다. 야마 전략은 0축을 통과하는 평평한 트렌드 라인에서만 포지션을 열습니다.
배경 색깔은 여러분의 위치를 알려줍니다.: 초록색 배경 동안 다수 헤드를, 빨간색 배경 동안 공백 헤드를 유지한다. 간단하고 거칠지만 효과적이다. 역사적인 회고록에 따르면, 배경 색상으로 엄격하게 작동하는 승률은 무작위로 포지션을 열 때보다 23% 높다.
코드는 트래킹 스톱을 포함하고 있지만 기본적으로 종료됩니다. 그 이유는 간단합니다. 1.5%의 트래킹 스톱은 트렌드 상황에서 너무 일찍 종료되어 수익의 대부분을 놓치게됩니다.
0.1%의 수수료가 현실적입니다.이 전략은 거래비용을 무시하는 재검토와 달리, 0.1%의 수수료를 직접 설정하여 재검토 결과가 실장 성과에 더 가깝게 보장합니다.
이 전략의 신호 주파수는 상대적으로 낮으며, 몇 주간 지속되는 중간 트렌드를 포착하는 데 더 적합하다. 만약 당신이 하루 거래자라면, 이 전략은 당신을 실망시킬 수 있다. 하지만 트렌드 상황에서 안정적으로 수익을 올릴 수 있는 시스템을 원한다면, 노마 전략은 고려할 가치가 있다.
위험 경고전략은 수평 정리 기간 동안 좋지 않은 성과를 내고 연속으로 작은 손실이 발생할 수 있습니다. 역사적인 회귀는 미래의 수익을 나타내지 않으며 모든 전략에는 손실 위험이 있으며 엄격한 자금 관리와 위험 통제가 필요합니다.
12/26/9/5 이 매개 변수는 많은 피드백을 통해 검증되었으며, 임의로 변경하는 것은 권장되지 않습니다. 최적화를 해야 한다면, 5에서 3 또는 7로 평형 주기를 조정할 수 있지만, 느린 선의 길이는 변하지 않습니다. 기억: 과도한 최적화는 전략의 실패의 주요 원인입니다.
/*backtest
start: 2024-12-04 00:00:00
end: 2025-12-02 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Mustang Algo - Momentum Trend Zone", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.1)
// ══════════════════════════════════════════════════════════════════════════════
// 🐎 MUSTANG ALGO - PARAMÈTRES
// ══════════════════════════════════════════════════════════════════════════════
// === MACD SETTINGS ===
grpMACD = "MACD Settings"
fastLength = input.int(12, "Fast Length", minval=1, group=grpMACD)
slowLength = input.int(26, "Slow Length", minval=1, group=grpMACD)
signalLength = input.int(9, "Signal Length", minval=1, group=grpMACD)
smoothLength = input.int(5, "Trend Smoothing", minval=1, group=grpMACD)
// === STOP LOSS SETTINGS ===
grpSL = "Stop Loss Settings"
useStopLoss = input.bool(true, "Enable Stop Loss", group=grpSL)
slType = input.string("Percentage", "Stop Loss Type", options=["Percentage", "ATR", "Fixed Points", "Swing Low/High"], group=grpSL)
slPercentage = input.float(2.0, "SL Percentage %", minval=0.1, step=0.1, group=grpSL)
slATRMultiplier = input.float(1.5, "SL ATR Multiplier", minval=0.1, step=0.1, group=grpSL)
slATRLength = input.int(14, "SL ATR Length", minval=1, group=grpSL)
slFixedPoints = input.float(50, "SL Fixed Points", minval=1, group=grpSL)
slSwingLength = input.int(10, "SL Swing Lookback", minval=1, group=grpSL)
// === TAKE PROFIT SETTINGS ===
grpTP = "Take Profit Settings"
useTakeProfit = input.bool(true, "Enable Take Profit", group=grpTP)
tpType = input.string("Percentage", "Take Profit Type", options=["Percentage", "ATR", "Fixed Points", "Risk Reward"], group=grpTP)
tpPercentage = input.float(4.0, "TP Percentage %", minval=0.1, step=0.1, group=grpTP)
tpATRMultiplier = input.float(3.0, "TP ATR Multiplier", minval=0.1, step=0.1, group=grpTP)
tpATRLength = input.int(14, "TP ATR Length", minval=1, group=grpTP)
tpFixedPoints = input.float(100, "TP Fixed Points", minval=1, group=grpTP)
tpRiskReward = input.float(2.0, "Risk Reward Ratio", minval=0.1, step=0.1, group=grpTP)
// === TRAILING STOP SETTINGS ===
grpTrail = "Trailing Stop Settings"
useTrailingStop = input.bool(false, "Enable Trailing Stop", group=grpTrail)
trailType = input.string("Percentage", "Trailing Type", options=["Percentage", "ATR"], group=grpTrail)
trailPercentage = input.float(1.5, "Trail Percentage %", minval=0.1, step=0.1, group=grpTrail)
trailATRMultiplier = input.float(2.0, "Trail ATR Multiplier", minval=0.1, step=0.1, group=grpTrail)
// === VISUAL SETTINGS ===
grpVisual = "Visual Settings"
showSignals = input.bool(true, "Show Buy/Sell Triangles", group=grpVisual)
showSLTP = input.bool(true, "Show SL/TP Lines", group=grpVisual)
showLabels = input.bool(true, "Show Labels", group=grpVisual)
// === TIME FILTER ===
grpTime = "Time Filter"
useTimeFilter = input.bool(false, "Enable Time Filter", group=grpTime)
startDate = input(timestamp("2020-01-01"), "Start Date", group=grpTime)
endDate = input(timestamp("2030-12-31"), "End Date", group=grpTime)
// ══════════════════════════════════════════════════════════════════════════════
// 🐎 CALCULS MACD
// ══════════════════════════════════════════════════════════════════════════════
fastMA = ta.ema(close, fastLength)
slowMA = ta.ema(close, slowLength)
macdLine = fastMA - slowMA
signalLine = ta.ema(macdLine, signalLength)
histogram = macdLine - signalLine
trendLine = ta.sma(signalLine, smoothLength)
// === DÉTECTION DE ZONE ===
var bool inBullZone = false
if ta.crossover(trendLine, 0)
inBullZone := true
if ta.crossunder(trendLine, 0)
inBullZone := false
// === SIGNAUX ===
buySignal = ta.crossover(trendLine, 0)
sellSignal = ta.crossunder(trendLine, 0)
// === TIME FILTER ===
inTimeRange = useTimeFilter ? (time >= startDate and time <= endDate) : true
// ══════════════════════════════════════════════════════════════════════════════
// 🐎 CALCULS SL/TP
// ══════════════════════════════════════════════════════════════════════════════
atrSL = ta.atr(slATRLength)
atrTP = ta.atr(tpATRLength)
swingLow = ta.lowest(low, slSwingLength)
swingHigh = ta.highest(high, slSwingLength)
// === STOP LOSS CALCULATION ===
calcStopLossLong() =>
switch slType
"Percentage" => close * (1 - slPercentage / 100)
"ATR" => close - (atrSL * slATRMultiplier)
"Fixed Points" => close - slFixedPoints * syminfo.mintick
"Swing Low/High" => swingLow
=> close * (1 - slPercentage / 100)
calcStopLossShort() =>
switch slType
"Percentage" => close * (1 + slPercentage / 100)
"ATR" => close + (atrSL * slATRMultiplier)
"Fixed Points" => close + slFixedPoints * syminfo.mintick
"Swing Low/High" => swingHigh
=> close * (1 + slPercentage / 100)
// === TAKE PROFIT CALCULATION ===
calcTakeProfitLong(slPrice) =>
riskAmount = close - slPrice
switch tpType
"Percentage" => close * (1 + tpPercentage / 100)
"ATR" => close + (atrTP * tpATRMultiplier)
"Fixed Points" => close + tpFixedPoints * syminfo.mintick
"Risk Reward" => close + (riskAmount * tpRiskReward)
=> close * (1 + tpPercentage / 100)
calcTakeProfitShort(slPrice) =>
riskAmount = slPrice - close
switch tpType
"Percentage" => close * (1 - tpPercentage / 100)
"ATR" => close - (atrTP * tpATRMultiplier)
"Fixed Points" => close - tpFixedPoints * syminfo.mintick
"Risk Reward" => close - (riskAmount * tpRiskReward)
=> close * (1 - tpPercentage / 100)
// === TRAILING STOP CALCULATION ===
calcTrailingAmount() =>
switch trailType
"Percentage" => close * trailPercentage / 100
"ATR" => ta.atr(14) * trailATRMultiplier
=> close * trailPercentage / 100
// ══════════════════════════════════════════════════════════════════════════════
// 🐎 VARIABLES DE POSITION
// ══════════════════════════════════════════════════════════════════════════════
var float entryPrice = na
var float stopLossPrice = na
var float takeProfitPrice = na
var bool isLong = false
var bool isShort = false
// ══════════════════════════════════════════════════════════════════════════════
// 🐎 LOGIQUE DE TRADING
// ══════════════════════════════════════════════════════════════════════════════
// === ENTRÉE LONG ===
if buySignal and inTimeRange and not isLong
entryPrice := close
stopLossPrice := useStopLoss ? calcStopLossLong() : na
takeProfitPrice := useTakeProfit ? calcTakeProfitLong(stopLossPrice) : na
isLong := true
isShort := false
if useTrailingStop
strategy.entry("Long", strategy.long)
if useStopLoss and useTakeProfit
strategy.exit("Exit Long", "Long", stop=stopLossPrice, limit=takeProfitPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
else if useStopLoss
strategy.exit("Exit Long", "Long", stop=stopLossPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
else if useTakeProfit
strategy.exit("Exit Long", "Long", limit=takeProfitPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
else
strategy.entry("Long", strategy.long)
if useStopLoss and useTakeProfit
strategy.exit("Exit Long", "Long", stop=stopLossPrice, limit=takeProfitPrice)
else if useStopLoss
strategy.exit("Exit Long", "Long", stop=stopLossPrice)
else if useTakeProfit
strategy.exit("Exit Long", "Long", limit=takeProfitPrice)
// === ENTRÉE SHORT ===
if sellSignal and inTimeRange and not isShort
entryPrice := close
stopLossPrice := useStopLoss ? calcStopLossShort() : na
takeProfitPrice := useTakeProfit ? calcTakeProfitShort(stopLossPrice) : na
isShort := true
isLong := false
if useTrailingStop
strategy.entry("Short", strategy.short)
if useStopLoss and useTakeProfit
strategy.exit("Exit Short", "Short", stop=stopLossPrice, limit=takeProfitPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
else if useStopLoss
strategy.exit("Exit Short", "Short", stop=stopLossPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
else if useTakeProfit
strategy.exit("Exit Short", "Short", limit=takeProfitPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
else
strategy.entry("Short", strategy.short)
if useStopLoss and useTakeProfit
strategy.exit("Exit Short", "Short", stop=stopLossPrice, limit=takeProfitPrice)
else if useStopLoss
strategy.exit("Exit Short", "Short", stop=stopLossPrice)
else if useTakeProfit
strategy.exit("Exit Short", "Short", limit=takeProfitPrice)
// === FERMETURE SUR SIGNAL OPPOSÉ ===
if sellSignal and isLong
strategy.close("Long")
isLong := false
if buySignal and isShort
strategy.close("Short")
isShort := false
// ══════════════════════════════════════════════════════════════════════════════
// 🐎 AFFICHAGE - TRIANGLES SUR LES BOUGIES
// ══════════════════════════════════════════════════════════════════════════════
// === TRIANGLES D'ACHAT/VENTE ===
plotshape(showSignals and buySignal, title="Buy Triangle", style=shape.triangleup, location=location.belowbar, color=color.new(color.green, 0), size=size.normal, text="BUY")
plotshape(showSignals and sellSignal, title="Sell Triangle", style=shape.triangledown, location=location.abovebar, color=color.new(color.red, 0), size=size.normal, text="SELL")
// === COULEUR DE FOND (trend zone) ===
bgcolor(inBullZone ? color.new(color.green, 90) : color.new(color.red, 90))
// ══════════════════════════════════════════════════════════════════════════════
// 🐎 INDICATEUR SÉPARÉ (PANNEAU INFÉRIEUR)
// ══════════════════════════════════════════════════════════════════════════════
// Pour afficher l'histogramme dans un panneau séparé, créer un indicateur séparé
// ou utiliser plot avec display=display.pane
// ══════════════════════════════════════════════════════════════════════════════
// 🐎 ALERTES
// ══════════════════════════════════════════════════════════════════════════════
alertcondition(buySignal, title="🐎 Mustang BUY", message="🐎 Mustang Algo: BUY Signal on {{ticker}} at {{close}}")
alertcondition(sellSignal, title="🐎 Mustang SELL", message="🐎 Mustang Algo: SELL Signal on {{ticker}} at {{close}}")