Why is my drawdown so high?

in the shared imagemy drawdown is shown has 95% and return -94%.


I am trying to do just 1 buy and 1 sell trade for one equity and fixed price. the leverage i have decided is only of 50%. so max drawdown i expect uis 50%. The blue line in the chart i am assuming shows returns, which also doesnt make sense, as what i am trying to execute is a profitabl trade (have hard coded this).

Any way i can print out all trades that are executed in the logs ?

from blueshift_library.technicals.indicators import bollinger_band, ema

from blueshift.finance import commission, slippage
from blueshift.api import( symbol,
order_target_percent,
set_commission,
set_slippage,
get_datetime,
schedule_function,
date_rules,
time_rules
)

def initialize(context):
“”"
A function to define things to do at the start of the strategy
“”"
print(“get_datetime”,get_datetime())
# universe selection
context.securities = [symbol(‘RELIANCE’)]

# define strategy parameters
context.params = {'indicator_lookback':15,
                  'indicator_freq':'1m',
                  'buy_signal_threshold':0.5,
                  'sell_signal_threshold':-0.5,
                  'square_off_signal_threshold':0,
                  'SMA_period_short':5,
                  'SMA_period_mid':8,
                  'SMA_period_long':13,
                  'BBands_period':300,
                  'trade_freq':1,
                  'leverage':.5}

# variables to track signals and target portfolio
context.signals = dict((security,0) for security in context.securities)
context.target_position = dict((security,0) for security in context.securities)
context.buy_order = dict((security,0) for security in context.securities)
context.sell_order = dict((security,0) for security in context.securities)

# set trading cost and slippage to zero
set_commission(commission.PerShare(cost=20.0, min_trade_cost=0.0))
set_slippage(slippage.FixedSlippage(2.00))
schedule_function(run_strategy, date_rules.every_day(), time_rules.market_open(hours=1,minutes = 0))
# if the day closes quare off
schedule_function(square_off, date_rules.every_day(), time_rules.market_close(hours=0,minutes = 5))

def run_strategy(context, data):
“”"
A function to define core strategy steps
“”"
generate_signals(context, data)
generate_target_position(context, data)
rebalance(context, data)

def generate_signals(context, data):
“”"
A function to define define the signal generation
“”"
try:
price_data = data.history(context.securities, ‘close’,
context.params[‘indicator_lookback’],
context.params[‘indicator_freq’])
except:
return

for security in context.securities:
    px = price_data.loc[:,security].values
    context.signals[security] = signal_function(px, context.params)

def generate_target_position(context, data):
“”"
A function to define target portfolio
“”"
num_secs = len(context.securities)
weight = round(1.0/num_secs,2)*context.params[‘leverage’]

for security in context.securities:

    if context.signals[security] != None:
   
        if (context.signals[security] > context.params['buy_signal_threshold'])&(context.buy_order[security] ==0):
            context.target_position[security] = weight
            context.buy_order[security]  = context.buy_order[security] + 1

    #     elif context.signals[security] < context.params['sell_signal_threshold']:
    #         context.target_position[security] = -weight

        elif (context.signals[security] == context.params['square_off_signal_threshold'])&(context.sell_order[security]==0):
            context.target_position[security] = 0
            context.sell_order[security] = context.sell_order[security] + 1
    else:
        context.target_position[security] = None

def signal_function(px, params):
“”"
The main trading logic goes here, called by generate_signals above
“”"
print(“px”,px)
ind5 = ema(px, params[‘SMA_period_short’])
ind8 = ema(px, params[‘SMA_period_mid’])
ind13 = ema(px, params[‘SMA_period_long’])
last_px = px[-1]
print(“last_px”,last_px,“ind5”,ind5,“ind8”,ind8,“ind13”,ind13)
if last_px >= 2600:
return 1
elif last_px >= 2650:
return 0
else:
return
# if (last_px>=ind5) & (last_px>=ind8) & (last_px>=ind13):
# print (“1”)
# return 0
# elif (last_px<ind5) & (last_px<=ind8) & (last_px<=ind13):
# print (“-1”)
# return 1
# else:
# print (“0”)
# return

def rebalance(context,data):
“”"
A function to rebalance - all execution logic goes here
“”"
for security in context.securities:
if context.target_position[security] != None:
print(“context.target_position[security]”,context.target_position[security])
order_target_percent(security, context.target_position[security])

def square_off(context,data):
for sec in context.securities:
order_target_percent(sec,0)


?



Thanks,

Abhishek

Hi Abhishek,



You can do a full backtest to check the trade logs. Have attached the images for reference - 







Hope this helps!



Thanks,

Akshay

The issue here missing documentation I think. In the call to set_slippage with FixedSlippage at 2.0, this number is treated as percentage slippage at present, and half of it is added so - and it is extremely high (a number 2.0 leads to a 100% slippage!). I think it is best to leave it as default slippage model (i.e. commenting out the set_slippage call) or change the FixedSlippage value to 0.0016 (i.e.0.16%) for an approx Rs 2 slippage (given approx share price of 2500 for reliance). I can see the nomenclature is a bit confusing here. We will consider moving this to a fixed spread (i.e. no percentage) in a future release.



To see the transactions, you do not need to use print statments. Simply run a full backtest ("new backtest" orange button), and once complete, check out the transactions tab.

Thank you so much @Prodipta. This was very helpful.

@Prodipta, for a use case i still want to know if my order went through ? And then apply some stop loss, how can i know if and when the purchase was successfull ?

Hi Abhishek,



You can check the transactions tab after generating a full backtest. 



Hope that helps!



Thanks,

Akshay