| Overall Statistics |
|
Total Trades 5 Average Win 0% Average Loss 0% Compounding Annual Return -63.956% Drawdown 3.700% Expectancy 0 Net Profit -1.112% Sharpe Ratio -3.567 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 1.186 Beta 10.795 Annual Standard Deviation 0.253 Annual Variance 0.064 Information Ratio -3.088 Tracking Error 0.23 Treynor Ratio -0.084 Total Fees $5.60 Estimated Strategy Capacity $4000000.00 Lowest Capacity Asset NGG ROOA6XQS4GH1 |
#region imports
from AlgorithmImports import *
#endregion
import numpy as np
import pandas as pd
class Tgang(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 2, 25) # Set Start Date
self.SetEndDate(2022, 2, 28) # Set End Date
self.SetCash(30000) # Set Strategy Cash
#self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) #set brokerage and account type for consideration of trading fees
# self.activeStocks = set()
# can set PDT models for 4x leverage but have to do on security level? (e.g. self.Securities["AAPL"].MarginModel = PatternDayTradingMarginModel())
#add SPY for scheduling events
self.AddEquity("SPY", Resolution.Minute)
self.AddEquity("TSLA", Resolution.Minute)
self.SetBenchmark("SPY") # set benchmark
# add universe and update settings
self.AddUniverse(self.UniverseCoarseFilter, self.UniverseFineFilter)
self.UniverseSettings.Resolution = Resolution.Minute
#self.UniverseSettings.SetDataNormalizationMode = DataNormalizationMode.SplitAdjusted
#self.UniverseSettings.FeeModel = ConstantFeeModel(1.0)
#self.UniverseSettings.Leverage = 2
self.previousClose = {}
self.pp = {}
self.pp_s1 = {}
self.pp_s2 = {}
self.pp_r1 = {}
self.pp_r2 = {}
self.monthlyBar = {}
#schedule yday close once per day to identify stocks > 2% move
#self.ScheduleOn(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 1), self.YdayClose)
#schedule update of previous close for universe stocks
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 1), self.UpdateYdayClose)
self.Schedule.On(self.DateRules.MonthStart("SPY", 1), self.TimeRules.AfterMarketOpen("SPY", 1), self.UpdatePivots)
#self.percentagebuy = 0.08
# self.AddEquity("SPY", Resolution.Minute)
def UniverseCoarseFilter(self, coarse):
#universe runs daily at midnight
filtered = [x.Symbol for x in coarse if x.Price > 10 and x.DollarVolume > 1000000]
return filtered
def UniverseFineFilter(self, fine):
#universe runs daily at midnight
filtered = [x.Symbol for x in fine if x.MarketCap > 50000000000 and x.EarningReports.FileDate + timedelta(days=5) < self.Time]
return filtered
def OnSecuritiesChanged(self, changes):
#add previous close and pivot points
for security in changes.AddedSecurities:
symbol = security.Symbol
#get previous close
if symbol not in self.previousClose:
history = self.History(symbol, 1, Resolution.Daily)
if not history.empty:
history = history.close.unstack(0)[symbol]
if not history.empty:
self.previousClose[symbol] = history[0]
#setup monthly bars
if symbol not in self.monthlyBar:
self.monthlyBar[symbol] = MonthlyBar(self, symbol)
#get pp's from monthly bars
#--------------------------------------------------------------------------
#if symbol not in self.pp:
# history = self.monthlyBar[symbol].close
# self.pp[symbol] = history[0]
#--------------------------------------------------------------------------
#remove previous close and pp's
for security in changes.RemovedSecurities:
symbol = security.Symbol
#remove previous close
if symbol in self.previousClose:
self.previousClose.pop(symbol, None)
#remove monthly bar
#if symbol in self.monthlyBar:
# monthlyBar = self.monthlyBar.pop(symbol, None)
# self.SubscriptionManager.RemoveConsolidator(symbol, monthlyBar.consolidator)
# prevent code delay after order --> set true after market order (e.g. self.MarketOrder("TSLA", 50, True))
# you can check if an indicator is ready and return if not (e.g. if not self.sma.IsReady: Return)
# check if trade event active before searching new trade events. This prevents algo from processing data when not ready for new position.
# you can plot in this area (e.g. self.Plot("Benchmark", "52w-High", high))
def OnData(self, data):
#if have positions, no need to scan for new trades
#if self.Portfolio.Count > 1:
# return
#dictionary for percent change from last close
percentChangeDaily = {}
if self.Portfolio.Invested:
return
#populate dictionary
for symbol, previousClose in self.previousClose.items():
if self.CurrentSlice.ContainsKey(symbol):
price = self.CurrentSlice[symbol].Close
change = (price - previousClose) / previousClose
percentChangeDaily[symbol] = change
symbols = list(percentChangeDaily.keys())
sortedSymbols = sorted(symbols, key=lambda x: percentChangeDaily[x], reverse=True)
selected = sortedSymbols[:5]
for symbol in selected:
self.SetHoldings(symbol, 0.2)
#for symbol in selected:
# self.SetHoldings(symbol, 1)
#self.StopMarketOrder(symbol, self.Portfolio[symbol].Quantity, self.CurrentSlice[symbol].Close * 0.95)
#Check time for live debugging
checkhour = self.Time.hour
checkminute = self.Time.minute
#TRADING EXECUTION
#self.buyquantity = round((self.percentagebuy*self.Portfolio.TotalPortfolioValue)/data[symbol].Close)
def OnOrderEvent(self, orderEvent):
# set target orders
pass
def UpdateYdayClose(self):
for symbol in self.previousClose:
if self.CurrentSlice.ContainsKey(symbol):
self.previousClose[symbol] = self.CurrentSlice[symbol].Close
def UpdatePivots(self):
pass
for symbol in self.pp:
if self.CurrentSlice.ContainsKey(symbol):
history = self.monthlyBar
#self.pp[symbol] = (history.high(0)[symbol] + history.low(0)[symbol] + history.close(0)[symbol]) / 3
# credit Louis tutorial videos
class MonthlyBar:
def __init__(self, algorithm, symbol):
self.algorithm = algorithm
self.symbol = symbol
self.consolidator = TradeBarConsolidator(self.CustomMonthly)
self.consolidator.DataConsolidated += self.OnDataConsolidated
algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
def OnDataConsolidated(self, sender, bar):
self.algorithm.Debug(f"Data Consolidatoed for {self.symbol} at {bar.EndTime} with bar: {bar}")
def CustomMonthly(self, dt):
start = dt.replace(day=1).date()
end = dt.replace(day=28) + timedelta(4)
end = (end - timedelta(end.day-1)).date()
return CalendarInfo(start, end - start)