Strategy · Pine Script v5 · On the chart

3Commas Bot DCA Backtester & Signals FREE

by hasnocool· code credited to FriendOfTheTrend

This overlay strategy backtests a dollar-cost-averaging bot on the price chart.

View on GitHub

Repaints

GitHub stars106on the repository
Pine versionv5runs as is
Lines of code441
Settings14inputs
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

441 lines of Pine Script v5 from 3Commas Bot DCA Backtester & Signals FREE.pine, published under GPL-3.0. Keep the author's credit and licence lines when you reuse it.

3Commas Bot DCA Backtester & Signals FREE.pine
// © FriendOfTheTrend
//@version=5
strategy('3Commas Bot DCA Backtester & Signals FREE', shorttitle="3Commas Bot DCA Backtester & Signals FREE", overlay=true, precision=2, pyramiding=51, 
 calc_on_every_tick=true, backtest_fill_limits_assumption=1, default_qty_type=strategy.fixed, currency=currency.USD, slippage=1, commission_type=strategy.commission.percent,
 commission_value=.05, process_orders_on_close=true, initial_capital=26000, margin_long=100, margin_short=100)
//Choose Strategy
strategy = input.string("MACD", title="Buy Signal Strategy", options=["MFI", "RSI", "MACD", "Stochastic RSI"], tooltip="This is your buy signal strategy. MACD triggers a buy signal when the MACD signal line crosses above the MACD line. MFI triggers a buy signal when MFI is below your threshold level in the next setting. RSI triggers a buy signal when RSI is below your threshold level in the next setting. Stochastic RSI triggers a buy signal when the K line crosses above the D line.", group="Strategy")
strategyLevelTrigger = input.int(20, title="Signal Threshold Level", tooltip="This number is the threshold that MFI or RSI will need to be below to trigger a buy signal. So if you set it to 20, the MFI or RSI that you chose above will trigger a buy signal when it goes below this number. This setting has no affect on the MACD or Stochastic RSI even when a value is set.", group="Strategy")
strategyLength = input.int(14, title="Indicator Length", tooltip="This is the length used for RSI and MFI. MACD uses the standard 12, 26, 9 lengths and Stochastic RSI uses 3, 3, 14, 14 lengths. MACD and Stochastic RSI will not be affected by this input number.")
//Inputs
stoplossOn = input.bool(false, title="Stoploss On", group="DCA Bot Settings")
stoploss = input.float(5, title="Stoploss %", minval=.0001, step=.001, group="DCA Bot Settings")/100
takeProfit = input.float(.5, title="Take Profit %", minval=.0001, step=.001, group="DCA Bot Settings")/100
avgDown = input.float(.5, title="Average Down %", minval=.0001, step=.001, group="DCA Bot Settings")/100
percentScale = input.float(1.2, title="Avg Down % Multiplier", minval=.0001, step=.001, group="DCA Bot Settings")
multiplier = input.float(1.5, title="Volume Multiplier", minval=1, step=.001, tooltip="Increasing this value above 1 will multiply each new orders volume by the amount you input. This makes your buys bigger every time you average down so you don't need as big of a bounce when it recovers to get out in profit.", group="DCA Bot Settings")
maxOrders = input.int(12, title="Max # Of Orders", group="DCA Bot Settings")
quantity = input.float(100, title="Size Of Base Order", minval=.000000001, step=.000000001, group="DCA Bot Settings")
//Info Table On/Off
dataTableOn = input.bool(true, title="Info Table On/Off", group="Info Tables")
//Average Down Levels On/Off
orderLevelsOn = input.bool(true, title="Turn Average Down Levels On/Off", group="Average Down Levels")
//Table Positions
bright = position.bottom_right
bleft = position.bottom_left
bcenter = position.bottom_center
tright = position.top_right
tleft = position.top_left
tcenter = position.top_center
mright = position.middle_right
mleft = position.middle_left
mcenter = position.middle_center
tablePosition = input.string(bright, title="Percentage Table Position", options=[bright, bleft, bcenter, tright, tleft, tcenter, mright, mleft, mcenter], group="Info Tables")
//Buy Signals
buy = false
//MACD
fastMa = ta.sma(close, 12)
slowMa = ta.sma(close, 26)
macd = fastMa - slowMa
signal = ta.sma(macd, 9)
if  strategy == "MACD" and ta.crossover(macd, signal)
    buy := true
//MFI
mfi = ta.mfi(close, strategyLength)
if strategy == "MFI" and mfi <= strategyLevelTrigger
    buy := true
//RSI
rsi = ta.rsi(close, strategyLength)
if strategy == "RSI" and rsi <= strategyLevelTrigger
    buy := true
//Stochastic RSI
smoothK = 3
smoothD = 3
lengthRSI = 14
lengthStoch = 14
rsi1 = ta.rsi(close, lengthRSI)
k = ta.sma(ta.stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = ta.sma(k, smoothD)
if  strategy == "Stochastic RSI" and ta.crossover(k, d)
    buy := true
//Alerts
if buy
    alert("Place Open Deal Code From 3Commas Here.", alert.freq_once_per_bar_close)
// Order Quantity Adjustments With Volume Multiplier
quantityConverted = quantity/close
quantMultiplied1 = quantityConverted * multiplier
quantMultiplied2 = quantMultiplied1 * multiplier
quantMultiplied3 = quantMultiplied2 * multiplier
quantMultiplied4 = quantMultiplied3 * multiplier
quantMultiplied5 = quantMultiplied4 * multiplier
quantMultiplied6 = quantMultiplied5 * multiplier
quantMultiplied7 = quantMultiplied6 * multiplier
quantMultiplied8 = quantMultiplied7 * multiplier
quantMultiplied9 = quantMultiplied8 * multiplier
quantMultiplied10 = quantMultiplied9 * multiplier
quantMultiplied11 = quantMultiplied10 * multiplier
quantMultiplied12 = quantMultiplied11 * multiplier
quantMultiplied13 = quantMultiplied12 * multiplier
quantMultiplied14 = quantMultiplied13 * multiplier
quantMultiplied15 = quantMultiplied14 * multiplier
quantMultiplied16 = quantMultiplied15 * multiplier
quantMultiplied17 = quantMultiplied16 * multiplier
quantMultiplied18 = quantMultiplied17 * multiplier
quantMultiplied19 = quantMultiplied18 * multiplier
quantMultiplied20 = quantMultiplied19 * multiplier
quantMultiplied21 = quantMultiplied20 * multiplier
quantMultiplied22 = quantMultiplied21 * multiplier
quantMultiplied23 = quantMultiplied22 * multiplier
quantMultiplied24 = quantMultiplied23 * multiplier
quantMultiplied25 = quantMultiplied24 * multiplier
quantMultiplied26 = quantMultiplied25 * multiplier
quantMultiplied27 = quantMultiplied26 * multiplier
quantMultiplied28 = quantMultiplied27 * multiplier
quantMultiplied29 = quantMultiplied28 * multiplier
quantMultiplied30 = quantMultiplied29 * multiplier
quantMultiplied31 = quantMultiplied30 * multiplier
quantMultiplied32 = quantMultiplied31 * multiplier
quantMultiplied33 = quantMultiplied32 * multiplier
quantMultiplied34 = quantMultiplied33 * multiplier
quantMultiplied35 = quantMultiplied34 * multiplier
quantMultiplied36 = quantMultiplied35 * multiplier
quantMultiplied37 = quantMultiplied36 * multiplier
quantMultiplied38 = quantMultiplied37 * multiplier
quantMultiplied39 = quantMultiplied38 * multiplier
quantMultiplied40 = quantMultiplied39 * multiplier
quantMultiplied41 = quantMultiplied40 * multiplier
quantMultiplied42 = quantMultiplied41 * multiplier
quantMultiplied43 = quantMultiplied42 * multiplier
quantMultiplied44 = quantMultiplied43 * multiplier
quantMultiplied45 = quantMultiplied44 * multiplier
quantMultiplied46 = quantMultiplied45 * multiplier
quantMultiplied47 = quantMultiplied46 * multiplier
quantMultiplied48 = quantMultiplied47 * multiplier
quantMultiplied49 = quantMultiplied48 * multiplier
quantMultiplied50 = quantMultiplied49 * multiplier
// Average Down Levels
avgDown1 = (avgDown * percentScale) + avgDown
avgDown2 = (avgDown1 * percentScale) + avgDown
avgDown3 = (avgDown2 * percentScale) + avgDown
avgDown4 = (avgDown3 * percentScale) + avgDown
avgDown5 = (avgDown4 * percentScale) + avgDown
avgDown6 = (avgDown5 * percentScale) + avgDown
avgDown7 = (avgDown6 * percentScale) + avgDown
avgDown8 = (avgDown7 * percentScale) + avgDown
avgDown9 = (avgDown8 * percentScale) + avgDown
avgDown10 = (avgDown9 * percentScale) + avgDown
avgDown11 = (avgDown10 * percentScale) + avgDown
avgDown12 = (avgDown11 * percentScale) + avgDown
avgDown13 = (avgDown12 * percentScale) + avgDown
avgDown14 = (avgDown13 * percentScale) + avgDown
avgDown15 = (avgDown14 * percentScale) + avgDown
avgDown16 = (avgDown15 * percentScale) + avgDown
avgDown17 = (avgDown16 * percentScale) + avgDown
avgDown18 = (avgDown17 * percentScale) + avgDown
avgDown19 = (avgDown18 * percentScale) + avgDown
avgDown20 = (avgDown19 * percentScale) + avgDown
avgDown21 = (avgDown20 * percentScale) + avgDown
avgDown22 = (avgDown21 * percentScale) + avgDown
avgDown23 = (avgDown22 * percentScale) + avgDown
avgDown24 = (avgDown23 * percentScale) + avgDown
avgDown25 = (avgDown24 * percentScale) + avgDown
avgDown26 = (avgDown25 * percentScale) + avgDown
avgDown27 = (avgDown26 * percentScale) + avgDown
avgDown28 = (avgDown27 * percentScale) + avgDown
avgDown29 = (avgDown28 * percentScale) + avgDown
avgDown30 = (avgDown29 * percentScale) + avgDown
avgDown31 = (avgDown30 * percentScale) + avgDown
avgDown32 = (avgDown31 * percentScale) + avgDown
avgDown33 = (avgDown32 * percentScale) + avgDown
avgDown34 = (avgDown33 * percentScale) + avgDown
avgDown35 = (avgDown34 * percentScale) + avgDown
avgDown36 = (avgDown35 * percentScale) + avgDown
avgDown37 = (avgDown36 * percentScale) + avgDown
avgDown38 = (avgDown37 * percentScale) + avgDown
avgDown39 = (avgDown38 * percentScale) + avgDown
avgDown40 = (avgDown39 * percentScale) + avgDown
avgDown41 = (avgDown40 * percentScale) + avgDown
avgDown42 = (avgDown41 * percentScale) + avgDown
avgDown43 = (avgDown42 * percentScale) + avgDown
avgDown44 = (avgDown43 * percentScale) + avgDown
avgDown45 = (avgDown44 * percentScale) + avgDown
avgDown46 = (avgDown45 * percentScale) + avgDown
avgDown47 = (avgDown46 * percentScale) + avgDown
avgDown48 = (avgDown47 * percentScale) + avgDown
avgDown49 = (avgDown48 * percentScale) + avgDown
avgDown50 = (avgDown49 * percentScale) + avgDown
//Strategy Trade Signal
if strategy.opentrades == 0 and buy and barstate.isconfirmed 
    strategy.entry('Bull #1', strategy.long, qty=quantityConverted, comment='Buy #1')
// Plot Entry & Average Down Levels
plot(strategy.opentrades.entry_price(0), title="Order #1", color=color.white)
plot(maxOrders >= 2 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown) : na, title="Order #2", color=color.green)
plot(maxOrders >= 3 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown1) : na, title="Order #3", color=color.green)
plot(maxOrders >= 4 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown2) : na, title="Order #4", color=color.green)
plot(maxOrders >= 5 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown3) : na, title="Order #5", color=color.green)
plot(maxOrders >= 6 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown4) : na, title="Order #6", color=color.green)
plot(maxOrders >= 7 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown5) : na, title="Order #7", color=color.green)
plot(maxOrders >= 8 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown6) : na, title="Order #8", color=color.green)
plot(maxOrders >= 9 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown7) : na, title="Order #9", color=color.green)
plot(maxOrders >= 10 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown8) : na, title="Order #10", color=color.green)
plot(maxOrders >= 11 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown9) : na, title="Order #11", color=color.green)
plot(maxOrders >= 12 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown10) : na, title="Order #12", color=color.green)
plot(maxOrders >= 13 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown11) : na, title="Order #13", color=color.green)
plot(maxOrders >= 14 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown12) : na, title="Order #14", color=color.green)
plot(maxOrders >= 15 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown13) : na, title="Order #15", color=color.green)
plot(maxOrders >= 16 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown14) : na, title="Order #16", color=color.green)
plot(maxOrders >= 17 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown15) : na, title="Order #17", color=color.green)
plot(maxOrders >= 18 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown16) : na, title="Order #18", color=color.green)
plot(maxOrders >= 19 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown17) : na, title="Order #19", color=color.green)
plot(maxOrders >= 20 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown18) : na, title="Order #20", color=color.green)
plot(maxOrders >= 21 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown19) : na, title="Order #21", color=color.green)
plot(maxOrders >= 22 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown20) : na, title="Order #22", color=color.green)
plot(maxOrders >= 23 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown21) : na, title="Order #23", color=color.green)
plot(maxOrders >= 24 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown22) : na, title="Order #24", color=color.green)
plot(maxOrders >= 25 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown23) : na, title="Order #25", color=color.green)
plot(maxOrders >= 26 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown24) : na, title="Order #26", color=color.green)
plot(maxOrders >= 27 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown25) : na, title="Order #27", color=color.green)
plot(maxOrders >= 28 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown26) : na, title="Order #28", color=color.green)
plot(maxOrders >= 29 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown27) : na, title="Order #29", color=color.green)
plot(maxOrders >= 30 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown28) : na, title="Order #30", color=color.green)
plot(maxOrders >= 31 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown29) : na, title="Order #31", color=color.green)
plot(maxOrders >= 32 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown30) : na, title="Order #32", color=color.green)
plot(maxOrders >= 33 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown31) : na, title="Order #33", color=color.green)
plot(maxOrders >= 34 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown32) : na, title="Order #34", color=color.green)
plot(maxOrders >= 35 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown33) : na, title="Order #35", color=color.green)
plot(maxOrders >= 36 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown34) : na, title="Order #36", color=color.green)
plot(maxOrders >= 37 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown35) : na, title="Order #37", color=color.green)
plot(maxOrders >= 38 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown36) : na, title="Order #38", color=color.green)
plot(maxOrders >= 39 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown37) : na, title="Order #39", color=color.green)
plot(maxOrders >= 40 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown38) : na, title="Order #40", color=color.green)
plot(maxOrders >= 41 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown39) : na, title="Order #41", color=color.green)
plot(maxOrders >= 42 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown40) : na, title="Order #42", color=color.green)
plot(maxOrders >= 43 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown41) : na, title="Order #43", color=color.green)
plot(maxOrders >= 44 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown42) : na, title="Order #44", color=color.green)
plot(maxOrders >= 45 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown43) : na, title="Order #45", color=color.green)
plot(maxOrders >= 46 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown44) : na, title="Order #46", color=color.green)
plot(maxOrders >= 47 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown45) : na, title="Order #47", color=color.green)
plot(maxOrders >= 48 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown46) : na, title="Order #48", color=color.green)
plot(maxOrders >= 49 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown47) : na, title="Order #49", color=color.green)
plot(maxOrders >= 50 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown48) : na, title="Order #50", color=color.green)
plot(maxOrders >= 51 and orderLevelsOn ? strategy.opentrades.entry_price(0) * (1 - avgDown49) : na, title="Order #51", color=color.green)
if strategy.opentrades == 1 and maxOrders >= 2
    strategy.entry('Bull #1', strategy.long, qty=quantMultiplied1, limit=strategy.opentrades.entry_price(0) * (1 - avgDown),
     comment="Buy #2 " + str.tostring(avgDown * 100, format.percent))
if strategy.opentrades == 2 and maxOrders >= 3
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied2, limit=strategy.opentrades.entry_price(0) * (1 - avgDown1),
     comment="Buy #3 " + str.tostring(avgDown1 * 100, format.percent))
if strategy.opentrades == 3 and maxOrders >= 4
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied3, limit=strategy.opentrades.entry_price(0) * (1 - avgDown2), 
     comment="Buy #4 " + str.tostring(avgDown2 * 100, format.percent))
if strategy.opentrades == 4 and maxOrders >= 5
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied4, limit=strategy.opentrades.entry_price(0) * (1 - avgDown3),
     comment="Buy #5 " + str.tostring(avgDown3 * 100, format.percent))
if strategy.opentrades == 5 and maxOrders >= 6
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied5, limit=strategy.opentrades.entry_price(0) * (1 - avgDown4),
     comment="Buy #6 " + str.tostring(avgDown4 * 100, format.percent))
if strategy.opentrades == 6 and maxOrders >= 7
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied6, limit=strategy.opentrades.entry_price(0) * (1 - avgDown5),
     comment="Buy #7 " + str.tostring(avgDown5 * 100, format.percent))
if strategy.opentrades == 7 and maxOrders >= 8
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied7, limit=strategy.opentrades.entry_price(0) * (1 - avgDown6),
     comment="Buy #8 " + str.tostring(avgDown6 * 100, format.percent))
if strategy.opentrades == 8 and maxOrders >= 9
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied8, limit=strategy.opentrades.entry_price(0) * (1 - avgDown7),
     comment="Buy #9 " + str.tostring(avgDown7 * 100, format.percent))
if strategy.opentrades == 9 and maxOrders >= 10
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied9, limit=strategy.opentrades.entry_price(0) * (1 - avgDown8),
     comment="Buy #10 " + str.tostring(avgDown8 * 100, format.percent))
if strategy.opentrades == 10 and maxOrders >= 11
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied10, limit=strategy.opentrades.entry_price(0) * (1 - avgDown9),
     comment="Buy #11 " + str.tostring(avgDown9 * 100, format.percent))
if strategy.opentrades == 11 and maxOrders >= 12
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied11, limit=strategy.opentrades.entry_price(0) * (1 - avgDown10),
     comment="Buy #12 " + str.tostring(avgDown10 * 100, format.percent))
if strategy.opentrades == 12 and maxOrders >= 13
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied12, limit=strategy.opentrades.entry_price(0) * (1 - avgDown11),
     comment="Buy #13 " + str.tostring(avgDown11 * 100, format.percent))
if strategy.opentrades == 13 and maxOrders >= 14
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied13, limit=strategy.opentrades.entry_price(0) * (1 - avgDown12),
     comment="Buy #14 " + str.tostring(avgDown12 * 100, format.percent))
if strategy.opentrades == 14 and maxOrders >= 15
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied14, limit=strategy.opentrades.entry_price(0) * (1 - avgDown13),
     comment="Buy #15 " + str.tostring(avgDown13 * 100, format.percent))
if strategy.opentrades == 15 and maxOrders >= 16
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied15, limit=strategy.opentrades.entry_price(0) * (1 - avgDown14),
     comment="Buy #16 " + str.tostring(avgDown14 * 100, format.percent))
if strategy.opentrades == 16 and maxOrders >= 17
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied16, limit=strategy.opentrades.entry_price(0) * (1 - avgDown15),
     comment="Buy #17 " + str.tostring(avgDown15 * 100, format.percent))
if strategy.opentrades == 17 and maxOrders >= 18
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied17, limit=strategy.opentrades.entry_price(0) * (1 - avgDown16),
     comment="Buy #18 " + str.tostring(avgDown16 * 100, format.percent))
if strategy.opentrades == 18 and maxOrders >= 19
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied18, limit=strategy.opentrades.entry_price(0) * (1 - avgDown17),
     comment="Buy #19 " + str.tostring(avgDown17 * 100, format.percent))
if strategy.opentrades == 19 and maxOrders >= 20
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied19, limit=strategy.opentrades.entry_price(0) * (1 - avgDown18),
     comment="Buy #20 " + str.tostring(avgDown18 * 100, format.percent))
if strategy.opentrades == 20 and maxOrders >= 21
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied20, limit=strategy.opentrades.entry_price(0) * (1 - avgDown19),
     comment="Buy #21 " + str.tostring(avgDown19 * 100, format.percent))
if strategy.opentrades == 21 and maxOrders >= 22
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied21, limit=strategy.opentrades.entry_price(0) * (1 - avgDown20),
     comment="Buy #22 " + str.tostring(avgDown20 * 100, format.percent))
if strategy.opentrades == 22 and maxOrders >= 23
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied21, limit=strategy.opentrades.entry_price(0) * (1 - avgDown21),
     comment="Buy #23 " + str.tostring(avgDown21 * 100, format.percent))
if strategy.opentrades == 23 and maxOrders >= 24
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied22, limit=strategy.opentrades.entry_price(0) * (1 - avgDown22),
     comment="Buy #24 " + str.tostring(avgDown22 * 100, format.percent))
if strategy.opentrades == 24 and maxOrders >= 25
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied23, limit=strategy.opentrades.entry_price(0) * (1 - avgDown23),
     comment="Buy #25 " + str.tostring(avgDown23 * 100, format.percent))
if strategy.opentrades == 25 and maxOrders >= 26
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied24, limit=strategy.opentrades.entry_price(0) * (1 - avgDown24),
     comment="Buy #26 " + str.tostring(avgDown24 * 100, format.percent))
if strategy.opentrades == 26 and maxOrders >= 27
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied25, limit=strategy.opentrades.entry_price(0) * (1 - avgDown25),
     comment="Buy #27 " + str.tostring(avgDown25 * 100, format.percent))
if strategy.opentrades == 27 and maxOrders >= 28
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied26, limit=strategy.opentrades.entry_price(0) * (1 - avgDown26),
     comment="Buy #28 " + str.tostring(avgDown26 * 100, format.percent))
if strategy.opentrades == 28 and maxOrders >= 29
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied27, limit=strategy.opentrades.entry_price(0) * (1 - avgDown27),
     comment="Buy #29 " + str.tostring(avgDown27 * 100, format.percent))
if strategy.opentrades == 29 and maxOrders >= 30
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied28, limit=strategy.opentrades.entry_price(0) * (1 - avgDown28),
     comment="Buy #30 " + str.tostring(avgDown28 * 100, format.percent))
if strategy.opentrades == 30 and maxOrders >= 31
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied29, limit=strategy.opentrades.entry_price(0) * (1 - avgDown29),
     comment="Buy #31 " + str.tostring(avgDown29 * 100, format.percent))
if strategy.opentrades == 31 and maxOrders >= 32
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied30, limit=strategy.opentrades.entry_price(0) * (1 - avgDown30),
     comment="Buy #32 " + str.tostring(avgDown30 * 100, format.percent))
if strategy.opentrades == 32 and maxOrders >= 33
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied31, limit=strategy.opentrades.entry_price(0) * (1 - avgDown31),
     comment="Buy #33 " + str.tostring(avgDown31 * 100, format.percent))
if strategy.opentrades == 33 and maxOrders >= 34
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied32, limit=strategy.opentrades.entry_price(0) * (1 - avgDown32),
     comment="Buy #34 " + str.tostring(avgDown32 * 100, format.percent))
if strategy.opentrades == 34 and maxOrders >= 35
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied33, limit=strategy.opentrades.entry_price(0) * (1 - avgDown33),
     comment="Buy #35 " + str.tostring(avgDown33 * 100, format.percent))
if strategy.opentrades == 35 and maxOrders >= 36
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied34, limit=strategy.opentrades.entry_price(0) * (1 - avgDown34),
     comment="Buy #36 " + str.tostring(avgDown34 * 100, format.percent))
if strategy.opentrades == 36 and maxOrders >= 37
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied35, limit=strategy.opentrades.entry_price(0) * (1 - avgDown35),
     comment="Buy #37 " + str.tostring(avgDown35 * 100, format.percent))
if strategy.opentrades == 37 and maxOrders >= 38
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied36, limit=strategy.opentrades.entry_price(0) * (1 - avgDown36),
     comment="Buy #38 " + str.tostring(avgDown36 * 100, format.percent))
if strategy.opentrades == 38 and maxOrders >= 39
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied37, limit=strategy.opentrades.entry_price(0) * (1 - avgDown37),
     comment="Buy #39 " + str.tostring(avgDown37 * 100, format.percent))
if strategy.opentrades == 39 and maxOrders >= 40
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied38, limit=strategy.opentrades.entry_price(0) * (1 - avgDown38),
     comment="Buy #40 " + str.tostring(avgDown38 * 100, format.percent))
if strategy.opentrades == 40 and maxOrders >= 41
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied39, limit=strategy.opentrades.entry_price(0) * (1 - avgDown39),
     comment="Buy #41 " + str.tostring(avgDown39 * 100, format.percent))
if strategy.opentrades == 41 and maxOrders >= 42
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied40, limit=strategy.opentrades.entry_price(0) * (1 - avgDown40),
     comment="Buy #42 " + str.tostring(avgDown40 * 100, format.percent))
if strategy.opentrades == 42 and maxOrders >= 43
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied41, limit=strategy.opentrades.entry_price(0) * (1 - avgDown41),
     comment="Buy #43 " + str.tostring(avgDown41 * 100, format.percent))
if strategy.opentrades == 43 and maxOrders >= 44
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied42, limit=strategy.opentrades.entry_price(0) * (1 - avgDown42),
     comment="Buy #44 " + str.tostring(avgDown42 * 100, format.percent))
if strategy.opentrades == 44 and maxOrders >= 45
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied43, limit=strategy.opentrades.entry_price(0) * (1 - avgDown43),
     comment="Buy #45 " + str.tostring(avgDown43 * 100, format.percent))
if strategy.opentrades == 45 and maxOrders >= 46
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied44, limit=strategy.opentrades.entry_price(0) * (1 - avgDown44),
     comment="Buy #46 " + str.tostring(avgDown44 * 100, format.percent))
if strategy.opentrades == 46 and maxOrders >= 47
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied45, limit=strategy.opentrades.entry_price(0) * (1 - avgDown45),
     comment="Buy #47 " + str.tostring(avgDown45 * 100, format.percent))
if strategy.opentrades == 47 and maxOrders >= 48
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied46, limit=strategy.opentrades.entry_price(0) * (1 - avgDown46),
     comment="Buy #48 " + str.tostring(avgDown46 * 100, format.percent))
if strategy.opentrades == 48 and maxOrders >= 49
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied47, limit=strategy.opentrades.entry_price(0) * (1 - avgDown47),
     comment="Buy #49 " + str.tostring(avgDown47 * 100, format.percent))
if strategy.opentrades == 49 and maxOrders >= 50
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied48, limit=strategy.opentrades.entry_price(0) * (1 - avgDown48),
     comment="Buy #50 " + str.tostring(avgDown48 * 100, format.percent))
 
if strategy.opentrades == 50 and maxOrders >= 51
    strategy.entry("Bull #1", strategy.long, qty=quantMultiplied49, limit=strategy.opentrades.entry_price(0) * (1 - avgDown49),
     comment="Buy #51 " + str.tostring(avgDown49 * 100, format.percent))
// Exit Long Position
stoplossPrice = 0.0
if stoplossOn and strategy.opentrades == maxOrders
    stoplossPrice := strategy.opentrades.entry_price(maxOrders - 1) * (1 - stoploss)
strategy.exit("Bull #1", limit=strategy.position_avg_price * (1 + takeProfit), stop=stoplossOn and strategy.opentrades == maxOrders ? stoplossPrice : na, comment_profit='Take Profit On ' + str.tostring(strategy.opentrades) + " Orders", comment_loss="Stoploss Hit @ -" + str.tostring(stoploss*100, "#.##") + "% From Last Order")
// Find Max Number Of Orders
maxOrdersAtOnce = ta.highest(strategy.opentrades, 10000)
largestOrder = "Highest # Of Open Trades " + str.tostring(maxOrdersAtOnce, "#.##")
// Function that calculates the average amount of bars in a trade.
avgBarsPerTrade() =>
    sumBarsPerTrade = 0
    for tradeNo = 0 to strategy.closedtrades - 1
        // Loop through all closed trades, starting with the oldest.
        sumBarsPerTrade += strategy.closedtrades.exit_bar_index(tradeNo) - strategy.closedtrades.entry_bar_index(tradeNo) + 1
    result = nz(sumBarsPerTrade / strategy.closedtrades)
//Label Text
stoplossText = stoplossOn ? "SL " + str.tostring(stoploss*100, "#.##") + "%" : "SL Off"
percToRecover = (((strategy.position_avg_price * (1 + takeProfit)) / close) - 1) * 100
avgPrice = "Avg Price $" + str.tostring(strategy.position_avg_price, "#.##")
pnl = "Trade PnL " + str.tostring(((close - strategy.position_avg_price) / strategy.position_avg_price) * 100, format.percent)
tpPrice = "TP Price $" + str.tostring(strategy.position_avg_price * (1 + takeProfit), "#.##")
posSize = "Pos Size " + str.tostring(strategy.position_size, "#.##") + " Units"
numOrders = "# Of Open Orders " +str.tostring(strategy.opentrades)
percRecovery = "From Take Profit " + str.tostring(percToRecover, format.percent) + "↑"
closedTrades = "Total # Trades " + str.tostring(strategy.closedtrades)
initialCapital = "Initial Capital $" + str.tostring(strategy.initial_capital)
maxDrawdown = "Max Drawdown $" + str.tostring(strategy.max_drawdown, "#.##")
avgBarsPerTrade = "Avg Bars Per Trade " + str.tostring(avgBarsPerTrade(), "#")
grossProfit = "Gross Profit $" + str.tostring(strategy.grossprofit, "#.##")
netProfit = "Net Profit $" + str.tostring(strategy.netprofit, "#.##")
equity = "Portfolio Value $" + str.tostring(strategy.equity, "#.##")
percentProfit = "Percent Profit " + str.tostring((strategy.netprofit/strategy.initial_capital)*100, format.percent)
// Plot Average Price, SL And TP Level
avgPriceLine = plot(strategy.position_avg_price, title="Position Average Price", color=color.aqua, linewidth=4)
tpLevel = plot(strategy.position_avg_price * (1+takeProfit), title="Take Profit Level", color=color.red, linewidth=4)
stopLevel = plot(stoplossOn and strategy.opentrades == maxOrders ? stoplossPrice : na, title="Stoploss Level", color=color.orange, linewidth=2, style=plot.style_cross)
//Plot Price Difference Table
dataTable = table.new(tablePosition, columns=2, rows=19, bgcolor=color.blue, frame_color=color.white, frame_width=1, border_color=color.white, border_width=1)
if dataTableOn
    table.cell(table_id=dataTable, column=0, row=0, text="Current Trade", height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.navy)
    table.cell(table_id=dataTable, column=0, row=1, text=avgPrice, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=2, text=tpPrice, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=3, text=pnl, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=4, text=percRecovery, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=5, text=posSize, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=6, text=numOrders, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=7, text="Overall Performance", height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.navy)
    table.cell(table_id=dataTable, column=0, row=8, text=closedTrades, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=9, text=largestOrder, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=10, text=maxDrawdown, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=11, text=avgBarsPerTrade, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=12, text=grossProfit, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=13, text=netProfit, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=14, text=percentProfit, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=15, text=equity, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=0, row=16, text=initialCapital, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
    table.cell(table_id=dataTable, column=1, row=0, text="Settings", height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.navy)
    table.cell(table_id=dataTable, column=1, row=1, text=stoplossText, height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.purple)
    table.cell(table_id=dataTable, column=1, row=2, text="TP " + str.tostring(takeProfit*100) + "%", height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.purple)
    table.cell(table_id=dataTable, column=1, row=3, text="AD " + str.tostring(avgDown*100) + "%", height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.purple)
    table.cell(table_id=dataTable, column=1, row=4, text="AD%M " + str.tostring(percentScale) + "x", height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.purple)
    table.cell(table_id=dataTable, column=1, row=5, text="VM " + str.tostring(multiplier) + "x", height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.purple)
    table.cell(table_id=dataTable, column=1, row=6, text="M#O " + str.tostring(maxOrders), height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.purple)
    table.cell(table_id=dataTable, column=1, row=7, text="BO $" + str.tostring(quantity), height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center, bgcolor=color.purple)
// Share price too high for base order label
warningTable = table.new(position.top_center, columns=1, rows=1, bgcolor=color.orange)
if strategy.closedtrades == 0 and close > quantity
    table.cell(table_id=warningTable, column=0, row=0, text="Share Price Is Higher Than Base Order", height=0, text_color=color.white, text_halign=text.align_left, text_valign= text.align_center)
Expand (518 lines)

Overview

3Commas Bot DCA Backtester & Signals FREE opens a long base order when the selected oscillator signals: MACD line cross, MFI or RSI below a threshold, or Stochastic RSI K crossing above D. Further orders average down by a scaled percentage, with size multiplied up to a maximum order count. A take-profit percent closes the position; the stop loss is off unless enabled. It draws average-down levels and an information table, and it recalculates on every tick so live-bar signals can change.

Details

Published by

hasnocool on GitHub

Code credit

FriendOfTheTrend, as written in the script's header

Type

Strategy, Pine Script v5

Draws

On the price chart

Category

Oscillators & momentum, Mean reversion

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • Signals can change on the live bar or after it closes (repainting)
  • The strategy can add several entries in the same direction
  • The strategy enters trades without a stop loss

Topics

analysisbtcusdtcryptocurrencydatapandaspythonsimulationtradingtradingview

Settings

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

SettingTypeDefaultVariable
Buy Signal StrategystringMACDstrategy
Signal Threshold Levelint20strategyLevelTrigger
Indicator Lengthint14strategyLength
Stoploss OnboolfalsestoplossOn
Stoploss %float5stoploss
Take Profit %float.5takeProfit
Average Down %float.5avgDown
Avg Down % Multiplierfloat1.2percentScale
Volume Multiplierfloat1.5multiplier
Max # Of Ordersint12maxOrders
Size Of Base Orderfloat100quantity
Info Table On/OffbooltruedataTableOn
Show all 14 settings
SettingTypeDefaultVariable
Turn Average Down Levels On/OffbooltrueorderLevelsOn
Percentage Table PositionstringbrighttablePosition
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

330 stars

Alert BB + RSI [Alorse] is a multi-symbol mean-reversion strategy designed for cryptocurrency trading. It evaluates Bollinger Bands and the Relative Strength Index (RSI) across up to 20 user-defined ticker symbols simultaneously. The strategy enters long posit

Strategy v4 Oscillators & momentumVolatility & bands
Updated 2 months ago · None stated GitHub repository of Alert BB + RSI [Alorse]
285 stars

Mean Reversion Strategy is an overlay strategy that identifies pullbacks using a long-term EMA, RSI, and candlestick patterns. It generates long signals when a bullish engulfing candle forms below the EMA while RSI is oversold, and short signals when a bearish

Strategy v4 Mean reversionCandlestick patterns
Updated 3 years ago · None stated GitHub repository of Mean Reversion Strategy
104 stars

This strategy combines Bollinger Bands with a short RSI to fade moves that leave the bands and then return. A long requires the prior bar below the lower band and oversold, then a close back inside the band while RSI is between 30 and 50. Shorts mirror that at

Strategy v5 Oscillators & momentumVolatility & bands
Updated 3 years ago · MIT GitHub repository of Bollinger Bands and RSI Strategy
53 stars

This strategy implements Larry Connors' 2-period RSI mean-reversion algorithm overlaid on the price chart. It filters trades using a long-term Simple Moving Average (SMA), entering long positions when the price trades above the SMA and the short-term RSI drops

Strategy v6 Oscillators & momentumMean reversion
Updated 2 months ago · MPL-2.0 GitHub repository of Larry Connors 2-Period RSI Strategy

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