lionshare

BACKTEST SCRIPT 0.999 ALPHA

TRADINGVIEW BACKTEST SCRIPT by Lionshare (c) 2015
THS IS A REAL ALTERNATIVE FOR LONG AWAITED TV NATIVE BACKTEST ENGINE.
READY FOR USE JUST RIGHT NOW.

For user provided trading strategy, executes the trades on pricedata history and continues to make it over live datafeed.
Calculates and (plots on premise) the next performance statistics:
  • profit - i.e. gross profit/loss.
  • profit_max - maximum value of gross profit/loss.
  • profit_per_trade - each trade's profit/loss.
  • profit_per_stop_trade - profit/loss per "stop order" trade.
  • profit_stop - gross profit/loss caused by stop orders.
  • profit_stop_p - percentage of "stop orders" profit/loss in gross profit/loss.
  • security_if_bought_back - size of security portfolio if bought back.
  • trades_count_conseq_profit - consecutive gain from profitable series.
  • trades_count_conseq_profit_max - maxmimum gain from consecutive profitable series achieved.
  • trades_count_conseq_loss - same as for profit, but for loss.
  • trades_count_conseq_loss_max - same as for profit, but for loss.
  • trades_count_conseq_won - number of trades, that were won consecutively.
  • trades_count_conseq_won_max - maximum number of trades, won consecutively.
  • trades_count_conseq_lost - same as for won trades, but for lost.
  • trades_count_conseq_lost_max - same as for won trades, but for lost.
  • drawdown - difference between local equity highs and lows.
  • profit_factor - profit-t-loss ratio.
  • profit_factor_r - profit(without biggest winning trade)-to-loss ratio.
  • recovery_factor - equity-to-drawdown ratio.
  • expected_value - median gain value of all wins and loss.
  • zscore - shows how much your seriality of consecutive wins/loss diverges from the one of normal distributed process. valued in sigmas. zscore of +3 or -3 sigmas means nonrandom realitonship of wins series-to-loss series.
  • confidence_limit - the limit of confidence in zscore result. values under 0.95 are considered inconclusive.
  • sharpe - sharpe ratio - shows the level of strategy stability. basically it is how the profit/loss is deviated around the expected value.
  • sortino - the same as sharpe, but is calculated over the negative gains.
  • k - Kelly criterion value, means the percentage of your portfolio, you can trade the scripted strategy for optimal risk management.
  • k_margin - Kelly criterion recalculated to be meant as optimal margin value.

DISCLAIMER :

The SCRIPT is in ALPHA stage. So there could be some hidden bugs.
Though the basic functionality seems to work fine.
Initial documentation is not detailed. There could be english grammar mistakes also.

NOW Working hard on optimizing the script. Seems, some heavier strategies (especially those using the multiple SECURITY functions) call TV processing power limitation errors.

Docs are here:
https://docs.google.com/document/d/1lwZz...
Open-source Skript

Ganz im Sinne von TradingView hat der Autor dieses Skripts es als Open-Source veröffentlicht, damit Trader es verstehen und überprüfen können. Ein Hoch auf den Autor! Sie können es kostenlos verwenden, aber die Wiederverwendung dieses Codes in einer Publikation unterliegt den Hausregeln. Sie können das Skript den Favoriten hinzufügen, um es auf dem Chart zu verwenden.

Möchten Sie dieses Skript auf einem Chart verwenden?
study(title = "BACKTEST SCRIPT 0.999 ALPHA", shorttitle="BACKTEST SCRIPT 0.999 ALPHA", overlay=true)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// STRATEGY : GENERATING TRADING SIGNALS ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PUT YOUR STRATEGY CODE BELOW! GENERATE (AND/OR PLOT) SOME SIGNALS WHICH YOU WILL USE IN YOUR TRADING RULES RIGHT AFTER THAT
// below is just a basic 'moving average crossover' example
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// two "close" price averages - fast and slow - we'll monitor them for crossovers.
ema_fast = ema(close, 8)
ema_slow = ema(close, 34)

// Below are the series (cross_up/cross_down). we'll use them later for initiating the trades.
cross_up = cross(ema_fast, ema_slow) and ema_fast > ema_slow // <--- this expression does basically give a late one, but confirmed LONG setup. if TRUE - script should BUY.
cross_down = cross(ema_fast, ema_slow) and ema_fast < ema_slow // <--- this expression does basically give a late one, but confirmed SHORT setupl. if TRUE - script should SELL.

// Some plots here. they are not used during backtest, so you can simply delete the whole block, in case you don't need it.
plot(ema_fast)
plot(ema_slow)
plot_positive_high = plot(ema_fast > ema_slow ? ema_fast : na, style = linebr, color = green, linewidth = 1)
plot_positive_low = plot(ema_fast > ema_slow ? ema_slow : na, style = linebr, color = green, linewidth = 1)
plot_negative_high = plot(ema_fast < ema_slow ? ema_slow: na, style = linebr, color = red, linewidth = 1)
plot_negative_low = plot(ema_fast < ema_slow ? ema_fast : na, style = linebr, color = red, linewidth = 1)
fill(plot_positive_low, plot_positive_high, green)
fill(plot_negative_low, plot_negative_high, red)

// Now we need to make our cross_ups & cross_downs to initiate the trades.


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// STRATEGY : ORDER RULES BASED ON STRATEGY TRADING SIGNALS ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CAREFULLY HERE!!! ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MAINTAIN THE VARIABLES NAMES!!! /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// JUST PUT YOUR RULES TO APPROPRIATE FIELDS!!! // YOU'LL BE ABLE TO ACTIVATE THE DEDICATED RULES THROUGH THE DROPDOWN MENU ON THE "INPUT" TAB OF THE "FORMAT" DIALOG.//////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// ORDER TYPE "MARKET AT OPEN" (CODE 1001) - IF THE RULE IS TRUE, THE SCRIPT WILL TRY TO MAKE A TRADE @ BAR'S OPEN PRICE (IN CASE THE RULE IS ACTIVATED IN THE APPROPRIATE DROPDOWN LIST OF THE INPUT TAB).
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// market_at_open order rule 1
sell_market_at_open_rule_1 = cross_down  // <--- put your sell "market at open" rules here! or leave "na" if the rule is void. // <--- this rule (when TRUE) will generate a SELL advise for the TRADE MANAGER.
buy_market_at_open_rule_1 = cross_up  // <--- put your sell "market at open" rules here! or leave "na" if the rule is void. // <--- this rule (when TRUE) will generate a BUY advise for the TRADE MANAGER.

// market_at_open order rule 2
sell_market_at_open_rule_2 = na // <--- put your sell "market at open" rules here! or leave "na" if the rule is void.
buy_market_at_open_rule_2 = na // <--- put your buy "market at open" rules here! or leave "na" if the rule is void.

// market_at_open order rule 3
sell_market_at_open_rule_3 = na // <--- put your sell "market at open" rules here! or leave "na" if the rule is void.
buy_market_at_open_rule_3 = na // <--- put your buy "market at open" rules here! or leave "na" if the rule is void.

// market_at_open order rule 4
sell_market_at_open_rule_4 = na // <--- put your sell "market at open" rules here! or leave "na" if the rule is void.
buy_market_at_open_rule_4 = na // <--- put your buy "market at open" rules here! or leave "na" if the rule is void.

// market_at_open order rule 5
sell_market_at_open_rule_5 = na // <--- put your sell "market at open" rules here! or leave "na" if the rule is void.
buy_market_at_open_rule_5 = na // <--- put your buy "market at open" rules here! or leave "na" if the rule is void.

// filter
// !!! optional feature !!! IF TRUE - THE TRADE WILL BE FILTERED OUT, EVEN IF ALL THE ACTIVATED RULES ARE TRUE. FILTER ALSO CAN BE ACTIVATED/DEACTIVATED WITH THE HELP OF THE CHECKBOX ON THE INPUT TAB 
sell_market_at_open_filter = na // <--- put your filter code for sell trades here!
buy_market_at_open_filter = na // <--- put your filter code for buy trades here!

// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// ORDER TYPE : "STOP" (CODE 2001) - IF 'USE STOP ORDERS' CHECKBOX IS ACTIVATED - THE STOP ORDER WILL BE PLACED FOR EACH TRADE. YOU CAN ADJUST THE STOPLOSS SIZE (0.002 = 2%INITIALLY).
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// filter
// !!! optional feature !!! IF TRUE - THE ORDER WILL BE DEACTIVATED
sell_stop_filter = na // <--- put your filter code for sell trades here!
buy_stop_filter = na // <--- put your filter code for buy trades here!

// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// RULES : ORDER TYPE "LIMIT" (CODE 3001)
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// limit order rule 1
sell_limit_rule_1 = na // <--- put your sell "limit" rules here! or leave "na" if the rule is void.
buy_limit_rule_1 = na // <--- put your buy "limit" rules here! or leave "na" if the rule is void.

// limit order rule 2
sell_limit_rule_2 = na // <--- put your sell "limit" rules here! or leave "na" if the rule is void.
buy_limit_rule_2 = na // <--- put your buy "limit" rules here! or leave "na" if the rule is void.

// limit order rule 3
sell_limit_rule_3 = na // <--- put your sell "limit" rules here! or leave "na" if the rule is void.
buy_limit_rule_3 = na // <--- put your buy "limit" rules here! or leave "na" if the rule is void.

// limit order rule 4
sell_limit_rule_4 = na // <--- put your sell "limit" rules here! or leave "na" if the rule is void.
buy_limit_rule_4 = na // <--- put your buy "limit" rules here! or leave "na" if the rule is void.

// limit order rule 5
sell_limit_rule_5 = na // <--- put your sell "limit" rules here! or leave "na" if the rule is void.
buy_limit_rule_5 = na // <--- put your buy "limit" rules here! or leave "na" if the rule is void.

// filter
// !!! optional feature !!! IF TRUE - THE ORDER WILL BE DEACTIVATED
sell_limit_filter = na // <--- put your filter code for sell trades here!
buy_limit_filter = na // <--- put your filter code for buy trades here!

// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// ORDER TYPE : "MARKET AT CLOSE" (CODE 6001)
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// market_at_close order rule 1
sell_market_at_close_rule_1 = na // <--- put your sell "market at close" rules here! or leave "na" if the rule is void.
buy_market_at_close_rule_1 = na // <--- put your buy "market at close" rules here! or leave "na" if the rule is void.

// market_at_close order rule 2
sell_market_at_close_rule_2 = na // <--- put your sell "market at close" rules here! or leave "na" if the rule is void.
buy_market_at_close_rule_2 = na // <--- put your buy "market at close" rules here! or leave "na" if the rule is void.

// market_at_close order rule 3
sell_market_at_close_rule_3 = na // <--- put your sell "market at close" rules here! or leave "na" if the rule is void.
buy_market_at_close_rule_3 = na // <--- put your buy "market at close" rules here! or leave "na" if the rule is void.

// market_at_close order rule 4
sell_market_at_close_rule_4 = na // <--- put your sell "market at close" rules here! or leave "na" if the rule is void.
buy_market_at_close_rule_4 = na // <--- put your buy "market at close" rules here! or leave "na" if the rule is void.

// market_at_close order rule 5
sell_market_at_close_rule_5 = na // <--- put your sell "market at close" rules here! or leave "na" if the rule is void.
buy_market_at_close_rule_5 = na // <--- put your buy "market at close" rules here! or leave "na" if the rule is void.

// filter
// !!! optional feature !!! IF TRUE - THE ORDER WILL BE DEACTIVATED
sell_market_at_close_filter = na // <--- put your filter code for sell trades here!
buy_market_at_close_filter = na // <--- put your filter code for buy trades here!

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// xxx STOP HERE!!! xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BACKTESTING : DO NOT SCRIPT TERRITORY!!! ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// ORDER TRIGGERS FOR USING WITH THE DROPDOWN MENU

// skip rule - just skips the rule - needed for deactivatibg the slot in the triggers listbox
// rule dispatcher
sell_rule(type, num)=>
    type == 1001 ?
        (num == 0 ? na :
            num == 1 ? sell_market_at_open_rule_1 :
                num == 2 ? sell_market_at_open_rule_2 :
                    num == 3 ? sell_market_at_open_rule_3 :
                        num == 4 ? sell_market_at_open_rule_4 :
                            num == 5 ? sell_market_at_open_rule_5 : na) :
                                type == 3001 ?
                                    (num == 0 ? na :
                                        num == 1 ? sell_limit_rule_1 :
                                            num == 2 ? sell_limit_rule_2 :
                                                num == 3 ? sell_limit_rule_3 :
                                                    num == 4 ? sell_limit_rule_4 :
                                                        num == 5 ? sell_limit_rule_5 : na) :                                                            
                                                            type == 6001 ?
                                                                (num == 0 ? na :
                                                                    num == 1 ? sell_market_at_close_rule_1 :
                                                                        num == 2 ? sell_market_at_close_rule_2 :
                                                                            num == 3 ? sell_market_at_close_rule_3 :
                                                                                num == 4 ? sell_market_at_close_rule_4 :
                                                                                    num == 5 ? sell_market_at_close_rule_5 : na) : na
buy_rule(type, num)=>
    type == 1001 ?
        (num == 0 ? na :
            num == 1 ? buy_market_at_open_rule_1 :
                num == 2 ? buy_market_at_open_rule_2 :
                    num == 3 ? buy_market_at_open_rule_3 :
                        num == 4 ? buy_market_at_open_rule_4 :
                            num == 5 ? buy_market_at_open_rule_5 : na) :
                                type == 3001 ?
                                    (num == 0 ? na :
                                        num == 1 ? buy_limit_rule_1 :
                                            num == 2 ? buy_limit_rule_2 :
                                                num == 3 ? buy_limit_rule_3 :
                                                    num == 4 ? buy_limit_rule_4 :
                                                        num == 5 ? buy_limit_rule_5 : na) :  
                                                            type == 6001 ?
                                                                (num == 0 ? na :
                                                                    num == 1 ? buy_market_at_close_rule_1 :
                                                                        num == 2 ? buy_market_at_close_rule_2 :
                                                                            num == 3 ? buy_market_at_close_rule_3 :
                                                                                num == 4 ? buy_market_at_close_rule_4 :
                                                                                    num == 5 ? buy_market_at_close_rule_5 : na) : na

// ------------------------------------------------
// TRIGGERS : ORDER TYPE "MARKET AT OPEN" (CODE 1001)
// ------------------------------------------------

// market_at_open order trigger 1
trigger_market_at_open_1_n = input(title = "Trigger : 'Market at Open' Order rule #:", type = integer, step = 1, defval = 1, minval = 0, maxval = 5)
sell_market_at_open_trigger_1 = na(sell_rule(1001, trigger_market_at_open_1_n)) ? true : sell_rule(1001, trigger_market_at_open_1_n)
buy_market_at_open_trigger_1 = na(buy_rule(1001, trigger_market_at_open_1_n)) ? true : buy_rule(1001, trigger_market_at_open_1_n)

// market_at_open order trigger 2
trigger_market_at_open_2_n = input(title = "Trigger : 'Market at Open' Order rule #:", type = integer, step = 1, defval = 0, minval = 0, maxval = 5)
sell_market_at_open_trigger_2 = na(sell_rule(1001, trigger_market_at_open_2_n)) ? true : sell_rule(1001, trigger_market_at_open_2_n)
buy_market_at_open_trigger_2 = na(buy_rule(1001, trigger_market_at_open_2_n)) ? true : buy_rule(1001, trigger_market_at_open_2_n)

// market_at_open order trigger 3
trigger_market_at_open_3_n = input(title = "Trigger : 'Market at Open' Order rule #:", type = integer, step = 1, defval = 0, minval = 0, maxval = 5)
sell_market_at_open_trigger_3 = na(sell_rule(1001, trigger_market_at_open_3_n)) ? true : sell_rule(1001, trigger_market_at_open_3_n)
buy_market_at_open_trigger_3 = na(buy_rule(1001, trigger_market_at_open_3_n)) ? true : buy_rule(1001, trigger_market_at_open_3_n)

// set filter on/off
use_market_at_open_filter = input(true, type = bool)

// market_at_open order trigger_mux
sell_market_at_open_trigger_mux = na(sell_rule(1001, trigger_market_at_open_1_n)) and
                                    na(sell_rule(1001, trigger_market_at_open_2_n)) and
                                        na(sell_rule(1001, trigger_market_at_open_3_n)) ? false : 
                                            sell_market_at_open_trigger_1*sell_market_at_open_trigger_2*sell_market_at_open_trigger_3
buy_market_at_open_trigger_mux = na(buy_rule(1001, trigger_market_at_open_1_n)) and
                                    na(buy_rule(1001, trigger_market_at_open_2_n)) and
                                        na(buy_rule(1001, trigger_market_at_open_3_n)) ? false : 
                                            buy_market_at_open_trigger_1*buy_market_at_open_trigger_2*buy_market_at_open_trigger_3

// ------------------------------------------------
// TRIGGERS : ORDER TYPE "LIMIT" (CODE 3001)
// ------------------------------------------------

// limit order trigger 1
trigger_limit_1_n = input(title = "Trigger : 'Limit Order' rule #:", type = integer, step = 1, defval = 0, minval = 0, maxval = 5)
sell_limit_trigger_1 = na(sell_rule(3001, trigger_limit_1_n)) ? true : sell_rule(3001, trigger_limit_1_n)
buy_limit_trigger_1 = na(buy_rule(3001, trigger_limit_1_n)) ? true : buy_rule(3001, trigger_limit_1_n)

// set filter on/off
use_limit_filter = input(true, type = bool)

// limit order trigger_mux
sell_limit_trigger_mux = na(sell_rule(3001, trigger_limit_1_n)) ? false : sell_limit_trigger_1
buy_limit_trigger_mux = na(buy_rule(3001, trigger_limit_1_n)) ? false : buy_limit_trigger_1

// ------------------------------------------------
// TRIGGERS : ORDER TYPE "STOP LIMIT" (CODE 4001)- RESERVED!
// ------------------------------------------------

// ------------------------------------------------
// TRIGGERS : ORDER TYPE "MARKET AT LASTPRICE" (CODE 5001) - RESERVED!
// ------------------------------------------------

// ------------------------------------------------
// TRIGGERS : ORDER TYPE "MARKET AT CLOSE" (CODE 6001)
// ------------------------------------------------

// market_at_close order trigger 1
trigger_market_at_close_1_n = input(title = "Trigger : 'Market at Close' Order rule #:", type = integer, step = 1, defval = 0, minval = 0, maxval = 5)
sell_market_at_close_trigger_1 = na(sell_rule(6001, trigger_market_at_close_1_n)) ? true : sell_rule(6001, trigger_market_at_close_1_n)
buy_market_at_close_trigger_1 = na(buy_rule(6001, trigger_market_at_close_1_n)) ? true : buy_rule(6001, trigger_market_at_close_1_n)

// market_at_close order trigger 2
trigger_market_at_close_2_n = input(title = "Trigger : 'Market at Close' Order rule #:", type = integer, step = 1, defval = 0, minval = 0, maxval = 5)
sell_market_at_close_trigger_2 = na(sell_rule(6001, trigger_market_at_close_2_n)) ? true : sell_rule(6001, trigger_market_at_close_2_n)
buy_market_at_close_trigger_2 = na(buy_rule(6001, trigger_market_at_close_2_n)) ? true : buy_rule(6001, trigger_market_at_close_2_n)

// market_at_close order trigger 3
trigger_market_at_close_3_n = input(title = "Trigger : 'Market at Close' Order rule #:", type = integer, step = 1, defval = 0, minval = 0, maxval = 5)
sell_market_at_close_trigger_3 = na(sell_rule(6001, trigger_market_at_close_3_n)) ? true : sell_rule(6001, trigger_market_at_close_3_n)
buy_market_at_close_trigger_3 = na(buy_rule(6001, trigger_market_at_close_3_n)) ? true : buy_rule(6001, trigger_market_at_close_3_n)

// set filter on/off
use_market_at_close_filter = input(true, type = bool)

// market_at_close order trigger_mux
sell_market_at_close_trigger_mux = na(sell_rule(6001, trigger_market_at_close_1_n)) and
                                    na(sell_rule(6001, trigger_market_at_close_2_n)) and
                                        na(sell_rule(6001, trigger_market_at_close_3_n)) ? false : 
                                            sell_market_at_close_trigger_1*sell_market_at_close_trigger_2*sell_market_at_close_trigger_3//*sell_market_at_close_trigger_4*sell_market_at_close_trigger_5
buy_market_at_close_trigger_mux = na(buy_rule(6001, trigger_market_at_close_1_n)) and
                                    na(buy_rule(6001, trigger_market_at_close_2_n)) and
                                        na(buy_rule(6001, trigger_market_at_close_3_n)) ? false : 
                                            buy_market_at_close_trigger_1*buy_market_at_close_trigger_2*buy_market_at_close_trigger_3//*buy_market_at_close_trigger_4*buy_market_at_close_trigger_5
                                            

///////////////////////////////////////////////////
// SET UP WHICH ORDER TYPES TO USE
///////////////////////////////////////////////////

use_stop_orders = input(true, type = bool)
use_stop_filter = input(true, type = bool)
use_limit_orders = true//input(true, type = bool)
use_market_at_open_orders = true//input(true, type = bool)
use_market_at_lastprice_orders = false//input(true, type = bool)
use_market_at_close_orders = true//input(true, type = bool)

use_trailing_stop = false
use_take_profit = false

make_buy_first = input(true, type= bool)

///////////////////////////////////////////////////
// FEE-SLIPPAGE-STOP LOSS-TRAILING STOP-TAKE PROFIT PARAMETERS
///////////////////////////////////////////////////

fee = input(0.002, minval = 0, step = 0.001)
// slippage = input(0.002, minval = 0, step = 0.001)
slippage_market_at_open = input(0.002, minval = 0, step = 0.001)
slippage_stop = input(0.003, minval = 0, step = 0.001)
slippage_limit = 0
slippage_stop_limit = 0
slippage_market_at_lastprice = (high - avg(high, low))/high
slippage_market_at_close = input(0.001, minval = 0, step = 0.001)

stop_loss = input(0.02, step = 0.001, minval = 0.000)
trailing_stop = 0
take_profit = 0.002
fail_coeff = 0//input(0.0, step=0.01)

///////////////////////////////////////////////////
// SET BACKTEST START DATE
///////////////////////////////////////////////////

stats_start_year = input(title = "Backtest - start date (year): ", defval = 2015, minval = 0)
stats_start_month = input(title = "Backtest - start date (month): ", defval = 1, minval = 0, maxval = 12)
stats_start_day = input(title = "Backtest - start date (day): ", defval = 1, maxval = 0, maxval = 31)
start_n = not na(valuewhen(year >= stats_start_year and month >= stats_start_month and dayofmonth >= stats_start_day and hour >= 0 and minute >= 0 and second >= 0, n, 0)) ? (na(start_n[1]) ? n : start_n[1]) : na

///////////////////////////////////////////////////
// SET UP ORDER PRICES
///////////////////////////////////////////////////

ask_price_max = high //max(security(tickerid, "1", high, true), high)
ask_price_min = low //min(security(tickerid, "1", high, true), high)

bid_price_max = high //max(security(tickerid, "1", low, true), low)
bid_price_min = low //min(security(tickerid, "1", low, true), low)

ask_price_last = avg(ask_price_min, ask_price_max)
bid_price_last = avg(bid_price_min, bid_price_max)

///////////////////////////////////////////////////
// BACKTESTING : PORTFOLIO STATE
///////////////////////////////////////////////////

// initial
portfolio_usd = 0
portfolio_btc = 1

// is_bought, is_sold
is_first_trade = trades_count[1] == 0
is_bought = is_first_trade ? (make_buy_first ? false : true) : (is_sell_trade_completed[1] ? false : (is_buy_trade_completed[1] ? true : is_bought[1]))
is_sold = is_first_trade ? (make_buy_first ? true : true) : (is_buy_trade_completed[1] ? false : (is_sell_trade_completed[1] ? true : is_sold[1]))

_update_portfolio_state(bar_open_state, change_state_marker) =>
    result = (na(change_state_marker) or change_state_marker) ? not bar_open_state : bar_open_state
    result

///////////////////////////////////////////////////
// BACKTESTING : EXECUTION
///////////////////////////////////////////////////

// functions
_is_in_range(_price, min, max) => 
    result = (_price>=min) and (_price<=max) ? true : false
    result

// ------------------------------------------------
// EXECUTION : ORDER TYPE "MARKET AT OPEN" (CODE 1001)
// ------------------------------------------------

// // market_at_open orders - set
// определение возможной цены для market_at_open order
price_one_can_market_at_open_sell = open
price_one_can_market_at_open_buy = open

// цена входа - по ордеру (= эффективная цена входа пониженная на размер комиссии и проскальзывания)
sell_market_at_open_price = price_one_can_market_at_open_sell
buy_market_at_open_price = price_one_can_market_at_open_buy

// цена входа - эффективная (с учетом риска)
sell_market_at_open_price_effective = sell_market_at_open_price*(1-slippage_market_at_open)*(1-fee)
buy_market_at_open_price_effective = buy_market_at_open_price*(1+slippage_market_at_open)*(1+fee)

// market_at_open orders - execute
is_sell_market_at_open_advised = sell_market_at_open_trigger_mux
is_buy_market_at_open_advised = buy_market_at_open_trigger_mux

can_sell_market_at_open = _update_portfolio_state(is_bought, false)
can_buy_market_at_open = _update_portfolio_state(is_sold, false)

sell_market_at_open_signal = is_sell_market_at_open_advised and can_sell_market_at_open
buy_market_at_open_signal = is_buy_market_at_open_advised and can_buy_market_at_open

is_sell_market_at_open_event = use_market_at_open_orders ? sell_market_at_open_signal : false
is_buy_market_at_open_event = use_market_at_open_orders ?  buy_market_at_open_signal : false

is_sell_market_at_open_filter = use_market_at_open_filter ? (na(sell_market_at_open_filter) ? false : sell_market_at_open_filter) : false
is_buy_market_at_open_filter = use_market_at_open_filter ? (na(buy_market_at_open_filter) ? false : buy_market_at_open_filter) : false

is_sell_market_at_open_trade_completed = is_sell_market_at_open_event and not is_sell_market_at_open_filter
is_buy_market_at_open_trade_completed = is_buy_market_at_open_event and not is_buy_market_at_open_filter

sell_market_at_open_trade_price = use_market_at_open_orders ? (is_sell_market_at_open_trade_completed ? sell_market_at_open_price_effective : na) : na
buy_market_at_open_trade_price = use_market_at_open_orders ? (is_buy_market_at_open_trade_completed ? buy_market_at_open_price_effective : na) : na

// ------------------------------------------------
// EXECUTION : ORDER TYPE "STOP" (CODE 2001)
// ------------------------------------------------

//// stop orders - set
// определение цены для stop limit orderрешено
price_one_can_stop_sell = is_buy_market_at_open_trade_completed ? buy_market_at_open_trade_price : is_buy_trade_completed[1] ? buy_trade_price[1] : na
price_one_can_stop_buy = is_sell_market_at_open_trade_completed ? sell_market_at_open_trade_price : is_sell_trade_completed[1] ? sell_trade_price[1] : na

// цена входа - эффективная (с учетом риска)
sell_stop_price_effective = is_buy_market_at_open_trade_completed ? price_one_can_stop_sell*(1-stop_loss) : (is_buy_trade_completed[1] ? buy_trade_price[1]*(1-stop_loss) : (not is_sell_trade_completed[1] ? sell_stop_price_effective[1] : na))
buy_stop_price_effective = is_sell_market_at_open_trade_completed ? price_one_can_stop_buy*(1+stop_loss) : (is_sell_trade_completed[1] ? sell_trade_price[1]*(1+stop_loss) : (not is_buy_trade_completed[1] ? buy_stop_price_effective[1] : na))

// цена входа - по ордеру (= эффективная цена входа пониженная на размер комиссии и проскальзывания)
sell_stop_price = sell_stop_price_effective/((1-slippage_stop)*(1-fee))
buy_stop_price = buy_stop_price_effective/((1+slippage_stop)*(1+fee))

// stop limit orders - execute
//!!! разобраться
is_sell_stop_advised = _is_in_range(sell_stop_price, bid_price_min, ask_price_max)
is_buy_stop_advised = _is_in_range(buy_stop_price, bid_price_min, ask_price_max)

can_sell_stop = _update_portfolio_state(can_sell_market_at_open, is_sell_market_at_open_trade_completed)
can_buy_stop = _update_portfolio_state(can_buy_market_at_open, is_buy_market_at_open_trade_completed)

sell_stop_signal = is_sell_stop_advised and can_sell_stop
buy_stop_signal = is_buy_stop_advised and can_buy_stop

is_sell_stop_event = use_stop_orders ? sell_stop_signal : false
is_buy_stop_event = use_stop_orders ?  buy_stop_signal : false

is_sell_stop_filter = use_stop_filter ? (na(sell_stop_filter) ? false : sell_stop_filter) : false
is_buy_stop_filter = use_stop_filter ? (na(buy_stop_filter) ? false : buy_stop_filter) : false

//!!! разобраться
is_sell_stop_trade_completed = is_sell_stop_event and not is_sell_stop_filter
is_buy_stop_trade_completed = is_buy_stop_event and not is_buy_stop_filter

sell_stop_trade_price = use_stop_orders ? (is_sell_stop_trade_completed ? sell_stop_price_effective : na) : na
buy_stop_trade_price = use_stop_orders ? (is_buy_stop_trade_completed ? buy_stop_price_effective : na) : na

// ------------------------------------------------
// EXECUTION : ORDER TYPE "LIMIT" (CODE 3001)
// ------------------------------------------------

// определение возможной цены для limit order
price_one_can_limit_sell = sell_limit_trigger_mux
price_one_can_limit_buy = buy_limit_trigger_mux

// цена входа - по ордеру
// !!! эффективная цена входа расчитывается на базе цены входа по ордеру, выданному стратегией

sell_limit_price = price_one_can_limit_sell
buy_limit_price = price_one_can_limit_buy

// цена входа - эффективная (с учетом комиссии и проскальзывания)
sell_limit_price_effective = sell_limit_price*(1-slippage_limit)*(1-fee)
buy_limit_price_effective = buy_limit_price*(1+slippage_limit)*(1+fee)

// limit orders - execute
is_sell_limit_advised = _is_in_range(sell_limit_price, bid_price_min, ask_price_max)
is_buy_limit_advised = _is_in_range(buy_limit_price, bid_price_min, ask_price_max)

can_sell_limit = _update_portfolio_state(can_sell_stop, is_sell_stop_trade_completed)
can_buy_limit = _update_portfolio_state(can_buy_stop, is_buy_stop_trade_completed)

sell_limit_signal = is_sell_limit_advised and can_sell_limit
buy_limit_signal = is_buy_limit_advised and can_buy_limit

is_sell_limit_event = use_limit_orders ? sell_limit_signal : false
is_buy_limit_event = use_limit_orders ? buy_limit_signal : false

is_sell_limit_filter = use_limit_filter ? (na(sell_limit_filter) ? false : sell_limit_filter) : false
is_buy_limit_filter = use_limit_filter ? (na(buy_limit_filter) ? false : buy_limit_filter) : false

is_sell_limit_trade_completed = is_sell_limit_event and not is_sell_limit_filter
is_buy_limit_trade_completed = is_buy_limit_event and not is_buy_limit_filter

sell_limit_trade_price = use_limit_orders ? (is_sell_limit_trade_completed ? sell_limit_price_effective : na) : na
buy_limit_trade_price = use_limit_orders ? (is_buy_limit_trade_completed ? buy_limit_price_effective : na) : na

// ------------------------------------------------
// EXECUTION : ORDER TYPE "MARKET AT CLOSE" (CODE 5001)
// ------------------------------------------------

// // market_at_close orders - set
// определение возможной цены для market_at_close order
price_one_can_market_at_close_sell = close
price_one_can_market_at_close_buy = close

// цена входа - по ордеру (= эффективная цена входа пониженная на размер комиссии и проскальзывания)
sell_market_at_close_price = price_one_can_market_at_close_sell
buy_market_at_close_price = price_one_can_market_at_close_buy

// цена входа - эффективная (с учетом риска)
sell_market_at_close_price_effective = sell_market_at_close_price*(1-slippage_market_at_close)*(1-fee)
buy_market_at_close_price_effective = buy_market_at_close_price*(1+slippage_market_at_close)*(1+fee)

// market_at_close orders - execute
is_sell_market_at_close_advised = sell_market_at_close_trigger_mux
is_buy_market_at_close_advised = buy_market_at_close_trigger_mux

can_sell_market_at_close = _update_portfolio_state(can_sell_limit, is_sell_limit_trade_completed)
can_buy_market_at_close = _update_portfolio_state(can_buy_limit, is_buy_limit_trade_completed)

sell_market_at_close_signal = is_sell_market_at_close_advised and can_sell_market_at_close
buy_market_at_close_signal = is_buy_market_at_close_advised and can_buy_market_at_close

is_sell_market_at_close_event = use_market_at_close_orders ? sell_market_at_close_signal : false
is_buy_market_at_close_event = use_market_at_close_orders ?  buy_market_at_close_signal : false

is_sell_market_at_close_filter = use_market_at_close_filter ? (na(sell_market_at_close_filter) ? false : sell_market_at_close_filter) : false
is_buy_market_at_close_filter = use_market_at_close_filter ? (na(buy_market_at_close_filter) ? false : buy_market_at_close_filter) : false

is_sell_market_at_close_trade_completed = is_sell_market_at_close_event and not is_sell_market_at_close_filter
is_buy_market_at_close_trade_completed = is_buy_market_at_close_event and not is_buy_market_at_close_filter

sell_market_at_close_trade_price = use_market_at_close_orders ? (is_sell_market_at_close_trade_completed ? sell_market_at_close_price_effective : na) : na
buy_market_at_close_trade_price = use_market_at_close_orders ? (is_buy_market_at_close_trade_completed ? buy_market_at_close_price_effective : na) : na

// ------------------------------------------------
// EXECUTION : COMBINING ORDERS
// ------------------------------------------------
// limit, stop limit, market_at_open orders combined into one entity
// !!! это виртуальная надстройка аналитического уровня  

is_sell_trade_completed = is_sell_market_at_open_trade_completed ? true : is_sell_stop_trade_completed ? true : is_sell_limit_trade_completed ? true : is_sell_market_at_close_trade_completed ? true : false
is_buy_trade_completed = is_buy_market_at_open_trade_completed ? true : is_buy_stop_trade_completed ? true : is_buy_limit_trade_completed ? true : is_buy_market_at_close_trade_completed ? true : false

// !!! если обе сделки были на одной свече
sell_trade_price = is_sell_market_at_open_trade_completed ? sell_market_at_open_trade_price : is_sell_stop_trade_completed ? sell_stop_trade_price : is_sell_limit_trade_completed ? sell_limit_trade_price : is_sell_market_at_close_trade_completed ? sell_market_at_close_trade_price : na
buy_trade_price = is_buy_market_at_open_trade_completed ? buy_market_at_open_trade_price : is_buy_stop_trade_completed ? buy_stop_trade_price : is_buy_limit_trade_completed ? buy_limit_trade_price : is_buy_market_at_close_trade_completed ? buy_market_at_close_trade_price : na

//
sells_line = (nz(valuewhen(sell_trade_price, n, 0)) > nz(valuewhen(buy_trade_price, n, 0))) ? fixnan(sell_trade_price) : (not na(buy_trade_price) ? fixnan(sell_trade_price) : na)
buys_line = (nz(valuewhen(buy_trade_price, n, 0)) > nz(valuewhen(sell_trade_price, n, 0))) ? fixnan(buy_trade_price) : (not na(sell_trade_price) ? fixnan(buy_trade_price) : na)

///////////////////////////////////////////////////
// BACKTESTING : STATS
///////////////////////////////////////////////////

// Прибыль/убыток со сделки (PnL per trade)
trades_count_profit_per_trade = not na(sell_trade_price) or not na(buy_trade_price) ? ((sells_line - buys_line >= 0) ? sells_line - buys_line : (sells_line - buys_line*(1+fail_coeff) > 0 ? 0 : sells_line - buys_line*(1+fail_coeff))) : na
trades_count_profit_per_stop_trade = not na(sell_stop_trade_price) or not na(buy_stop_trade_price) ? ((sells_line - buys_line >= 0) ? sells_line - buys_line : (sells_line - buys_line*(1+fail_coeff) > 0 ? 0 : sells_line - buys_line*(1+fail_coeff))) : na
trades_count_profit_per_market_at_open_trade = not na(sell_market_at_open_price) or not na(buy_market_at_open_price) ? ((sells_line - buys_line >= 0) ? sells_line - buys_line : (sells_line - buys_line*(1+fail_coeff) > 0 ? 0 : sells_line - buys_line*(1+fail_coeff))) : na

// Количество серий
// маркер серии
trades_series_marker = n >= start_n ? (valuewhen(trades_count_profit_per_trade>=0, n,0)>valuewhen(trades_count_profit_per_trade<0, n,0) ? 1 : -1) : na
// количество серий проигрышных и выигрышных сделок (= кол-ву смен маркера)
trades_count_series_number = n >= start_n ? (nz(trades_series_marker) != nz(trades_series_marker[1]) ? nz(trades_count_series_number[1]) + 1 : nz(trades_count_series_number[1])) : na
// количество выигрышных сделок в серии
trades_count_conseq_won = n >= start_n ? (nz(trades_series_marker) == 1 ? (trades_count_profit_per_trade >= 0 ? nz(trades_count_conseq_won[1]) + 1 : nz(trades_count_conseq_won[1])) : 0) : na
trades_count_conseq_won_max = n >= start_n ? (trades_count_conseq_won > nz(trades_count_conseq_won_max[1]) ? trades_count_conseq_won : nz(trades_count_conseq_won_max[1])) : na
// количество проигрышных сделок в серии
trades_count_conseq_lost = n >= start_n ? (nz(trades_series_marker) == -1 ? (trades_count_profit_per_trade < 0 ? nz(trades_count_conseq_lost[1]) + 1 : nz(trades_count_conseq_lost[1])) : 0) : na
trades_count_conseq_lost_max = n >= start_n ? (trades_count_conseq_lost > nz(trades_count_conseq_lost_max[1]) ? trades_count_conseq_lost : nz(trades_count_conseq_lost_max[1])) : na

// Прибыль/убыток (PnL)
profit = n >= start_n ? nz(profit[1]) + nz(trades_count_profit_per_trade) : na
profit_stop = n >= start_n ? nz(profit_stop[1]) + nz(trades_count_profit_per_stop_trade) : na
profit_stop_p = n >= start_n ? abs(profit_stop)/(profit + abs(profit_stop)) : na
profit_max = n >= start_n ? (nz(profit) > nz(profit_max[1]) ? nz(profit) : nz(profit_max[1])) : na

profit_ma_slow_l = 13//input(13, minval = 1)
profit_ma_fast_l = 5//input(5, minval = 1)
profit_ma_slow = ema(profit, profit_ma_slow_l)
profit_ma_fast = ema(profit, profit_ma_fast_l)

// Количество коротких позиций (Short trades)
trades_count_sells = n >= start_n ? nz(trades_count_sells[1]) + nz(is_sell_trade_completed) : na

// Количество длинных позиций (Long trades)
trades_count_buys = n >= start_n ? nz(trades_count_buys[1]) + nz(is_buy_trade_completed) : na

// Общее количество сделок (Total trades)
trades_count = n >= start_n ? trades_count_sells + trades_count_buys : na

// Прибыль по сделкам с положительным результатом (Gross Profit) 
trades_count_profit = n >= start_n ? (not na(trades_count_profit_per_trade) ? (trades_count_profit_per_trade >= 0 ? nz(trades_count_profit[1]) + trades_count_profit_per_trade : nz(trades_count_profit[1])) : nz(trades_count_profit[1])) : na

// Убыток по сделкам с отрицательным результатом (Gross Loss) 
trades_count_loss = n >= start_n ? (not na(trades_count_profit_per_trade) ? (trades_count_profit_per_trade < 0 ? nz(trades_count_loss[1]) + abs(trades_count_profit_per_trade) : nz(trades_count_loss[1])) : nz(trades_count_loss[1])) : na

// Максимальная прибыль со сделки (Largest Winning Trade)
trades_count_largest_win = n >= start_n ? (nz(trades_count_profit_per_trade) > nz(trades_count_largest_win[1]) ? nz(trades_count_profit_per_trade) : nz(trades_count_largest_win[1])) : na

// Максимальный убыток со сделки (Largest Loosing Trade)
trades_count_largest_lost = n >= start_n ? (nz(trades_count_profit_per_trade) < nz(trades_count_largest_lost[1]) ? abs(nz(trades_count_profit_per_trade)) : nz(trades_count_largest_lost[1])) : na

// Непрерывная прибыль (Consecutive Profit)
trades_count_conseq_profit = n >= start_n ? (nz(trades_series_marker) == 1 ? (trades_count_profit_per_trade >= 0 ? nz(trades_count_conseq_profit[1]) + nz(trades_count_profit_per_trade) : nz(trades_count_conseq_profit[1])) : 0) : na
// Максимальная непрерывная прибыль (Maximum Consecutive Profit)
trades_count_conseq_profit_max = n >= start_n ? (trades_count_conseq_profit > nz(trades_count_conseq_profit_max[1]) ? trades_count_conseq_profit : nz(trades_count_conseq_profit_max[1])) : na

// Непрерывный убыток (Consecutive Loss)
trades_count_conseq_loss =  n >= start_n ? (nz(trades_series_marker) == -1 ? (trades_count_profit_per_trade < 0 ? nz(trades_count_conseq_loss[1]) + abs(nz(trades_count_profit_per_trade)) : nz(trades_count_conseq_loss[1])) : 0) : na
// Максимальный непрерывный убыток (Maximum Consecutive Loss)
trades_count_conseq_loss_max =  n >= start_n ? (trades_count_conseq_loss > nz(trades_count_conseq_loss_max[1]) ? trades_count_conseq_loss : nz(trades_count_conseq_loss_max[1])) : na

// Количество прибыльных сделок (Winning Trades)
trades_count_won = n >= start_n ? (not na(trades_count_profit_per_trade) ? (trades_count_profit_per_trade >= 0 ? nz(trades_count_won[1]) + 1 : nz(trades_count_won[1])) : nz(trades_count_won[1])) : na

// Количество убыточных сделок (Losing trades)
trades_count_lost = n >= start_n ? (not na(trades_count_profit_per_trade) ? (trades_count_profit_per_trade < 0 ? nz(trades_count_lost[1]) + 1 : nz(trades_count_lost[1])) : nz(trades_count_lost[1])) : na

// Средняя прибыль со сделки (Average Profit)
average_profit = n >= start_n ? trades_count_profit/trades_count_won : na

// Средний убыток со сделки (Average Loss)
average_loss = n >= start_n ? trades_count_loss/trades_count_lost : na

// Просадка (Maximum Drawdown)
drawdown = trades_count_conseq_loss
drawdown_max = trades_count_conseq_loss_max

// Профит-фактор (Profit Factor)
profit_factor = n >= start_n ? trades_count_profit/trades_count_loss : na
//.. средний профит-фактор (Profit Factor average)
profit_factor_avg = n >= start_n ? cum(profit_factor)/(n-start_n) : na
//.. достоверный профит-фактор
profit_factor_r = n >= start_n ? (trades_count_profit-trades_count_largest_win)/trades_count_loss : na

// Процентное соотношение массы прибыльных/убыточных сделок к общей прибыли
trades_count_profit_p = n >= start_n ? trades_count_profit/profit : na
trades_count_loss_p = n >= start_n ? trades_count_loss/profit : na

// Процентное соотношение числа прибыльных/убыточных сделок к их общему числу
trades_count_won_p = n >= start_n ? trades_count_won/trades_count : na
trades_count_lost_p = n >= start_n ? trades_count_lost/trades_count : na

// Фактор восстановления (Recovery Factor)
recovery_factor = profit/drawdown_max

// Количество фин. инструмента, при обратном выкупе на всю сумму прибыли
security_if_bought_back = n >= start_n ? (profit >= 0 ? profit/close*(1-slippage_market_at_open)*(1-fee) : 0) : na

// Математическое ожидание (Expected Value)
expected_value = profit/trades_count
expected_value_ma_slow_l = 13//input(13, minval = 1)
expected_value_ma_fast_l = 5//input(5, minval = 1)
expected_value_ma_slow = ema(expected_value, expected_value_ma_slow_l)
expected_value_ma_fast = ema(expected_value, expected_value_ma_fast_l)
// alt // expected_value_2 = trades_count_won_p*average_profit - trades_count_lost_p*average_loss

// Стандартное отклонение (Standard Deviation)
diff = n >= start_n ? (na(trades_count_profit_per_trade) ? na : trades_count_profit_per_trade - expected_value) : na
diff_pow = n >= start_n ? pow(nz(diff),2) : na
diff_sum = n >= start_n ? nz(diff_sum[1]) + nz(diff_pow) : na
disp = n >= start_n ? diff_sum/(trades_count-1) : na
std = sqrt(disp)

diff_negative = n >= start_n ? (na(trades_count_profit_per_trade) ? na : (trades_count_profit_per_trade < 0 ? trades_count_profit_per_trade - expected_value : diff_negative[1])) : na
diff_negative_pow = n >= start_n ? pow(nz(diff_negative),2) : na
diff_negative_sum = n >= start_n ? nz(diff_negative_sum[1]) + nz(diff_negative_pow) : na
disp_negative = n >= start_n ? diff_negative_sum/(trades_count_loss-1) : na
std_negative = sqrt(disp_negative)

// Коэффициент Шарпа (Sharpe Ratio)

// ... Коэффициент Шарпа – показатель эффективности торговой стратегии. Вычисляется как отношение средней премии за риск к среднему отклонению прибыли.
sharpe = expected_value/std

// Коэффициент Сортино (Sortino Ratio)
// ... Коэффициент Сортино – показатель эффективности торговой стратегии, позволяющий оценить доходность и риск торговой стратегии. Математически он рассчитывается аналогично коэффициенту Шарпа, однако вместо волатильности используется так называемая «волатильность вниз». В этом случае волатильность рассчитывается по доходностям ниже минимально допустимого уровня прибыли торговой стратегии.
// ... Рассчитывается по формуле:
// ... Sortino Ratio = R – T / σd, где
// ... R – средняя доходность стратегии,
// ... T – минимально допустимый уровень доходности стратегии,
// ... σd – отклонение прибыли стратегии в отрицательную сторону.
// ... Этот коэффициент очень схож с коэффициентом Шарпа за исключением того, что при оценке риска берутся только отрицательные значения доходности.
sortino = expected_value/std_negative

// Z-счет (Z-score) // ... Z-счет – показатель эффективности торговой стратегии, характеризует склонность стратегии к чередованию прибыльных и убыточных сделок.
zscore(trades_n, trades_won_n, trades_lost_n, trades_series_n) =>
    x = 2*trades_won_n*trades_lost_n
    tct = trades_n
    tcs = trades_series_n
    zscore = (tct*(tcs - 0.5) - x)/sqrt((x*(x - tct))/(tct - 1))
stats_zscore =  n >= start_n ? zscore(trades_count, trades_count_won, trades_count_lost, trades_count_series_number) : na

// Доверительный интервал (Confidence limit)
N(z) =>
    d = 0.398942*exp(-(pow(z,2)/2))
    y = 1/(1 + 0.2316419*abs(z))
    f = 1 - d*((1.330274429*pow(y,5)) - (1.821255978*pow(y,4)) + (1.781477937*pow(y,3)) - (0.356563782*pow(y,2)) + (0.31938153*y))
    r = z < 0 ? 1-f : f
    r
confidence_limit = 1 - ((1 - N(abs(stats_zscore)))*2)

// Критерий Келли
k = trades_count_won_p-(1-trades_count_won_p)/profit_factor
k_margin = 100*profit/cum(pow(nz(trades_count_profit_per_trade),2))

///////////////////////////////////////////////////
// BACKTESTING : PLOTTING TRADES & STATS
///////////////////////////////////////////////////

show_stops = true//input(true, type = bool)

show_is_soldbought = false//input(false, type = bool)

show_is_sellbuy_at_market_open_advised = false//input(false, type = bool)
show_is_sellbuy_stop_advised = false//input(false, type = bool)
show_is_sellbuy_limit_advised = false//input(false, type = bool)
show_is_sellbuy_at_market_close_advised = false//input(false, type = bool)

show_filters = false//input(false, type = bool)

show_stats = input(false, type = bool)
show_profit = input(false, type = bool)
show_profit_stop = false//input(false, type = bool)
show_profit_stop_p = input(false, type = bool)
show_profit_per_trade = input(true, type = bool)
show_security_if_rebought = false//input(false, type = bool)
show_profit_factor = input(false, type = bool)
show_recovery_factor = input(false, type = bool)
show_expected_value = input(false, type = bool)
show_zscore = input(false, type = bool)
show_confidence_limit = input(false, type = bool)
show_std = false//input(false, type = bool)
show_sharpe = input(false, type = bool)
show_sortino = input(false, type = bool)
show_k = input(false, type = bool)

// PLOT TRADES

plotshape(show_filters ? is_sell_market_at_open_filter : na, style = shape.xcross, location = location.top, color = silver)
plotshape(show_filters ? is_sell_stop_filter : na, style = shape.xcross, location = location.top, color = black)
plotshape(show_filters ? is_sell_limit_filter : na, style = shape.xcross, location = location.top, color = orange)
plotshape(show_filters ? is_sell_market_at_close_filter : na, style = shape.xcross, location = location.top, color = red)

plotshape(show_filters ? is_buy_market_at_open_filter : na, style = shape.xcross, location = location.bottom, color = silver)
plotshape(show_filters ? is_buy_stop_filter : na, style = shape.xcross, location = location.bottom, color = black)
plotshape(show_filters ? is_buy_limit_filter : na, style = shape.xcross, location = location.bottom, color = orange)
plotshape(show_filters ? is_buy_market_at_close_filter : na, style = shape.xcross, location = location.bottom, color = red)

bgcolor(show_is_soldbought ? (is_bought and is_sold ? orange : is_bought ? olive : is_sold ? purple : na) : na, transp = 90)

bgcolor(show_is_sellbuy_at_market_open_advised ? (is_sell_market_at_open_advised and is_buy_market_at_open_advised ? yellow : is_sell_market_at_open_advised ? fuchsia : is_buy_market_at_open_advised ? lime : na) : na, transp = 90)
bgcolor(show_is_sellbuy_stop_advised ? (is_sell_stop_advised and is_buy_stop_advised ? yellow : is_sell_stop_advised ? fuchsia : is_buy_stop_advised ? lime : na) : na, transp = 90)
bgcolor(show_is_sellbuy_limit_advised ? (is_sell_limit_advised and is_buy_limit_advised ? yellow : is_sell_limit_advised ? fuchsia : is_buy_limit_advised ? lime : na) : na, transp = 90)
bgcolor(show_is_sellbuy_at_market_close_advised ? (is_sell_market_at_close_advised and is_buy_market_at_close_advised ? yellow : is_sell_market_at_close_advised ? fuchsia : is_buy_market_at_close_advised ? lime : na) : na, transp = 90)

// уровни стоп-лимит

plot(show_stops ? (not is_sell_stop_event ? sell_stop_price : na) : na, style = circles, color = gray)
plot(show_stops ? (is_sell_stop_event ? sell_stop_price : na) : na, style = circles, color = red, linewidth = 1)
plot(show_stops ? (not is_sell_stop_event ? sell_stop_price_effective : na) : na, style = cross, color = red, linewidth = 1)
plot(show_stops ? (is_sell_stop_event and not is_sell_stop_trade_completed ? sell_stop_price_effective : na) : na, style = cross, color = red, linewidth = 1)

plot(show_stops ? (not is_buy_stop_event ? buy_stop_price : na) : na, style = circles, color = gray)
plot(show_stops ? (is_buy_stop_event ? buy_stop_price : na) : na, style = circles, color = green, linewidth = 1)
plot(show_stops ? (not is_buy_stop_event ? buy_stop_price_effective : na) : na, style = cross, color = green, linewidth = 1)
plot(show_stops ? (is_buy_stop_event and not is_buy_stop_trade_completed ? buy_stop_price_effective : na) : na, style = cross, color = green, linewidth = 1)

// точки совершения сделок, включая стоп-лимит ордера
plot(sell_trade_price, style = circles, color = red, linewidth = 5)
plot(buy_trade_price, style = circles, color = green, linewidth = 5)

// доп. маркировка market_at_open trades
plot(sell_market_at_open_trade_price, style = circles, color = white, linewidth = 2)
plot(buy_market_at_open_trade_price, style = circles, color =  white, linewidth = 2)
// доп. маркировка stop trades
plot(sell_stop_trade_price, style = cross, color = yellow, linewidth = 2)
plot(buy_stop_trade_price, style = cross, color =  yellow, linewidth = 2)
// доп. маркировка limit trades
plot(sell_limit_trade_price, style = linebr, color = yellow, linewidth = 2)
plot(buy_limit_trade_price, style = linebr, color = yellow, linewidth = 2)
// доп. маркировка market_at_open trades
plot(sell_market_at_close_trade_price, style = circles, color = orange, linewidth = 2)
plot(buy_market_at_close_trade_price, style = circles, color =  orange, linewidth = 2)


// уровни сделок (для расчета прибыльности сделок)
// plot(sells_line, color = red, style = linebr, linewidth = 2)
// plot(buys_line, color = green, style = linebr, linewidth = 2)

// PLOT STATS

show_multiplier = 1//input(1, minval = 0)
plot(show_stats and show_profit_per_trade ? trades_count_profit_per_market_at_open_trade : na, color = silver, style = cross, linewidth = 2)
plot(show_stats and show_profit_per_trade ? trades_count_profit_per_stop_trade : na, color = black, style = cross, linewidth = 2)
plot(show_stats and show_profit_per_trade ? trades_count_profit_per_trade : na, color = trades_count_profit_per_trade>=0 ? lime : fuchsia, style = circles, linewidth = 2)

// plotshape(show_stats and show_profit_per_trade ? trades_count_profit_per_trade : na, style = shape.square, location = location.absolute, color = trades_count_profit_per_trade>=0 ? lime : fuchsia)

plot(show_stats and show_profit ? profit*show_multiplier : na, color = teal, style = area, transp = 80, linewidth = 0)
plot(show_stats and show_profit ? profit*show_multiplier : na, color = na(profit_ma_slow) ? black : (profit_ma_fast >= profit_ma_slow ? green : red), style = line, linewidth = 3)

plot(show_stats and show_profit_stop ? profit_stop*show_multiplier : na, color = red, style = area, transp = 95, linewidth = 0)
plot(show_stats and show_profit_stop_p ? profit_stop_p*show_multiplier : na, color = red, style = line, linewidth = 1)

// plot(show_stats and show_security_if_bought_back ? security_if_bought_back : na, color = maroon, linewidth = 0, transp = 90, style = area)

plot(show_stats and show_profit ? profit_ma_fast : na, color = olive)
plot(show_stats and show_profit ? profit_ma_slow : na, color = maroon)
// plot(profit_max)
// plot(trades_count_conseq_profit, color = green)
// plot(trades_count_conseq_profit_max, color = green, linewidth = 2)
// plot(trades_count_conseq_loss, color = red)
// plot(trades_count_conseq_loss_max, color = red, linewidth = 2)
// plot(drawdown)
// plot(trades_count_conseq_won, color = green)
// plot(trades_count_conseq_won_max, color = green)
// plot(trades_count_conseq_lost, color = red)
// bgcolor(color = trades_count_conseq_lost > 0 ? red : trades_count_conseq_won > 0 ? green : na)
// plot(trades_count_conseq_lost_max, color = red)
// bgcolor(color = na(expected_value_ma_slow) ? na : (expected_value_ma_fast >= expected_value_ma_slow ? olive : maroon))

plot(show_stats and show_profit_factor ? profit_factor : na, color = black, style = line, linewidth = 3)
plot(show_stats and show_profit_factor ? profit_factor_r : na, color = black, style = line, linewidth = 2)
plot(show_stats and show_recovery_factor ? recovery_factor : na, color = navy, linewidth = 3)
plot(show_stats and show_expected_value? expected_value : na, color = na(expected_value_ma_slow) ? black : (expected_value_ma_fast >= expected_value_ma_slow ? lime : purple), linewidth = 3)
plot(show_stats and show_zscore ? stats_zscore : na, linewidth = 1)
plot(show_stats and show_confidence_limit ? confidence_limit : na, color = navy, linewidth = 1)
plot(show_stats and show_std ? std : na, color=lime)
plot(show_stats and show_sharpe ? sharpe : na, color = orange, linewidth = 3)
plot(show_stats and show_sortino ? sortino : na, color = aqua, linewidth = 3)
plot(show_stats and show_k ? k : na, linewidth = 2)
plot(show_stats and show_k ? k_margin : na, linewidth = 1)