Overall Statistics |
Total Trades 642 Average Win 1.00% Average Loss -1.22% Compounding Annual Return -3.832% Drawdown 36.900% Expectancy -0.031 Net Profit -15.845% Sharpe Ratio -0.189 Loss Rate 47% Win Rate 53% Profit-Loss Ratio 0.82 Alpha -0.025 Beta -0.154 Annual Standard Deviation 0.149 Annual Variance 0.022 Information Ratio -0.323 Tracking Error 0.149 Treynor Ratio 0.182 Total Fees $659.00 |
''' For notes, etc. Full API (C# only): https://www.quantconnect.com/lean/docs Python API with examples (doesn't include every method but does include most): https://www.quantconnect.com/docs/algorithm-reference/overview Time example: https://www.quantconnect.com/forum/discussion/142/how-to-get-simulated-time-and-date Crisis Events: https://www.quantconnect.com/blog/leans-tear-sheet-the-lean-report-creator/ Bracket Orders https://www.quantconnect.com/forum/discussion/3328/futures-quot-bracket-order-quot-example/p1 To do: - Universe Selection - Option intergration - Going back certain number of periods using slices to get indicator values prior to our current period - Trailing Stop Loss ''' class MultipleSymbolConsolidationAlgorithm(QCAlgorithm): # Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. def Initialize(self): #Initial investment and backtest period self.SetStartDate(2015, 1, 1) self.SetEndDate(datetime.now().date() - timedelta(1)) self.SetCash(20000) #Brokerage Model self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) # This is the period of bars we'll be creating BarPeriod = TimeSpan.FromMinutes(20) # This is the period of our rsi indicators RSIPeriod = 30 # This is the period of our vwap indicators VWAPPeriod = 10 # This is the period of our volume moving average TEMAvolumePeriod = 8 # This is the the volume of the last bar SMAvolumeOnePeriod = 1 # This is the period of our sma indicators SimpleMovingAveragePeriod = 30 # This is the period of our last price SimpleMovingAverageonePeriod = 1 # This is the period of our ema indicators ExponentialMovingAveragePeriod = 8 # This is the period of our tema indicators TripleExponentialMovingAveragePeriod = 8 # This is the number of consolidated bars we'll hold in symbol data for reference RollingWindowSize = 30 # Holds all of our data keyed by each symbol self.Data = {} # Contains all of our equity symbols EquitySymbols = ["AAPL"] # initialize our equity data for symbol in EquitySymbols: equity = self.AddEquity(symbol) self.Data[symbol] = SymbolData(equity.Symbol, BarPeriod, RollingWindowSize) # loop through all our symbols and request data subscriptions and initialize indicator for symbol, symbolData in self.Data.items(): # define the indicator symbolData.SMA = SimpleMovingAverage(self.CreateIndicatorName(symbol, "SMA" + str(SimpleMovingAveragePeriod), Resolution.Minute), SimpleMovingAveragePeriod) # define the indicator symbolData.RSI = RelativeStrengthIndex(self.CreateIndicatorName(symbol, "RSI" + str(RSIPeriod), Resolution.Minute), RSIPeriod, MovingAverageType.Simple) # define the indicator symbolData.SMAone = SimpleMovingAverage(self.CreateIndicatorName(symbol, "SMA" + str(SimpleMovingAverageonePeriod), Resolution.Minute), SimpleMovingAverageonePeriod) # define a consolidator to consolidate data for this symbol on the requested period consolidator = TradeBarConsolidator(BarPeriod) # write up our consolidator to update the indicator consolidator.DataConsolidated += self.OnDataConsolidated # we need to add this consolidator so it gets auto updates self.SubscriptionManager.AddConsolidator(symbolData.Symbol, consolidator) def OnDataConsolidated(self, sender, bar): self.Data[bar.Symbol.Value].SMA.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].SMAone.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].RSI.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].Bars.Add(bar) # OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. # Argument "data": Slice object, dictionary object with your stock data def OnData(self,data): # loop through each symbol in our structure for symbol in self.Data.keys(): symbolData = self.Data[symbol] stopLossPercent = .99 profitTargetPercent = 1.02 # this check proves that this symbol was JUST updated prior to this OnData function being called if symbolData.IsReady() and symbolData.WasJustUpdated(self.Time): #----TIME VARIABLES---- # Set up pre-market close time CloseTimeString = "15:44:00" CloseOutTime = datetime.strptime(CloseTimeString, "%H:%M:%S") CloseTime = datetime.time(CloseOutTime) #self.Debug(str(CloseTime) + " CLOSETIME ") # Get symbol trade time DataSymbolTime = data[symbol].Time DataTime = datetime.time(DataSymbolTime) #self.Debug(str(DataTime) + " DATATIME ") #----TIME VARIABLES---- # Check to see if we are near market close if DataTime < CloseTime: #if we do not own this symbol if not self.Portfolio[symbol].Invested: #if RSI value is less than 'x' if float(symbolData.RSI.Current.Value) < 35: #Liquidate opposite symbol self.Liquidate() self.Debug("LIQUIDATING in loop...") #Cancel open ordersif there are any openOrders = self.Transactions.GetOpenOrders() if len(openOrders)> 0: for x in openOrders: self.Transactions.CancelOrder(x.Id) # Set Position Size posSize = self.CalculateOrderQuantity(symbol, 1) # Market Order to buy self.MarketOrder(symbol, posSize) # Stop Loss/Profit Taker self.StopLimitOrder(symbol, -posSize, float(symbolData.SMAone.Current.Value) * stopLossPercent, float(symbolData.SMAone.Current.Value) * profitTargetPercent) # End of a trading day event handler. This method is called at the end of the algorithm day (or multiple times if trading multiple assets). # Method is called 10 minutes before closing to allow user to close out position. def OnEndOfDay(self): #Liquidate all symbol self.Liquidate() self.Debug("LIQUIDATING at end of day...") ''' #Cancel open ordersif there are any openOrders = self.Transactions.GetOpenOrders() if len(openOrders)> 0: for x in openOrders: self.Transactions.CancelOrder(x.Id) ''' ''' i = 0 for symbol in sorted(self.Data.keys()): symbolData = self.Data[symbol] # we have too many symbols to plot them all, so plot every other i += 1 if symbolData.IsReady() and i%2 == 0: self.Plot(symbol, symbol, symbolData.SMA.Current.Value) ''' class SymbolData(object): def __init__(self, symbol, barPeriod, windowSize): self.Symbol = symbol # The period used when population the Bars rolling window self.BarPeriod = barPeriod # A rolling window of data, data needs to be pumped into Bars by using Bars.Update( tradeBar ) and can be accessed like: # mySymbolData.Bars[0] - most first recent piece of data # mySymbolData.Bars[5] - the sixth most recent piece of data (zero based indexing) self.Bars = RollingWindow[IBaseDataBar](windowSize) # The simple moving average indicator for our symbol self.SMA = None # Returns true if all the data in this instance is ready (indicators, rolling windows, ect...) def IsReady(self): return self.Bars.IsReady and self.SMA.IsReady # Returns true if the most recent trade bar time matches the current time minus the bar's period, this # indicates that update was just called on this instance def WasJustUpdated(self, current): return self.Bars.Count > 0 and self.Bars[0].Time == current - self.BarPeriod