Back to Community
playing jnug/jdst with 257% return in two years

EMA strategy is used. I am still improving this algo.
Intraday trade only, no margin usage, and maximal 8 transaction allowed in one day.
Any comment is welcomed.

Clone Algorithm
230
Loading...
Backtest from to with initial capital
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
import talib
import pytz
from datetime import datetime, timedelta

def initialize(context):   
    set_long_only()

    # set a fixed slippage
    set_slippage(slippage.FixedSlippage(spread=0.01))
    set_commission(commission.PerShare(cost=0, min_trade_cost=0))
    
    context.gdxj = sid(32133) #  (gdxj)
    context.jnug = sid(45570) #  (jnug)
    context.jdst = sid(45571) #  (jdst) 
    
    context.EMA_period_minute = 300
    context.EMA_period_day = 20

    context.low_volatility_threshold = 0.02
    context.order_value = 40000
    context.day_loss_limit = 3000
    context.ratio_of_all_cash_per_trade = 0.8
    context.fixed_order_value = 40000
    context.use_fixed_order_value = False
    context.is_previous_day_reach_loss_limit = False
    context.loss_limit_reach_rest = False
    
    context.day_ema_list=[0,0,0,0,0,0]
    context.day_ema_index = 0
    
    # Define our flag for when we are finished trading for the day.
    context.end_of_day = False
    
    #How many minutes before market close should we close all positions?
    context.close_time = 5
    
    context.day_trade_num_limit = 5 #Day trade number limit, if too frequency trade was conduct, that means there is no momentum in the trend, let stop trade today
    
    context.day_trade_count = 0
    
    context.start_value_per_day = context.portfolio.portfolio_value
    
    #Trade prohibit timer after one trade in minutes, for long mintues EMA, we does not expect two many flip within short time
    context.trade_prohibit_timer = 30
    
    #Last buy trade time
    context.last_buy_trade_time = get_datetime().astimezone(pytz.timezone('US/Pacific'))
    context.current_time = get_datetime().astimezone(pytz.timezone('US/Pacific'));
    #Schedule a function to set our flag to stop trading 2 minutes before our close position function. Since scheduled functions run after handle_data this will allow orders to be placed in the same minute that stop_trading runs, but not the next minute.
    schedule_function(stop_trading, date_rules.every_day(), time_rules.market_close(minutes=context.close_time + 2))
        
    #Schedule a function to close all positions and finish trading for the day at the defined number of minutes before market close. 
    schedule_function(close_positions, date_rules.every_day(), time_rules.market_close(minutes=context.close_time))
    
    #Schedule a function to set our flag to begin trading at the start of each day
    schedule_function(start_trading, date_rules.every_day(), time_rules.market_open(minutes=10))
                    
#Run every minute.
def handle_data(context, data):
    context.current_time = get_datetime().astimezone(pytz.timezone('US/Pacific'));
        
    #Check for open orders first. If orders are pending we can't do anything yet. Also check our flag to see if we've closed our positions for the day.
    if not get_open_orders() and not context.end_of_day and get_time_diff_in_minutes(context.last_buy_trade_time, context.current_time) \
        >= context.trade_prohibit_timer:
        #Calculate EMA values. We need the last value in the array that EMA generates, which is provided by the [-1] at the end.
        jnug_EMA = talib.EMA(data.history(context.jnug, "price", context.EMA_period_minute, frequency="1m"), timeperiod=context.EMA_period_minute)[-1]
        jdst_EMA = talib.EMA(data.history(context.jdst, "price", context.EMA_period_minute, frequency="1m"), timeperiod=context.EMA_period_minute)[-1]
        #If the current price of jnug is greater than the EMA order 95% of our available cash
        if data.current(context.jnug, 'price') > jnug_EMA and context.jnug not in context.portfolio.positions :
            #Before we can order jnug we must close any position in jdst, and we can only order jnug after the sale has completed
            if context.jdst in context.portfolio.positions:
                order_target(context.jdst, 0)
            else:
                order_target_value(context.jnug, context.order_value)
                context.day_trade_count = context.day_trade_count + 1
                context.last_buy_trade_time = context.current_time
        #Inverse of the previous situation
        elif data.current(context.jdst, 'price') > jdst_EMA and context.jdst not in context.portfolio.positions:
            if context.jnug in context.portfolio.positions:
                order_target(context.jnug, 0)
            else:
                order_target_value(context.jdst, context.order_value)
                context.day_trade_count = context.day_trade_count + 1
                context.last_buy_trade_time = context.current_time
                
    if context.day_trade_count >= context.day_trade_num_limit:
        context.end_of_day = True

    check_daily_loss_limit(context, data)
    
#Close all positions and disable trading for today. This is scheduled to run each day 5 minutes before market close.
def close_positions(context, data):
    #Close positions
    if context.jdst in context.portfolio.positions:
                order_target(context.jdst, 0)
    if context.jnug in context.portfolio.positions:
                order_target(context.jnug, 0)

def check_daily_loss_limit(context, data) :
    if context.start_value_per_day > context.portfolio.portfolio_value and \
    context.start_value_per_day - context.portfolio.portfolio_value >= context.day_loss_limit :
        close_positions(context, data)
        context.is_previous_day_reach_loss_limit = True
        context.end_of_day = True
        
#Set our flag to allow trading at the beginning of the day .
def start_trading(context, data):
    context.end_of_day = False
    context.day_trade_count = 0
    context.start_value_per_day = context.portfolio.portfolio_value
    context.last_buy_trade_time = get_datetime().astimezone(pytz.timezone('US/Pacific'));
    context.day_ema_list[context.day_ema_index] = talib.EMA(data.history(context.gdxj, "price", context.EMA_period_day, frequency="1d"), timeperiod=context.EMA_period_day)[-1]
    price_distance_percent_with_day_ema = 2 * abs(context.day_ema_list[context.day_ema_index] - context.day_ema_list[(context.day_ema_index + 1) % 6]) /  \
        (context.day_ema_list[context.day_ema_index] + context.day_ema_list[(context.day_ema_index + 1) % 6])
    
    # Low Volatility, better not to trade at this time
    if price_distance_percent_with_day_ema <= context.low_volatility_threshold :
        context.end_of_day = True
        
    if context.use_fixed_order_value == True :
        context.order_value = context.fixed_order_value
    else:
        context.order_value = context.portfolio.portfolio_value * context.ratio_of_all_cash_per_trade
    if context.loss_limit_reach_rest == True :
        if context.is_previous_day_reach_loss_limit == True:
            context.end_of_day = True
            context.is_previous_day_reach_loss_limit = False
        
#Set our flag to stop trading for the day.
def stop_trading(context, data):
    context.end_of_day = True
    context.day_ema_index = (context.day_ema_index + 1) % 6
    
#Get the time difference in minutes
def get_time_diff_in_minutes(oldtime, newtime):
    if oldtime.hour <= 6 : 
        return 100
    time_diff = newtime.minute + (newtime.hour-oldtime.hour) * 60 - oldtime.minute
    return time_diff
There was a runtime error.
10 responses

Have you live traded this? If so what was your experience? I am working on a JNUG and JDST daytrading algo myself.

Best,
Need4Greed

I tried trading a variant of ths, but somehow he executions I got were not like the backtest. Happy to collaborate on something Gold.. I have a few algo's that did not stand the test of time as the market changed a few times radically

Gotcha. I'd be happy to tell you the strategy I'm working on, I think you could help. I know it works every day over the past two months based on Yahoo finance data (all I have free access to) and hope to backtest further with quantopian.

If you look at JNUG and JDST over the past two months, every day in the mornings they either slope steeply upward or downward. I believe this is due to the unusually high trading volumes that occur in the morning. I have manually backtested a strategy that buys either JNUG or JDST when it moves .6% above open price, and to start protecting gains when it moves .7% above that buy price. I have paper-traded it for a while and it has worked great, but I'm having some issues with the code. Want to help? I'm happy to send you screenshots of the chart trends I've noticed.

happy to help, send me the screenshots and or Quantopian code you have so far

I attached the code. Haven't looked at JDST or trailing stops yet. Would like to send you a picture I marked up to help you visualize the strategy but don't know the best way to do so.

Clone Algorithm
6
Loading...
Backtest from to with initial capital
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
def initialize(context):
    context.jnug=sid(45570)
    # sets global variable context.jnug equal to the ETF we want to trade
    context.open_orders = get_open_orders()
    # sets this global variable equal to a data frame with info about orders we have made (purchases we still hold, I think)
    context.i = 0
    # This supposedly global variable is used for my program logic. It starts as 0. When a purchase is made, it equals 1.
    set_slippage(slippage.FixedSlippage(spread=0.00))
    # ETFs track an index, so my purchases cannot affect the ETF's price. The ETF price changes as the index changes.
    
    for minute1 in range(1, 2, 1):
        # Runs a function that gets the open price of the ETF JNUG every minute in first 1 minute (once per day, first minute)
        schedule_function(GoldOpen,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute1),half_days=False)
    
    for minute2 in range(1, 45, 1):
        # Runs a function that looks for a buy point and acts on it every minute in first 45 minutes (only want early morning buys!)
        schedule_function(BuyGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute2),half_days=False)
    
    for minute3 in range(1, 385, 1):
        # Runs every minute up until 3:55: checks to see if the initial stop loss was ever hit
        schedule_function(InitialStop,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute3),half_days=False)
    
    for minute4 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        schedule_function(SellGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute4),half_days=False)
    
    for minute6 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        schedule_function(RecordTransactions,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute6),half_days=False)
        
    for minute5 in range(385, 390, 1):
        # Runs every minute in last 5 minutes of the day, checks if I still have any JNUG shares and then sells them.
        schedule_function(EndDaySell,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute5),half_days=False)
    
def before_trading_start(context, data):
    context.i = 0
    print('context.i reset to %.5f') % (context.i)

def GoldOpen(context, data):
    context.jnugOpen=data.history(sid(45570), 'open', 1, '1m')[-1]
    # stores the open price of JNUG at 9:31
    context.jnugBuy = 1.006*context.jnugOpen
    context.jnugStop = .999*context.jnugOpen
    context.jnugProfit = 1.009*context.jnugBuy
    # global variables that store values where we want to buy and sell
    print('JNUG open price: %.5f') % (context.jnugOpen)
    

def BuyGold(context, data):
    if context.i == 0:
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        if context.jnug not in get_open_orders() and data.can_trade(sid(45570))==True:
            context.jnugCurrent = data.current(context.jnug,'price')
            if context.jnugCurrent >= context.jnugBuy and context.jnugCurrent <= context.jnugOpen*1.008: # don't want to buy overextended!
                context.jnug_id = order_percent(sid(45570), 1, style=LimitOrder(context.jnugBuy))
                # does this mean I can reference this order now? If I use context.jnug_id again will it order again? (I don't want that)
                record(leverage = context.account.leverage)
                print('Bought for %.5f!') % (context.jnugCurrent)
                context.i += 1
                # prevents this function from running again today
                print('context.i = %.5f') % (context.i)
                my_JNUG_amount = context.portfolio.positions[context.jnug].amount
                print('Amount bought: %s') % (my_JNUG_amount)
                # confirms the context.i variable was changed
                print(context.i == 1)
                # verifies the change
                print('Order ID: %s') % (get_order(context.jnug_id))   

def InitialStop(context, data):
    if context.i == 1:
        context.jnugCurrent = data.current(context.jnug,'price')
        print('context.i worked!')
        # shows my program logic is working
        context.open_orders = get_open_orders()
        # line below makes sure this function only runs when a purchase has been made already
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if get_order(context.jnug_id).status == 1: # ensures the sell function only runs if my original buy order was filled, I hope
            print('Order status worked!')
            if context.jnugCurrent == context.jnugOpen or context.jnugCurrent <= context.jnugOpen: # if price is at or below stop loss (open price)
                my_JNUG_amount = context.portfolio.positions[context.jnug].amount
                order_target(context.jnug, -1*my_JNUG_amount, style=LimitOrder(context.jnugBuy))
                print('JNUG sold due to initial stop at %.5f') % (context.jnugCurrent)
                print('Amount sold: %s') % (my_JNUG_amount)
                context.i += 1
                # prevents this from running again after a sell has been made
                print('context.i = %.5f') % (context.i)
                
def SellGold(context, data):
    if context.i == 1:
        context.jnugCurrent = data.current(context.jnug,'price')
        context.open_orders = get_open_orders()
    
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if get_order(context.jnug_id).status == 1:
            if context.jnugCurrent >= context.jnugProfit:
                my_JNUG_amount = context.portfolio.positions[context.jnug].amount
                order_target(context.jnug, -1*my_JNUG_amount, style=LimitOrder(context.jnugCurrent))
                print('JNUG sold for profit at %.5f') % (context.jnugCurrent)
                print('Amount sold: %s') % (my_JNUG_amount)
                my_JNUG_amount = 0
                context.i += 1 
                print('context.i = %.5f') % (context.i)                

def RecordTransactions(context, data):
    my_JNUG_amount = context.portfolio.positions[context.jnug].amount
    print('JNUG amount: %s') % (my_JNUG_amount)
    
                
def EndDaySell(context, data):
    if context.i == 1:
        context.jnugCurrent = data.current(context.jnug,'price')
        context.open_orders = get_open_orders()
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if get_order(context.jnug_id).status == 1:
            my_JNUG_amount = context.portfolio.positions[context.jnug].amount
            order_target(context.jnug, -1*my_JNUG_amount, style=LimitOrder(context.jnugCurrent))
            my_JNUG_amount = 0
            print('JNUG sold at end of day for %.5f') % (context.jnugCurrent)
            print('Amount sold: %s') % (my_JNUG_amount)
            context.i += 1
            print('context.i = %.5f') % (context.i)

    
            
        

    
    
There was a runtime error.

Some of the problems I am having:

  • It is buying and selling different amounts, despite what I tried to code
  • Some days it never executes any of the sell functions

Made some major changes to the code and added a trailing stop loss. Can't figure out why my leverage is getting out of control. Do you think these gains are reasonable?

Clone Algorithm
14
Loading...
Backtest from to with initial capital
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
def initialize(context):
    context.jnug=sid(45570)
    # sets global variable context.jnug equal to the ETF we want to trade
    context.i = 0
    # This supposedly global variable is used for my program logic. It starts as 0. When a purchase is made, it equals 1.
    set_slippage(slippage.FixedSlippage(spread=0.00))
    # ETFs track an index, so my purchases cannot affect the ETF's price. The ETF price changes as the index changes.
    
    for minute1 in range(1, 2, 1):
        # Runs a function that gets the open price of the ETF JNUG every minute in first 1 minute (once per day, first minute)
        schedule_function(GoldOpen,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute1),half_days=False)
    
    for minute2 in range(1, 45, 1):
        # Runs a function that looks for a buy point and acts on it every minute in first 45 minutes (only want early morning buys!)
        schedule_function(BuyGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute2),half_days=False)
    
    #for minute3 in range(1, 385, 1):
        # Runs every minute up until 3:55: checks to see if the initial stop loss was ever hit
        #schedule_function(InitialStop,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute3),half_days=False)
    
    #for minute4 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        #schedule_function(SellGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute4),half_days=False)
    
    #for minute6 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        #schedule_function(RecordTransactions,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute6),half_days=False)

    for minute4 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        schedule_function(TrackGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute4),half_days=False)        

    for minute5 in range(375, 390, 1):
        # Runs every minute in last 5 minutes of the day, checks if I still have any JNUG shares and then sells them.
        schedule_function(EndDaySell,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute5),half_days=False)

    for minute7 in range(2, 390, 1):
        # Runs every minute in last 5 minutes of the day, checks if I still have any JNUG shares and then sells them.
        schedule_function(InitialStop,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute7),half_days=False)

    for minute7 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        schedule_function(Trail,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute7),half_days=False)  

def before_trading_start(context, data):
    context.n = 1
    context.i = 0
    context.my_JNUG_amountStart = context.portfolio.positions[context.jnug].amount
    print('my_JNUG_amount reset to %s') % (context.my_JNUG_amountStart)
    print('context.i reset to %.5f') % (context.i)

def GoldOpen(context, data):
    context.jnugOpen=data.history(sid(45570), 'open', 1, '1m')[-1]
    # stores the open price of JNUG at 9:31
    context.jnugBuy = 1.006*context.jnugOpen
    context.jnugStop = .998*context.jnugOpen
    context.jnugTrail = 0
    context.jnugProfit = 1.003*context.jnugBuy
    # global variables that store values where we want to buy and sell
    print('JNUG open price: %.5f') % (context.jnugOpen)
    
def BuyGold(context, data):
    if context.i == 0:
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        if context.jnug not in get_open_orders() and data.can_trade(sid(45570))==True and my_JNUG_amount == context.my_JNUG_amountStart:
            context.jnugCurrent = data.current(context.jnug,'price')
            if context.jnugCurrent >= context.jnugBuy and context.jnugCurrent <= context.jnugOpen*1.008: # don't want to buy overextended!
                context.jnug_id = order_percent(sid(45570), 1, style=LimitOrder(context.jnugBuy))
                # does this mean I can reference this order now? If I use context.jnug_id again will it order again? (I don't want that)
                record(leverage = context.account.leverage)
                print('Bought for %.5f!') % (context.jnugCurrent)
                context.i += 1
                #print('Order ID: %s') % (get_order(context.jnug_id))   

"""def CheckBoughtOrSold(context, data):
    if context.i == 1:
        print(context.portfolio.portfolio_value)
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        if my_JNUG_amount > context.my_JNUG_amountStart:
            print('Shares bought: %s') % (my_JNUG_amount)
        if my_JNUG_amount < context.my_JNUG_amountStart:
            print('Shares sold: %s') % (my_JNUG_amount)   """

def InitialStop(context, data):
    if context.i == 1:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart and get_order(context.jnug_id).status == 1:
            if context.jnugCurrent2 <= context.jnugStop:
                order_percent(context.jnug, -1)
                print('JNUG sold at initial stop for %.5f') % (context.jnugCurrent2)
                print('Amount sold: %s') % (my_JNUG_amount)
                context.i -= 3 
                print('context.i = %.5f') % (context.i)   
     
def TrackGold(context, data):
    if context.i == 1:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart and get_order(context.jnug_id).status == 1:
            if context.jnugCurrent2 >= context.jnugProfit*1.001:
                print('Potential to move up stop')
                context.i += 2 
                print('context.i = %.5f, only for trail function now') % (context.i)   
                
def Trail(context, data):
    if context.i == 3:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart and get_order(context.jnug_id).status == 1:
            if context.jnugCurrent2 <= context.jnugProfit*(1-.004*context.n):
                order_percent(context.jnug, -1)
                print('JNUG reached trail!') % (context.jnugCurrent2)
                print('Amount sold: %s') % (my_JNUG_amount)
                context.i += 1 
                print('context.i = %.5f') % (context.i)   
            
            elif context.jnugCurrent2 >= context.jnugProfit*(1+.002*context.n):
                context.n += 1
                print('Trail moved up!')

def EndDaySell(context, data):
    if context.i == 1 or context.i == 3:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount        
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart:
            print('Trying to sell!')
            order_percent(context.jnug, -1)
            print('JNUG sold at end of day for %.5f') % (context.jnugCurrent)
            print('Amount sold: %s') % (my_JNUG_amount)
            context.i -= 3
            print('context.i = %.5f') % (context.i)
There was a runtime error.

the lverage is going insane and the main reason would be that you try to try the state but do it inaccuately. In principle you dont have to do this: you look in the positions object what you have and cancel all standing orders and then order again. dont try to count as that is too fragile. I ahve added code to track what you're doing but I dont know what the idea behind the algo is so I'm not able to 'fix' it

Clone Algorithm
1
Loading...
Backtest from to with initial capital
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
def initialize(context):
    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'    : 1,    # Show cash values in logging window or not.  
            'log_ids'     : 1,    # 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,  
            'start' : [],   # Start dates, option like ['2007-05-07', '2010-04-26']  
            'stop'  : []    # Stop  dates, option like ['2008-02-13', '2010-11-15']  
        }
        
    # for profit_vs_risk()
    c.max_lvrg = 0
    c.risk_hi  = 0
    c.date_prv = ''
    c.cash_low = c.portfolio.starting_cash
    c.date_end = str(get_environment('end').date())
    log.info('{} to {}  {}  {}'.format(str(get_datetime().date()), c.date_end,
        int(c.cash_low), get_environment('data_frequency')))
    
    context.jnug=sid(45570)
    # sets global variable context.jnug equal to the ETF we want to trade
    context.i = 0
    # This supposedly global variable is used for my program logic. It starts as 0. When a purchase is made, it equals 1.
    set_slippage(slippage.FixedSlippage(spread=0.00))
    # ETFs track an index, so my purchases cannot affect the ETF's price. The ETF price changes as the index changes.
    
    for minute1 in range(1, 2, 1):
        # Runs a function that gets the open price of the ETF JNUG every minute in first 1 minute (once per day, first minute)
        schedule_function(GoldOpen,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute1),half_days=False)
    
    for minute2 in range(1, 45, 1):
        # Runs a function that looks for a buy point and acts on it every minute in first 45 minutes (only want early morning buys!)
        schedule_function(BuyGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute2),half_days=False)
    
    #for minute3 in range(1, 385, 1):
        # Runs every minute up until 3:55: checks to see if the initial stop loss was ever hit
        #schedule_function(InitialStop,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute3),half_days=False)
    
    #for minute4 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        #schedule_function(SellGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute4),half_days=False)
    
    #for minute6 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        #schedule_function(RecordTransactions,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute6),half_days=False)

    for minute4 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        schedule_function(TrackGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute4),half_days=False)        

    for minute5 in range(375, 390, 1):
        # Runs every minute in last 5 minutes of the day, checks if I still have any JNUG shares and then sells them.
        schedule_function(EndDaySell,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute5),half_days=False)

    for minute7 in range(2, 390, 1):
        # Runs every minute in last 5 minutes of the day, checks if I still have any JNUG shares and then sells them.
        schedule_function(InitialStop,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute7),half_days=False)

    for minute7 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        schedule_function(Trail,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute7),half_days=False)  

def before_trading_start(context, data):
    context.n = 1
    context.i = 0
    context.my_JNUG_amountStart = context.portfolio.positions[context.jnug].amount
    print('my_JNUG_amount reset to %s') % (context.my_JNUG_amountStart)
    print('context.i reset to %.5f') % (context.i)

def GoldOpen(context, data):
    context.jnugOpen=data.history(context.jnug, 'open', 1, '1m')[-1]
    # stores the open price of JNUG at 9:31
    context.jnugBuy = 1.006*context.jnugOpen
    context.jnugStop = .998*context.jnugOpen
    context.jnugTrail = 0
    context.jnugProfit = 1.003*context.jnugBuy
    # global variables that store values where we want to buy and sell
    print('JNUG open price: %.5f') % (context.jnugOpen)
    
def BuyGold(context, data):
    if context.i == 0:
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        if not get_open_orders(context.jnug) and data.can_trade(context.jnug) and my_JNUG_amount == context.my_JNUG_amountStart:
            context.jnugCurrent = data.current(context.jnug,'price')
            if context.jnugCurrent >= context.jnugBuy and context.jnugCurrent <= context.jnugOpen*1.008: # don't want to buy overextended!
                context.jnug_id = order_percent(context.jnug, 1.0, style=LimitOrder(context.jnugBuy))
                # does this mean I can reference this order now? If I use context.jnug_id again will it order again? (I don't want that)
                record(leverage = context.account.leverage)
                context.i += 1

"""def CheckBoughtOrSold(context, data):
    if context.i == 1:
        print(context.portfolio.portfolio_value)
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        if my_JNUG_amount > context.my_JNUG_amountStart:
            print('Shares bought: %s') % (my_JNUG_amount)
        if my_JNUG_amount < context.my_JNUG_amountStart:
            print('Shares sold: %s') % (my_JNUG_amount)   """

def InitialStop(context, data):
    if context.i == 1:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart and get_order(context.jnug_id).status == 1:
            if context.jnugCurrent2 <= context.jnugStop:
                order_percent(context.jnug, -1)
                print('JNUG sold at initial stop for %.5f') % (context.jnugCurrent2)
                print('Amount sold: %s') % (my_JNUG_amount)
                context.i -= 3 
                print('context.i = %.5f') % (context.i)   
     
def TrackGold(context, data):
    if context.i == 1:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart and get_order(context.jnug_id).status == 1:
            if context.jnugCurrent2 >= context.jnugProfit*1.001:
                print('Potential to move up stop')
                context.i += 2 
                #print('context.i = %.5f, only for trail function now') % (context.i)   
                
def Trail(context, data):
    if context.i == 3:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart and get_order(context.jnug_id).status == 1:
            if context.jnugCurrent2 <= context.jnugProfit*(1-.004*context.n):
                context.open_orders = get_open_orders(context.jnug)
                for ii in context.open_orders:
                    cancel_order(ii)
                order_percent(context.jnug, -1.0)
                print('JNUG reached trail!') % (context.jnugCurrent2)
                print('Amount sold: %s') % (my_JNUG_amount)
                context.i += 1 
                print('context.i = %.5f') % (context.i)   
            
            elif context.jnugCurrent2 >= context.jnugProfit*(1+.002*context.n):
                context.n += 1
                #print('Trail moved up!')

def EndDaySell(context, data):
    if context.i == 1 or context.i == 3:
        context.jnugCurrent2 = data.history(context.jnug, 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders(context.jnug)
        for ii in context.open_orders:
            cancel_order(ii)
        #print('Trying to sell!')
        order_percent(context.jnug, -1.0)
       # print('JNUG sold at end of day for %.5f') % (context.jnugCurrent)
       # print('Amount sold: %s') % (my_JNUG_amount)
        context.i -= 3
        #print('context.i = %.5f') % (context.i)
            
            
            
def handle_data(context, data):  
    track_orders(context, data)
    profit_vs_risk(context, data)

def profit_vs_risk(context, data):
    ''' Custom chart and/or log of profit_vs_risk returns and related information
    '''
    # # # # # # # # # #  Options  # # # # # # # # # #
    record_max_lvrg = 1          # Maximum leverage encountered
    record_leverage = 1          # Leverage (context.account.leverage)
    record_q_return = 0          # Quantopian returns (percentage)
    record_profit_vs_risk      = 0         # Profit vs Risk returns (percentage)
    record_pnl      = 1          # Profit-n-Loss
    record_shorting = 1          # Total value of any shorts
    record_risk     = 0          # Risked, maximum cash spent or shorts in excess of cash at any time
    record_risk_hi  = 0          # Highest risk overall
    record_cash     = 0          # Cash available
    record_cash_low = 0          # Any new lowest cash level
    logging         = 1          # Also log to the logging window conditionally (1) or not (0)
    log_method      = 'daily'  # 'daily' or 'risk_hi'

    c = context                          # For brevity
    new_cash_low = 0                     # To trigger logging in cash_low case
    date = str(get_datetime().date())    # To trigger logging in daily case
    cash = c.portfolio.cash

    if int(cash) < c.cash_low:    # New cash low
        new_cash_low = 1
        c.cash_low   = int(cash)
        if record_cash_low:
            record(CashLow = int(c.cash_low))

    profit_vs_risk_rtrn      = 0        # Profit vs Risk returns based on maximum spent
    profit_loss   = 0        # Profit-n-loss
    shorts        = 0        # Shorts value
    start         = c.portfolio.starting_cash
    cash_dip      = int(max(0, start - cash))

    if record_cash:
        record(Cash = int(c.portfolio.cash))  # Cash

    if record_leverage:
        record(Lvrg = c.account.leverage)     # Leverage

    if record_max_lvrg:
        if c.account.leverage > c.max_lvrg:
            c.max_lvrg = c.account.leverage
            record(MaxLv = c.max_lvrg)        # Maximum leverage

    if record_pnl:
        profit_loss = c.portfolio.pnl
        record(PnL = profit_loss)             # "Profit and Loss" in dollars

    for p in c.portfolio.positions:
        shrs = c.portfolio.positions[p].amount
        if shrs < 0:
            shorts += int(abs(shrs * data.current([p],'price')))

    if record_shorting:
        record(Shorts = shorts)               # Shorts value as a positve

    risk = int(max(cash_dip, shorts))
    if record_risk:
        record(Risk = risk)                   # Amount in play, maximum of shorts or cash used

    new_risk_hi = 0
    if risk > c.risk_hi:
        c.risk_hi = risk
        new_risk_hi = 1

        if record_risk_hi:
            record(RiskHi = c.risk_hi)        # Highest risk overall

    if record_profit_vs_risk:      # Profit_vs_Risk returns based on max amount actually spent (risk high)
        if c.risk_hi != 0:     # Avoid zero-divide
            profit_vs_risk_rtrn = 100 * (c.portfolio.portfolio_value - start) / c.risk_hi
            record(profit_vs_risk = profit_vs_risk_rtrn)            # Profit_vs_Risk returns

    q_rtrn = 100 * (c.portfolio.portfolio_value - start) / start
    if record_q_return:
        record(QRet = q_rtrn)                 # Quantopian returns to compare to profit_vs_risk returns curve

    from pytz import timezone
    if logging:
        if log_method == 'risk_hi' and new_risk_hi \
          or log_method == 'daily' and c.date_prv != date \
          or c.date_end == date \
          or new_cash_low:
            qret   = 'QRet '    + '%.1f' % q_rtrn
            mxlv   = 'MaxLv '   + '%.1f' % c.max_lvrg   if record_max_lvrg else ''
            profit_vs_risk    = 'profit_vs_risk '     + '%.1f' % profit_vs_risk_rtrn     if record_profit_vs_risk      else ''
            pnl    = 'PnL '     + '%.0f' % profit_loss  if record_pnl      else ''
            csh    = 'Cash '    + '%.0f' % cash         if record_cash     else ''
            csh_lw = 'CshLw '   + '%.0f' % c.cash_low   if record_cash_low else ''
            shrt   = 'Shrt '    + '%.0f' % shorts       if record_shorting else ''
            risk   = 'Risk '    + '%.0f' % risk         if record_risk     else ''
            rsk_hi = 'RskHi '   + '%.0f' % c.risk_hi    if record_risk_hi  else ''
            minute = get_datetime().astimezone(timezone('US/Eastern')).time().minute
            log.info('{} {} {} {} {} {} {} {} {} {}'.format(
                    minute, mxlv, qret, profit_vs_risk, pnl, csh, csh_lw, shrt, risk, rsk_hi))

    if c.date_end == date:    # Log on last day, like cash 125199  portfolio 126890
        log.info('cash {}  portfolio {}'.format(
                int(cash), int(c.portfolio.portfolio_value)))

    c.date_prv = date
def track_orders(context, data):  
    '''  Show orders when made and filled.  
           Info: https://www.quantopian.com/posts/track-orders  
    '''  
    c = context  
    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)  
      if o.dt == o.created: continue        # No chance of fill yet.  
      cash = ''  
      prc  = data.current(o.sid, 'price') if data.can_trade(o.sid) else c.portfolio.positions[o.sid].last_sale_price  
      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  
        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.status == 1:            # Complete  
          if 0 < c.trac[o.id] < o.amount:  
            filled   = 'all {}/{}'.format(o.filled - c.trac[o.id], o.amount)  
          filled_amt = o.filled  
        else:                                    # c.trac[o.id] value is previously filled total  
          filled_amt = o.filled - c.trac[o.id]   # filled this time, can be 0  
          c.trac[o.id] = o.filled                # save fill value for increments math  
          filled = '{}/{}'.format(filled_amt, o.amount)  
        if filled_amt:  
          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  
            cb = c.portfolio.positions[o.sid].cost_basis  
            if cb:  
              pnl  = -filled_amt * (prc - 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) + '  {}  {}'.format(cash, o.id[-4:] if c.t_options['log_ids'] else ''))  
      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 = data.current(o.sid, 'price') if data.can_trade(o.sid) else c.portfolio.positions[o.sid].last_sale_price  
        c.trac[o.id] = 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, '%.2f' % prc, style).ljust(52) + '  {}  {}'.format(cash, o.id[-4:] if c.t_options['log_ids'] else ''))
There was a runtime error.

Thanks for adding those tools.

An interesting case for seeing leverage move with changes in short share price. The column after INFO below is minute of the day. On the last line, price went from 81.11 to 100.94 and leverage (the number before cash) correspondingly from 2.48 to 7.85.

2016-04-06 12:45 _trac:231 INFO  375   Sell -173 JNUG (-177.0) at 76.54               1.02  cash 26848  47b0  
2016-04-06 12:46 _trac:231 INFO  376      Sold -173 JNUG (-350.0) at 76.44            2.01  cash 40070  47b0  
2016-04-07 06:31 _trac:231 INFO    1   Buy 138 JNUG (-350.0) at 81.96 limit 81.81     2.52  cash 40070  2073  
2016-04-07 07:40 _trac:231 INFO   70      Bot 138 JNUG (-212.0) at 81.68  (-1165) limit 81.81  1.51  cash 28798  2073  
2016-04-07 07:46 _trac:231 INFO   76   Sell -143 JNUG (-212.0) at 81.01               1.48  cash 28798  b2e4  
2016-04-07 07:47 _trac:231 INFO   77      Sold -143 JNUG (-355.0) at 81.11            2.48  cash 40396  b2e4  
2016-04-11 06:34 _trac:231 INFO    4   Buy 45 JNUG (-355.0) at 100.94 limit 100.78    7.85  cash 40396  5606  

On the first line, with leverage of 1.02, there is an order to sell 100% of the portfolio value using order_percent() while the position is already short, at -177 shares, driving leverage to 2.01 the next minute when the sell goes through. The cherry on top is that leverage goes negative sometimes too.
Try replacing the four instances of order_percent() with order_target_percent() as a start.

I added leverage to track_orders here and set its start date to where leverage begins climbing.
Modified the overall N. McGee code quite a bit just to be able to wrap my head around it a little better perhaps.

Clone Algorithm
13
Loading...
Backtest from to with initial capital
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
def initialize(context):
    set_slippage(slippage.FixedSlippage(spread=0.00))
    c = context
    c.jnug=sid(45570)
    c.i = 0

    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'    : 1,    # Show cash values in logging window or not.
            'log_ids'     : 1,    # 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,
            'start' : ['2016-02-18'],   # Start dates, option like ['2007-05-07', '2010-04-26']
            'stop'  : []    # Stop  dates, option like ['2008-02-13', '2010-11-15']
        }

    # for profit_vs_risk()
    c.max_lvrg = 0
    c.risk_hi  = 0
    c.date_prv = ''
    c.cash_low = c.portfolio.starting_cash
    c.date_end = str(get_environment('end').date())
    log.info('{} to {}  {}  {}'.format(str(get_datetime().date()), c.date_end,
        int(c.cash_low), get_environment('data_frequency')))

    for minute1 in range(1, 2, 1):
        schedule_function(GoldOpen,date_rules.every_day(),time_rules.market_open(minutes=minute1))
    for minute2 in range(1, 45, 1):
        schedule_function(BuyGold,date_rules.every_day(),time_rules.market_open(minutes=minute2))
    for minute4 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        schedule_function(TrackGold,date_rules.every_day(),time_rules.market_open(minutes=minute4))
    for minute5 in range(375, 390, 1):
        schedule_function(EndDaySell,date_rules.every_day(),time_rules.market_open(minutes=minute5))
    for minute7 in range(2, 390, 1):
        schedule_function(InitialStop,date_rules.every_day(),time_rules.market_open(minutes=minute7))
    for minute7 in range(1, 385, 1):
        schedule_function(Trail,date_rules.every_day(),time_rules.market_open(minutes=minute7))
    for i in range(1, 391):
      schedule_function(track_orders,   date_rules.every_day(), time_rules.market_open(minutes=i))
      schedule_function(profit_vs_risk, date_rules.every_day(), time_rules.market_open(minutes=i))
        
def before_trading_start(context, data):
    context.n = 1
    context.i = 0
    context.JNUG_amountStart = context.portfolio.positions[context.jnug].amount

def GoldOpen(context, data):
    c = context
    c.jnugOpen   = data.current(c.jnug, 'open')
    c.jnugStop   = .998  * c.jnugOpen
    c.jnugBuy    = 1.006 * c.jnugOpen
    c.jnugProfit = 1.003 * c.jnugBuy
    c.jnugTrail  = 0

def BuyGold(context, data):
    c = context
    if c.i != 0: return
    if get_open_orders(c.jnug):    return 
    if not data.can_trade(c.jnug): return
    if c.portfolio.positions[c.jnug].amount != c.JNUG_amountStart: return
    c.jnugCurrent = data.current(c.jnug, 'price')
    if not (c.jnugCurrent >= c.jnugBuy and c.jnugCurrent <= c.jnugOpen * 1.008): return
    c.jnug_id = order_percent(c.jnug, 1.0, style=LimitOrder(c.jnugBuy))
    c.i += 1

def InitialStop(context, data):
    c = context
    if c.i != 1: return
    if get_order(c.jnug_id).status != 1: return
    if c.portfolio.positions[c.jnug].amount <= c.JNUG_amountStart: return 
    if data.current(c.jnug,  'price') > c.jnugStop: return
    order_percent(c.jnug, -1)
    c.i -= 3

def TrackGold(context, data):
    c = context
    if c.i != 1: return
    if get_order(c.jnug_id).status != 1: return
    if c.portfolio.positions[c.jnug].amount <= c.JNUG_amountStart: return
    if data.current(c.jnug,  'price') < c.jnugProfit * 1.001:      return
    c.i += 2

def Trail(context, data):
    c = context
    if c.i != 3: return
    if get_order(c.jnug_id).status != 1: return
    if c.portfolio.positions[c.jnug].amount <= c.JNUG_amountStart: return
    c.jnugCurrent2 = data.current(c.jnug,  'price')
    if c.jnugCurrent2 <= c.jnugProfit * (1 - .004 * c.n):
        order_percent(c.jnug, -1)
        c.i += 1
    elif c.jnugCurrent2 >= c.jnugProfit * (1 + .002 * c.n):
        c.n += 1

def EndDaySell(context, data):
    c = context
    if not (c.i == 1 or c.i == 3): return
    if c.portfolio.positions[c.jnug].amount <= c.JNUG_amountStart: return
    order_percent(c.jnug, -1)
    c.i -= 3


def profit_vs_risk(context, data):
    ''' Custom chart and/or log of profit_vs_risk returns and related information
    '''
    # # # # # # # # # #  Options  # # # # # # # # # #
    record_max_lvrg = 1          # Maximum leverage encountered
    record_leverage = 1          # Leverage (context.account.leverage)
    record_q_return = 0          # Quantopian returns (percentage)
    record_profit_vs_risk = 0    # Profit vs Risk returns (percentage)
    record_pnl      = 0          # Profit-n-Loss
    record_shorting = 1          # Total value of any shorts
    record_risk     = 0          # Risked, maximum cash spent or shorts in excess of cash at any time
    record_risk_hi  = 1          # Highest risk overall
    record_cash     = 0          # Cash available
    record_cash_low = 1          # Any new lowest cash level
    logging         = 0          # Also log to the logging window conditionally (1) or not (0)
    log_method      = 'risk_hi'  # 'daily' or 'risk_hi'

    c = context                          # For brevity
    new_cash_low = 0                     # To trigger logging in cash_low case
    date = str(get_datetime().date())    # To trigger logging in daily case
    cash = c.portfolio.cash

    if int(cash) < c.cash_low:    # New cash low
        new_cash_low = 1
        c.cash_low   = int(cash)
        if record_cash_low:
            record(CashLow = int(c.cash_low))

    profit_vs_risk_rtrn      = 0        # Profit vs Risk returns based on maximum spent
    profit_loss   = 0        # Profit-n-loss
    shorts        = 0        # Shorts value
    start         = c.portfolio.starting_cash
    cash_dip      = int(max(0, start - cash))

    if record_cash:
        record(Cash = int(c.portfolio.cash))  # Cash

    if record_leverage:
        record(Lvrg = c.account.leverage)     # Leverage

    if record_max_lvrg:
        if c.account.leverage > c.max_lvrg:
            c.max_lvrg = c.account.leverage
            record(MaxLv = c.max_lvrg)        # Maximum leverage

    if record_pnl:
        profit_loss = c.portfolio.pnl
        record(PnL = profit_loss)             # "Profit and Loss" in dollars

    for p in c.portfolio.positions:
        shrs = c.portfolio.positions[p].amount
        if shrs < 0:
            shorts += int(abs(shrs * data.current([p],'price')))

    if record_shorting:
        record(Shorts = shorts)               # Shorts value as a positve

    risk = int(max(cash_dip, shorts))
    if record_risk:
        record(Risk = risk)                   # Amount in play, maximum of shorts or cash used

    new_risk_hi = 0
    if risk > c.risk_hi:
        c.risk_hi = risk
        new_risk_hi = 1

        if record_risk_hi:
            record(RiskHi = c.risk_hi)        # Highest risk overall

    if record_profit_vs_risk:      # Profit_vs_Risk returns based on max amount actually spent (risk high)
        if c.risk_hi != 0:     # Avoid zero-divide
            profit_vs_risk_rtrn = 100 * (c.portfolio.portfolio_value - start) / c.risk_hi
            record(profit_vs_risk = profit_vs_risk_rtrn)            # Profit_vs_Risk returns

    q_rtrn = 100 * (c.portfolio.portfolio_value - start) / start
    if record_q_return:
        record(QRet = q_rtrn)                 # Quantopian returns to compare to profit_vs_risk returns curve

    from pytz import timezone
    if logging:
        if log_method == 'risk_hi' and new_risk_hi \
          or log_method == 'daily' and c.date_prv != date \
          or c.date_end == date \
          or new_cash_low:
            qret   = 'QRet '    + '%.1f' % q_rtrn
            mxlv   = 'MaxLv '   + '%.1f' % c.max_lvrg   if record_max_lvrg else ''
            profit_vs_risk    = 'profit_vs_risk '     + '%.1f' % profit_vs_risk_rtrn     if record_profit_vs_risk      else ''
            pnl    = 'PnL '     + '%.0f' % profit_loss  if record_pnl      else ''
            csh    = 'Cash '    + '%.0f' % cash         if record_cash     else ''
            csh_lw = 'CshLw '   + '%.0f' % c.cash_low   if record_cash_low else ''
            shrt   = 'Shrt '    + '%.0f' % shorts       if record_shorting else ''
            risk   = 'Risk '    + '%.0f' % risk         if record_risk     else ''
            rsk_hi = 'RskHi '   + '%.0f' % c.risk_hi    if record_risk_hi  else ''
            minute = get_datetime().astimezone(timezone('US/Eastern')).time().minute
            log.info('{} {} {} {} {} {} {} {} {} {}'.format(
                    minute, mxlv, qret, profit_vs_risk, pnl, csh, csh_lw, shrt, risk, rsk_hi))

    if c.date_end == date:    # Log on last day, like cash 125199  portfolio 126890
        log.info('cash {}  portfolio {}'.format(
                int(cash), int(c.portfolio.portfolio_value)))

    c.date_prv = date
    
def track_orders(context, data):
    '''  Show orders when made and filled.
           Info: https://www.quantopian.com/posts/track-orders
    '''
    c = context
    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)
      if o.dt == o.created: continue        # No chance of fill yet.
      cash = ''
      prc  = data.current(o.sid, 'price') if data.can_trade(o.sid) else c.portfolio.positions[o.sid].last_sale_price
      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
        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, '%.2f' % c.account.leverage, 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.status == 1:            # Complete
          if 0 < c.trac[o.id] < o.amount:
            filled   = 'all {}/{}'.format(o.filled - c.trac[o.id], o.amount)
          filled_amt = o.filled
        else:                                    # c.trac[o.id] value is previously filled total
          filled_amt = o.filled - c.trac[o.id]   # filled this time, can be 0
          c.trac[o.id] = o.filled                # save fill value for increments math
          filled = '{}/{}'.format(filled_amt, o.amount)
        if filled_amt:
          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
            cb = c.portfolio.positions[o.sid].cost_basis
            if cb:
              pnl  = -filled_amt * (prc - 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) + '  {}  {}  {}'.format('%.2f' % c.account.leverage, cash, o.id[-4:] if c.t_options['log_ids'] else ''))
      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 = data.current(o.sid, 'price') if data.can_trade(o.sid) else c.portfolio.positions[o.sid].last_sale_price
        c.trac[o.id] = 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, '%.2f' % prc, style).ljust(52) + '  {}  {}  {}'.format('%.2f' % c.account.leverage, cash, o.id[-4:] if c.t_options['log_ids'] else ''))

There was a runtime error.

In addition to the use of order_target_percent() that Blue suggested, the other issue is that your sell order is for -100% instead of 0%, which causes you to go short. Unless I'm misinterpreting things, I'm assuming that you are only intending to take long positions on JNUG. Attached is my correction.

As far as the original post in this thread, the algorithm has promise, but needs some tweaks. The biggest issue is that it starts way too early. If you're using 200/30 EMA crossover, and begin trading at 9:40, over 90% of the data being used is from the previous day, which is no good. It seems like often, JNUG might open at 5% up, but then decline over the first hour. As far as this algorithm is concerned, the short MA is higher than the long MA, so it buys as the price is declining. If you move the start time to an hour, the returns go up to 400%, and the drawdown is reduced by 5-6%. The second issue is the condition for low volatility is too conservative. It misses a lot of good buying opportunities because of breakouts during a period that was considered low volatility at the beginning of the day. Personally, I set support and resistance levels before trading start, and do not allow the algorithm to enter a position if the price is between support and resistance.

I used this algorithm to learn Python and Quantopian, and am live trading one that is inspired by it, but bears little resemblance to it now, though the basic premise is the same. Since starting in June, I've had a couple of really good days (5-10%+ returns), one awful day (lost 7% because of a poorly thought out change), but otherwise not much of anything, as volatility has been relatively low in this timeframe. The good news is that JNUG and JDST are so liquid that I end up getting better results in live trading than I do in backtesting (I backtest every day and compare to the actual results), even with 0% slippage.

Clone Algorithm
5
Loading...
Backtest from to with initial capital
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
def initialize(context):
    context.jnug=sid(45570)
    # sets global variable context.jnug equal to the ETF we want to trade
    context.i = 0
    # This supposedly global variable is used for my program logic. It starts as 0. When a purchase is made, it equals 1.
    set_slippage(slippage.FixedSlippage(spread=0.00))
    # ETFs track an index, so my purchases cannot affect the ETF's price. The ETF price changes as the index changes.
    
    for minute1 in range(1, 2, 1):
        # Runs a function that gets the open price of the ETF JNUG every minute in first 1 minute (once per day, first minute)
        schedule_function(GoldOpen,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute1),half_days=False)
    
    for minute2 in range(1, 45, 1):
        # Runs a function that looks for a buy point and acts on it every minute in first 45 minutes (only want early morning buys!)
        schedule_function(BuyGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute2),half_days=False)
    
    #for minute3 in range(1, 385, 1):
        # Runs every minute up until 3:55: checks to see if the initial stop loss was ever hit
        #schedule_function(InitialStop,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute3),half_days=False)
    
    #for minute4 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        #schedule_function(SellGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute4),half_days=False)
    
    #for minute6 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        #schedule_function(RecordTransactions,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute6),half_days=False)

    for minute4 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        schedule_function(TrackGold,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute4),half_days=False)        

    for minute5 in range(375, 390, 1):
        # Runs every minute in last 5 minutes of the day, checks if I still have any JNUG shares and then sells them.
        schedule_function(EndDaySell,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute5),half_days=False)

    for minute7 in range(2, 390, 1):
        # Runs every minute in last 5 minutes of the day, checks if I still have any JNUG shares and then sells them.
        schedule_function(InitialStop,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute7),half_days=False)

    for minute7 in range(1, 385, 1):
        # Runs every minute until 3:55, designed to see if profit target was hit, and then will sell if so.
        schedule_function(Trail,date_rule=date_rules.every_day(),time_rule=time_rules.market_open(hours=0,minutes=minute7),half_days=False)  

def before_trading_start(context, data):
    context.n = 1
    context.i = 0
    context.my_JNUG_amountStart = context.portfolio.positions[context.jnug].amount
    print('my_JNUG_amount reset to %s') % (context.my_JNUG_amountStart)
    print('context.i reset to %.5f') % (context.i)

def GoldOpen(context, data):
    context.jnugOpen=data.history(sid(45570), 'open', 1, '1m')[-1]
    # stores the open price of JNUG at 9:31
    context.jnugBuy = 1.006*context.jnugOpen
    context.jnugStop = .998*context.jnugOpen
    context.jnugTrail = 0
    context.jnugProfit = 1.003*context.jnugBuy
    # global variables that store values where we want to buy and sell
    print('JNUG open price: %.5f') % (context.jnugOpen)
    
def BuyGold(context, data):
    if context.i == 0:
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        if context.jnug not in get_open_orders() and data.can_trade(sid(45570))==True and my_JNUG_amount == context.my_JNUG_amountStart:
            context.jnugCurrent = data.current(context.jnug,'price')
            if context.jnugCurrent >= context.jnugBuy and context.jnugCurrent <= context.jnugOpen*1.008: # don't want to buy overextended!
                context.jnug_id = order_target_percent(sid(45570), 1, style=LimitOrder(context.jnugBuy))
                # does this mean I can reference this order now? If I use context.jnug_id again will it order again? (I don't want that)
                record(leverage = context.account.leverage)
                print('Bought for %.5f!') % (context.jnugCurrent)
                context.i += 1
                #print('Order ID: %s') % (get_order(context.jnug_id))   

"""def CheckBoughtOrSold(context, data):
    if context.i == 1:
        print(context.portfolio.portfolio_value)
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        if my_JNUG_amount > context.my_JNUG_amountStart:
            print('Shares bought: %s') % (my_JNUG_amount)
        if my_JNUG_amount < context.my_JNUG_amountStart:
            print('Shares sold: %s') % (my_JNUG_amount)   """

def InitialStop(context, data):
    if context.i == 1:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart and get_order(context.jnug_id).status == 1:
            if context.jnugCurrent2 <= context.jnugStop:
                order_target_percent(context.jnug, 0)
                print('JNUG sold at initial stop for %.5f') % (context.jnugCurrent2)
                print('Amount sold: %s') % (my_JNUG_amount)
                context.i -= 3 
                print('context.i = %.5f') % (context.i)   
     
def TrackGold(context, data):
    if context.i == 1:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart and get_order(context.jnug_id).status == 1:
            if context.jnugCurrent2 >= context.jnugProfit*1.001:
                print('Potential to move up stop')
                context.i += 2 
                print('context.i = %.5f, only for trail function now') % (context.i)   
                
def Trail(context, data):
    if context.i == 3:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart and get_order(context.jnug_id).status == 1:
            if context.jnugCurrent2 <= context.jnugProfit*(1-.004*context.n):
                order_target_percent(context.jnug, 0)
                print('JNUG reached trail!') % (context.jnugCurrent2)
                print('Amount sold: %s') % (my_JNUG_amount)
                context.i += 1 
                print('context.i = %.5f') % (context.i)   
            
            elif context.jnugCurrent2 >= context.jnugProfit*(1+.002*context.n):
                context.n += 1
                print('Trail moved up!')

def EndDaySell(context, data):
    if context.i == 1 or context.i == 3:
        context.jnugCurrent2 = data.history(sid(45570), 'close', 1, '1m')[-1]
        context.open_orders = get_open_orders()
        my_JNUG_amount = context.portfolio.positions[context.jnug].amount        
        # line below makes sure our order has processed. Otherwise we will sell before we really hold anything
        #if context.jnug not in context.open_orders:
        if my_JNUG_amount > context.my_JNUG_amountStart:
            print('Trying to sell!')
            order_target_percent(context.jnug, 0)
            print('JNUG sold at end of day for %.5f') % (context.jnugCurrent)
            print('Amount sold: %s') % (my_JNUG_amount)
            context.i -= 3
            print('context.i = %.5f') % (context.i)
There was a runtime error.