Overall Statistics Total Trades 34 Average Win 0% Average Loss -1.58% Compounding Annual Return 69.580% Drawdown 10.400% Expectancy -1 Net Profit 22.448% Sharpe Ratio 2.243 Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha 1.502 Beta -49.033 Annual Standard Deviation 0.243 Annual Variance 0.059 Information Ratio 2.162 Tracking Error 0.243 Treynor Ratio -0.011 Total Fees \$185.90
```import numpy as np
import pandas as pd

from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Common")

from datetime import datetime, timedelta
from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Data.Market import TradeBar
import json
import math
from QuantConnect.Data import SubscriptionDataSource
from QuantConnect.Python import PythonData

class TemplateAlgorithmUniverseSelection(QCAlgorithm):
'''Advanced Template Architecture'''

def Initialize(self):

'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialize.'''

# Chart - Master Containers for the Charts:
stockPlot_1 = Chart('RSI')
stockPlot_2 = Chart('Margin Remaining')

#Establish universe-wide settings
self.UniverseSettings.Resolution = Resolution.Daily
self.UniverseSettings.Leverage = 2

#Initial investment and backtest period
self.SetStartDate(2019,1,1)                                  #Set Start Date
self.SetEndDate(datetime.now().date() - timedelta(1))        #Set End Date
self.SetCash(1000000)                                        #Set Strategy Cash

#Initialize list of Open Orders
self.OpenOrders = self.Transactions.GetOpenOrders()

#Capture initial investment for risk off purposes
self.marginRemaining = self.Portfolio.MarginRemaining
self.OpenPortValue = self.Portfolio.TotalPortfolioValue
self.ClosingPortValue = self.Portfolio.TotalPortfolioValue
self.CurrentPortValue = self.Portfolio.TotalPortfolioValue
self.CurrentHoldValue = self.Portfolio.TotalHoldingsValue
self.OpenHoldValue = self.Portfolio.TotalHoldingsValue
self.ClosingHoldValue = self.Portfolio.TotalHoldingsValue

#Universe
self.AddEquity("SPY", Resolution.Daily)
self.AddUniverse(self.CoarseSelectionFunction, self.MyFineFundamentalFunction)

#Brokerage Model
self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)

'''Schedule Functions Here'''

self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 1), self.CheckLiveTrading)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 1), self.Charts)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 1), self.CheckDailyLosses)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 1), self.UpdatePortValues)

for x in range (20,390,20):
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", x), self.UpdatePortValues)

for y in range (23,390,23):
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", y), self.CheckDailyLosses)

self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose("SPY", 1), self.CapturePortfolioValue)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose("SPY", 1), self.ClearOpenOrders)

'''Set Warmup Here'''
self.SetWarmup(TimeSpan.FromDays(30))

#Universe Selection
def CoarseSelectionFunction(self, coarse):

sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
filtered = [ x.Symbol for x in sortedByDollarVolume
if x.Price > 10 and x.DollarVolume > 10000000 ]

return filtered[:500]

def MyFineFundamentalFunction(self, fine):

sortedByPeRatio = sorted(fine, key=lambda x: x.ValuationRatios.PERatio, reverse=False)

return [ x.Symbol for x in sortedByPeRatio[:10] ]

#OnData
def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''
'''Arguments:
data: Slice object keyed by symbol containing the stock data'''

weighting = 1.0 / self.Securities.Count

for security in self.Securities.Values:
if not self.Securities[security.Symbol].Invested:
self.SetHoldings(security.Symbol, weighting)

#Charts
def Charts(self):

#Plot any relevant portfolio metrics
self.Plot('Margin Remaining', 'Margin Remaining', self.marginRemaining)
#self.PlotIndicator('RSI', self.tslaRsi, self.vixRsi, self.spyRsi)

#AtClose
def OnEndOfDay(self):

self.Log("Trading Day Has Ended")

#MarginCallWarning
def OnMarginCallWarning(self):

#Get a list of open orders to avoid margin issues
self.OpenOrders = self.Transactions.GetOpenOrders()

#Cancel any open orders.
if len(self.OpenOrders)> 0:
for x in self.OpenOrders:
self.Transactions.CancelOrder(x.Id)

#Rebalance to free up capital
self.Log("Rebalacing due to tight margin conditions")
self.MarginCall()
self.Log("WARNING: Day Start Portfolio Value: \${0} | Current Portfolio Value: \${1} | Loss: {2}%".format(

round(self.ClosingPortValue,2),
round(self.Portfolio.TotalPortfolioValue,2),
round( ( (int(self.ClosingPortValue)/int(self.Portfolio.TotalPortfolioValue)) -1)*100,2), ) )

#CheckLive
#Check connection at open and note the value gap
def CheckLiveTrading(self):

#Capture portfolio metrics at open. Verify live connection. Log previous close and overnight gap up/down
self.OpenOrders = self.Transactions.GetOpenOrders()
self.OpenPortValue = self.Portfolio.TotalPortfolioValue
self.OpenHoldValue = self.Portfolio.TotalHoldingsValue
self.Gap = round( ( ( ( int(self.OpenPortValue)/int(self.ClosingPortValue) ) - 1) * 100),2)

#Perform actions based on overnight changes in portfolio value
if self.Gap >= 10.00:
self.Log("Huge gap up today! {0}%!".format(self.Gap))
self.OhWow()

if self.Gap <= -4.25:
self.Log("Huge gap down today! {0}%!".format(self.Gap))
self.OhShit()

self.Log("Trading Live! || Yesterday's Closing Value: \${0}|| Opening Value: {1}% gap".format(self.ClosingPortValue, self.Gap))

return

#CaputureValue
#Capture the closing value of the portfolio and any open orders
def CapturePortfolioValue(self):

self.OpenOrders = self.Transactions.GetOpenOrders()
self.ClosingPortValue = self.Portfolio.TotalPortfolioValue
self.ClosingHoldValue = self.Portfolio.TotalHoldingsValue

self.Log("End Of Day Portfolio Values Have Been Captured")

return

#ClearOrders
#Clear open orders if there are 5 or more
def ClearOpenOrders(self):

#Get a list of open orders to avoid margin issues
self.OpenOrders = self.Transactions.GetOpenOrders()

#Cancel any open orders.
if len(self.OpenOrders)> 5:
for x in self.OpenOrders:
self.Transactions.CancelOrder(x.Id)

self.Log("Open Orders Have Been Closed.")

else:
return

#Update Portfolio Values
def UpdatePortValues(self):

if(self.IsMarketOpen("SPY")):

self.marginRemaining = self.Portfolio.MarginRemaining
self.CurrentPortValue = self.Portfolio.TotalPortfolioValue
self.CurrentHoldValue = self.Portfolio.TotalHoldingsValue

self.Log("Portfolio Values Have Been Updated")

#CheckLosses
#Check intraday losses and run a defensive function if a 5.6% drop is recognized at any time
def CheckDailyLosses(self):

if(self.IsMarketOpen("SPY")):

self.CurrentPerformance = round( ((float(self.CurrentPortValue)/float(self.ClosingPortValue))-1)*100,2)

if (self.CurrentPortValue <= self.ClosingPortValue*0.944):
self.HighLosses()

else: self.Log("Current Performance: {0}%".format(self.CurrentPerformance))

return

#HighLosses
#Liquidate most holdings after a 5.6% drop from previous portfolio close value.
def HighLosses(self):

#Get a list of open orders to avoid margin issues
self.OpenOrders = self.Transactions.GetOpenOrders()

#Cancel any open orders.
if len(self.OpenOrders)> 0:
for x in self.OpenOrders:
self.Transactions.CancelOrder(x.Id)

#Set portfolio to risk averse proportions and log important information
self.OhShit()

#Log important portfolio information when this function fires
self.Log("WARNING: Rebalancing due to excessive daily losses || Day Start Portfolio Value: \${0} || Current Portfolio Value: \${1} || Loss: {2}% || Gap at open: {3}%".format(

round(self.ClosingPortValue,2),
round(self.Portfolio.TotalPortfolioValue,2),
round( ( (int(self.ClosingPortValue)/int(self.Portfolio.TotalPortfolioValue)) -1)*100,2),
self.Gap) )

#Reset the reference point to catch any further 5.6% decreases with the new holdings.
self.ClosingPortValue = self.Portfolio.TotalPortfolioValue

#If there were any open orders left this will log how many.  We cancelled them all, so this would be on the broker or connectivity
if (len(self.OpenOrders)> 0):
self.Log("Number of open orders: {0}".format( len(self.OpenOrders )))

return

#Ohshit
def OhShit(self):
return

#OhWow
def OhWow(self):
return

#MarginCall
def MarginCall(self):
return

#SPY
def SpyFunc(self):

self.Log("SPY Function Has Fired.  || SPY RSI: {0}".format(
round(self.spyRsi.Current.Value),3))

#Used to control leverage
self.OpenOrders = self.Transactions.GetOpenOrders()

return

#TSLA
def TslaFunc(self):

self.Log("TSLA Function Has Fired.  || Relevant Metrics: TSLA RSI: {0}".format(
round(self.tslaRsi.Current.Value,3)))

#Refresh open orders
self.OpenOrders = self.Transactions.GetOpenOrders()

return

#TVIX
def Func3(self):

#Get open orders. Used to prevent inappropriate use of leverage
self.OpenOrders = self.Transactions.GetOpenOrders()

return

'''
class Vix(PythonData):
#New VIX Object

def GetSource(self, config, date, isLiveMode):
#if isLiveMode:
return SubscriptionDataSource("http://www.cboe.com/publish/scheduledtask/mktdata/datahouse/vixcurrent.csv", SubscriptionTransportMedium.RemoteFile);

def Reader(self, config, line, date, isLiveMode):

# New VIX object
index = Vix()
index.Symbol = config.Symbol

#if isLiveMode:
if not (line.strip() and line[0].isdigit()): return None

try:
# Example File Format:
# Date,       Open       High        Low       Close     Volume      Turnover
# 1/1/2008  7792.9    7799.9     7722.65    7748.7    116534670    6107.78
data = line.split(',')
index.Time = datetime.strptime(data[0], "%m/%d/%Y")
index.Value = data[4]
index["Close"] = float(data[4])

except ValueError:
# Do nothing
return None

return index
'''                        ```