Strategy · Pine Script v5 · On the chart

3Commas Visible DCA Strategy

by hasnocool· code credited to MGTG

This strategy simulates a dollar-cost averaging (DCA) trading bot that enters positions when a short moving average crosses over or under a long moving average.

View on GitHub

GitHub stars106on the repository
Pine versionv5runs as is
Lines of code152
Settings15inputs
LicenceGPL-3.0
Last update2 years ago18 Sep 2024

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

152 lines of Pine Script v5 from 3Commas Visible DCA Strategy.pine, published under GPL-3.0. Keep the author's credit and licence lines when you reuse it.

3Commas Visible DCA Strategy.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © MGTG
//@version=5
Strategy = input.string('Long', options=['Long'], group='Strategy', inline='1',
 tooltip='Long bots profit when asset prices rise, Short bots profit when asset prices fall'
 + '\n\n' + 'Please note: to run a Short bot on a spot exchange account, you need to own the asset you want to trade. The bot will sell the asset at the current chart price and buy it back at a lower price - the profit made is actually trapped equity released from an asset you own that is declining in value.')
Profit_currency = input.string('Quote (USDT)', 'Profit currency', options=['Quote (USDT)', 'Quote (BTC)', 'Quote (BUSD)'], group='Strategy', inline='1')
Base_order_size = input.int(10, 'Base order Size', group='Strategy', inline='2', 
 tooltip='The Base Order is the first order the bot will create when starting a new deal.')
Safety_order_size = input.int(20, 'Safety order Size', group='Strategy', inline='2',
 tooltip="Enter the amount of funds your Safety Orders will use to Average the cost of the asset being traded, this can help your bot to close deals faster with more profit. Safety Orders are also known as Dollar Cost Averaging and help when prices moves in the opposite direction to your bot's take profit target.")
Triger_Type = input.string('Over', 'Entry at Cross Over / Under', options=['Over', 'Under'], group='Deal start condition > Trading View custom signal', inline='1',
 tooltip='Deal start condition decision')
Short_Moving_Average  = input.string('SMA', 'Short Moving Average', group='Deal start condition > Trading View custom signal', inline='2',
 options=["SMA", "EMA", "HMA"])
Short_Period         = input.int(5, 'Period', group='Deal start condition > Trading View custom signal', inline='2')
Long_Moving_Average  = input.string('HMA', 'Long Moving Average', group='Deal start condition > Trading View custom signal', inline='3',
 options=["SMA", "EMA", "HMA"])
Long_Period          = input.int(50, 'Period', group='Deal start condition > Trading View custom signal', inline='3')
Target_profit = input.float(1.5, 'Target profit (%)', step=0.05, group='Take profit / Stop Loss', inline='1') * 0.01
Stop_Loss = input.int(15, 'Stop Loss (%)', group='Take profit / Stop Loss', inline='1',
 tooltip='This is the percentage that price needs to move in the opposite direction to your take profit target, at which point the bot will execute a Market Order on the exchange account to close the deal for a smaller loss than keeping the deal open.'
 + '\n' + 'Please note, the Stop Loss is calculated from the price the Safety Order at on the exchange account and not the Dollar Cost Average price.') * 0.01
Max_safety_trades_count = input.int(10, 'Max safety trades count', maxval=10, group='Safety orders', inline='1')
Price_deviation = input.float(0.4, 'Price deviation to open safety orders (% from initial order)', step=0.01, group='Safety orders', inline='2') * 0.01
Safety_order_volume_scale = input.float(1.8, 'Safety order volume scale', step=0.01, group='Safety orders', inline='3')
Safety_order_step_scale = input.float(1.19, 'Safety order step scale', step=0.01, group='Safety orders', inline='3')
initial_capital = 8913
strategy(
 title='3Commas Visible DCA Strategy', 
 overlay=true, 
 initial_capital=initial_capital, 
 pyramiding=11, 
 process_orders_on_close=true, 
 commission_type=strategy.commission.percent, 
 commission_value=0.01, 
 max_bars_back=5000, 
 max_labels_count=50)
// Position
status_none  = strategy.position_size == 0
status_long  = strategy.position_size[1] == 0 and strategy.position_size > 0
status_long_offset  = strategy.position_size[2] == 0 and strategy.position_size[1] > 0
status_short = strategy.position_size[1] == 0 and strategy.position_size < 0
status_increase = strategy.opentrades[1] < strategy.opentrades
Short_Moving_Average_Line = 
 Short_Moving_Average == 'SMA' ? ta.sma(close, Short_Period) :
 Short_Moving_Average == 'EMA' ? ta.ema(close, Short_Period) :
 Short_Moving_Average == 'HMA' ? ta.sma(close, Short_Period) : na
Long_Moving_Average_Line = 
 Long_Moving_Average == 'SMA' ? ta.sma(close, Long_Period) :
 Long_Moving_Average == 'EMA' ? ta.ema(close, Long_Period) :
 Long_Moving_Average == 'HMA' ? ta.sma(close, Long_Period) : na
 
Base_order_Condition      = Triger_Type == "Over" ? ta.crossover(Short_Moving_Average_Line, Long_Moving_Average_Line) : ta.crossunder(Short_Moving_Average_Line, Long_Moving_Average_Line) // Buy when close crossing lower band
safety_order_deviation(index) => Price_deviation * math.pow(Safety_order_step_scale,  index - 1)
pd = Price_deviation
ss = Safety_order_step_scale
step(i) =>
 i == 1 ? pd :
 i == 2 ? pd + pd * ss :
 i == 3 ? pd + (pd + pd * ss) * ss :
 i == 4 ? pd + (pd + (pd + pd * ss) * ss) * ss : 
 i == 5 ? pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss : 
 i == 6 ? pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss : 
 i == 7 ? pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss : 
 i == 8 ? pd + (pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss) * ss : 
 i == 9 ? pd + (pd + (pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss) * ss) * ss : 
 i == 10 ? pd + (pd + (pd + (pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss) * ss) * ss) * ss : na
long_line(i) =>
 close[1] - close[1] * (step(i))
Safe_order_line(i) =>
 i == 0 ? ta.valuewhen(status_long, long_line(0), 0) :
 i == 1 ? ta.valuewhen(status_long, long_line(1), 0) :
 i == 2 ? ta.valuewhen(status_long, long_line(2), 0) :
 i == 3 ? ta.valuewhen(status_long, long_line(3), 0) :
 i == 4 ? ta.valuewhen(status_long, long_line(4), 0) :
 i == 5 ? ta.valuewhen(status_long, long_line(5), 0) :
 i == 6 ? ta.valuewhen(status_long, long_line(6), 0) :
 i == 7 ? ta.valuewhen(status_long, long_line(7), 0) :
 i == 8 ? ta.valuewhen(status_long, long_line(8), 0) : 
 i == 9 ? ta.valuewhen(status_long, long_line(9), 0) :
 i == 10 ? ta.valuewhen(status_long, long_line(10), 0) : na
TP_line = strategy.position_avg_price * (1 + Target_profit) 
SL_line = Safe_order_line(Max_safety_trades_count) * (1 - Stop_Loss)
safety_order_size(i) => Safety_order_size * math.pow(Safety_order_volume_scale, i - 1)
plot(Short_Moving_Average_Line, 'Short MA', color=color.new(color.white, 0), style=plot.style_line)
plot(Long_Moving_Average_Line, 'Long MA', color=color.new(color.green, 0), style=plot.style_line)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 1 ? Safe_order_line(1) : na, 'Safety order1', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 2 ? Safe_order_line(2) : na, 'Safety order2', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 3 ? Safe_order_line(3) : na, 'Safety order3', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 4 ? Safe_order_line(4) : na, 'Safety order4', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 5 ? Safe_order_line(5) : na, 'Safety order5', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 6 ? Safe_order_line(6) : na, 'Safety order6', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 7 ? Safe_order_line(7) : na, 'Safety order7', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 8 ? Safe_order_line(8) : na, 'Safety order8', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 9 ? Safe_order_line(9) : na, 'Safety order9', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 10 ? Safe_order_line(10) : na, 'Safety order10', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 ? TP_line : na, 'Take Profit', color=color.new(color.orange, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 ? SL_line : na, 'Safety', color=color.new(color.aqua, 0), style=plot.style_linebr)
currency = 
 Profit_currency == 'Quote (USDT)' ? ' USDT' :
 Profit_currency == 'Quote (BTC)'  ? ' BTC' :
 Profit_currency == 'Quote (BUSD)' ? ' BUSD' : na
if Base_order_Condition
    strategy.entry('Base order', strategy.long, qty=Base_order_size/close, when=Base_order_Condition and strategy.opentrades == 0,
     comment='BO' + ' - ' + str.tostring(Base_order_size) + str.tostring(currency))
for i = 1 to Max_safety_trades_count by 1
    i_s = str.tostring(i)
    strategy.entry('Safety order' + i_s, strategy.long, qty=safety_order_size(i)/close,
     limit=Safe_order_line(i), when=(strategy.opentrades <= i) and strategy.position_size > 0 and not(strategy.position_size == 0), 
     comment='SO' + i_s + ' - ' + str.tostring(safety_order_size(i))  + str.tostring(currency))
for i = 1 to Max_safety_trades_count by 1
    i_s = str.tostring(i)
    strategy.cancel('Safety order' + i_s, when=status_none)
    strategy.exit('TP/SL','Base order', limit=TP_line, stop=SL_line, comment = Safe_order_line(100) > close ? 'SL' + i_s + ' - ' +  str.tostring(Base_order_size) + str.tostring(currency) : 'TP' + i_s + ' - ' +  str.tostring(Base_order_size) + str.tostring(currency)) 
    strategy.exit('TP/SL','Safety order' + i_s, limit=TP_line, stop=SL_line, comment = Safe_order_line(100) > close ? 'SL' + i_s + ' - ' +  str.tostring(safety_order_size(i)) + str.tostring(currency) : 'TP' + i_s + ' - ' +  str.tostring(safety_order_size(i)) + str.tostring(currency)) 
    
bot_usage(i) =>
 i == 1 ? Base_order_size + safety_order_size(1) :
 i == 2 ? Base_order_size + safety_order_size(1) + safety_order_size(2) :
 i == 3 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) :
 i == 4 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) : 
 i == 5 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) :
 i == 6 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) : 
 i == 7 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) + safety_order_size(7) : 
 i == 8 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) + safety_order_size(7) + safety_order_size(8) : 
 i == 9 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) + safety_order_size(7) + safety_order_size(8) + safety_order_size(9) :
 i == 10 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) + safety_order_size(7) + safety_order_size(8) + safety_order_size(9) + safety_order_size(10) : na
equity = strategy.equity
bot_use = bot_usage(Max_safety_trades_count)
bot_dev = float(step(Max_safety_trades_count)) * 100
bot_ava = (bot_use / equity) * 100
string label = 
 'Balance                                      : ' + str.tostring(math.round(equity, 0), '###,###,###,###') + ' USDT' + '\n' + 
 'Max amount for bot usage           : ' + str.tostring(math.round(bot_use, 0), '###,###,###,###') + ' USDT' + '\n' + 
 'Max safety order price deviation : ' + str.tostring(math.round(bot_dev, 0), '##.##') + ' %' + '\n' + 
 '% of available balance                : ' + str.tostring(math.round(bot_ava, 0), '###,###,###,###') + ' %' 
 + (bot_ava > 100 ? '\n \n' +  '⚠ Warning! Bot will use amount greater than you have on exchange' : na) 
if status_long
    day_label = 
     label.new(
     x=time[1], 
     y=high * 1.03, 
     text=label, 
     xloc=xloc.bar_time, 
     yloc=yloc.price, 
     color=bot_ava > 100 ? color.new(color.yellow, 0) : color.new(color.black, 50), 
     style=label.style_label_lower_right, 
     textcolor=bot_ava > 100 ? color.new(color.red, 0) : color.new(color.silver, 0), 
     size=size.normal, 
     textalign=text.align_left)
Expand (177 lines)

Overview

3Commas Visible DCA Strategy manages trades by placing scaled safety orders as price drops, lowering the average position entry price. Exits occur when reaching a target profit percentage or hitting a stop loss percentage. Primary input settings allow adjustments to moving average types and periods, base and safety order sizes, target profit, stop loss, and DCA scaling parameters. It plots directly on the main price chart.

Details

Published by

hasnocool on GitHub

Code credit

MGTG, as written in the script's header

Type

Strategy, Pine Script v5

Draws

On the price chart

Category

Moving averages, Mean reversion

Markets

Crypto

Timeframes

Any timeframe

Risk Notes

  • The strategy can add several entries in the same direction

Topics

analysisbtcusdtcryptocurrencydatapandaspythonsimulationtradingtradingview

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
StrategystringLongStrategy
Profit currencystringQuote (USDT)Profit_currency
Base order Sizeint10Base_order_size
Safety order Sizeint20Safety_order_size
Entry at Cross Over / UnderstringOverTriger_Type
Short Moving AveragestringSMAShort_Moving_Average
Periodint5Short_Period
Long Moving AveragestringHMALong_Moving_Average
Periodint50Long_Period
Target profit (%)float1.5Target_profit
Stop Loss (%)int15Stop_Loss
Max safety trades countint10Max_safety_trades_count
Show all 15 settings
SettingTypeDefaultVariable
Price deviation to open safety orders (% from initial order)float0.4Price_deviation
Safety order volume scalefloat1.8Safety_order_volume_scale
Safety order step scalefloat1.19Safety_order_step_scale
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

218 stars

The Mean Reversion Strategy Template calculates a baseline mean using SMA, EMA, or VWAP alongside upper and lower deviation bands based on standard deviation, ATR, or percentage offsets. It generates long and short entries when price touches, bounces from, or

Strategy v6 Mean reversionMoving averages
Updated 3 months ago · None stated GitHub repository of Mean Reversion Strategy Template

Bollinger Bands Strategy

by cklose2000
105 stars

This strategy generates buy and sell signals based on Bollinger Band crossovers combined with a simple moving average trend filter. It enters a long position when price crosses above the lower band while trading above the SMA filter line, and enters a short po

Strategy v5 Volatility & bandsMoving averages
Updated 1 year ago · None stated GitHub repository of Bollinger Bands Strategy
53 stars

This strategy identifies long entry opportunities based on short-term price pullbacks below a major trend filter. It enters long when three consecutive lower closes occur below the 200-period simple moving average, followed by the current bar closing back abov

Strategy v6 TrendMoving averages
Updated 2 months ago · MPL-2.0 GitHub repository of Ivan Scherman Pattern - TP/SL

FVG RSI Strategy (Optimized)

by skywalker0803r
42 stars

This strategy plots on the price chart and trades fair value gaps filtered by RSI and two EMAs. It opens a long when a bullish gap, a rising candle, RSI below the oversold level, and price under both EMAs align, and a short on the opposite conditions. Each tra

Strategy v5 SMC / ICT / price actionOscillators & momentum
Updated 2 months ago · None stated GitHub repository of FVG RSI Strategy (Optimized)

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers