neutronix community bot ML + Alerts 4h-daily (mod. capissimo)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// NEUTRONIX Community BOT Copyright gravisxv
// You are fully authorized to copy, modify and rework the code according to open source license
// LVQ-based Strategy © capissimo
// SL-TP code from theCrypster 2020 open source study script
// MESA © 2013  John F. Ehlers
// Mesa code from dongyun open source study script
// LVQ-based Strategy modified by gravisxv for study purpose
// Neutronix v1
// Fixed repaint, added more filtering (vwap - vwma) for longer timeframes, fixed reverse signal check, added rsi period and volume settings , ALL filters are now on by default
// Vwap is plotted as additional visual confirmation
// Neutronix v2
// Major rework of options panel (removed most of unused AI settings)
// Enabled profitable lower timeframes trading(1 minute+) via option 'aggressive stance'('Reverse signals' option might work too in certain market conditions), added take profit and stop loss alarms
// Display infos about volatility and last valid trading signal,
// Important: set your alarms with 'Once per bar'. The setting 'Once per bar close' works as well but it might be late.
// Neutronix v2.1
// Added volatility filter multiplier option to magnify volatility filter effect
// Added safety exits option as a stop measure when price is starting to move against the trade direction
// Added directional movement filter for removing false signals
// Added Take Profit alarm work for both long-short
// Neutronix v2.2
// Quick fix on a formula
// Converted to V5
// Neutronix v3 
// Significant release for more automatization
// Important: Signals are fully synchronized with alerts via correct candles (the problem was persistent in v2).
// Removed useless options from the panel
// Immediate or delayed alert mode (removed feature sry maybe next)
// Added more signals for added risks-rewards in ai-automatic mode
// Option to enable heikenashi smoothing
// Automatic exits-trend exits with manual level tp always on (they work together)
// Added DCA for short-long in emulation mode(you need to use external alert systems for safety orders) and SWING trading
// Possibility of exit in immediate trend or wait at next trend
// Institutional trading option catch whales movements and avoid range market situations
// Scalping filters on-off switch
// Changed machine learning feed data to include monetary movements
// Manual mode consist of supertrend mode red/green zones and dual hma moving indicators for expert users.
// Exit Long-Short Global alerts provide exit alarms when takeprofit/stoploss/changetradedirection signals are triggered
// Neutronix v4
// AI signals are now more efficient with possibility of fine-tuning
// Added multiple modalities for exit option
// The filters now offer a full suite of parameters to remove unwanted signals
// Changed DCAbot into Supertrend Pivot, scalping and swing updated too
// Some changes to takeprofit/stop loss levels
// --to be completed--


// No excuses to stop trading now
// the gem of bots 

// --happy trade--

//_____ ___  ____ _ 
//|  __ \|  \/  | | |
//| |  \/| .  . | | |
//| | __ | |\/| | | |
//| |_\ \| |  | |_|_|
// \____/\_|  |_(_|_)
                   
                   
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  _   _   _____   _   _   _____   ____     ___    _   _   ___  __  __     ____    ___    __  __   __  __   _   _   _   _   ___   _____  __   __    ____     ___    _____ 
//| \ | | | ____| | | | | |_   _| |  _ \   / _ \  | \ | | |_ _| \ \/ /    / ___|  / _ \  |  \/  | |  \/  | | | | | | \ | | |_ _| |_   _| \ \ / /   | __ )   / _ \  |_   _|
//|  \| | |  _|   | | | |   | |   | |_) | | | | | |  \| |  | |   \  /    | |     | | | | | |\/| | | |\/| | | | | | |  \| |  | |    | |    \ V /    |  _ \  | | | |   | |  
//| |\  | | |___  | |_| |   | |   |  _ <  | |_| | | |\  |  | |   /  \    | |___  | |_| | | |  | | | |  | | | |_| | | |\  |  | |    | |     | |     | |_) | | |_| |   | |  
//|_| \_| |_____|  \___/    |_|   |_| \_\  \___/  |_| \_| |___| /_/\_\    \____|  \___/  |_|  |_| |_|  |_|  \___/  |_| \_| |___|   |_|     |_|     |____/   \___/    |_|  
// 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                                                                                                                                                                         

// If you do appreciate the bot please consider a small donation to support me and/or other authors on TV(reminder Neutronix bot will ALWAYS be free):
// BTC 36hcvdyoRqw8VcoEQvSKZ6AYGPFYEP4upp
// XRP rf5VFsp5HnmAwiuQugQsrNALwPkCWesAGL
// LTC M8U1xdoU34peZTz7b8Ve48ubLGQoGW9myn
// TRON TEUziyvYmhjnuH3bzgvCdRoZBLcvMbGPqo

//@version=5
indicator('neutronix community bot version Machine Learning + Alerts 4h - daily (based on capissimo ML)', '', true, max_labels_count=200, max_bars_back=5000)

// LVQ-based Strategy (FX and Crypto)

// Description: 

// Learning Vector Quantization (LVQ) can be understood as a special case of 
// an artificial neural network, more precisely, it applies a winner-take-all 
// learning-based approach. It is based on prototype supervised learning 
// classification task and trains its weights through a competitive 
// learning algorithm.

// Algorithm:

// Initialize weights
// Train for 1 to N number of epochs
//   Select a training example
//   Compute the winning vector
//   Update the winning vector
// Classify test sample

// The LVQ algorithm offers a framework to test various indicators easily to see  
// if they have got any *predictive value*. One can easily add cog, wpr and others.
// Note: TradingViews's playback feature helps to see this strategy in action.
// The algo is tested with BTCUSD/1Hour.

// Warning: This is a preliminary version!
// ***Warning***: Signals LARGELY depend on hyperparams (lrate and epochs).

// Style tags: Trend Following, Trend Analysis
// Asset class: Equities, Futures, ETFs, Currencies and Commodities
// Dataset: FX Minutes/Hours+++/Days


//-------------------- Inputs

trmode  = input.string(defval='supertrend', title='Trading mode', options=['ai','scalping','supertrend','swing','manual'])
ftt  = input.string(defval='auto', title='Exit mode', options=['auto','macross', 'atr','percent'])

//Candles set
cs = input(close, 'Dataset')
h = input(false, title = "Signals from Heikin Ashi Candles?")

//
aggressive = input(true, 'Institutional Trading', group='Filter options')
fss = input(true, 'Ema filter ?', group='Filter options')
lfema1= input.int(15, 'EMA1 period', minval=1, maxval=500, group='Filter options')
lfema2 = input.int(33, 'EMA2 period', minval=1, maxval=500, group='Filter options')
vff = input(false, 'Volume filter ?', group='Filter options')
ths= input.int(46, 'Volume Threshold', minval=1, maxval=100, group='Filter options')
//
trail = input(true, 'Trailing Stop?', group='Take profits') 
stopPer = input.float(9, title='Stop Loss %', group='Take profits') / 100
takePer = input.float(15, title='Take Profit %', group='Take profits') / 100
lauto = input.int(14, "AUTO Exit length", group="Take profits")
atfactor = input.int(3, "ATR Exit factor", group="Take profits")
atperiod = input.int(12, "ATR Exit period", group="Take profits")
//
leftBars = input(4,title="Pivot bars", group="Pivot Reversal Supertrend settings")
rightBars = input(1, group="Pivot Reversal Supertrend settings")
atrPeriod = input(10, "ATR Length", group="Pivot Reversal Supertrend settings")
factor = input.float(3.0, "Factor", step = 0.1, group="Pivot Reversal Supertrend settings")
//
lgh = input.int(15, 'Price Channel length', minval=1, maxval=99, group="Price Channel Scalping")
//
fasth = input.int(12, 'Fast Moving Average', minval=1, maxval=99, group="Manual DMAC Settings")
slowh = input.int(46, title="Slow Moving Average", group="Manual DMAC Settings")

//-------------------- System Variables
//PARAMS
srg = h ? request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, cs, lookahead=barmerge.lookahead_off) : cs
lrate       = 0.05
epochs = 5 //after 4 no improvements
//epochs      = 5
ds = srg
p = input.int(14, title='LBW ~1-1000',maxval=1000, group='AI options')
res = input.int(1, title='LBW Factor ~1-10',maxval=10, group='AI options')
reverse = input(true, title = "Reverse Ai Signals ?", group='AI options')
startYear = input.int(2020, 'Training Start Year', minval=2010, group='AI options')
startMonth = input.int(1, 'Training Start Month', minval=1, maxval=12, group='AI options')
startDay = input.int(1, 'Training Start Day', minval=1, maxval=31, group='AI options')
stopYear = input.int(2021, 'Training Stop Year', minval=2010, group='AI options')
stopMonth = input.int(8, 'Training Stop Month', minval=1, maxval=12, group='AI options')
stopDay = input.int(1, 'Training Stop Day', minval=1, maxval=31, group='AI options')

var BUY = -1
var SELL = 1
var HOLD = 0

VWAP = ta.vwap(srg)  //VWAP using source candles
var cc = 0
//BUY = 1  //-- some TFs and assets require reversing the signals!! IMPORTANT for LTF
//SELL = -1
//--------------------  Dynamic Arrays ///PART OF LVQ ALGORITHM

var int wnr = 0  // winner's signal
var int signal = HOLD

//--------------------  Regular arrays  ///STORING OLD CANDLES AND TRAINED WEIGHTS

var float[] features = array.new_float()  //-- training data
var float[] weights0 = array.new_float(1, 1.)  //-- learning vectors
var float[] weights1 = array.new_float(1, 100.0)

/// LEARNING VECTOR QUANTIZATION
norm(x, p) =>  // normalize features
    (x - ta.lowest(x, p)) / (ta.highest(x, p) - ta.lowest(x, p))

getwinner(features, weights0, weights1) =>  // compute the winning vector by Euclidean distance 
    d0 = 0.
    d1 = 0.
    size = array.size(features)
    for i = 0 to size - 1 by 1
        d0 := d0 + math.round(math.pow(array.get(features, i) - array.get(weights0, i), 2),2)// 
        d1 := d1 + math.round(math.pow(array.get(features, i) - array.get(weights1, i), 2),2)// EUCLID

        d1
    d0 > d1 ? SELL : d0 < d1 ? BUY : HOLD

update(features, weights0, weights1, w, lr) =>  // update the weight array of the winner
    size = array.size(features)
    for i = 0 to size - 1 by 1
        if w == SELL
            array.set(weights0, i, array.get(weights0, i) + lrate * (array.get(features, i) - array.get(weights0, i)))
        if w == BUY
            array.set(weights1, i, array.get(weights1, i) + lrate * (array.get(features, i) - array.get(weights1, i)))		
			

//-------------------- Logic

//x = ds[barstate.ishistory ? 0 : 1]
x = srg
periodStart = timestamp(startYear, startMonth, startDay, 0, 0)
periodStop = timestamp(stopYear, stopMonth, stopDay, 0, 0)

// The core logic
// Collect training data (i.e. features)
f1 = ta.cci(x, p*res)
//f2 = ta.rsi(x, 3*res) //cmo

// Train the model using particular training period
if time >= periodStart and time <= periodStop
    array.clear(features)
    array.push(features, f1)
    //array.push(features, f2)

    for i = 1 to epochs by 1
        w = getwinner(features, weights0, weights1)
        update(features, weights0, weights1, w, lrate)  //-- this is 'the act of learning'

// Classify new input sample
if time > periodStop
    array.clear(features)
    array.push(features, f1)
   // array.push(features, f2)

	wnr := getwinner(features, weights0, weights1)
	wnr

//////////////////////
//TREND FILTER
em100 = ta.ema(srg, lfema1)
em200 = ta.ema(srg, lfema2)

//FILTERS
filtersell = true
filterbuy = true

filtersell := em100 < em200 
filterbuy := em100 > em200 

stancesell = aggressive ? srg <= VWAP : 1
stancebuy =  aggressive ? srg > VWAP : 1

volumeBreak(thres) =>
    rsivol = ta.rsi(srg, 14)
    osc = ta.vwma(rsivol, 18)
    osc >= thres
fivol = volumeBreak(ths)

//Kama
getKAMA(src, length1, fastLength1, slowLength1) =>
    mom = math.abs(ta.change(src, length1))
    volatility = math.sum(math.abs(ta.change(src)), length1)
    er = volatility != 0 ? mom / volatility : 0
    fastAlpha = 2 / (fastLength1 + 1)
    slowAlpha = 2 / (slowLength1 + 1)
    sc = math.pow(er * (fastAlpha - slowAlpha) + slowAlpha, 2)
    kama = 0.0
    kama := sc * src + (1 - sc) * nz(kama[1])
    kama
    
//kamafat = getKAMA(srg, 7,2,2)
kamafat = getKAMA(srg, 10,2,30)
plot(ftt=='macross'?kamafat:1, color=color.blue)

//--ATR Exit
[ATRStop , direct] = ta.supertrend(atfactor, atperiod)

plot(ftt=="atr"?ATRStop:na, color=color.black)

// Tilson swing
gt(src1, fast_ma_len, factor) => ta.ema(src1, fast_ma_len) * (1 + factor) - ta.ema(ta.ema(src1, fast_ma_len), fast_ma_len) * factor
t3(src1, fast_ma_len, factor) => gt(gt(gt(src1, fast_ma_len, factor), fast_ma_len, factor), fast_ma_len, factor)	
rT3 = 0.7
tilT3 = t3(srg, 20, rT3)

//Manual Settings
fasthull = ta.hma(srg, fasth)
slowhull = ta.hma(srg, slowh)
	
//Price channel
hh = ta.highest(high[1], lgh)
ll = ta.lowest(low[1], lgh)
centerln = (hh + ll) / 2  //price to track
//plot(centerln, color=color.green)
//plot (hh, color=color.maroon)
//plot(ll, color=color.teal)

//Pivot Reversal Supertrend
swh = ta.pivothigh(leftBars, rightBars)
swl = ta.pivotlow(leftBars, rightBars)
[supertrend, direction] = ta.supertrend(factor, atrPeriod)
swh_cond = not na(swh)
hprice = 0.0
hprice := swh_cond ? swh : hprice[1]
le = false
le := swh_cond ? true : (le[1] and high > hprice ? false : le[1])
//if (le and direction < 0)
//	strategy.entry("PivRevLE", strategy.long, comment="PivRevLE", stop=hprice + syminfo.mintick)
swl_cond = not na(swl)
lprice = 0.0
lprice := swl_cond ? swl : lprice[1]
se = false
se := swl_cond ? true : (se[1] and low < lprice ? false : se[1])
//if (se and direction > 0)
	//strategy.entry("PivRevSE", strategy.short, comment="PivRevSE", stop=lprice - syminfo.mintick)

// Generate signal - 
//SCALPING price chan
if (trmode=='scalping')
	signal := close <= hh and stancebuy and (fss?filterbuy:1) and (vff?fivol:1)  ? BUY : close >= ll and stancesell and (fss?filtersell:1) and (vff?fivol:1) ? SELL : nz(signal[1])
//AUTO
if (trmode=='ai')
	signal := (wnr == (reverse?BUY:SELL)) and stancesell and (fss?filtersell:1) and (vff?fivol:1)  ? SELL :  (wnr == (reverse?SELL:BUY)) and stancebuy and (fss?filterbuy:1) and (vff?fivol:1)  ? BUY : nz(signal[1])     
// PivRev Supertrend (Old DCABOT)
if (trmode=='supertrend')
	signal := le and direction < 0 and stancebuy and (fss?filterbuy:1) and (vff?fivol:1) ? BUY : se and direction > 0 and stancesell and (fss?filtersell:1) and (vff?fivol:1) ? SELL : nz(signal[1])
if (trmode=='swing')
	signal := tilT3 > srg and stancesell and (fss?filtersell:1) and (vff?fivol:1) ? SELL : tilT3 < srg and stancebuy and (fss?filterbuy:1) and (vff?fivol:1)  ? BUY : nz(signal[1])
//
changed = ta.change(signal)

if changed
    cc := cc + 1
    cc
    
int long_short = 0
// CHECK IF OLD SIGNAL IS SHORT OR LONG TO AVOID COPY
startLongTrade = changed and signal == BUY and (nz(long_short[1]) == 0 or nz(long_short[1]) == -1)
startShortTrade = changed and signal == SELL and (nz(long_short[1]) == 0 or nz(long_short[1]) == 1)
endLongTrade = changed and signal == SELL
endShortTrade = changed and signal == BUY

//IMPORTED CODE FROM TP ALERT VERSION
//SL TP
long_last = startLongTrade and (nz(long_short[1]) == 0 or nz(long_short[1]) == -1)
short_last = startShortTrade and (nz(long_short[1]) == 0 or nz(long_short[1]) == 1)
long_short := long_last ? 1 : short_last ? -1 : long_short[1]

longPrice = 0.
shortPrice = 0.
//entry price

longPrice := ta.valuewhen(trail?close:long_last,close,0)// and cs!=open?barstate.isconfirmed:1, close, 0)
shortPrice := ta.valuewhen(trail?close:short_last, close, 0)

//fixed sltp prices
longStop = longPrice * (1 - stopPer)
shortStop = shortPrice * (1 + stopPer)
longTake = longPrice * (1 + takePer)
shortTake = shortPrice * (1 - takePer)

//plot sltp lines
plot(long_short == 1 ? longStop : na, style=plot.style_linebr, color=color.new(color.red, 0), linewidth=1, title='Long Fixed SL')
plot(long_short == -1 ? shortStop : na, style=plot.style_linebr, color=color.new(color.red, 0), linewidth=1, title='Short Fixed SL')
//plot(long_short == 1 ? longTake : na, style=plot.style_linebr, color=color.new(color.green, 0), linewidth=1, title='Long Fixed TP')
//plot(long_short == -1 ? shortTake : na, style=plot.style_linebr, color=color.new(color.green, 0), linewidth=1, title='Short Fixed TP')

//remove first bar for SL/TP (you can't enter a trade at bar close THEN hit your SL on that same bar) -- MODIFIED
longBar1 = ta.barssince(long_last)
shortBar1 = ta.barssince(short_last)
longBar2 = longBar1 > 1 ? true : false
//longBar2 = true //no
shortBar2 = shortBar1 > 1 ? true : false
//shortBar2 = true

longSLhit = false
shortSLhit = false

longSLhit := long_short == 1 and longBar2 and (low < longStop) and not changed
shortSLhit := long_short == -1 and shortBar2 and (high > shortStop) and not changed

//Rendering stoploss
plotshape(longSLhit, style=shape.labelup, location=location.belowbar, color=color.new(color.purple, 0), size=size.tiny, title='Long SL', text=' Long SL', textcolor=color.new(color.white, 0))
plotshape(shortSLhit, style=shape.labeldown, location=location.abovebar, color=color.new(color.purple, 0), size=size.tiny, title='Short SL', text=' Short SL', textcolor=color.new(color.white, 0))

//check for TP hit during bar
bool longTPhit = false
bool shortTPhit = false

//Exit checks: price is in target
//

if(ftt=="auto")
    longTPhit := long_short == 1 and longBar2 and (wnr == SELL and ta.rsi(srg,lauto) < 70) and not changed and not longSLhit
    shortTPhit := long_short == -1 and shortBar2 and (wnr == BUY and ta.rsi(srg,lauto) > 30) and not changed and not shortSLhit
    
else if(ftt=="macross")
    longTPhit := long_short == 1 and longBar2 and (ta.crossunder(close,kamafat)) and not changed and not longSLhit
	shortTPhit := long_short == -1 and shortBar2 and (ta.crossover(close,kamafat)) and not changed and not shortSLhit

else if(ftt=="atr")
	longTPhit := long_short == 1 and longBar2 and (ta.crossunder(low,ATRStop)) and not changed and not longSLhit
	shortTPhit := long_short == -1 and shortBar2 and (ta.crossover(high,ATRStop)) and not changed and not shortSLhit

else if(ftt=="percent")
	longTPhit := long_short == 1 and longBar2  and (high > longTake) and not changed and not longSLhit
	shortTPhit := long_short == -1 and longBar2 and (low < shortTake) and not changed and not shortSLhit


plotshape(longTPhit, style=shape.labeldown, location=location.abovebar, color=color.new(color.olive, 0), size=size.tiny, title='Long TP', text='Long TP', textcolor=color.new(color.white, 0))
plotshape(shortTPhit, style=shape.labelup, location=location.belowbar, color=color.new(color.olive, 0), size=size.tiny, title='Short TP', text='Short TP', textcolor=color.new(color.white, 0))
//reset long_short if SL/TP hit during bar
long_short := (long_short == 1 or long_short == 0) and longBar2 and (longSLhit or longTPhit) ? 0 : (long_short == -1 or long_short == 0) and shortBar2 and (shortSLhit or shortTPhit) ? 0 : long_short
//

//-------------------- Rendering

plotshape(startLongTrade, 'BUY', shape.labelup, location.belowbar, color.new(color.green, 0), size=size.small)
plotshape(startShortTrade, 'SELL', shape.labeldown, location.abovebar, color.new(color.red, 0), size=size.small)
plot(endLongTrade ? high : na, 'StopBuy', color.new(color.green, 0), 2, plot.style_cross)
plot(endShortTrade ? low : na, 'StopSell', color.new(color.red, 0), 2, plot.style_cross)
//plot(VWAP, color=color.new(color.aqua, 0), linewidth=2, title='VWap')
plot(trmode=='manual'?fasthull:na, color=color.blue, linewidth=2)
plot(trmode=='manual'?slowhull:na, color=color.maroon, linewidth=2)
plot(trmode=='swing'?tilT3:na, color=color.new(color.red, 0))
plot(trmode=='scalping'?centerln:na, color=color.lime, linewidth=4)

//-------------------- Alerting
conditionTP = longTPhit or shortTPhit
//alertcondition(startLongTrade and  barstate.isconfirmed, 'Long', 'Go long!',alertmenow?alert.freq_all:alert.freq_once_per_bar_close)
alertcondition(startLongTrade, 'Long', 'Go BUY',alert.freq_once_per_bar)
alertcondition(startShortTrade, 'Short', 'Go SELL!',alert.freq_once_per_bar)
//
alertcondition(startLongTrade or startShortTrade, 'Alert Global Trade', 'Deal Time!',alert.freq_all)

alertcondition(condition=conditionTP or startShortTrade or longSLhit, title='Exit Long Global', message='TP Hit @ ${{plot("TP")}}')
alertcondition(condition=conditionTP or startLongTrade or shortSLhit, title='Exit Short Global', message='TP Hit @ ${{plot("TP")}}')
alertcondition(condition=conditionTP or longSLhit or shortSLhit, title='Exit Global', message='TP Hit @ ${{plot("TP")}}')
alertcondition(condition=conditionTP, title='Exit TP Global', message='TP Hit @ ${{plot("TP")}}')

alertcondition(condition=longSLhit, title='Long Stop Loss', message='Long SL Hit @ ${{plot("Long SL")}}')
alertcondition(condition=shortSLhit, title='Short Stop Loss', message='Short SL Hit @ ${{plot("Short SL")}}')
alertcondition(condition=longSLhit or shortSLhit, title='Global Stop Loss', message='Global SL Hit @ ${{plot("Long SL")}}')

alertcondition(condition=longTPhit, title='Exit Long', message='Long TP Hit @ ${{plot("Long TP")}}')
alertcondition(condition=shortTPhit, title='Exit Short', message='Short TP Hit @ ${{plot("Short TP")}}')

//-------------------- Backtesting (not 100% accurate but works)

lot_size = 0.01

ohl3 = srg

var float start_long_trade = 0.
var float long_trades = 0.
var float start_short_trade = 0.
var float short_trades = 0.
var int wins = 0
var int trade_count = 0

if startLongTrade
    start_long_trade := ohl3
    start_long_trade
if endLongTrade
    trade_count := 1
    ldiff = ohl3 - start_long_trade
    wins := ldiff > 0 ? 1 : 0
    long_trades := ldiff * lot_size
    long_trades
if startShortTrade
    start_short_trade := ohl3
    start_short_trade
if endShortTrade
    trade_count := 1
    sdiff = start_short_trade - ohl3
    wins := sdiff > 0 ? 1 : 0
    short_trades := sdiff * lot_size
    short_trades

cumreturn = ta.cum(long_trades) + ta.cum(short_trades)  //-- cumulative return 
totaltrades = ta.cum(trade_count)
totalwins = ta.cum(wins)
totallosses = totaltrades - totalwins == 0 ? 1 : totaltrades - totalwins

//-------------------- Information

var label lbl = na

tbase = (time - time[1]) / 1000
tcurr = (timenow - time_close[1]) / 1000

buyz = 'BUY'
sellz = 'SELL'


info = 'CR=' + str.tostring(cumreturn, '#.#') + '\nTrades: ' + str.tostring(cc, '#') + '\nWin/Loss: ' + str.tostring(totalwins / totallosses, '#.##') + '\nWinrate: ' + str.tostring(totalwins / totaltrades, '#.#%') + '\nBar Time: ' + str.tostring(tcurr / tbase, '#.#%') + '\nActual volatility: ' + str.tostring(ta.atr(1), '#.##') + '\nCurrent signal: ' + (signal == 1 ? sellz : buyz) + '\nCurrent price: ' + str.tostring(close) 

if input(true, 'Show Information?') and barstate.islast
    lbl := label.new(bar_index, close, info, xloc.bar_index, yloc.price, color.new(color.blue, 100), label.style_label_left, color.black, size.small, text.align_left)
    label.delete(lbl[1])


