| Overall Statistics |
|
Total Trades 125 Average Win 0.05% Average Loss -0.04% Compounding Annual Return -1.365% Drawdown 1.500% Expectancy -0.636 Net Profit -1.363% Sharpe Ratio -2.892 Probabilistic Sharpe Ratio 0.000% Loss Rate 84% Win Rate 16% Profit-Loss Ratio 1.26 Alpha -0.009 Beta 0.01 Annual Standard Deviation 0.003 Annual Variance 0 Information Ratio 0.179 Tracking Error 0.141 Treynor Ratio -0.995 Total Fees $125.00 Estimated Strategy Capacity $14000000.00 Lowest Capacity Asset IBM 2T |
class MeasuredFluorescentPinkButterfly(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2018, 1, 1) # Set Start Date
self.SetEndDate(2019, 1, 1)
self.SetCash(10000) # Set Strategy Cash
self.AddEquity("IBM", Resolution.Minute)
dailyConsolidator = TradeBarConsolidator(TimeSpan.FromDays(1))
dailyConsolidator.DataConsolidated += self.DailyConsolidator
self.SubscriptionManager.AddConsolidator("IBM", dailyConsolidator)
self.entrySignalMessage = ""
self.entryPrice = None
self.highestPrice = None
self.timeInTrade = None
self.limitMarketTicket = None
self.openPrice = None
self.stopLoss = 0.99
self.trailingStopLoss = 0.984
self.targetStop = 1.08
# self.obv = OnBalanceVolume()
# self.RegisterIndicator("IBM", self.obv, TimeSpan.FromDays(1))
self.closeWindow = RollingWindow[float](3)
self.openWindow = RollingWindow[float](3)
self.highWindow = RollingWindow[float](3)
#self.obvWindow = RollingWindow[float](3)
self.SetWarmup(8)
def DailyConsolidator(self, sender, bar):
self.closeWindow.Add(self.Securities["IBM"].Close)
self.highWindow.Add(self.Securities["IBM"].Close)
#self.obvWindow.Add(self.obv.Current.Value)
def OnData(self, data):
if self.Time.hour == 9 and self.Time.minute == 31:
self.openWindow.Add(self.Securities["IBM"].Open)
if self.Time.hour <= 9 and self.Time.minute <= 32: return
if self.EntrySignalFired():
if not self.Portfolio.Invested:
quantity = self.CalculateOrderQuantity("IBM", 0.025)
self.marketTicket = self.MarketOrder("IBM", quantity, tag=self.entrySignalMessage)
if self.Portfolio.Invested and ((self.entryPrice and self.highestPrice) != None):
if not self.Transactions.GetOpenOrders("IBM"):
self.Debug(f"order price = {self.entryPrice}")
self.stopMarketTicket = self.StopMarketOrder("IBM", \
-self.Portfolio["IBM"].Quantity, \
(self.stopLoss * self.entryPrice))
self.limitMarketTicket = self.LimitOrder("IBM", \
-self.Portfolio["IBM"].Quantity, \
(self.targetStop * self.entryPrice))
# if self.Securities["IBM"].Close > self.highestPrice and ((self.Securities["IBM"].Close*self.trailingStopLoss) < (self.entryPrice*self.stopLoss)):
# self.highestPrice = self.Securities["IBM"].Close
# updateFields = UpdateOrderFields()
# updateFields.StopPrice = self.Securities["IBM"].Close * self.trailingStopLoss
if not self.Portfolio["IBM"].Invested:
if not self.limitMarketTicket is None:
self.limitMarketTicket.Cancel()
self.entryPrice = None
self.highestPrice = None
if self.ExitSignalFired():
if self.Portfolio["IBM"].Invested:
self.Liquidate()
self.entryPrice = None
self.highestPrice = None
def EntrySignalFired(self):
if not (self.closeWindow.IsReady and self.openWindow.IsReady and self.highWindow.IsReady): return
# obvList = list(self.obvWindow)
# obvList.reverse()
# obvMax = max(obvList[:-1])
if self.highWindow[0] < self.highWindow[1] and \
self.closeWindow[0] < self.openWindow[1] and \
self.openWindow[0] < self.highWindow[0] and self.Securities["IBM"].Price > self.highWindow[0]:
return True
return False
def ExitSignalFired(self):
if (self.timeInTrade != None) and (self.Time - self.timeInTrade).days >= 8:
return True
def OnOrderEvent(self, orderEvent):
order = self.Transactions.GetOrderById(orderEvent.OrderId)
if order.Type == OrderType.Market and order.Status == OrderStatus.Filled:
self.entryPrice = orderEvent.FillPrice
self.highestPrice = orderEvent.FillPrice
self.timeInTrade = self.Time
if order.Type == OrderType.StopMarket and order.Status == OrderStatus.Filled:
self.limitMarketTicket.Cancel()
if order.Type == OrderType.Limit and order.Status == OrderStatus.Filled:
self.stopMarketTicket.Cancel()