Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -11.991 Tracking Error 0.012 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 |
import numpy as np # needed for NaN handling import math # ceil and floor are useful for rounding from datetime import timedelta from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Indicators") AddReference("QuantConnect.Common") import statistics from System import * from QuantConnect import * import talib class MyAlgorithm(QCAlgorithm): def Initialize(self): self.symbols = None # over simplistic tracking of position age self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) #self.SetSlippageModel(VolumeShareSlippageModel()) # SMA self.SetStartDate(2019,1,1) #Set Start Date self.SetEndDate(2020,6,28) #Set End Date self.SetCash(1000) #self.SetWarmUp(50, Resolution.Minute) self.SetBenchmark("SPY") self.UniverseSettings.Resolution = Resolution.Minute self.UniverseSettings.Leverage = 1 self.AddSecurity("SPY", Resolution.Minute).Symbol self.Max_Candidates = 100 self.Max_BuyOrdersAtOnce = 20 self.MyLeastPrice = 1.50 self.MyMostPrice = 5.00 self.MyFireSalePrice = self.MyLeastPrice self.MyFireSaleAge = 6 #self.time = { }; self.averages = { }; #self.changes = None #self.index = 0 self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x))) # esto es para resolution menor de day #self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction) self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.CoarseSelectionFunction, self.FineSelectionFunction)) #BEFORE TRADING START en initialize self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", -10), Action(self.before_trading_start)) # Rebalance EveryThisManyMinutes = 10 TradingDayHours = 6.5 TradingDayMinutes = int(TradingDayHours * 60) #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.Every(timedelta(minutes=EveryThisManyMinutes)), Action(self.my_rebalance)) for minutz in range(1, TradingDayMinutes, EveryThisManyMinutes): self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", minutz), Action(self.my_rebalance)) # Prevent excessive Logging of canceled orders at market close. self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose("SPY", 1), Action(self.cancel_open_orders)) def OnSecuritiesChanged(self, changes): self.Debug("checking") self.changes = changes def CoarseSelectionFunction(self, coarse): sorted(coarse, key = lambda x: x.DollarVolume, reverse = True) # We are going to use a dictionary to refer the object that will keep the moving averages #self.Debug('coarse ' +str(coarse)) for cf in coarse: if cf.HasFundamentalData: if cf.Symbol not in self.averages: self.averages[cf.Symbol] = SymbolData(cf.Symbol) # Updates the SymbolData object with current EOD price avg = self.averages[cf.Symbol] avg.update(cf.EndTime, cf.AdjustedPrice) # Filter the values of the dict: we only want up-trending securities #values = list(filter(lambda x: x.is_downtrend, self.averages.values())) #values.sort(key = lambda x: x.scale , reverse = False) values = sorted(self.averages.values(), key = lambda x: x.scale, reverse = True)[:self.Max_Candidates] self.values = list(values) #for x in self.values: # self.Debug('values ' + str(x.symbol) + ' price ' + str(x.price) + ' scale ' + str(x.scale)) self.g = [x for x in self.values if (float(x.price) >= self.MyLeastPrice) and (float(x.price) <= self.MyMostPrice)] return [ x.symbol for x in self.g[:self.Max_Candidates] ] def FineSelectionFunction(self, fine): self.filtered = [x for x in fine if (x.SecurityReference.SecurityType == 'ST00000001') and (x.SecurityReference.IsDepositaryReceipt == False) and not (x.CompanyReference.IsLimitedPartnership) and (x.SecurityReference.IsPrimaryShare) and (x.SecurityReference.ExchangeId != 'OTC')] #and x.CompanyReference.StandardName == ".*L[. ]?P.?$"] # Not when-issued equities. LowVar = 0.06 * len(self.filtered) HighVar = 0.4 * len(self.filtered) self.filtered_h = [x.Symbol for x in self.filtered[:int(HighVar)]] self.filtered_l = [x.Symbol for x in self.filtered[-int(LowVar):]] self.symbols = self.filtered_h + self.filtered_l return self.symbols def before_trading_start(self): #update prices of my active securities and do some checks about the time they have been in my portfolio pass def cancel_open_orders(self): pass def my_rebalance(self): #do my buy and sells checking minute bars prices by comparing it to period daily prices mean data = self.CurrentSlice for symbol, symbol_data in self.averages.items(): if not (data.ContainsKey(symbol) and data[symbol] is not None): continue current_price = data[symbol].Price mean = symbol_data.fast.Current.Value # daily mean self.Quit(f"{symbol}; Current price: {current_price}; Mean: {mean}") self.Quit() def OnData(self, data): pass class SymbolData(object): def __init__(self, symbol): self.symbol = symbol #SMA (daily resolution) self.fast = SimpleMovingAverage(3) self.slow = SimpleMovingAverage(45) self.price = 0 self.is_downtrend = False self.scale = 0 def update(self, time, value): self.price = value if self.fast.Update(time, value) and self.slow.Update(time, value): fast = self.fast.Current.Value slow = self.slow.Current.Value self.is_downtrend = fast < slow self.scale = (fast-slow)/slow if self.is_downtrend: self.scale = (fast - slow) / slow