0% found this document useful (0 votes)
34 views6 pages

Swing

The document outlines a swing trading strategy implemented in Pine Script, focusing on cash-based position sizing and risk management. Key components include the use of exponential moving averages (EMAs) for trade signals, martingale and pyramiding techniques for position management, and advanced safeguards like volatility and momentum filters. The strategy also features a detailed risk table for tracking investments and current exposure.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views6 pages

Swing

The document outlines a swing trading strategy implemented in Pine Script, focusing on cash-based position sizing and risk management. Key components include the use of exponential moving averages (EMAs) for trade signals, martingale and pyramiding techniques for position management, and advanced safeguards like volatility and momentum filters. The strategy also features a detailed risk table for tracking investments and current exposure.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

//@version=6

strategy("Swing Trading Pro (Cash-Based)",


overlay=true,
initial_capital=670608,
default_qty_type=strategy.cash,
default_qty_value=44707,
commission_type=strategy.commission.percent,
commission_value=0,
slippage=0,
pyramiding=4)

// 1. SWING TRADING CONFIGURATION


fastEmaLen = input.int(13, "Fast EMA", minval=5, maxval=20)
mediumEmaLen = input.int(48, "Medium EMA", minval=21, maxval=100)
slowEmaLen = input.int(200, "Slow EMA", minval=100, maxval=300)

// 2. CASH MANAGEMENT
initPosSize = input.float(44707, "Initial Position (₹)", minval=10000,
maxval=100000)
maxMartingale = 3
maxPyramiding = 3
inputDefStopLoss = input.float(6.0, "Stop Loss (%)", minval=6.0, maxval=10.0)
var float stopLossPct = inputDefStopLoss

// 3. SWING TARGETS
profitTarget1 = input.float(8.0, "First Target (%)", minval=6.0, maxval=25.0)
profitTarget2 = input.float(30.0, "Final Target (%)", minval=25.0, maxval=60.0)
partialPct = input.int(25, "Partial % at Target", minval=10, maxval=40)

// 4. CORE INDICATORS
fastEma = ta.ema(close, fastEmaLen)
mediumEma = ta.ema(close, mediumEmaLen)
slowEma = ta.ema(close, slowEmaLen)
weeklyClose = request.security(syminfo.tickerid, "W", close)
weeklyTrend = weeklyClose > ta.ema(weeklyClose, 10)
rsi = ta.rsi(close, 14)
volumeSpike = volume > ta.sma(volume, 20) * 1.5

// 5. TRADE CONDITIONS
bullishSwing = fastEma > mediumEma and mediumEma > slowEma and close > slowEma
bearishSwing = fastEma < mediumEma or close < slowEma
entryCondition = bullishSwing and weeklyTrend and rsi > 50 and volumeSpike

// 6. POSITION TRACKING WITH ACTUAL CASH


var float entryPrice = na
var int entryBar = na
var int martingaleSteps = 0
var int pyramidSteps = 0
var bool firstTargetHit = false
var string positionType = ""
var bool defenseActive = false

// Track actual cash used for each position


var float baseCash = 0.0
var float mg1Cash = 0.0
var float mg2Cash = 0.0
var float mg3Cash = 0.0
var float totalInvestment = 0.0
// 7. ADVANCED SAFEGUARDS
// 7.1 Volatility Filter
atr = ta.atr(14)
volatilityFilter = close > ta.lowest(low, 5) + (atr * 1.5)

// 7.2 Momentum Confirmation


rsiBearish = rsi < 50 and rsi < rsi[1]
momentumFilter = not (rsiBearish and close < close[1])

// 7.5 TREND STRENGTH CONFIRMATION


adxLength = input.int(14, "ADX Length", minval=10, maxval=20)
adxThreshold = input.int(25, "ADX Threshold", minval=20, maxval=30)
[diPlus, diMinus, adxValue] = ta.dmi(adxLength, adxLength)
strongTrend = adxValue > adxThreshold

// 7.6 EMA Slope Filter


emaSlopeLookback = input.int(5, "EMA Slope Lookback", minval=3, maxval=10)
mediumEmaRising = mediumEma > mediumEma[emaSlopeLookback]
longEmaRising = slowEma > slowEma[emaSlopeLookback * 2]

// 8. CASH-BASED POSITION SIZING


currentExposure() =>
strategy.position_size * close

// Pyramiding availability check


canAddPyramid() =>
pyramidSteps < maxPyramiding and (currentExposure() + initPosSize) <=
strategy.equity

// Martingale availability check


canAddMartingale() =>
// Calculate required cash
float requiredCash = 0.0
if martingaleSteps == 0
requiredCash := baseCash * 2
else if martingaleSteps == 1
requiredCash := (mg1Cash > 0 ? mg1Cash : baseCash) * 2
else if martingaleSteps == 2
requiredCash := (mg2Cash > 0 ? mg2Cash : mg1Cash) * 2

martingaleSteps < maxMartingale and (currentExposure() + requiredCash) <=


strategy.equity

// Entry System - cash-based with whole shares


if entryCondition and strategy.position_size == 0 and barstate.isconfirmed
// Calculate shares based on cash amount
targetShares = initPosSize / close
actualShares = math.floor(targetShares)
baseCashActual = actualShares * close

if actualShares >= 1
strategy.entry("Init", strategy.long, qty=actualShares)
entryPrice := close
entryBar := bar_index
martingaleSteps := 0
pyramidSteps := 0
firstTargetHit := false
positionType := ""
defenseActive := false
stopLossPct := inputDefStopLoss
baseCash := baseCashActual
totalInvestment := baseCashActual
mg1Cash := 0.0
mg2Cash := 0.0
mg3Cash := 0.0

// Update hold bars counter


var int holdBars = 0
if strategy.position_size > 0
holdBars := holdBars + 1
else
holdBars := 0

// Position PnL calculation


currentPnL = strategy.position_size > 0 ?
((close - strategy.position_avg_price) / strategy.position_avg_price) * 100 :
0

// Martingale entry with cash calculation


if strategy.position_size > 0 and positionType != "PY" and barstate.isconfirmed
if currentPnL <= -stopLossPct and canAddMartingale()
// Calculate cash to invest
cashToInvest = 0.0
if martingaleSteps == 0
cashToInvest := baseCash * 2
else if martingaleSteps == 1
cashToInvest := (mg1Cash > 0 ? mg1Cash : baseCash) * 2
else if martingaleSteps == 2
cashToInvest := (mg2Cash > 0 ? mg2Cash : mg1Cash) * 2

// Calculate shares based on cash amount


targetShares = cashToInvest / close
actualShares = math.floor(targetShares)

if actualShares >= 1
cashActual = actualShares * close
strategy.entry("MG"+str.tostring(martingaleSteps+1), strategy.long,
qty=actualShares)

// Record actual cash used


if martingaleSteps == 0
mg1Cash := cashActual
else if martingaleSteps == 1
mg2Cash := cashActual
else if martingaleSteps == 2
mg3Cash := cashActual

totalInvestment := totalInvestment + cashActual


martingaleSteps += 1
positionType := "MG"

// Pyramiding entry with cash calculation


if strategy.position_size > 0 and positionType != "MG" and barstate.isconfirmed
if currentPnL >= profitTarget1/3 and canAddPyramid()
// Calculate shares based on cash amount
targetShares = initPosSize / close
actualShares = math.floor(targetShares)
if actualShares >= 1
cashActual = actualShares * close
strategy.entry("PY"+str.tostring(pyramidSteps+1), strategy.long,
qty=actualShares)
pyramidSteps := pyramidSteps + 1
positionType := "PY"
totalInvestment := totalInvestment + cashActual

// Profit Taking
if strategy.position_size > 0 and not firstTargetHit and currentPnL >=
profitTarget1 and barstate.isconfirmed
strategy.close("Partial", qty_percent=partialPct)
firstTargetHit := true

// 9. DEFENSIVE PARTIAL EXITS


defenseLevel = input.float(2.5, "Defense Trigger (%)", minval=1.0, maxval=3.5)
if strategy.position_size > 0 and not defenseActive and
currentPnL <= -defenseLevel and barstate.isconfirmed
strategy.close("Defense", qty_percent=25)
defenseActive := true
stopLossPct := stopLossPct * 0.75 // Tighten SL by 25%

// Reset defense if recovery happens


if strategy.position_size > 0 and defenseActive and
currentPnL >= 0 and barstate.isconfirmed
defenseActive := false
stopLossPct := inputDefStopLoss // Restore original SL

// 10. SIMPLIFIED EXIT CONDITIONS


bearishSignal = fastEma < mediumEma or close < slowEma
minHoldPeriod = input.int(10, "Min Hold Bars", minval=3, maxval=30)
exitCondition = (currentPnL >= profitTarget2) or (bearishSignal and holdBars >=
minHoldPeriod)

// Main exit execution


if strategy.position_size > 0 and exitCondition and barstate.isconfirmed
strategy.close_all("Exit")
entryPrice := na
positionType := ""
martingaleSteps := 0
pyramidSteps := 0
firstTargetHit := false
defenseActive := false
stopLossPct := inputDefStopLoss
holdBars := 0

// 11. VISUALIZATION
plot(fastEma, "Fast EMA", color.blue)
plot(mediumEma, "Medium EMA", color.orange)
plot(slowEma, "Slow EMA", color.red, linewidth=2)

plotshape(series=strategy.position_size == 0 and entryCondition,


title="Entry", style=shape.triangleup, color=color.green, size=size.small)

// 12. RISK TABLE WITH ACTUAL CASH


var table riskTable = table.new(position.top_right, 3, 10,
bgcolor=color.new(color.gray, 90))
if barstate.islast
// Column headers
table.cell(riskTable, 0, 0, "Position", bgcolor=color.gray)
table.cell(riskTable, 1, 0, "Target Cash", bgcolor=color.gray)
table.cell(riskTable, 2, 0, "Actual Cash", bgcolor=color.gray)

// Base position
table.cell(riskTable, 0, 1, "Base", bgcolor=color.silver)
table.cell(riskTable, 1, 1, "₹" + str.tostring(math.round(initPosSize)))
table.cell(riskTable, 2, 1, baseCash > 0 ? "₹" +
str.tostring(math.round(baseCash)) : "—")

// Martingale steps
table.cell(riskTable, 0, 2, "MG1", bgcolor=color.silver)
table.cell(riskTable, 1, 2, "₹" + str.tostring(math.round(initPosSize * 2)))
table.cell(riskTable, 2, 2, mg1Cash > 0 ? "₹" +
str.tostring(math.round(mg1Cash)) : "—")

table.cell(riskTable, 0, 3, "MG2", bgcolor=color.silver)


table.cell(riskTable, 1, 3, "₹" + str.tostring(math.round(initPosSize * 4)))
table.cell(riskTable, 2, 3, mg2Cash > 0 ? "₹" +
str.tostring(math.round(mg2Cash)) : "—")

table.cell(riskTable, 0, 4, "MG3", bgcolor=color.silver)


table.cell(riskTable, 1, 4, "₹" + str.tostring(math.round(initPosSize * 8)))
table.cell(riskTable, 2, 4, mg3Cash > 0 ? "₹" +
str.tostring(math.round(mg3Cash)) : "—")

// CURRENT POSITION STATUS


currentStep = ""
if positionType == "MG"
currentStep := "MG" + str.tostring(martingaleSteps)

table.cell(riskTable, 0, 5, "Position Status:", bgcolor=color.blue)


table.cell(riskTable, 1, 5, positionType != "" ? positionType : "None",
bgcolor=color.blue)
table.cell(riskTable, 2, 5, currentStep, bgcolor=color.blue)

// DEFENSE STATUS
defenseStatus = defenseActive ? "Active" : "Inactive"
table.cell(riskTable, 0, 6, "Defense System:", bgcolor=color.purple)
table.cell(riskTable, 1, 6, defenseStatus, bgcolor=color.purple)
table.cell(riskTable, 2, 6, defenseActive ? "SL: " + str.tostring(stopLossPct,
"#.#") + "%" : "", bgcolor=color.purple)

// TOTAL INVESTMENT
table.cell(riskTable, 0, 7, "Total Invested:", bgcolor=color.navy)
table.cell(riskTable, 1, 7, "₹" + str.tostring(math.round(totalInvestment)),
bgcolor=color.navy)
table.cell(riskTable, 2, 7,
str.tostring((totalInvestment/strategy.initial_capital)*100, "#.##") + "%",
bgcolor=color.navy)

// CURRENT EXPOSURE
currExp = currentExposure()
table.cell(riskTable, 0, 8, "Current Exposure:", bgcolor=color.orange)
table.cell(riskTable, 1, 8, "₹" + str.tostring(math.round(currExp)),
bgcolor=color.orange)
table.cell(riskTable, 2, 8,
str.tostring((currExp/strategy.initial_capital)*100, "#.##") + "%",
bgcolor=color.orange)
// POSITION PROGRESS
positionProgress = ""
if positionType == "MG"
positionProgress := str.tostring(martingaleSteps) + "/3 MG Steps"

table.cell(riskTable, 0, 9, "Progress:", bgcolor=color.fuchsia)


table.cell(riskTable, 1, 9, positionProgress, bgcolor=color.fuchsia)
table.cell(riskTable, 2, 9, firstTargetHit ? "Target1 Hit" : "",
bgcolor=color.fuchsia)

You might also like