← กลับหน้ารายการ

Feroce Fikingo CSI

Strategy ผู้เขียน: echoone1 Profit Factor: 1.025

ลิงก์ TradingView

เปิดใน TradingView

Equity Chart

Equity chart

เปิดรูปเต็มขนาด

คำอธิบาย

Feroce Fikingo CSI
Strategia basata su cicli
Bitcoin grafico a 4h

รูป Preview

Preview

Pine Script Source

// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © echoone1

//@version=6
strategy("Feroce Fikingo CSI", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10)

// =====================
// INPUTS (configurabili)
// =====================
//// ADX
adxLen        = input.int(14, "ADX Length", minval=3)
slopeLen      = input.int(3, "Slope lookback (bars)", minval=1)
minADX        = input.float(20.0, "Min ADX (strength)", step=0.1)
adxSlopeThr   = input.float(0.0, "ADX slope threshold", step=0.01)

//// CSM (Cycle Swing Momentum)
csmRsiLen     = input.int(14, "CSM: RSI length", minval=3)
csmFastEma    = input.int(3, "CSM: fast EMA (on RSI)")
csmSlowEma    = input.int(9, "CSM: slow EMA (on RSI)")

//// Filters
useEMA        = input.bool(true, "Use EMA trend filter?")
emaLen        = input.int(200, "EMA length")

useMACD       = input.bool(true, "Use MACD confirmation?")
macdFast      = input.int(12, "MACD fast")
macdSlow      = input.int(26, "MACD slow")
macdSig       = input.int(9,  "MACD signal")

useVolFilter  = input.bool(true, "Use volatility filter (ATR/price)?")
volAtrLen     = input.int(14, "Volatility ATR length")
volMinRatio   = input.float(0.002, "Min volatility (ATR/price)", step=0.0001)

//// Money management - ATR based
useStopLoss   = input.bool(true, "Use Stop Loss (ATR based)?")
stopATRmult   = input.float(1.0, "Stop = ATR ×", step=0.1)

usePartial    = input.bool(true, "Use Partial Take Profit?")
partialPct    = input.float(50.0, "Partial %", minval=1, maxval=100, step=1) // percent of position to close
partialRR     = input.float(1.0, "Partial TP R:R", step=0.1)

finalRR       = input.float(2.0, "Final TP R:R", step=0.1)
useTrailing   = input.bool(true, "Use Trailing Stop?")
trailATRmult  = input.float(1.5, "Trailing ATR multiplier", step=0.1)

//// Visual
showSignals   = input.bool(true, "Show entry/exit signals?")
showTPSLlines = input.bool(true, "Show TP/SL lines while trade active?")
showBGZone    = input.bool(true, "Show background trend zone?")

// =====================
// MANUAL ADX (Wilder RMA) - compatible
// =====================
upMove   = math.max(high - high[1], 0.0)
downMove = math.max(low[1] - low, 0.0)
plusDM_raw  = (upMove > downMove) ? upMove : 0.0
minusDM_raw = (downMove > upMove) ? downMove : 0.0

tr = ta.tr(true)
trRma = ta.rma(tr, adxLen)
plusDMrma = ta.rma(plusDM_raw, adxLen)
minusDMrma = ta.rma(minusDM_raw, adxLen)

plusDI = (trRma != 0.0) ? (100.0 * plusDMrma / trRma) : 0.0
minusDI = (trRma != 0.0) ? (100.0 * minusDMrma / trRma) : 0.0
dx = (plusDI + minusDI != 0.0) ? (100.0 * math.abs(plusDI - minusDI) / (plusDI + minusDI)) : 0.0
adx = ta.rma(dx, adxLen)

// slope (manual)
adxSlope = (adx - adx[slopeLen]) / math.max(slopeLen, 1)

// =====================
// Cycle Swing Momentum (RSI -> fast/slow EMA -> diff)
// =====================
csm_rsi = ta.rsi(close, csmRsiLen)
csm_fast = ta.ema(csm_rsi, csmFastEma)
csm_slow = ta.ema(csm_rsi, csmSlowEma)
csm = csm_fast - csm_slow
csmSlope = (csm - csm[slopeLen]) / math.max(slopeLen, 1)

// =====================
// EMA filter
// =====================
emaTrend = ta.ema(close, emaLen)
trendLongOK = not useEMA or (close > emaTrend)
trendShortOK = not useEMA or (close < emaTrend)

// =====================
// MACD (optional)
// =====================
macdLine = ta.ema(close, macdFast) - ta.ema(close, macdSlow)
macdSignalLine = ta.ema(macdLine, macdSig)
macdOK_long = not useMACD or (macdLine > macdSignalLine)
macdOK_short = not useMACD or (macdLine < macdSignalLine)

// =====================
// Volatility
// =====================
atrVol = ta.atr(volAtrLen)
volatilityRatio = atrVol / close
volOK = not useVolFilter or (volatilityRatio > volMinRatio)

// =====================
// ENTRY / EXIT LOGIC
// =====================
// ADX rising = slope above threshold
adxUp = adxSlope > adxSlopeThr
adxDown = adxSlope < -adxSlopeThr  // require significant negative slope to exit; adjust threshold via input

// require ADX magnitude too
adxStrong = adx > minADX

csmUp = csmSlope > 0
csmDown = csmSlope < 0

longSignal = adxStrong and adxUp and csmUp and trendLongOK and macdOK_long and volOK
shortSignal = adxStrong and adxUp and csmDown and trendShortOK and macdOK_short and volOK

// exit when ADX turns down (slope negative beyond threshold)
exitByAdx_long = adxDown and strategy.position_size > 0
exitByAdx_short = adxDown and strategy.position_size < 0

// =====================
// EXECUTION
// =====================
// entries
if (longSignal)
    strategy.entry("Long", strategy.long)

if (shortSignal)
    strategy.entry("Short", strategy.short)

// exits by ADX weakening
if (exitByAdx_long)
    strategy.close("Long", comment="Chiudi secondo ADX")
if (exitByAdx_short)
    strategy.close("Short", comment="Chiudi secondo adx")

// =====================
// POSITION MANAGEMENT: SL / Partial / Final / Trailing (ATR-based)
// =====================
var line longSLLine = na
var line longTPLine = na
var line shortSLLine = na
var line shortTPLine = na

prevPos = nz(strategy.position_size[1], 0)

// When a new long opens (position switched from <=0 to >0), create lines (if enabled)
if (strategy.position_size > 0 and prevPos <= 0)
    entryP = strategy.position_avg_price
    slP = entryP - atrVol * stopATRmult
    // partial & final TP calculated from R:R relative to stop distance
    riskDist = entryP - slP
    tpPartialP = entryP + riskDist * partialRR
    tpFinalP = entryP + riskDist * finalRR

    // create lines only if flag true
    if showTPSLlines
        longSLLine := line.new(bar_index, slP, bar_index + 1, slP, xloc=xloc.bar_index, extend=extend.right, color=color.new(#ff4d4d, 0), style=line.style_dashed, width=1)
        longTPLine := line.new(bar_index, tpFinalP, bar_index + 1, tpFinalP, xloc=xloc.bar_index, extend=extend.right, color=color.new(#33cc33, 0), style=line.style_solid, width=1)

// When a new short opens
if (strategy.position_size < 0 and prevPos >= 0)
    entryP = strategy.position_avg_price
    slP = entryP + atrVol * stopATRmult
    riskDist = slP - entryP
    tpPartialP = entryP - riskDist * partialRR
    tpFinalP = entryP - riskDist * finalRR

    if showTPSLlines
        shortSLLine := line.new(bar_index, slP, bar_index + 1, slP, xloc=xloc.bar_index, extend=extend.right, color=color.new(#ff4d4d, 0), style=line.style_dashed, width=1)
        shortTPLine := line.new(bar_index, tpFinalP, bar_index + 1, tpFinalP, xloc=xloc.bar_index, extend=extend.right, color=color.new(#33cc33, 0), style=line.style_solid, width=1)

// Update TP/SL lines coordinates each bar while position active
if strategy.position_size > 0 and showTPSLlines
    entryP = strategy.position_avg_price
    slP = entryP - atrVol * stopATRmult
    riskDist = entryP - slP
    tpFinalP = entryP + riskDist * finalRR
    // update lines
    if not na(longSLLine)
        line.set_xy1(longSLLine, bar_index, slP)
        line.set_xy2(longSLLine, bar_index + 1, slP)
    if not na(longTPLine)
        line.set_xy1(longTPLine, bar_index, tpFinalP)
        line.set_xy2(longTPLine, bar_index + 1, tpFinalP)

if strategy.position_size < 0 and showTPSLlines
    entryP = strategy.position_avg_price
    slP = entryP + atrVol * stopATRmult
    riskDist = slP - entryP
    tpFinalP = entryP - riskDist * finalRR
    if not na(shortSLLine)
        line.set_xy1(shortSLLine, bar_index, slP)
        line.set_xy2(shortSLLine, bar_index + 1, slP)
    if not na(shortTPLine)
        line.set_xy1(shortTPLine, bar_index, tpFinalP)
        line.set_xy2(shortTPLine, bar_index + 1, tpFinalP)

// Remove lines when position closes
if strategy.position_size == 0 and prevPos != 0
    if not na(longSLLine)
        line.delete(longSLLine)
        longSLLine := na
    if not na(longTPLine)
        line.delete(longTPLine)
        longTPLine := na
    if not na(shortSLLine)
        line.delete(shortSLLine)
        shortSLLine := na
    if not na(shortTPLine)
        line.delete(shortTPLine)
        shortTPLine := na

// Place exits (strategy.exit) for SL, partial, final, trailing — idempotent; safe to call each bar
if strategy.position_size > 0
    entryP = strategy.position_avg_price
    stopP = entryP - atrVol * stopATRmult
    riskDist = entryP - stopP
    if useStopLoss
        strategy.exit("SL Long", from_entry="Long", stop=stopP)
    if usePartial
        // partial percent closes at partialTP (qty_percent)
        strategy.exit("Partial Long", from_entry="Long", limit = entryP + riskDist * partialRR, qty_percent = math.round(partialPct))
    // final TP closes remaining
    strategy.exit("Final Long", from_entry="Long", limit = entryP + riskDist * finalRR)
    if useTrailing
        strategy.exit("Trail Long", from_entry="Long", trail_points = atrVol * trailATRmult, trail_offset = atrVol * trailATRmult)

if strategy.position_size < 0
    entryP = strategy.position_avg_price
    stopP = entryP + atrVol * stopATRmult
    riskDist = stopP - entryP
    if useStopLoss
        strategy.exit("SL Short", from_entry="Short", stop=stopP)
    if usePartial
        strategy.exit("Partial Short", from_entry="Short", limit = entryP - riskDist * partialRR, qty_percent = math.round(partialPct))
    strategy.exit("Final Short", from_entry="Short", limit = entryP - riskDist * finalRR)
    if useTrailing
        strategy.exit("Trail Short", from_entry="Short", trail_points = atrVol * trailATRmult, trail_offset = atrVol * trailATRmult)

// =====================
// VISUALS: signals, background zone (bgcolor called at global scope)
// =====================
bullZone = adxStrong and adxUp and csmUp
bearZone = adxStrong and adxUp and csmDown

// background color computed and applied at global scope
bgColor = showBGZone ? (bullZone ? color.new(#1b8a1b, 90) : bearZone ? color.new(#8a1b1b, 90) : na) : na
bgcolor(bgColor)

if showSignals and longSignal
    label.new(bar_index, low, "BUY", style=label.style_label_up, color=color.new(#1b8a1b, 0), textcolor=color.white)
if showSignals and shortSignal
    label.new(bar_index, high, "SELL", style=label.style_label_down, color=color.new(#8a1b1b, 0), textcolor=color.white)

plotshape(showSignals and longSignal, title="Long", location=location.belowbar, color=color.new(#00aa00, 0), style=shape.triangleup, size=size.small)
plotshape(showSignals and shortSignal, title="Short", location=location.abovebar, color=color.new(#ff3333, 0), style=shape.triangledown, size=size.small)

// helpful plots (hidden by default)
plot(emaTrend, title="EMA Trend", color=color.new(#00cccc, 0))
plot(adx, title="ADX (manual)", color=color.new(#ffa500, 0), display=display.none)
plot(csm, title="CSM", color=color.new(#7a3fb7, 0), display=display.none)

// volatility percent (hidden)
plot(volatilityRatio * 100, title="Volatility % (ATR/price)", display=display.none)
hline(volMinRatio * 100, "Vol threshold %", color=color.new(#ff3333, 0), linestyle=hline.style_dotted)