Back to Community
Runaway Leverage - Momentum Strategy based on the DOW by (Leo P. Williams)

I would love nothing more than to eliminate the runaway leverage in this algorithm while maintaining the returns. Hence, I am in a sharing mood. If one if you should figure this out, feel free to share it publicly or with me at [email protected]. I like this algorithm because it trades the DOW, the safest of all stocks in my opinion. I'm new to python, three months of experience to be exact, and I literally learned it simply because this platform forced me to. Any improvements we can make to keep leverage 2 or below would be great for swing trading, and any improvement we can make between 4 and below, closing out that same day would be great for a day trading Algo.

Thanks in advance,

Leo

Clone Algorithm
63
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import morningstar
from brokers.ib import IBExchange
from quantopian.pipeline.data.quandl import yahoo_index_vix as vix
from quantopian.pipeline import CustomFactor
import talib

def initialize(context):
    schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(minutes=1))
    schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_open())
    attach_pipeline(make_pipeline(), 'my_pipeline')
    context.vix_hist = {}
    context.vl = 18
    context.vs = 26
    context.trail = {}
         
def make_pipeline():
    pipe = Pipeline()
    pipe.add(GetVIX(inputs=[vix.close]), 'VixClose') 
    return pipe
 
def before_trading_start(context, data):
    context.output = pipeline_output('my_pipeline')
    context.security_listF = {}
    context.vix = context.output["VixClose"].iloc[0]
    context.can_trade = 0
    
    context.security_list = [symbol('MMM'),symbol('AXP'),symbol('AAPL'),symbol('BA'),symbol('CAT'),symbol('CVX'),symbol('CSCO'),symbol('KO'),symbol('DIS'),symbol('DD'),symbol('XOM'),symbol('GE'),symbol('GS'),symbol('HD'),symbol('IBM'),symbol('INTC'),symbol('JNJ'),symbol('JPM'),symbol('MCD'),symbol('MRK'),symbol('MSFT'),symbol('NKE'),symbol('PFE'),symbol('PG'),symbol('TRV'),symbol('UTX'),symbol('UNH'),symbol('VZ'),symbol('V'),symbol('WMT')]
     
def my_rebalance(context,data):

     pc = data.history(context.security_list,'price',bar_count=5,frequency='1d')
     hi = data.history(context.security_list,'price',bar_count=30,frequency='1d')
     ma = data.history(context.security_list,'price',20,'1d').mean()
     ma2 = data.history(context.security_list,'price',200,'1d').mean()
     mx  = data.history(context.security_list,'price',200,'1d')

     for s in context.security_list: 
         if context.vix <= context.vl:
             if pc[s][-2] == max(hi[s]) and pc[s][-2] > ma[s]:
               if mx[s][-1] > mx[s][-200] and ma[s] > ma2[s]:
                  print s.symbol  
                  context.security_listF[s] = s
                
         if len(context.security_listF) > 0 and context.portfolio.cash > 0:
           context.can_trade = 1
           context.div = (context.portfolio.cash/len(context.security_listF))
     
     for s in context.security_listF:
         #if context.can_trade == 1:
           if s not in context.portfolio.positions and s not in get_open_orders(): 
             if data.can_trade(s):
               if context.vix <= context.vl:
                 cp = data.current(s,'price')
                 context.trail[s] = cp * .97
                 shares = (context.div/cp)
                 order_target(s,shares,style=MarketOrder(IBExchange.SMART))
                 order_target(s,0,style=StopOrder(context.trail[s],IBExchange.SMART))
                 #print s.symbol
                
                 
     if len(context.security_listF) > 0:
         record(stock_traded=len(context.security_listF))
         record(vix=context.vix)
 
def my_record_vars(context, data):
    
    for s in context.portfolio.positions:
        cp = data.current(s,'price')
        ma = data.history(s,'price',20,'1d').mean()
        amt = context.portfolio.positions[s].amount
        cb =  context.portfolio.positions[s].cost_basis
        if (cp * .97) > context.trail[s] and amt > 0:
            context.trail[s] = (cp * .97)
            order_target(s,0,style=StopOrder(context.trail[s]))
        if context.vix > context.vl and amt > 0:
            order_target(s,0)
            
        
    
    record(cash=context.portfolio.cash)
    record(leverage=context.account.leverage)

def handle_data(context,data):
    pass

class GetVIX(CustomFactor):  
    window_length = 1  
    def compute(self, today, assets, out, vix):  
        out[:] = vix[-1]
There was a runtime error.
13 responses
     oo = get_open_orders()  
     for s in context.security_listF:  
        if s in oo: continue  
        if s in context.portfolio.positions: continue  
        if context.vix > context.vl: continue  
        if not context.can_trade == 1: continue  
        if not data.can_trade(s): continue

        # the solution is the next two lines  
        val = context.portfolio.cash / len(context.security_listF)  
        order_target_value(s, val, style=MarketOrder(IBExchange.SMART))

        # understand that stop will only be entered if current shares, so this one never does anything  
        #   currently due to positions condition above. The other one does.  
        context.trail[s] = data.current(s,'price') * .97  
        order_target(s, 0, style=StopOrder(context.trail[s],IBExchange.SMART))  

Thanks. Can you post the working example? How much did this change impact the return?

Hey Blue. I don't see how what you're doing is any different from what I've already done. You're simply using continue statements as opposed to nested if's. Can you post a working example with the change you made? Remember, the objective is to maintain as much of the momentum gain as I originally coded, but limiting the leverage to 2. A bit shocked, I didn't get more responses, given all the rambling that goes on here.

  for s in context.security_list:  
     if context.vix <= context.vl:  
         if pc[s][-2] == max(hi[s]) and pc[s][-2] > ma[s]:  
           if mx[s][-1] > mx[s][-200] and ma[s] > ma2[s]:  
              print s.symbol  
              context.security_listF[s] = s  

     if len(context.security_listF) > 0 and context.portfolio.cash > 0:  
       context.can_trade = 1  
       context.div = (context.portfolio.cash/len(context.security_listF))  

 for s in context.security_listF:  
     #if context.can_trade == 1:  
       if s not in context.portfolio.positions and s not in get_open_orders():  
         if data.can_trade(s):  
           if context.vix <= context.vl:  
             cp = data.current(s,'price')  
             context.trail[s] = cp * .97  
             shares = (context.div/cp)  
             order_target(s,shares,style=MarketOrder(IBExchange.SMART))  
             order_target(s,0,style=StopOrder(context.trail[s],IBExchange.SMART))  

The main change might be dropping the use of .div. You can ignore the continue business, some find that style easier to understand and work with, and since I had changed it for my understanding, I left it in place.

Run this and look at the logs. Then you might want to try my two lines and compare the logging output between the two. From that I'm sure you'll figure out where to go from there. Notice start and stop dates are entered for the tracking, out of initialize to make that easy for you to change. Also I added leverage in the output. It is focused on a time when leverage jumps to 8.

The code also contains https://www.quantopian.com/posts/margin. If you turn that on you'll see that your version carries a cumulative 94 million margin overnight if you total them all up which it does.

In the custom chart, you can see that the leverage high of 32 and spending 121 million results in 7% returns adjusted for the amount risked. Replace with my two lines (or perhaps just drop your use of .div, always operate against current cash instead) and returns will be 70% or so.

Clone Algorithm
42
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import morningstar
from brokers.ib import IBExchange
from quantopian.pipeline.data.quandl import yahoo_index_vix as vix
from quantopian.pipeline import CustomFactor
import talib

def initialize(context):
    schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(minutes=1))
    schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_open())
    attach_pipeline(make_pipeline(), 'my_pipeline')
    context.vix_hist = {}
    context.vl = 18
    context.vs = 26
    context.trail = {}
    context.security_list = [symbol('MMM'),symbol('AXP'),symbol('AAPL'),symbol('BA'),symbol('CAT'),symbol('CVX'),symbol('CSCO'),symbol('KO'),symbol('DIS'),symbol('DD'),symbol('XOM'),symbol('GE'),symbol('GS'),symbol('HD'),symbol('IBM'),symbol('INTC'),symbol('JNJ'),symbol('JPM'),symbol('MCD'),symbol('MRK'),symbol('MSFT'),symbol('NKE'),symbol('PFE'),symbol('PG'),symbol('TRV'),symbol('UTX'),symbol('UNH'),symbol('VZ'),symbol('V'),symbol('WMT')]
    
    context.track_start = ['2003-11-03']
    context.track_stop  = ['2004-01-12']
         
def make_pipeline():
    pipe = Pipeline()
    pipe.add(GetVIX(inputs=[vix.close]), 'VixClose') 
    return pipe
 
def before_trading_start(context, data):
    context.output = pipeline_output('my_pipeline')
    context.security_listF = {}
    context.vix = context.output["VixClose"].iloc[0]
    context.can_trade = 0
    
def my_rebalance(context,data):
     pc = data.history(context.security_list,'price',bar_count=5,frequency='1d')
     hi = data.history(context.security_list,'price',bar_count=30,frequency='1d')
     ma = data.history(context.security_list,'price',20,'1d').mean()
     ma2 = data.history(context.security_list,'price',200,'1d').mean()
     mx  = data.history(context.security_list,'price',200,'1d')

     for s in context.security_list: 
         if context.vix <= context.vl:
             if pc[s][-2] == max(hi[s]) and pc[s][-2] > ma[s]:
               if mx[s][-1] > mx[s][-200] and ma[s] > ma2[s]:
                  #print s.symbol  
                  context.security_listF[s] = s
                
         if len(context.security_listF) > 0 and context.portfolio.cash > 0:
           context.can_trade = 1
           context.div = (context.portfolio.cash/len(context.security_listF))
     
     for s in context.security_listF:
         #if context.can_trade == 1:
           if s not in context.portfolio.positions and s not in get_open_orders(): 
             if data.can_trade(s):
               if context.vix <= context.vl:
                 cp = data.current(s,'price')
                 context.trail[s] = cp * .97
                 shares = (context.div/cp)
                 order_target(s,shares,style=MarketOrder(IBExchange.SMART))
                 order_target(s,0,style=StopOrder(context.trail[s],IBExchange.SMART))
                 #print s.symbol
                 
     if 0 and len(context.security_listF) > 0:
         record(stock_traded=len(context.security_listF))
         record(vix=context.vix)
 
     track_orders(context, data)
    
def my_record_vars(context, data):
    for s in context.portfolio.positions:
        cp = data.current(s,'price')
        #ma = data.history(s,'price',20,'1d').mean()
        amt = context.portfolio.positions[s].amount
        #cb =  context.portfolio.positions[s].cost_basis
        if (cp * .97) > context.trail[s] and amt > 0:
            context.trail[s] = (cp * .97)
            order_target(s,0,style=StopOrder(context.trail[s]))
        if context.vix > context.vl and amt > 0:
            order_target(s,0)
    
    #record(cash=context.portfolio.cash)
    #record(leverage=context.account.leverage)

    track_orders(context, data)
    
class GetVIX(CustomFactor):  
    window_length = 1  
    def compute(self, today, assets, out, vix):  
        out[:] = vix[-1]
        
def pvr(context, data):
    ''' Custom chart and/or logging of profit_vs_risk returns and related information
    '''
    import time
    from datetime import datetime
    from pytz import timezone      # Python will only do once, makes this portable.
                                   #   Move to top of algo for better efficiency.
    c = context  # Brevity is the soul of wit -- Shakespeare [for readability]
    if 'pvr' not in c:

        # For real money, you can modify this to total cash input minus any withdrawals
        manual_cash = c.portfolio.starting_cash
        time_zone   = 'US/Pacific'   # Optionally change to your own time zone for wall clock time

        c.pvr = {
            'options': {
                # # # # # # # # # #  Options  # # # # # # # # # #
                'logging'         : 0,    # Info to logging window with some new maximums
                'log_summary'     : 126,  # Summary every x days. 252/yr

                'record_pvr'      : 1,    # Profit vs Risk returns (percentage)
                'record_pvrp'     : 0,    # PvR (p)roportional neg cash vs portfolio value
                'record_cash'     : 0,    # Cash available
                'record_max_lvrg' : 1,    # Maximum leverage encountered
                'record_max_risk' : 1,    # Highest risk overall
                'record_shorting' : 0,    # Total value of any shorts
                'record_max_shrt' : 0,    # Max value of shorting total
                'record_cash_low' : 1,    # Any new lowest cash level
                'record_q_return' : 0,    # Quantopian returns (percentage)
                'record_pnl'      : 0,    # Profit-n-Loss
                'record_risk'     : 0,    # Risked, max cash spent or shorts beyond longs+cash
                'record_leverage' : 1,    # End of day leverage (context.account.leverage)
                # All records are end-of-day or the last data sent to chart during any day.
                # The way the chart operates, only the last value of the day will be seen.
                # # # # # # # # #  End options  # # # # # # # # #
            },
            'pvr'        : 0,      # Profit vs Risk returns based on maximum spent
            'cagr'       : 0,
            'max_lvrg'   : 0,
            'max_shrt'   : 0,
            'max_risk'   : 0,
            'days'       : 0.0,
            'date_prv'   : '',
            'date_end'   : get_environment('end').date(),
            'cash_low'   : manual_cash,
            'cash'       : manual_cash,
            'start'      : manual_cash,
            'tz'         : time_zone,
            'begin'      : time.time(),  # For run time
            'run_str'    : '{} to {}  ${}  {} {}'.format(get_environment('start').date(), get_environment('end').date(), int(manual_cash), datetime.now(timezone(time_zone)).strftime("%Y-%m-%d %H:%M"), time_zone)
        }
        if c.pvr['options']['record_pvrp']: c.pvr['options']['record_pvr'] = 0 # if pvrp is active, straight pvr is off
        if get_environment('arena') not in ['backtest', 'live']: c.pvr['options']['log_summary'] = 1 # Every day when real money
        log.info(c.pvr['run_str'])
    p = c.pvr ; o = c.pvr['options'] ; pf = c.portfolio ; pnl = pf.portfolio_value - p['start']
    def _pvr(c):
        p['cagr'] = ((pf.portfolio_value / p['start']) ** (1 / (p['days'] / 252.))) - 1
        ptype = 'PvR' if o['record_pvr'] else 'PvRp'
        log.info('{} {} %/day   cagr {}   Portfolio value {}   PnL {}'.format(ptype, '%.4f' % (p['pvr'] / p['days']), '%.3f' % p['cagr'], '%.0f' % pf.portfolio_value, '%.0f' % pnl))
        log.info('  Profited {} on {} activated/transacted for PvR of {}%'.format('%.0f' % pnl, '%.0f' % p['max_risk'], '%.1f' % p['pvr']))
        log.info('  QRet {} PvR {} CshLw {} MxLv {} MxRisk {} MxShrt {}'.format('%.2f' % (100 * pf.returns), '%.2f' % p['pvr'], '%.0f' % p['cash_low'], '%.2f' % p['max_lvrg'], '%.0f' % p['max_risk'], '%.0f' % p['max_shrt']))
    def _minut():
        dt = get_datetime().astimezone(timezone(p['tz']))
        return str((dt.hour * 60) + dt.minute - 570).rjust(3)  # (-570 = 9:31a)
    date = get_datetime().date()
    if p['date_prv'] != date:
        p['date_prv'] = date
        p['days'] += 1.0
    do_summary = 0
    if o['log_summary'] and p['days'] % o['log_summary'] == 0 and _minut() == '100':
        do_summary = 1              # Log summary every x days
    if do_summary or date == p['date_end']:
        p['cash'] = pf.cash
    elif p['cash'] == pf.cash and not o['logging']: return  # for speed

    shorts = sum([z.amount * z.last_sale_price for s, z in pf.positions.items() if z.amount < 0])
    new_key_hi = 0                  # To trigger logging if on.
    cash       = pf.cash
    cash_dip   = int(max(0, p['start'] - cash))
    risk       = int(max(cash_dip, -shorts))

    if o['record_pvrp'] and cash < 0:   # Let negative cash ding less when portfolio is up.
        cash_dip = int(max(0, cash_dip * p['start'] / pf.portfolio_value))
        # Imagine: Start with 10, grows to 1000, goes negative to -10, should not be 200% risk.

    if int(cash) < p['cash_low']:             # New cash low
        new_key_hi = 1
        p['cash_low'] = int(cash)             # Lowest cash level hit
        if o['record_cash_low']: record(CashLow = p['cash_low'])

    if c.account.leverage > p['max_lvrg']:
        new_key_hi = 1
        p['max_lvrg'] = c.account.leverage    # Maximum intraday leverage
        if o['record_max_lvrg']: record(MxLv    = p['max_lvrg'])

    if shorts < p['max_shrt']:
        new_key_hi = 1
        p['max_shrt'] = shorts                # Maximum shorts value
        if o['record_max_shrt']: record(MxShrt  = p['max_shrt'])

    if risk > p['max_risk']:
        new_key_hi = 1
        p['max_risk'] = risk                  # Highest risk overall
        if o['record_max_risk']:  record(MxRisk = p['max_risk'])

    # Profit_vs_Risk returns based on max amount actually invested, long or short
    if p['max_risk'] != 0: # Avoid zero-divide
        p['pvr'] = 100 * pnl / p['max_risk']
        ptype = 'PvRp' if o['record_pvrp'] else 'PvR'
        if o['record_pvr'] or o['record_pvrp']: record(**{ptype: p['pvr']})

    if o['record_shorting']: record(Shorts = shorts)             # Shorts value as a positve
    if o['record_leverage']: record(Lv     = c.account.leverage) # Leverage
    if o['record_cash']    : record(Cash   = cash)               # Cash
    if o['record_risk']    : record(Risk   = risk)  # Amount in play, maximum of shorts or cash used
    if o['record_q_return']: record(QRet   = 100 * pf.returns)
    if o['record_pnl']     : record(PnL    = pnl)                # Profit|Loss

    if o['logging'] and new_key_hi:
        log.info('{}{}{}{}{}{}{}{}{}{}{}{}'.format(_minut(),
            ' Lv '     + '%.1f' % c.account.leverage,
            ' MxLv '   + '%.2f' % p['max_lvrg'],
            ' QRet '   + '%.1f' % (100 * pf.returns),
            ' PvR '    + '%.1f' % p['pvr'],
            ' PnL '    + '%.0f' % pnl,
            ' Cash '   + '%.0f' % cash,
            ' CshLw '  + '%.0f' % p['cash_low'],
            ' Shrt '   + '%.0f' % shorts,
            ' MxShrt ' + '%.0f' % p['max_shrt'],
            ' Risk '   + '%.0f' % risk,
            ' MxRisk ' + '%.0f' % p['max_risk']
        ))
    if do_summary: _pvr(c)
    if get_datetime() == get_environment('end'):   # Summary at end of run
        _pvr(c) ; elapsed = (time.time() - p['begin']) / 60  # minutes
        log.info( '{}\nRuntime {} hr {} min'.format(p['run_str'], int(elapsed / 60), '%.1f' % (elapsed % 60)))

def track_orders(context, data):
    '''  Show orders when made and filled.
           Info: https://www.quantopian.com/posts/track-orders
    '''
    c = context
    if 'trac' not in c:
        c.t_options = {           # __________    O P T I O N S    __________
            'log_neg_cash': 1,    # Show cash only when negative.
            'log_cash'    : 0,    # Show cash values in logging window or not.
            'log_ids'     : 0,    # Include order id's in logging window or not.
            'log_unfilled': 1,    # When orders are unfilled. (stop & limit excluded).
        }    # Move these to initialize() for better efficiency.
        c.trac = {}
        c.t_dates  = {  # To not overwhelm the log window, start/stop dates can be entered.
            'active': 0,
            
            # for "Runaway Leverage - Momentum Strat ..."
            'start' :  context.track_start,
            'stop'  :  context.track_stop,
            
            
            #'start' : [],   # Start dates, option like ['2007-05-07', '2010-04-26']
            #'stop'  : []    # Stop  dates, option like ['2008-02-13', '2010-11-15']
        }
    from pytz import timezone     # Python only does once, makes this portable.
                                  #   Move to top of algo for better efficiency.
    # If 'start' or 'stop' lists have something in them, triggers ...
    if c.t_dates['start'] or c.t_dates['stop']:
        date = str(get_datetime().date())
        if   date in c.t_dates['start']:    # See if there's a match to start
            c.t_dates['active'] = 1
        elif date in c.t_dates['stop']:     #   ... or to stop
            c.t_dates['active'] = 0
    else: c.t_dates['active'] = 1           # Set to active b/c no conditions.
    if c.t_dates['active'] == 0: return     # Skip if not active.
    def _minute():   # To preface each line with the minute of the day.
        bar_dt = get_datetime().astimezone(timezone('US/Eastern'))
        return str((bar_dt.hour * 60) + bar_dt.minute - 570).rjust(3) # (-570 = 9:31a)
    def _trac(to_log):      # So all logging comes from the same line number,
        log.info(to_log)    #   for vertical alignment in the logging window.

    for oid in c.trac.copy():               # Existing known orders
      o = get_order(oid)
      c.trac[o.id]['cb'] = c.portfolio.positions[o.sid].cost_basis \
            if c.portfolio.positions[o.sid].cost_basis else c.trac[o.id]['cb']
      if o.dt == o.created: continue        # No chance of fill yet.
      cash = ''
      if (c.t_options['log_neg_cash'] and c.portfolio.cash < 0) or c.t_options['log_cash']:
        cash = 'cash {}'.format(int(c.portfolio.cash))
      if o.status == 2:                     # Canceled
        prc = '%.2f' % data.current(o.sid, 'price') if data.can_trade(o.sid) else 'unknwn'
        do  = 'Buy' if o.amount > 0 else 'Sell' ; style = ''
        if o.stop:
          style = ' stop {}'.format(o.stop)
          if o.limit: style = ' stop {} limit {}'.format(o.stop, o.limit)
        elif o.limit: style = ' limit {}'.format(o.limit)
        _trac(' {}     Canceled {} {} {}{} at {}   {}  {}'.format(_minute(), do, o.amount,
           o.sid.symbol, style, prc, cash, o.id[-4:] if c.t_options['log_ids'] else ''))
        del c.trac[o.id]
      elif o.filled:                        # Filled at least some.
        filled = '{}'.format(o.amount)
        filled_amt = 0
        if o.filled == o.amount:            # Complete
          if 0 < c.trac[o.id]['amnt'] < o.amount:
            filled   = 'all {}/{}'.format(o.filled - c.trac[o.id]['amnt'], o.amount)
          filled_amt = o.filled
        else:                               # ['amnt'] is previously filled total
          filled_amt = o.filled - c.trac[o.id]['amnt']   # filled this time, can be 0
          c.trac[o.id]['amnt'] = o.filled                # save for increments math
          filled = '{}/{}'.format(filled_amt, o.amount)
        if filled_amt:
          prc = c.portfolio.positions[o.sid].last_sale_price if o.sid in c.portfolio.positions else 'unknwn'
          prc = data.history(o.sid, 'price', 1, '1d')[-1] if prc is 'unknwn' else prc
          now = ' ({})'.format(c.portfolio.positions[o.sid].amount) \
                      if c.portfolio.positions[o.sid].amount else ' _'
          pnl = ''  # for the trade only
          amt = c.portfolio.positions[o.sid].amount ; style = ''
          if (amt - o.filled) * o.filled < 0:  # Profit-taking scenario including short-buyback
            if c.trac[o.id]['cb']:
              pnl  = -filled_amt * (prc - c.trac[o.id]['cb'])
              sign = '+' if pnl > 0 else '-'
              pnl  = '  ({}{})'.format(sign, '%.0f' % abs(pnl))
          if o.stop:
            style = ' stop {}'.format(o.stop)
            if o.limit: style = ' stop () limit {}'.format(o.stop, o.limit)
          elif o.limit: style = ' limit {}'.format(o.limit)
          if o.filled == o.amount: del c.trac[o.id]
          _trac(' {}      {} {} {}{} at {}{}{}'.format(_minute(),
            'Bot' if o.amount > 0 else 'Sold', filled, o.sid.symbol, now,
            '%.2f' % prc, pnl, style).ljust(52) + \
            '  {}  {} lv {}'.format(cash, o.id[-4:] if c.t_options['log_ids'] else '', '%.1f' % c.account.leverage))
      elif c.t_options['log_unfilled'] and not (o.stop or o.limit):
        _trac(' {}         {} {}{} unfilled  {}'.format(_minute(), o.sid.symbol, o.amount,
         ' limit' if o.limit else '', o.id[-4:] if c.t_options['log_ids'] else ''))

    oo = get_open_orders().values()
    if not oo: return                       # Handle new orders
    cash = ''
    if (c.t_options['log_neg_cash'] and c.portfolio.cash < 0) or c.t_options['log_cash']:
      cash = 'cash {}'.format(int(c.portfolio.cash))
    for oo_list in oo:
      for o in oo_list:
        if o.id in c.trac: continue         # Only new orders beyond this point
        prc  = '%.2f' % data.current(o.sid, 'price') if data.can_trade(o.sid) else 'unknwn'
        c.trac[o.id] = {'amnt': 0, 'cb': 0} ; style = ''
        now  = ' ({})'.format(c.portfolio.positions[o.sid].amount) \
                    if c.portfolio.positions[o.sid].amount else ' _'
        if o.stop:
          style = ' stop {}'.format(o.stop)
          if o.limit: style = ' stop {} limit {}'.format(o.stop, o.limit)
        elif o.limit: style = ' limit {}'.format(o.limit)
        _trac(' {}   {} {} {}{} at {}{}'.format(_minute(), 'Buy' if o.amount > 0 else 'Sell',
          o.amount, o.sid.symbol, now, prc, style).ljust(52) + \
           '  {}  {}'.format(cash, o.id[-4:] if c.t_options['log_ids'] else ''))

def handle_data(context, data):
    pvr(context, data)
    track_orders(context, data)

        
There was a runtime error.

It took me a long time to figure out how to perfectly control leverage, I think everyone solves the issue slightly differently depending on how their algo is set up. People who don't live trade don't run into as many problems with execution

The way I do it is to use order() and specify exactly how many shares I should be ordering based on the cash that I have available. Sell first, wait until all sell orders have filled, then execute your buys. You can use a flag that will only return true once all sell orders are finished and one that signals all stocks are ordered and in the proper allocations and keep repeating the function in handle_data() until the flag returns true.

Currently you have your ordering logic split up into two functions that are both buying and selling in the same minute 1 minute after eachother using a _target() ordering function that doesn't know about the other orders because they haven't executed yet.

Once margin is under control like that, then you can just multiply ordering for any margin leverage target. I did that and found that it ran higher than a target of 2 for a little while. That would surely be due to partial fills with the higher volume and you can investigate with the track_orders code (already present) if you might want to look for a way to further limit margin excess over target when that happens.

It may be that I'm not understanding what Blue is stating, and my apologies on that. It appears he has diagnosed why this is happening, as opposed to crafting the solution, which is of course valuable. However, my goal is very simple, keep leverage under 2, while maintaining symmetric gains, if possible. If I uncomment the line if context.can_trade == 1, the code will not abuse leverage. However, the gains are substantially lower. However, I also notice times where there are funds that are not invested, which is where I felt there was wiggle room to make up for what was lost in decreased usage of leverage. I don't want to over-complicate this. Again, I've been on here all of three months. I'm no expert by any means, but I do firmly understand trading concepts.

This is the ordering I suggested, it has max intraday leverage 1.02, no margin to speak of.

Clone Algorithm
42
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import morningstar
from brokers.ib import IBExchange
from quantopian.pipeline.data.quandl import yahoo_index_vix as vix
from quantopian.pipeline import CustomFactor
import talib

def initialize(context):
    schedule_function(rebalance, date_rules.every_day(), time_rules.market_open(minutes=1))
    schedule_function(record_vars, date_rules.every_day(), time_rules.market_open())
    schedule_function(cancel_oos, date_rules.every_day(), time_rules.market_close())
    attach_pipeline(make_pipeline(), 'pipeline')
    context.vix_hist = {}
    context.vl = 18
    context.vs = 26
    context.trail = {}
    context.security_list = [symbol('MMM'),symbol('AXP'),symbol('AAPL'),symbol('BA'),symbol('CAT'),symbol('CVX'),symbol('CSCO'),symbol('KO'),symbol('DIS'),symbol('DD'),symbol('XOM'),symbol('GE'),symbol('GS'),symbol('HD'),symbol('IBM'),symbol('INTC'),symbol('JNJ'),symbol('JPM'),symbol('MCD'),symbol('MRK'),symbol('MSFT'),symbol('NKE'),symbol('PFE'),symbol('PG'),symbol('TRV'),symbol('UTX'),symbol('UNH'),symbol('VZ'),symbol('V'),symbol('WMT')]

    context.track_active = 1
    context.track_start  = []  # ['2003-11-03']
    context.track_stop   = ['2004-01-12']        # only run for awhile

def make_pipeline():
    pipe = Pipeline()
    pipe.add(GetVIX(inputs=[vix.close]), 'VixClose')
    return pipe

def before_trading_start(context, data):
    context.output = pipeline_output('pipeline')
    context.security_listF = {}
    context.vix = context.output["VixClose"].iloc[0]
    context.can_trade = 0

def rebalance(context,data):
     #if context.portfolio.cash <= 0: return

     pc  = data.history(context.security_list,'price',bar_count=5,frequency='1d')
     hi  = data.history(context.security_list,'price',bar_count=30,frequency='1d')
     ma  = data.history(context.security_list,'price',20,'1d').mean()
     ma2 = data.history(context.security_list,'price',200,'1d').mean()
     mx  = data.history(context.security_list,'price',200,'1d')

     for s in context.security_list:
         if context.vix <= context.vl:
             if pc[s][-2] == max(hi[s]) and pc[s][-2] > ma[s]:
               if mx[s][-1] > mx[s][-200] and ma[s] > ma2[s]:
                  #print s.symbol
                  context.security_listF[s] = s

         if len(context.security_listF) > 0 and context.portfolio.cash > 0:
           context.can_trade = 1
           context.div = (context.portfolio.cash/len(context.security_listF))

     for s in context.security_listF:
         #if context.can_trade == 1:
           if s not in context.portfolio.positions and s not in get_open_orders():
             if data.can_trade(s):
               if context.vix <= context.vl:
                 cp = data.current(s,'price')
                 context.trail[s] = cp * .97
                 #shares = (context.div/cp)
                 #order_target(s,shares,style=MarketOrder(IBExchange.SMART))
                 #order_target(s,0,style=StopOrder(context.trail[s],IBExchange.SMART))
                 #print s.symbol

                 # Blue
                 val = 1.0 * context.portfolio.cash / len(context.security_listF)
                 order_target_value(s, val, style=MarketOrder(IBExchange.SMART))

                 ''' This is with 1.0 *  on the val line above  ... MxLv 1.02
                 2017-06-05 13:00 _pvr:152 INFO PvR 0.0500 %/day   cagr 0.074   Portfolio value 85710   PnL 55710
                 2017-06-05 13:00 _pvr:153 INFO   Profited 55710 on 30226 activated/transacted for PvR of 184.3%
                 2017-06-05 13:00 _pvr:154 INFO   QRet 185.70 PvR 184.31 CshLw -226 MxLv 1.02 MxRisk 30226 MxShrt -997
                 2017-06-05 13:00 pvr:229 INFO 2002-10-17 to 2017-06-05  $30000  2017-06-06 22:26 US/Pacific
                 Runtime 0 hr 48.1 min
                 '''

     if 0 and len(context.security_listF) > 0:
         record(stock_traded=len(context.security_listF))
         record(vix=context.vix)

     track_orders(context, data)

def record_vars(context, data):
    for s in context.portfolio.positions:
        cp = data.current(s,'price')
        #ma = data.history(s,'price',20,'1d').mean()
        amt = context.portfolio.positions[s].amount
        #cb =  context.portfolio.positions[s].cost_basis
        if (cp * .97) > context.trail[s] and amt > 0:
            context.trail[s] = (cp * .97)
            order_target(s,0,style=StopOrder(context.trail[s]))
        if context.vix > context.vl and amt > 0:
            order_target(s,0)

    #record(cash=context.portfolio.cash)
    #record(leverage=context.account.leverage)

    track_orders(context, data)

class GetVIX(CustomFactor):
    window_length = 1
    def compute(self, today, assets, out, vix):
        out[:] = vix[-1]

def cancel_oos(context, data):
    oo = get_open_orders()
    for s in oo:
        for o in oo[s]: cancel_order(o.id)

def pvr(context, data):
    ''' Custom chart and/or logging of profit_vs_risk returns and related information
    '''
    import time
    from datetime import datetime
    from pytz import timezone      # Python will only do once, makes this portable.
                                   #   Move to top of algo for better efficiency.
    c = context  # Brevity is the soul of wit -- Shakespeare [for readability]
    if 'pvr' not in c:

        # For real money, you can modify this to total cash input minus any withdrawals
        manual_cash = c.portfolio.starting_cash
        time_zone   = 'US/Pacific'   # Optionally change to your own time zone for wall clock time

        c.pvr = {
            'options': {
                # # # # # # # # # #  Options  # # # # # # # # # #
                'logging'         : 0,    # Info to logging window with some new maximums
                'log_summary'     : 126,  # Summary every x days. 252/yr

                'record_pvr'      : 1,    # Profit vs Risk returns (percentage)
                'record_pvrp'     : 0,    # PvR (p)roportional neg cash vs portfolio value
                'record_cash'     : 0,    # Cash available
                'record_max_lvrg' : 1,    # Maximum leverage encountered
                'record_max_risk' : 0,    # Highest risk overall
                'record_shorting' : 0,    # Total value of any shorts
                'record_max_shrt' : 1,    # Max value of shorting total
                'record_cash_low' : 1,    # Any new lowest cash level
                'record_q_return' : 0,    # Quantopian returns (percentage)
                'record_pnl'      : 0,    # Profit-n-Loss
                'record_risk'     : 0,    # Risked, max cash spent or shorts beyond longs+cash
                'record_leverage' : 1,    # End of day leverage (context.account.leverage)
                # All records are end-of-day or the last data sent to chart during any day.
                # The way the chart operates, only the last value of the day will be seen.
                # # # # # # # # #  End options  # # # # # # # # #
            },
            'pvr'        : 0,      # Profit vs Risk returns based on maximum spent
            'cagr'       : 0,
            'max_lvrg'   : 0,
            'max_shrt'   : 0,
            'max_risk'   : 0,
            'days'       : 0.0,
            'date_prv'   : '',
            'date_end'   : get_environment('end').date(),
            'cash_low'   : manual_cash,
            'cash'       : manual_cash,
            'start'      : manual_cash,
            'tz'         : time_zone,
            'begin'      : time.time(),  # For run time
            'run_str'    : '{} to {}  ${}  {} {}'.format(get_environment('start').date(), get_environment('end').date(), int(manual_cash), datetime.now(timezone(time_zone)).strftime("%Y-%m-%d %H:%M"), time_zone)
        }
        if c.pvr['options']['record_pvrp']: c.pvr['options']['record_pvr'] = 0 # if pvrp is active, straight pvr is off
        if get_environment('arena') not in ['backtest', 'live']: c.pvr['options']['log_summary'] = 1 # Every day when real money
        log.info(c.pvr['run_str'])
    p = c.pvr ; o = c.pvr['options'] ; pf = c.portfolio ; pnl = pf.portfolio_value - p['start']
    def _pvr(c):
        p['cagr'] = ((pf.portfolio_value / p['start']) ** (1 / (p['days'] / 252.))) - 1
        ptype = 'PvR' if o['record_pvr'] else 'PvRp'
        log.info('{} {} %/day   cagr {}   Portfolio value {}   PnL {}'.format(ptype, '%.4f' % (p['pvr'] / p['days']), '%.3f' % p['cagr'], '%.0f' % pf.portfolio_value, '%.0f' % pnl))
        log.info('  Profited {} on {} activated/transacted for PvR of {}%'.format('%.0f' % pnl, '%.0f' % p['max_risk'], '%.1f' % p['pvr']))
        log.info('  QRet {} PvR {} CshLw {} MxLv {} MxRisk {} MxShrt {}'.format('%.2f' % (100 * pf.returns), '%.2f' % p['pvr'], '%.0f' % p['cash_low'], '%.2f' % p['max_lvrg'], '%.0f' % p['max_risk'], '%.0f' % p['max_shrt']))
    def _minut():
        dt = get_datetime().astimezone(timezone(p['tz']))
        return str((dt.hour * 60) + dt.minute - 570).rjust(3)  # (-570 = 9:31a)
    date = get_datetime().date()
    if p['date_prv'] != date:
        p['date_prv'] = date
        p['days'] += 1.0
    do_summary = 0
    if o['log_summary'] and p['days'] % o['log_summary'] == 0 and _minut() == '100':
        do_summary = 1              # Log summary every x days
    if do_summary or date == p['date_end']:
        p['cash'] = pf.cash
    elif p['cash'] == pf.cash and not o['logging']: return  # for speed

    shorts = sum([z.amount * z.last_sale_price for s, z in pf.positions.items() if z.amount < 0])
    new_key_hi = 0                  # To trigger logging if on.
    cash       = pf.cash
    cash_dip   = int(max(0, p['start'] - cash))
    risk       = int(max(cash_dip, -shorts))

    if o['record_pvrp'] and cash < 0:   # Let negative cash ding less when portfolio is up.
        cash_dip = int(max(0, cash_dip * p['start'] / pf.portfolio_value))
        # Imagine: Start with 10, grows to 1000, goes negative to -10, should not be 200% risk.

    if int(cash) < p['cash_low']:             # New cash low
        new_key_hi = 1
        p['cash_low'] = int(cash)             # Lowest cash level hit
        if o['record_cash_low']: record(CashLow = p['cash_low'])

    if c.account.leverage > p['max_lvrg']:
        new_key_hi = 1
        p['max_lvrg'] = c.account.leverage    # Maximum intraday leverage
        if o['record_max_lvrg']: record(MxLv    = p['max_lvrg'])

    if shorts < p['max_shrt']:
        new_key_hi = 1
        p['max_shrt'] = shorts                # Maximum shorts value
        if o['record_max_shrt']: record(MxShrt  = p['max_shrt'])

    if risk > p['max_risk']:
        new_key_hi = 1
        p['max_risk'] = risk                  # Highest risk overall
        if o['record_max_risk']:  record(MxRisk = p['max_risk'])

    # Profit_vs_Risk returns based on max amount actually invested, long or short
    if p['max_risk'] != 0: # Avoid zero-divide
        p['pvr'] = 100 * pnl / p['max_risk']
        ptype = 'PvRp' if o['record_pvrp'] else 'PvR'
        if o['record_pvr'] or o['record_pvrp']: record(**{ptype: p['pvr']})

    if o['record_shorting']: record(Shorts = shorts)             # Shorts value as a positve
    if o['record_leverage']: record(Lv     = c.account.leverage) # Leverage
    if o['record_cash']    : record(Cash   = cash)               # Cash
    if o['record_risk']    : record(Risk   = risk)  # Amount in play, maximum of shorts or cash used
    if o['record_q_return']: record(QRet   = 100 * pf.returns)
    if o['record_pnl']     : record(PnL    = pnl)                # Profit|Loss

    if o['logging'] and new_key_hi:
        log.info('{}{}{}{}{}{}{}{}{}{}{}{}'.format(_minut(),
            ' Lv '     + '%.1f' % c.account.leverage,
            ' MxLv '   + '%.2f' % p['max_lvrg'],
            ' QRet '   + '%.1f' % (100 * pf.returns),
            ' PvR '    + '%.1f' % p['pvr'],
            ' PnL '    + '%.0f' % pnl,
            ' Cash '   + '%.0f' % cash,
            ' CshLw '  + '%.0f' % p['cash_low'],
            ' Shrt '   + '%.0f' % shorts,
            ' MxShrt ' + '%.0f' % p['max_shrt'],
            ' Risk '   + '%.0f' % risk,
            ' MxRisk ' + '%.0f' % p['max_risk']
        ))
    if do_summary: _pvr(c)
    if get_datetime() == get_environment('end'):   # Summary at end of run
        _pvr(c) ; elapsed = (time.time() - p['begin']) / 60  # minutes
        log.info( '{}\nRuntime {} hr {} min'.format(p['run_str'], int(elapsed / 60), '%.1f' % (elapsed % 60)))

def track_orders(context, data):
    '''  Show orders when made and filled.
           Info: https://www.quantopian.com/posts/track-orders
    '''
    c = context
    if 'trac' not in c:
        c.t_options = {           # __________    O P T I O N S    __________
            'log_neg_cash': 1,    # Show cash only when negative.
            'log_cash'    : 0,    # Show cash values in logging window or not.
            'log_ids'     : 0,    # Include order id's in logging window or not.
            'log_unfilled': 1,    # When orders are unfilled. (stop & limit excluded).
        }    # Move these to initialize() for better efficiency.
        c.trac = {}
        c.t_dates  = {  # To not overwhelm the log window, start/stop dates can be entered.
            'active': context.track_active,

            # for "Runaway Leverage - Momentum Strat ..."
            'start' :  context.track_start,
            'stop'  :  context.track_stop,


            #'start' : [],   # Start dates, option like ['2007-05-07', '2010-04-26']
            #'stop'  : []    # Stop  dates, option like ['2008-02-13', '2010-11-15']
        }
    from pytz import timezone     # Python only does once, makes this portable.
                                  #   Move to top of algo for better efficiency.
    # If 'start' or 'stop' lists have something in them, triggers ...
    if c.t_dates['start'] or c.t_dates['stop']:
        date = str(get_datetime().date())
        if   date in c.t_dates['start']:    # See if there's a match to start
            c.t_dates['active'] = 1
        elif date in c.t_dates['stop']:     #   ... or to stop
            c.t_dates['active'] = 0
    else: c.t_dates['active'] = 1           # Set to active b/c no conditions.
    if c.t_dates['active'] == 0: return     # Skip if not active.
    def _minute():   # To preface each line with the minute of the day.
        bar_dt = get_datetime().astimezone(timezone('US/Eastern'))
        return str((bar_dt.hour * 60) + bar_dt.minute - 570).rjust(3) # (-570 = 9:31a)
    def _trac(to_log):      # So all logging comes from the same line number,
        log.info(to_log)    #   for vertical alignment in the logging window.

    for oid in c.trac.copy():               # Existing known orders
      o = get_order(oid)
      c.trac[o.id]['cb'] = c.portfolio.positions[o.sid].cost_basis \
            if c.portfolio.positions[o.sid].cost_basis else c.trac[o.id]['cb']
      if o.dt == o.created: continue        # No chance of fill yet.
      cash = ''
      if (c.t_options['log_neg_cash'] and c.portfolio.cash < 0) or c.t_options['log_cash']:
        cash = 'cash {}'.format(int(c.portfolio.cash))
      if o.status == 2:                     # Canceled
        prc = '%.2f' % data.current(o.sid, 'price') if data.can_trade(o.sid) else 'unknwn'
        do  = 'Buy' if o.amount > 0 else 'Sell' ; style = ''
        if o.stop:
          style = ' stop {}'.format(o.stop)
          if o.limit: style = ' stop {} limit {}'.format(o.stop, o.limit)
        elif o.limit: style = ' limit {}'.format(o.limit)
        _trac(' {}     Canceled {} {} {}{} at {}   {}  {}'.format(_minute(), do, o.amount,
           o.sid.symbol, style, prc, cash, o.id[-4:] if c.t_options['log_ids'] else ''))
        del c.trac[o.id]
      elif o.filled:                        # Filled at least some.
        filled = '{}'.format(o.amount)
        filled_amt = 0
        if o.filled == o.amount:            # Complete
          if 0 < c.trac[o.id]['amnt'] < o.amount:
            filled   = 'all {}/{}'.format(o.filled - c.trac[o.id]['amnt'], o.amount)
          filled_amt = o.filled
        else:                               # ['amnt'] is previously filled total
          filled_amt = o.filled - c.trac[o.id]['amnt']   # filled this time, can be 0
          c.trac[o.id]['amnt'] = o.filled                # save for increments math
          filled = '{}/{}'.format(filled_amt, o.amount)
        if filled_amt:
          prc = c.portfolio.positions[o.sid].last_sale_price if o.sid in c.portfolio.positions else 'unknwn'
          prc = data.history(o.sid, 'price', 1, '1d')[-1] if prc is 'unknwn' else prc
          now = ' ({})'.format(c.portfolio.positions[o.sid].amount) \
                      if c.portfolio.positions[o.sid].amount else ' _'
          pnl = ''  # for the trade only
          amt = c.portfolio.positions[o.sid].amount ; style = ''
          if (amt - o.filled) * o.filled < 0:  # Profit-taking scenario including short-buyback
            if c.trac[o.id]['cb']:
              pnl  = -filled_amt * (prc - c.trac[o.id]['cb'])
              sign = '+' if pnl > 0 else '-'
              pnl  = '  ({}{})'.format(sign, '%.0f' % abs(pnl))
          if o.stop:
            style = ' stop {}'.format(o.stop)
            if o.limit: style = ' stop () limit {}'.format(o.stop, o.limit)
          elif o.limit: style = ' limit {}'.format(o.limit)
          if o.filled == o.amount: del c.trac[o.id]
          _trac(' {}      {} {} {}{} at {}{}{}'.format(_minute(),
            'Bot' if o.amount > 0 else 'Sold', filled, o.sid.symbol, now,
            '%.2f' % prc, pnl, style).ljust(52) + \
            '  {}  {} lv {}'.format(cash, o.id[-4:] if c.t_options['log_ids'] else '', '%.1f' % c.account.leverage))
      elif c.t_options['log_unfilled'] and not (o.stop or o.limit):
        _trac(' {}         {} {}{} unfilled  {}'.format(_minute(), o.sid.symbol, o.amount,
         ' limit' if o.limit else '', o.id[-4:] if c.t_options['log_ids'] else ''))

    oo = get_open_orders().values()
    if not oo: return                       # Handle new orders
    cash = ''
    if (c.t_options['log_neg_cash'] and c.portfolio.cash < 0) or c.t_options['log_cash']:
      cash = 'cash {}'.format(int(c.portfolio.cash))
    for oo_list in oo:
      for o in oo_list:
        if o.id in c.trac: continue         # Only new orders beyond this point
        prc  = '%.2f' % data.current(o.sid, 'price') if data.can_trade(o.sid) else 'unknwn'
        c.trac[o.id] = {'amnt': 0, 'cb': 0} ; style = ''
        now  = ' ({})'.format(c.portfolio.positions[o.sid].amount) \
                    if c.portfolio.positions[o.sid].amount else ' _'
        if o.stop:
          style = ' stop {}'.format(o.stop)
          if o.limit: style = ' stop {} limit {}'.format(o.stop, o.limit)
        elif o.limit: style = ' limit {}'.format(o.limit)
        _trac(' {}   {} {} {}{} at {}{}'.format(_minute(), 'Buy' if o.amount > 0 else 'Sell',
          o.amount, o.sid.symbol, now, prc, style).ljust(52) + \
           '  {}  {}'.format(cash, o.id[-4:] if c.t_options['log_ids'] else ''))

def handle_data(context, data):
    pvr(context, data)
    track_orders(context, data)

There was a runtime error.

I was able to answer my own question, fix and recompose the algorithm using somewhat of a different entry/exit strategy. I'm still trading the DOW, now with leverage consistently under 2, but I'm able to get a return of 7000%, roughly 1/4 of the original I posted, but still 70 times the investment. That's basically 5 times your money, per year trading the safest stocks on the exchange. And since I'm going long, I can do this all through Robin Hood. I have to say I'm a bit disappointed that I didn't see many more answers on this one, but I was able to figure out what I needed anyway.

great, can you post the algo?

(on a side note) Sorry dont want to highjack the tread but i just wanted this to be addressed:

It might be problematic to do a back test of the current constituents of the DOW (as companies are added to the index over time), this could introduce a source of hind sight bias (since companies that got added tend to have outperformed those that got removed).

Again, sorry for potentially high jacking the thread.

Irrelevant in the big scheme of things. If you want to code for that, I seriously doubt you would see a huge difference. The stocks in the DOW and S&P500 serve as essentially a market baseline. In addition, most brokers will allow you a 2:1 margin on these stocks, essentially allowing you to double the profit on any algorithm. I personally don't even use the DOW anymore, though I did figure out how to control leverage and yield 85 times the investment over 14 years, using margin. That said, I have created a penny stock algorithm that which yields $70,000,000 on $1000 invested over 14 years, with a max draw down of 55% in 2008, which can be run in Robin Hood, using settled funds. I could care less about the DOW at this point. What I do not like about this platform is the one minute intervals, and I'm looking into QuantConnect at the moment. I simply need more granularity on stops when trading low floats.

L. Williams,

Can you please post the backtest that you achieved the 7000% mark on? Also, are you currently live-trading this on Robinhood?

Thanks,
Kern