Overall Statistics |
Total Trades 852 Average Win 0.18% Average Loss -0.12% Compounding Annual Return 0.319% Drawdown 5.900% Expectancy 0.013 Net Profit 0.585% Sharpe Ratio 0.112 Loss Rate 59% Win Rate 41% Profit-Loss Ratio 1.49 Alpha -0.028 Beta 1.584 Annual Standard Deviation 0.033 Annual Variance 0.001 Information Ratio -0.487 Tracking Error 0.033 Treynor Ratio 0.002 Total Fees $852.00 |
from datetime import datetime, timedelta import numpy as np import decimal as d import dateutil from QuantConnect.Brokerages import * ### <summary> ### Basic template algorithm simply initializes the date range and cash. This is a skeleton ### framework you can use for designing an algorithm. ### </summary> class BasicTemplateAlgorithm(QCAlgorithm): '''Basic template algorithm simply initializes the date range and cash''' def Initialize(self): '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.''' self.total_cash = 20000 self.SetStartDate(2017, 2, 1) # Set Start Date self.SetEndDate(2018, 12, 1) # Set End Date self.SetCash(self.total_cash) # Set Strategy Cash self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) self.capital_per_trade = 10000 #self.total_cash/2.0 self.symbol = "IWM" # Find more symbols here: http://quantconnect.com/data self.AddEquity(self.symbol, Resolution.Minute) self.prev_vidya = 0.0 self.vidya_period = 14 self.adx_period = 14 self.stop_loss = 4 self.profit_target = 0.3 self.adx_threshold = 28 self.per_stop_loss = self.stop_loss/100 self.per_profit_target = self.profit_target/100 self.enter_price = 0.0 self.enter = False self.exit = False # define our 30 minute trade bar consolidator. we can # access the 30 minute bar from the DataConsolidated events thirtyMinuteConsolidator = TradeBarConsolidator(timedelta(minutes=30)) # attach our event handler. The event handler is a function that will # be called each time we produce a new consolidated piece of data. thirtyMinuteConsolidator.DataConsolidated += self.ThirtyMinuteBarHandler # this call adds our 30-minute consolidator to # the manager to receive updates from the engine self.SubscriptionManager.AddConsolidator(self.symbol, thirtyMinuteConsolidator) # dailyConsolidator = TradeBarConsolidator(TimeSpan.FromDays(1)) # self.SubscriptionManager.AddConsolidator(self.symbol, dailyConsolidator) # dailyConsolidator.DataConsolidated += self.dailyBarHandler self.adx = self.ADX(self.symbol, self.adx_period, Resolution.Daily) self.cmo = self.CMO(self.symbol, self.vidya_period) self.RegisterIndicator(self.symbol, self.adx, Resolution.Daily) # self.RegisterIndicator(self.symbol, self.cmo, thirtyMinuteConsolidator) # def dailyBarHandler(self, sender, bar): # Chart('ADX') # self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose(self.symbol), # self.update_plots) def determine_vidya(self, period, cmo , prev_vidya, close): alpha = 2 / period * 1 float_close = float(close) float_cmo = float(cmo) # vidya1 = alpha + prev_vidya * (1 - alpha * cmo) vidya = float_close * alpha + prev_vidya * (1 - alpha * float_cmo) return vidya def ThirtyMinuteBarHandler(self, sender, bar): '''This is our event handler for our 30-minute trade bar defined above in Initialize(). So each time the consolidator produces a new 30-minute bar, this function will be called automatically. The sender parameter will be the instance of the IDataConsolidator that invoked the event ''' printafterdate = "2018-11-18" odate = dateutil.parser.parse(printafterdate) currentdatetime = str(self.Time) currentdate = currentdatetime[:10] ocurrentdate = dateutil.parser.parse(currentdate) self.cmo.Update(bar.EndTime, bar.Close) processafterdate = "2017-10-30" oprocessdate = dateutil.parser.parse(processafterdate) if self.adx.IsReady and self.cmo.IsReady and (ocurrentdate > oprocessdate): vidya = self.determine_vidya(self.vidya_period, self.cmo.Current.Value, self.prev_vidya, bar.Close) self.prev_vidya = vidya # if ocurrentdate > odate: # self.Debug(str(self.Time) + ":" + str(bar) + ",ADX:" + str(self.adx.Current.Value) + # ",CMO:" + str(self.cmo.Current.Value) + ",CMOTime:" + str(bar.EndTime)) if not self.Portfolio.Invested: tech1_cond = float(self.adx.Current.Value) > self.adx_threshold if (tech1_cond): self.Debug(str(bar.EndTime) + ":" + "Tech1 condition met") tech2_cond = vidya > float(bar.High) if (tech2_cond): self.Debug(str(bar.EndTime) + ":" + "Tech2 condition met") if tech1_cond and tech2_cond: self.enter = True self.Debug(str(bar.EndTime) + ":" + "Enter condition met") if self.Portfolio.Invested: stoploss_level = self.enter_price * (1 + self.per_stop_loss) stoploss_cond = bar.Close > stoploss_level if (stoploss_cond): self.Debug(str(bar.EndTime) + ":" + "Stoploss condition met") profit_level = self.enter_price * (1 - self.per_profit_target) profit_cond = bar.Close < profit_level if (profit_cond): self.Debug(str(bar.EndTime) + ":" + "Profit condition met") tech_cond = vidya < float(bar.Low) if tech_cond or stoploss_cond or profit_cond: self.exit = True self.Debug(str(bar.EndTime) + ":" + "Exit condition met") if self.enter == True: # per_quantity = 0.5 * self.capital_per_trade/float(bar.Open) self.SetHoldings(self.symbol, -0.5) self.enter_price = float(bar.Open) self.enter = False if (self.exit == True): self.Liquidate(self.symbol) self.exit_price = float(bar.Open) self.exit = False # else: # self.Debug(str(self.Time) + ":" + str(bar)) # # self.Debug("Daily Bar Handler" + str(self.Time) + " " + str(bar) + str(adx)) # float_bar_close = float(bar.Close) # self.determine_vma(float_bar_close) def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. Arguments: data: Slice object keyed by symbol containing the stock data ''' def update_plots(self): if not self.adx.IsReady: return # Plots can also be created just with this one line command. self.Plot('ADX', self.adx)