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 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 |
# Import modules required from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Python import PythonData from datetime import date, timedelta, datetime import decimal import numpy as np # Useful references: # https://www.quantconnect.com/lean/documentation/topic16.html # -> bad link for "Hard Method" Static Sourcing # https://www.quantconnect.com/docs/algorithm-reference/importing-custom-data class BasicTemplateAlgorithm(QCAlgorithm): def Initialize(self): '''Initialize algorithm.''' # Set backtest details self.SetStartDate(2018,9,1) self.SetEndDate(2018,9,8) self.SetCash(100000) #self.SetBenchmark("SPY") self.UniverseSettings.Resolution = Resolution.Minute # German XETRA (IBIS) exchange / Berlin time (9:00-17:30) # https://www.interactivebrokers.com/en/index.php?f=2222&exch=ibis self.SetTimeZone(TimeZones.Berlin) # Define Brokerage model and account type self.SetBrokerageModel( BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) # Define stocks for system self.assets = ["1COV"] # I'll eventually add more here... # System User Inputs self.trading_time_start = '09:02' #self.exchange_open_time = '09:00' # for reference (Berlin tz) self.trading_time_stop = '17:20' self.exchange_close_time = '17:30' # Berlin tz # Add equities to algorithm equities = {} equity_data = {} for asset in self.assets: equities[asset] = self.AddEquity(asset, Resolution.Minute) #market=Market.Germany # does this even matter for custom data? #market default seems to be Market.USA equity_data[asset] = self.AddData(MyCustomData, asset) equities[asset].MarginModel = PatternDayTradingMarginModel() # Just adding this so the algo will run self.spy = "SPY" self.AddEquity(self.spy, Resolution.Minute) # Create variable(s) used for algorithm self.entries = False # Schedule functions # Check for entry signals at self.trading_time_start start_split = self.trading_time_start.split(':') start_hrs = int(start_split[0]) start_minutes = int(start_split[1]) self.Log('call MyEntries at {}:{}'.format(start_hrs, start_minutes)) self.Schedule.On( self.DateRules.EveryDay(), self.TimeRules.At(start_hrs, start_minutes), Action(self.MyEntries) ) # Schedule closing all positions at self.trading_time_stop stop_split = self.trading_time_stop.split(':') stop_hrs = int(stop_split[0]) stop_minutes = int(stop_split[1]) self.Log('call CloseAllPositions at {}:{}'.format(stop_hrs, stop_minutes)) self.Schedule.On( self.DateRules.EveryDay(), self.TimeRules.At(stop_hrs, stop_minutes), Action(self.CloseAllPositions) ) # Schedule end of day function close_split = self.exchange_close_time.split(':') close_hrs = int(close_split[0]) close_minutes = int(close_split[1]) self.Log('call OnEndOfDay at {}:{}'.format(close_hrs, close_minutes)) self.Schedule.On( self.DateRules.EveryDay(), self.TimeRules.At(close_hrs, close_minutes), Action(self.OnEndOfDay) ) def MyEntries(self): '''Enter positions for the day.''' self.Log('MyEntries() called') try: for asset in self.assets: # Get latest closing price #self.Log('{} close: {}'.format(asset, self.close[asset])) # Place market entry order self.MarketOrder(asset, 100) except: pass # Update self.entries variable self.entries = True def CancelOpenOrders(self): '''Cancel all open orders.''' open_orders = self.Transactions.GetOpenOrders() if open_orders: for order in open_orders: self.Log('Cancelling order: {}'.format(order)) self.Transactions.CancelOrder(order.Id) def CancelSymbolOpenOrders(self, symbol): '''Cancel all open orders for a given symbol.''' open_orders = self.Transactions.GetOpenOrders(symbol) if open_orders: for order in open_orders: self.Log('Cancelling order: {}'.format(order)) self.Transactions.CancelOrder(order.Id) def CloseAllPositions(self): '''Close all positions.''' # Cancel open orders self.CancelOpenOrders() # Close all equity positions self.Log('Closing all positions for the end of the trading day') for asset in self.assets: shares = self.Portfolio[asset].Quantity if shares != 0: self.MarketOrder(asset, -shares) self.Log(' Close position for {} shares of {}'.format( shares, asset)) def OnData(self, slice): '''Each new data point will be pumped in here.''' # Skip once positions are entered for the day if self.entries: return # Get the latest prices? self.close = {} for asset in self.assets: if slice.ContainsKey(asset): self.close[asset] = data[asset].Close self.Debug("Time: {}, {} close: {}".format( datetime.now(), asset, self.close[asset])) def OnEndOfDay(self): '''Called at the end of every day.''' # Reset variable self.entries = False def OnOrderEvent(self, orderEvent): # Skip if not filled if orderEvent.Status != OrderStatus.Filled: return # Get order info order = self.Transactions.GetOrderById(orderEvent.OrderId) # Check for filled entry order current_qty = self.Portfolio[order.Symbol].Quantity order_qty = order.Quantity if current_qty == order_qty: self.Log('Filled entry order: {}'.format(order)) elif current_qty == 0: # Cancel other open exit order for symbol self.Log('Filled exit order: {}'.format(order)) self.CancelSymbolOpenOrders(order.Symbol) # Print order details when desired self.Log(str(orderEvent)) class MyCustomData(PythonData): ''' Custom Data Class REFs: https://www.quantconnect.com/forum/discussion/4079/python-best-practise-for-using-consolidator-on-custom-data/p1 ''' def GetSource(self, config, date, isLiveMode): file = "https://docs.google.com/spreadsheets/d/e/2PACX-1vReHX1zAOU8Kgylr1npfZjxw8b52vXA5EH5MpBkFqm2-eN1GVXYi7ei8T_a1xiJReDNulRerDmqpg9L/pub?output=csv" return SubscriptionDataSource( file, SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLiveMode): # If first character is not digit, pass if not (line.strip() and line[0].isdigit()): return None # New object asset = MyCustomData() asset.Symbol = config.Symbol #asset.DataType = MarketDataType.TradeBar try: # Example File Format: # Date Open High Low Close Volume # 2017-01-02 09:02:00+01:00 64.88 64.88 64.43 64.43 8082 # Date, Open High Low Close Volume Turnover # 2011-09-13 7792.9 7799.9 7722.65 7748.7 116534670 6107.78 data = line.split(',') _date = datetime.strptime(data[0].split(' ')[0], "%Y-%m-%d") _time = data[0].split(' ')[1] #asset.Time = ? asset.Value = decimal.Decimal(data[4]) asset["Open"] = float(data[1]) asset["High"] = float(data[2]) asset["Low"] = float(data[3]) asset["Close"] = float(data[4]) asset["Volume"] = float(data[5]) except ValueError: # Do nothing return None return asset