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 |
class TradingSetup(object): def __init__(self, symbol, entry, stop, profit, shares, order): self.Symbol = symbol self.Entry = entry self.Stop = stop self.Profit = profit self.Shares = shares self.StopEntryOrder = order self.StopLossOrder = None self.TakeProfitOrder = None self.Active = True self.Filled = False ######## NOT CURRENTLY IN USE ########## class RollingWindowNum(object): def __init__(self, symbol, size): self.Symbol = symbol self.Data = RollingWindow[float](size) #Is there a way to use Decimal instead of float? There would be an error if replace it by Decimal. self.Error = True #No data in the beginning = no trades class SymbolData(object): def __init__(self, symbol, barPeriod, windowSize): self.Symbol = symbol 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) # 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
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. # Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Orders import * from QuantConnect.Algorithm import * from QuantConnect.Data.Consolidators import * from QuantConnect.Data.Market import * from QuantConnect.Indicators import * from datetime import datetime, timedelta import pandas as pd import numpy as np from classes import * from decimal import Decimal # Important: import decimal.Decimal class class DayTrading(QCAlgorithm): def Initialize(self): self.SetStartDate(2016,1,4) #Set Start Date self.SetEndDate(2016,1,7) #Set End Date self.SetCash(100000) #Set Strategy Cash self.R = 200 #self.UniverseSettings.Resolution = Resolution.Minute self.UniverseSettings.ExtendedMarketHours = True self.AddUniverse("gapfinder", Resolution.Hour, self.Filter) #self.AddUniverse(self.Filter) self.AddEquity("SPY") self.gappers = [] self.universe = [] self.LookingForBreakout = False #When true, the bot starts to look for high wave candle self.PrevDay = self.Time - timedelta(1) #self.PrevDayClose[sym] = RollingWindowNum(symbol, 5) #threeMinConsolidator = TradeBarConsolidator(timedelta(minutes=3)) # attach our event handler. The event handler is a function that will # be called each time we produce a new consolidated piece of data. #threeMinConsolidator.DataConsolidated += self.threeMinBarHandler # this call adds our 3-minute consolidator to # the manager to receive updates from the engine #self.SubscriptionManager.AddConsolidator(sym, threeMinConsolidator) self.Schedule.On(self.DateRules.EveryDay("SPY"), \ self.TimeRules.AfterMarketOpen("SPY", 120), \ Action(self.MarketCloseLiquidate)) def Filter(self, coarse): #if self.Time.hour != 0 and self.Time.hour != 16: # I'm looking at 9:00 # return self.universe self.Log("test") self.Log("c:"+str(coarse)) try: sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) except: return self.universe filtered = [ x.Symbol for x in sortedByDollarVolume if x.Price > 5 and x.DollarVolume > 10000000 ] gappers = [] self.Log(filtered) for sym in filtered: if self.PrevDay != None : bar = self.History(sym, self.PrevDay, self.PrevDay, Resolution.Daily) if not bar.empty : GapPercentage = (sym.Price - bar.close) / bar.close self.Log(GapPercentage) self.universe = gappers return gappers def threeMinBarHandler(self, sender, bar): #This is our event handler for our 3-minute trade bar defined above in Initialize(). #So each time the consolidator produces a new 3-minute bar, this function will be called automatically. #The sender parameter will be the instance of the IDataConsolidator that invoked the event if bar.Symbol.Value not in self.gappers: #Only trade gappers. return if self.LookingForBreakout == True : #self.Log("bar:" + str(bar.Symbol.Value)) #self.Log(self.gappers) if self.IsHighWave(bar) : self.Log("Highwave found! " + str(bar.High) + str(bar.Low) + str(bar.Open) + str(bar.Close)) newTicket = self.StopLimitOrder(bar.Symbol, round(self.R / (bar.High - bar.Low) ) , bar.High , bar.High) self.Trades.append( TradingSetup(bar.Symbol, bar.High, bar.Low, 2*bar.High - bar.Low, round(self.R / (bar.High - bar.Low) ), newTicket) ) return def IsHighWave(self, bar): HighLowDiff = bar.High - bar.Low OpenCloseDiff = bar.Open - bar.Close if HighLowDiff / bar.Open >= 0.005 and ( OpenCloseDiff == 0 or ( HighLowDiff / OpenCloseDiff >= 2 and (bar.High - bar.Open) / OpenCloseDiff >=0.5 and (bar.Close - bar.Low) / OpenCloseDiff >=0.5 )) : return True return False ##### ORDER EVENT:entry triggered/stop triggered/tp triggered ###### def OnOrderEvent(self, orderEvent): #order = self.Transactions.GetOrderById(orderEvent.OrderId) self.Log(orderEvent) for trade in self.Trades : if orderEvent.OrderId == trade.StopEntryOrder.OrderId : if orderEvent.Status == OrderStatus.Canceled : return if orderEvent.Status == OrderStatus.PartiallyFilled : return #To trade live, it needs a better behaviour if orderEvent.Status == OrderStatus.Filled : trade.StopLossOrder = self.StopMarketOrder(trade.Symbol, -trade.Shares, trade.Stop) trade.TakeProfitOrder = self.LimitOrder(trade.Symbol, -trade.Shares, trade.Profit) self.Log("SL@"+str(trade.Stop)+":" + str(trade.StopLossOrder)) self.Log("TP@"+str(trade.Profit)+":" + str(trade.TakeProfitOrder)) return if trade.StopLossOrder != None and orderEvent.OrderId == trade.StopLossOrder.OrderId and orderEvent.Status == OrderStatus.Filled : #if trade.TakeProfitOrder != None: trade.TakeProfitOrder.Cancel() #One cancel the other return if trade.TakeProfitOrder != None and orderEvent.OrderId == trade.TakeProfitOrder.OrderId and orderEvent.Status == OrderStatus.Filled : #if trade.StopLossOrder != None: trade.StopLossOrder.Cancel() #One cancel the other return def MarketCloseLiquidate(self): self.Liquidate() self.PrevDay = self.Time openOrders = self.Transactions.GetOpenOrders() if len(openOrders) > 0: for x in openOrders: self.Transactions.CancelOrder(x.Id) #self.Log(str(x.Id) + " canceled") def OnData(self, data): self.data = data