Get The Code! (Option 2)
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © CapitalCodersLLC
//@version=6
// --- Strategy Definition ---
strategy('Capital Coders DCA Bot',
overlay = true,
margin_long = 0, // No margin used for long positions
margin_short = 0, // No margin used for short positions
pyramiding = 999, // Allow many entries, but we'll cap it with our 'Pyramid' input
default_qty_type = strategy.percent_of_equity,
default_qty_value = 10, // Each trade (initial or DCA) will use 10% of equity
initial_capital = 1000)
// --- Input Groups ---
grSS = 'Strategy Settings'
grInd = 'Indicator Settings'
g_time = '=================🕒|Live Trading|🕒================='
// --- Strategy Inputs ---
// 'Pyramid' controls the maximum number of open trades (1 initial + (n-1) safety trades)
Pyramid = input.int(10, 'Safety Trades', maxval = 999, group = grSS,
tooltip = 'Maximum number of DCA (safety) trades allowed.')
// 'exitLevelInput' is the profit target. We divide by 100 to convert it to a decimal (e.g., 5.0 -> 0.05)
exitLevelInput = input.float(5.0, 'Exit Level (%)', group = grSS,
tooltip = 'Profit target based on Average Entry Price') / 100
// --- Indicator Inputs ---
SMA1Input = input.int(14, 'Moving Average - Fast:', minval = 1, group = grInd, inline = 'SMA1')
SMA2Input = input.int(28, 'Slow:', minval = 1, group = grInd, inline = 'SMA1')
Type = input.string('Crossunder', title = 'Type', options = ['Crossunder', 'Crossover'], group = grInd)
SMA1Color = input.color(color.new(#d2cde9, 40), 'Color - Fast:', inline = 'SMA1Color', group = grInd)
SMA2Color = input.color(color.new(#2962ff, 40), 'Slow:', inline = 'SMA1Color', group = grInd)
// --- Live Trading Filter Inputs ---
LIVE = input.bool(false, 'LIVE MODE', confirm = true, group = g_time,
tooltip = 'Enable this to start trading from a fresh state at the \'Start Date/Time\'. Disables historical backtesting.')
liveDate = input.time(timestamp('24 Oct 2025'), 'Start Date/Time', group = g_time,
tooltip = 'Date/time when Live trading begins. Strategy will be flat before this time if LIVE MODE is on.')
timeZone = input.string('GMT+0', 'Time Zone', group = g_time,
tooltip = 'GMT and UTC is the same thing \nMatch this setting to bottom right time',
options = ['GMT-10', 'GMT-9', 'GMT-8', 'GMT-7', 'GMT-6', 'GMT-5', 'GMT-4', 'GMT-3', 'GMT+0', 'GMT+1', 'GMT+2', 'GMT+3', 'GMT+4', 'GMT+5', 'GMT+6', 'GMT+7', 'GMT+8', 'GMT+9', 'GMT+10', 'GMT+10:30', 'GMT+11', 'GMT+12', 'GMT+13', 'GMT+13:45'])
// --- Calculations ---
// 1. Live Trading Time Filter
// Deconstruct the input time to correctly build a timestamp with the selected timezone
startTimeYear = year(liveDate, timeZone)
startTimeMonth = month(liveDate, timeZone)
startTimeDay = dayofmonth(liveDate, timeZone)
starthour = hour(liveDate, timeZone)
startmin = minute(liveDate, timeZone)
// This is the precise start time in UNIX format, adjusted for the chosen timezone
startTime = timestamp(timeZone, startTimeYear, startTimeMonth, startTimeDay, starthour, startmin)
// 'LiveTrading' is true if LIVE mode is OFF (i.e., backtesting)
// OR if LIVE mode is ON *and* the current bar's time is after the specified start time.
LiveTrading = LIVE ? time > startTime : true
// 2. Indicator Calculations
SMA1 = ta.sma(close, SMA1Input)
SMA2 = ta.sma(close, SMA2Input)
// 3. Entry Condition Calculation
// Determine the entry signal based on the user's "Type" selection
cond = switch Type
'Crossover' => ta.crossover(SMA1, SMA2)
'Crossunder' => ta.crossunder(SMA1, SMA2)
// 4. Exit Level Calculation
// Calculate the Take Profit price based on the current average entry price
// This value is recalculated on every bar that the position is open.
ExitLevel = strategy.position_avg_price * (1 + exitLevelInput)
// --- Strategy Logic ---
// 1. Entry Logic
// This is the master condition for placing any long entry (initial or DCA)
longCondition = cond and // The SMA cross condition must be met
strategy.opentrades < Pyramid and // We haven't exceeded our max number of safety trades
(close <= strategy.position_avg_price or // The price is at/below our avg price (DCA logic)
strategy.position_size == 0) and // OR this is the very first entry
LiveTrading // The time filter must be true
// If all conditions are true, enter a long position
if longCondition
strategy.entry('Long Entry', strategy.long)
// 2. Exit Logic
// This block checks if we are currently in a position
if strategy.position_size > 0
// If yes, place/update a limit exit order at the calculated take profit level
// This order will adjust automatically every time a new DCA entry fills
strategy.exit('DCA Exit', 'Long Entry', limit = ExitLevel)
// --- Plotting ---
// Plot the SMAs
plot(SMA1, color = SMA1Color, title = 'Fast SMA')
plot(SMA2, color = SMA2Color, title = 'Slow SMA')
// Plot the average entry price (only when in a position)
plot(strategy.position_size > 0 ? strategy.position_avg_price : na,
title = 'Average Entry Price',
color = color.blue,
style = plot.style_linebr)
// Plot the take profit target level (only when in a position)
plot(strategy.position_size > 0 ? ExitLevel : na,
title = 'DCA Exit Level',
color = color.green, // This was orange in the v5, green here as per your v6 code
style = plot.style_linebr)
// Highlight the background when a new entry condition is met
bgcolor(longCondition ? color.new(color.green, 80) : na,
title = 'Entry Signal')
Last updated