
RSI는 8가지의 고전적인 그래프 형태를 통합하는 전략입니다. 긴 다리 크로스, 맨발 선/단, 공백점, 타워 바닥, 바늘은 형태를 유지하고 높은 점을 맞추고 있습니다. 리테크 데이터는 여러 형태의 조합이 단일 형태보다 35% 더 높은 승률을 보인다는 것을 보여줍니다.
전략의 핵심 논리는 간단하고 거칠다: 다중 헤드 신호는 SMA50 위에 있어야 하고, 공백 신호는 SMA50 아래에 있어야 한다. 이 디자인은 직접적으로 흔들리는 시장에서 대부분의 잡음 거래를 필터링한다.
10주기 최저점/최고점으로 스톱포드를 설정하는 것은 전통적인 고정점 스톱포드보다 더 과학적입니다. ATR 배수는 유효한 형태를 식별하기 위해 1.5배로 설정되어 있으며, 실제로 의미있는 가격 동작만을 포착하는 것을 보장합니다. 실험에 따르면, 이 동적 스톱포드 시스템은 높은 변동 기간 동안 고정 스톱포드보다 300% 더 잘 작동합니다.
전략의 기본 리스크 수익률은 2:1로 1위 리스크를 감수할 때마다 2위 수익을 목표로 한다. 다형 포트폴리오를 결합한 45%의 승률, 수학적 기대치는 0.35이며, 시장 평균을 훨씬 뛰어넘는 -0.1의 기대치이다. 이것이 양적 거래의 매력이다: 수학적 확률로 돈을 버는 것, 행운을 의지하지 않는다.
각 형태는 엄격한 수학적 정의를 가지고 있다. 예를 들어, 광의 머리 광의 발은 전체 K 선의 90% 이상을 차지하고, 상하의 그림자 선은 5%를 넘지 않는다. 이러한 정밀한 정의는 신호의 신뢰성을 보장한다.
전략 설정 최대 동시 거래 수는 1입니다. 이 디자인은 보수적으로 보이지만 실제로는 위험 관리의 핵심입니다. 통계학적으로 여러 개의 연관성이 높은 위치를 동시에 보유하는 것은 체계적인 위험을 2.5 배 증가시킵니다. 기회를 놓치지 않고 계정을 불필요한 위험을 감수하지 않도록하십시오.
이 전략은 일방적인 트렌드 시장에서, 특히 돌파적 행태에서 가장 잘 작동한다. 그러나 가로 수평의 흔들림 동안, 트렌드 필터링에 의존하기 때문에 몇 가지 반전 기회를 놓칠 수 있다. VIX 지수가 20 이하일 때 신중하게 사용하는 것이 좋습니다.
위험 경고: 역사적인 회귀는 미래의 수익을 의미하지 않으며, 전략은 연속적인 손실의 위험이 있다. 다양한 시장 환경에서 성능의 차이는 현저하며, 엄격한 자금 관리와 위험 통제가 필요하다.
/*backtest
start: 2024-11-11 00:00:00
end: 2025-11-11 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Candlestick Combo Strategy - [CLEVER]", overlay=true, initial_capital=100000)
// === User Inputs
sma_len = input.int(50, "SMA Length", minval=1)
atr_len = input.int(14, "ATR Length", minval=1)
atr_mult = input.float(1.5, "ATR Multiplier for pattern size", step=0.1)
rr = input.float(2.0, "Risk:Reward", step=0.1)
maxOpenTrades = input.int(1, "Max concurrent open trades", minval=1)
// === Indicators / Trend Filter
sma50 = ta.sma(close, sma_len)
myATR = ta.atr(atr_len)
uptrend = close > sma50
downtrend = close < sma50
// === Helper: Safe indexing
hasHistory(bars) =>
bar_index >= bars
// === Candlestick Patterns ===
// Long-Legged Doji
isLongLeggedDoji() =>
if not hasHistory(1)
false
else
candleBody = math.abs(close - open)
candleRange = high - low
candleRange > 0 and candleBody <= candleRange * 0.20 and
(high - math.max(open, close)) >= candleRange * 0.40 and
(math.min(open, close) - low) >= candleRange * 0.40
// Bullish Marubozu
isBullishMarubozu() =>
if not hasHistory(1)
false
else
body = close - open
candleRange = high - low
candleRange > 0 and body > 0 and body >= candleRange * 0.90 and
(high - close) <= candleRange * 0.05 and
(open - low) <= candleRange * 0.05
// Bearish Marubozu
isBearishMarubozu() =>
if not hasHistory(1)
false
else
body = open - close
candleRange = high - low
candleRange > 0 and body > 0 and body >= candleRange * 0.90 and
(open - high) <= candleRange * 0.05 and
(close - low) <= candleRange * 0.05
// Rising Window (gap up)
isRisingWindow() =>
if not hasHistory(1)
false
else
open > high[1] and close > open and close[1] > open[1]
// Falling Window (gap down)
isFallingWindow() =>
if not hasHistory(1)
false
else
open < low[1] and close < open and close[1] < open[1]
// Tower Bottom
isTowerBottom() =>
if not hasHistory(4)
false
else
largeBear = (open[4] - close[4]) > myATR * atr_mult
smallBase = true
for i = 3 to 1
smallBase := smallBase and ((high[i] - low[i]) < (open[4] - close[4]) * 0.5)
largeBull = (close > open) and ((close - open) > myATR * atr_mult)
largeBear and smallBase and largeBull
// Mat Hold
isMatHold() =>
if not hasHistory(4)
false
else
firstBullSize = (close[4] - open[4])
longBull = firstBullSize > myATR * atr_mult
gapUp = open[3] > high[4]
smallConsol = true
for i = 3 to 1
smallConsol := smallConsol and ((high[i] - low[i]) < firstBullSize * 0.3) and low[i] > low[4]
finalBull = (close > open) and ((close - open) > firstBullSize * 0.8)
longBull and gapUp and smallConsol and finalBull
// Matching High
isMatchingHigh() =>
if not hasHistory(2)
false
else
bullish1 = close[2] > open[2]
bullish2 = close[1] > open[1]
sameHigh = math.abs(high[2] - high[1]) <= myATR * 0.10
gapDown = open[1] < close[2]
bullish1 and bullish2 and sameHigh and gapDown
// === Trade Conditions
longSignal = uptrend and (isMatHold() or isTowerBottom() or isRisingWindow() or isBullishMarubozu())
shortSignal = downtrend and (isMatchingHigh() or isFallingWindow() or isBearishMarubozu() or isLongLeggedDoji())
// Plot signals on chart
plotshape(longSignal, title="Long Signal", style=shape.triangleup, location=location.belowbar, color=color.new(color.lime, 0), size=size.tiny)
plotshape(shortSignal, title="Short Signal", style=shape.triangledown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny)
// === Entry / Exit Logic with maxOpenTrades gating
canEnter() =>
strategy.opentrades < maxOpenTrades
if (longSignal and canEnter())
stopLevel = ta.lowest(low, 10)
risk = close - stopLevel
target = close + risk * rr
strategy.entry("Long", strategy.long)
strategy.exit("Exit Long", "Long", stop=stopLevel, limit=target)
if (shortSignal and canEnter())
stopLevel = ta.highest(high, 10)
risk = stopLevel - close
target = close - risk * rr
strategy.entry("Short", strategy.short)
strategy.exit("Exit Short", "Short", stop=stopLevel, limit=target)