0% found this document useful (0 votes)
32 views8 pages

Message

The document is a TradingView Pine Script for a Smart Grid Bot strategy that utilizes RSI and T3 indicators for trading decisions. It includes parameters for grid bounds, grid line quantity, and performance dashboards to track trading metrics. The script implements buy and sell logic based on RSI signals and grid levels, along with a performance summary table displaying various trading statistics.

Uploaded by

mmra4ever
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)
32 views8 pages

Message

The document is a TradingView Pine Script for a Smart Grid Bot strategy that utilizes RSI and T3 indicators for trading decisions. It includes parameters for grid bounds, grid line quantity, and performance dashboards to track trading metrics. The script implements buy and sell logic based on RSI signals and grid levels, along with a performance summary table displaying various trading statistics.

Uploaded by

mmra4ever
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/ 8

//@version=5

strategy('v1.08 Smart Grid Bot', overlay=true, pyramiding=300,


close_entries_rule='ANY', default_qty_type=strategy.cash, initial_capital=100.0,
currency='USD', commission_type=strategy.commission.percent, commission_value=0.05,
max_bars_back = 500, max_lines_count = 500, max_polylines_count = 100)

// Input parameters
i_upperBound = input.float(group='Grid Bounds', title='Upper Range', defval=50) //
manual upper bound
i_lowerBound = input.float(group='Grid Bounds', title='Lower Range', defval=0.225)
// manual lower bound
i_gridQty = input.int(group='Grid Lines', title='Grid Line Quantity', defval=60,
maxval=300, minval=3) // number of grid lines
/////////////////////////////////////////////////////////////////////////////////
// RSI
////////////////////////////////////////////////////////////////////////////////

// RSI Settings
rsiLengthInput = input.int(14, title='RSI Length', minval=1, group='RSI Settings')
rsiSourceInput = input.source(close, title='Source', group='RSI Settings')
//No_RSI_Use = input.bool (false, title = 'No RSI confirmation')
rsi_OB = 70 // not needed for long only grid bot.
rsi_OS = input.int(30, title='RSI Oversold', minval=1, group='RSI Settings')
signalPeriod = 1 // Signal Decay, not a useful factor a grid bot.

// RSI Calculation
change = ta.change(rsiSourceInput)
up = ta.rma(math.max(change, 0), rsiLengthInput)
down = ta.rma(-math.min(change, 0), rsiLengthInput)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - 100 / (1 + up / down)

// Signal Tracking
var int activeSignal = 0
var int barsRemaining = 0

// Signal Conditions
buyTrigger = ta.crossover(rsi, rsi_OS)
sellTrigger = ta.crossunder(rsi, rsi_OB)

if buyTrigger
activeSignal := 1
barsRemaining := signalPeriod
barsRemaining
else if sellTrigger
activeSignal := -1
barsRemaining := signalPeriod
barsRemaining
else if barsRemaining > 0
barsRemaining -= 1
barsRemaining
else
activeSignal := 0
activeSignal

// Active Signals
buyRSIActive = activeSignal == 1 and barsRemaining > 0
//sellRSIActive = activeSignal == -1 and barsRemaining > 0
plotshape(buyRSIActive, title='RSI Buy', location=location.belowbar,
style=shape.diamond, size=size.small, color=color.new(color.green, 0))
//plotshape(sellRSIActive, title='RSI_Sell', location=location.abovebar,
style=shape.diamond, size=size.small, color=color.new(color.red, 0))

/////////////////////////////////////////////////////////////////////////////////
// T3
////////////////////////////////////////////////////////////////////////////////

useT3 = true
crossT3 = input.bool(true, 'Cross confirmation? - T3')
inverseT3 = input.bool(false, 'Inverse? - T3')

lengthT3 = input(title='Length - T3', defval=5)


factorT3 = input.float(title='Factor - T3', minval=0, maxval=1, defval=0.7)
highlightMovementsT3 = input(title='Highlight Movements ? - T3', defval=true)
srcT3 = input(title='Source - T3', defval=close)

gdT3(srcT3, lengthT3) =>


ta.ema(srcT3, lengthT3) * (1 + factorT3) - ta.ema(ta.ema(srcT3, lengthT3),
lengthT3) * factorT3

t3 = gdT3(gdT3(gdT3(srcT3, lengthT3), lengthT3), lengthT3)

t3Color = highlightMovementsT3 ? t3 > t3[1] ? color.green : color.red : #6d1e7f

t3Signals = t3 > t3[1] ? 1 : -1


// Simplified condition for long and short signals based on `useT3` and
`highlightMovementsT3` inputs

basicLongCondition = t3Signals > 0 and close > t3


basicShortCondition = t3Signals < 0 and close < t3

t3SignalsLong = useT3 ? (highlightMovementsT3 ? basicLongCondition : close > t3) :


true
t3SignalsShort = useT3 ? (highlightMovementsT3 ? basicShortCondition : close <
t3) : true

// Simplified cross condition logic for long and short signals


t3SignalsLongCross = crossT3 ? not t3SignalsLong[1] and t3SignalsLong :
t3SignalsLong
t3SignalsShortCross = crossT3 ? not t3SignalsShort[1] and t3SignalsShort :
t3SignalsShort

// Applying inverse logic to final signals


t3SignalsLongFinal = inverseT3 ? t3SignalsShortCross : t3SignalsLongCross
t3SignalsShortFinal = inverseT3 ? t3SignalsLongCross : t3SignalsShortCross

plot(t3SignalsLongFinal ? 1 : 0, 'Heartbeat Long', display= display.data_window)


plot(t3SignalsShortFinal ? -1 : 0, 'Heartbeat Short', display= display.data_window)

plot(useT3 ? t3 : na, title='T3', linewidth=2, color=t3Color)

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// Functions to calculate grid bounds and build grid


f_getGridBounds(_bs, _bl, _bd, _up) =>
if _bs == 'Hi & Low'
_up ? ta.highest(close, _bl) * (1 + _bd) : ta.lowest(close, _bl) * (1 -
_bd)
else
avg = ta.sma(close, _bl)
_up ? avg * (1 + _bd) : avg * (1 - _bd)

f_buildGrid(_lb, _gw, _gq) =>


gridArr = array.new_float(0)
for i = 0 to _gq - 1 by 1
array.push(gridArr, _lb + _gw * i)
gridArr

f_getNearGridLines(_gridArr, _price) =>


arr = array.new_int(3)
for i = 0 to array.size(_gridArr) - 1 by 1
if array.get(_gridArr, i) > _price
array.set(arr, 0, i == array.size(_gridArr) - 1 ? i : i + 1)
array.set(arr, 1, i == 0 ? i : i - 1)
break
arr

// Grid calculations
var upperBound = i_upperBound
var lowerBound = i_lowerBound
var gridWidth = (upperBound - lowerBound) / (i_gridQty - 1)
var gridLineArr = f_buildGrid(lowerBound, gridWidth, i_gridQty)
var orderArr = array.new_bool(i_gridQty, false)

closeLineArr = f_getNearGridLines(gridLineArr, close)


nearTopGridLine = array.get(closeLineArr, 0)
nearBotGridLine = array.get(closeLineArr, 1)

// 1) BUY LOGIC: When the basic long condition is true, loop through all grid
levels
// and send an entry for every level that qualifies but has not yet been used.
if (buyRSIActive or basicLongCondition)
// Loop over all grid levels in your grid array
for i = 0 to array.size(gridLineArr) - 1
gridPrice = array.get(gridLineArr, i)
// Check if current price is below this grid level AND if we have not
already bought here.
if close < gridPrice and not array.get(orderArr, i)
// Mark this grid level as used
array.set(orderArr, i, true)
// Place the buy order.
strategy.entry(id = "GridBuy#" + str.tostring(i), direction =
strategy.long, qty = strategy.initial_capital / (i_gridQty - 1) / close, comment =
"#" + str.tostring(i))
// ------------------------------------
// 2) EXIT LOGIC
// Loop through each grid line except the very last
// because we'll check index+1 below.
for i = 0 to array.size(gridLineArr) - 2
// If we have an active buy from grid i
if array.get(orderArr, i)
// Next line above it is i + 1
nextLineIndex = i + 1
nextLinePrice = array.get(gridLineArr, nextLineIndex ) //I added in a -1 to
correct for the fact its closing orders 2 above instead of 1

// If price is above that line, we close and free up that grid


if close > nextLinePrice
array.set(orderArr, i, false)
strategy.close(id="GridBuy#" + str.tostring(i), comment="#" +
str.tostring(i))

closeLineArr := f_getNearGridLines(gridLineArr, close)


nearTopGridLine := array.get(closeLineArr, 0)
nearBotGridLine := array.get(closeLineArr, 1)

// Plotting grid lines


for i = 0 to array.size(gridLineArr) - 1 by 1
var line gridLine = na
gridLine := line.new(x1=bar_index - 100, y1=array.get(gridLineArr, i),
x2=bar_index, y2=array.get(gridLineArr, i), color=color.new(color.blue, 0),
width=1)
line.set_x1(gridLine, bar_index - 9990) // Start line from 100 bars ago
line.set_x2(gridLine, bar_index) // Extend the line to the current bar

//---------------------------------------------------------------------------------
-----------------------------------------------------------------------
// DASHBOARD PERFORMANCE TABLE/
//---------------------------------------------------------------------------------
-----------------------------------------------------------------------
i_tableTextSize = input.string(title="Dashboard Size", defval="Small",
options=["Auto", "Huge", "Large", "Normal", "Small", "Tiny"], group="Dashboards")
table_text_size(s) =>
switch s
"Auto" => size.auto
"Huge" => size.huge
"Large" => size.large
"Normal" => size.normal
"Small" => size.small
=> size.tiny
tableTextSize = table_text_size(i_tableTextSize)

/// Performance Summary Dashboard


//
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// Inspired by https://www.tradingview.com/script/uWqKX6A2/ - Thanks VertMT

i_showDashboard = input.bool(title="Performance Summary", defval=true,


group="Dashboards", inline="Show Dashboards")
f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) =>
_cellText = _title + "\n" + _value
table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor,
text_color=_txtcolor, text_size=tableTextSize)

// Draw dashboard table


if i_showDashboard
var bgcolor = color.new(color.black,0)

// Keep track of Wins/Losses streaks


newWin = (strategy.wintrades > strategy.wintrades[1]) and
(strategy.losstrades == strategy.losstrades[1]) and (strategy.eventrades ==
strategy.eventrades[1])
newLoss = (strategy.wintrades == strategy.wintrades[1]) and
(strategy.losstrades > strategy.losstrades[1]) and (strategy.eventrades ==
strategy.eventrades[1])

varip int winRow = 0


varip int lossRow = 0
varip int maxWinRow = 0
varip int maxLossRow = 0

if newWin
lossRow := 0
winRow := winRow + 1
if winRow > maxWinRow
maxWinRow := winRow

if newLoss
winRow := 0
lossRow := lossRow + 1
if lossRow > maxLossRow
maxLossRow := lossRow

// Prepare stats table


var table dashTable = table.new(position.top_right, 1, 15, border_width=1)

if barstate.islastconfirmedhistory
// Update table
dollarReturn = strategy.netprofit
f_fillCell(dashTable, 0, 0, "Start:", str.format("{0,date,long}",
strategy.closedtrades.entry_time(0)) , bgcolor, color.white) // + str.format("
{0,time,HH:mm}", strategy.closedtrades.entry_time(0))
f_fillCell(dashTable, 0, 1, "End:", str.format("{0,date,long}",
strategy.opentrades.entry_time(0)) , bgcolor, color.white) // + str.format("
{0,time,HH:mm}", strategy.opentrades.entry_time(0))
_profit = (strategy.netprofit / strategy.initial_capital) * 100
f_fillCell(dashTable, 0, 2, "Net Profit:", str.tostring(_profit, '##.##') +
"%", _profit > 0 ? color.teal : color.maroon, color.white)
_numOfDaysInStrategy = (strategy.opentrades.entry_time(0) -
strategy.closedtrades.entry_time(0)) / (1000 * 3600 * 24)
f_fillCell(dashTable, 0, 3, "Percent Per Day", str.tostring(_profit /
_numOfDaysInStrategy, '#########################.#####')+"%", _profit > 0 ?
color.teal : color.maroon, color.white)
_winRate = ( strategy.wintrades / strategy.closedtrades ) * 100
f_fillCell(dashTable, 0, 4, "Percent Profitable:", str.tostring(_winRate,
'##.##') + "%", _winRate < 50 ? color.maroon : _winRate < 75 ? #999900 :
color.teal, color.white)
f_fillCell(dashTable, 0, 5, "Profit Factor:",
str.tostring(strategy.grossprofit / strategy.grossloss, '##.###'),
strategy.grossprofit > strategy.grossloss ? color.teal : color.maroon, color.white)
f_fillCell(dashTable, 0, 6, "Total Trades:",
str.tostring(strategy.closedtrades), bgcolor, color.white)
f_fillCell(dashTable, 0, 8, "Max Wins In A Row:", str.tostring(maxWinRow,
'######') , bgcolor, color.white)
f_fillCell(dashTable, 0, 9, "Max Losses In A Row:",
str.tostring(maxLossRow, '######') , bgcolor, color.white)

// Monthly Table Performance Dashboard By @QuantNomad


//
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
i_showMonthlyPerformance = input.bool(true, 'Monthly Performance',
group='Dashboards', inline="Show Dashboards")
i_monthlyReturnPercision = 2

if i_showMonthlyPerformance
new_month = month(time) != month(time[1])
new_year = year(time) != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1

cur_month_pnl = 0.0
cur_year_pnl = 0.0

// Current Monthly P&L


cur_month_pnl := new_month ? 0.0 :
(1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1

// Current Yearly P&L


cur_year_pnl := new_year ? 0.0 :
(1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1

// Arrays to store Yearly and Monthly P&Ls


var month_pnl = array.new_float(0)
var month_time = array.new_int(0)

var year_pnl = array.new_float(0)


var year_time = array.new_int(0)

last_computed = false

if (not na(cur_month_pnl[1]) and (new_month or


barstate.islastconfirmedhistory))
if (last_computed[1])
array.pop(month_pnl)
array.pop(month_time)

array.push(month_pnl , cur_month_pnl[1])
array.push(month_time, time[1])

if (not na(cur_year_pnl[1]) and (new_year or barstate.islastconfirmedhistory))


if (last_computed[1])
array.pop(year_pnl)
array.pop(year_time)

array.push(year_pnl , cur_year_pnl[1])
array.push(year_time, time[1])

last_computed := barstate.islastconfirmedhistory ? true : nz(last_computed[1])

// Monthly P&L Table


var monthly_table = table(na)

if (barstate.islastconfirmedhistory)
monthly_table := table.new(position.bottom_right, columns = 14, rows =
array.size(year_pnl) + 1, border_width = 1)

table.cell(monthly_table, 0, 0, "", bgcolor = #cccccc,


text_size=tableTextSize)
table.cell(monthly_table, 1, 0, "Jan", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 2, 0, "Feb", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 3, 0, "Mar", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 4, 0, "Apr", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 5, 0, "May", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 6, 0, "Jun", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 7, 0, "Jul", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 8, 0, "Aug", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 9, 0, "Sep", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 10, 0, "Oct", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 11, 0, "Nov", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 12, 0, "Dec", bgcolor = #cccccc,
text_size=tableTextSize)
table.cell(monthly_table, 13, 0, "Year", bgcolor = #999999,
text_size=tableTextSize)

for yi = 0 to array.size(year_pnl) - 1
table.cell(monthly_table, 0, yi + 1,
str.tostring(year(array.get(year_time, yi))), bgcolor = #cccccc,
text_size=tableTextSize)

y_color = array.get(year_pnl, yi) > 0 ? color.new(color.teal, transp =


40) : color.new(color.gray, transp = 40)
table.cell(monthly_table, 13, yi + 1,
str.tostring(math.round(array.get(year_pnl, yi) * 100, i_monthlyReturnPercision)),
bgcolor = y_color, text_color=color.new(color.white, 0),text_size=tableTextSize)

for mi = 0 to array.size(month_time) - 1
m_row = year(array.get(month_time, mi)) - year(array.get(year_time,
0)) + 1
m_col = month(array.get(month_time, mi))
m_color = array.get(month_pnl, mi) > 0 ? color.new(color.teal, transp =
40) : color.new(color.maroon, transp = 40)

table.cell(monthly_table, m_col, m_row,


str.tostring(math.round(array.get(month_pnl, mi) * 100, i_monthlyReturnPercision)),
bgcolor = m_color, text_color=color.new(color.white, 0), text_size=tableTextSize)

You might also like