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 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
class QuantumSpinningAlgorithm(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): self.BarPeriod = timedelta(hours=1) self.BarPeriod2 = timedelta(days=5) self.BarPeriod3 = timedelta(hours=4) self.SetCash(100000) self.tp= 30/10000 self.sl = 20/10000 self.StopLoss = None self.ProfitTarget = None self.last_trail_level = None self.SimpleMovingAveragePeriod =14 self.RSIPeriod = 14 self.BBPeriod = 20 self.RSI_OB1 = 71 self.RSI_OB2 = 75 self.RSI_OS = 28 self.k1 = 2 self.k2 = 4 self.Quantity = 10000 # This is the number of consolidated bars we'll hold in symbol data for reference self.RollingWindowSize = 5 # Holds all of our data keyed by each symbol self.Data = {} # Contains all of our equity symbols #EquitySymbols = ["AAPL","SPY","IBM"] # Contains all of our forex symbols ForexSymbols =["EURUSD", "USDJPY", "EURGBP", "EURCHF", "USDCAD", "USDCHF", "GBPUSD", "AUDUSD","NZDUSD"] self.SetStartDate(2015, 12, 1) self.SetEndDate(2018, 1, 1) # initialize our forex data for symbol in ForexSymbols: forex = self.AddForex(symbol,Resolution.Hour) self.Data[symbol] = SymbolData(forex.Symbol, self.BarPeriod, self.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(self.SimpleMovingAveragePeriod), Resolution.Hour), self.SimpleMovingAveragePeriod) symbolData.Bolband = self.BB(symbol, self.BBPeriod, self.k1, MovingAverageType.Simple, Resolution.Hour) #symbolData.Bolband_stop = self.BB(symbol, self.BBPeriod, self.k2,MovingAverageType.Simple, Resolution.Hour) symbolData.RSI = self.RSI(symbol, self.RSIPeriod,Resolution.Hour) symbolData.RSI2 = self.RSI(symbol, self.RSIPeriod) symbolData.RSI3 = self.RSI(symbol, self.RSIPeriod, Resolution.Daily) symbolData.RSI4 = self.RSI(symbol, self.RSIPeriod) # define a consolidator to consolidate data for this symbol on the requested period consolidator = QuoteBarConsolidator(self.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) self.RegisterIndicator(symbolData.Symbol, symbolData.RSI, consolidator) # create the fourhour data consolidator fourhourConsolidator = QuoteBarConsolidator(self.BarPeriod2) # write up our consolidator to update the indicator fourhourConsolidator.DataConsolidated += self.OnDataConsolidated self.SubscriptionManager.AddConsolidator(symbolData.Symbol, fourhourConsolidator) # register the weekly consolidated bar data to automatically update the indicator self.RegisterIndicator(symbolData.Symbol, symbolData.RSI2, fourhourConsolidator) self.RegisterIndicator(symbolData.Symbol, symbolData.Bolband, fourhourConsolidator) # create the weekly data consolidator weeklyConsolidator = QuoteBarConsolidator(self.BarPeriod2) # write up our consolidator to update the indicator weeklyConsolidator.DataConsolidated += self.OnDataConsolidated self.SubscriptionManager.AddConsolidator(symbolData.Symbol, weeklyConsolidator) # register the weekly consolidated bar data to automatically update the indicator self.RegisterIndicator(symbolData.Symbol, symbolData.RSI4, weeklyConsolidator) self.Schedule.On(self.DateRules.WeekStart(symbol),self.TimeRules.At( 8, 5),self.StartTrading) def OnDataConsolidated(self, sender, bar): self.Data[bar.Symbol.Value].RSI2.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].RSI3.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].RSI4.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].RSI.Update(bar.Time, bar.Close) #self.Data[bar.Symbol.Value].SMA.Update(bar.Time, bar.Close) self.Data[bar.Symbol.Value].Bolband.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): pass def StartTrading(self): # loop through each symbol in our structure for symbol in self.Data.keys(): symbolData = self.Data[symbol] # this check proves that this symbol was JUST updated prior to this OnData function being called if symbolData.IsReady() and symbolData.WasJustUpdated(self.Time): #Set Current Price price = symbolData.Bars[0].Close #Set StopLoss level base_sl_level = price + self.sl holdings = self.Portfolio[symbol].Quantity value = self.Portfolio.TotalPortfolioValue cash = self.Portfolio.Cash # Log OHLC - This can be useful for debugging to see where price is moving self.Log('>> {} >> ON DATA >> >> >> >> >> >>'.format(symbol)) self.Log('>> SL >> Base Level:{} Last Trail Level:{}'.format(base_sl_level, self.last_trail_level)) self.Log('>> Account >> Cash:{}, Val:{}, Holdings:{}'.format(cash,value,holdings)) if not (self.Portfolio[symbol].Invested): #Short Sell the pair CurrentOrder= self.MarketOrder(symbol, -(self.Quantity)) #Set StopLoss order self.StopLoss = self.StopMarketOrder(symbol, self.Quantity, base_sl_level) self.last_trail_level = base_sl_level #Set Profit Target self.ProfitTarget = self.LimitOrder(symbol, self.Quantity, price-self.tp) else: if base_sl_level < self.last_trail_level: self.Log('>> Updating Trailing Stop >>') # Upate our stoploss order! update_order_fields = UpdateOrderFields() update_order_fields.StopPrice = base_sl_level self.StopLoss.Update(update_order_fields) # Log last sl_level self.last_trail_level = base_sl_level #If the StopLoss or ProfitTarget is filled, cancel the other def OnOrderEvent(self,orderEvent): # This will check for the boolean value of whether or not the order has been filled if not (orderEvent.Status == 'Filled'): return #python doesn't support null. Instead, check for None if (self.ProfitTarget is None) or (self.StopLoss is None): return filledOrderId = orderEvent.OrderId # If the ProfitTarget order was filled, close the StopLoss order if (self.ProfitTarget.OrderId == filledOrderId): self.StopLoss.Cancel() #If the StopLoss order was filled, close the ProfitTarget if (StopLoss.OrderId == filledOrderId): self.ProfitTarget.Cancel() 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 indicators for our symbol self.Bolband = None self.Bolband_stop =None self.RSI4 = None self.RSI3 = None self.RSI2 = None self.RSI = None 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.RSI.IsReady and self.Bolband.IsReady and self.RSI2.IsReady and self.RSI3.IsReady and self.RSI4.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