| 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