Overall Statistics |
Total Trades 291 Average Win 0.19% Average Loss -0.19% Compounding Annual Return -2.211% Drawdown 8.900% Expectancy -0.022 Net Profit -1.216% Sharpe Ratio -0.195 Loss Rate 51% Win Rate 49% Profit-Loss Ratio 1.01 Alpha -0.257 Beta 12.114 Annual Standard Deviation 0.092 Annual Variance 0.008 Information Ratio -0.41 Tracking Error 0.092 Treynor Ratio -0.001 Total Fees $583.75 |
import numpy as np import random class CustomModelsAlgorithm(QCAlgorithm): '''Demonstration of using custom fee, slippage and fill models for modelling transactions in backtesting. QuantConnect allows you to model all orders as deeply and accurately as you need.''' def Initialize(self): self.SetStartDate(2019,1,1) # Set Start Date self.security = self.AddEquity("LII", Resolution.Hour) self.lii = self.security.Symbol # set our models self.security.SetFillModel(CustomFillModel(self)) def OnData(self, data): open_orders = self.Transactions.GetOpenOrders(self.lii) if len(open_orders) != 0: return if self.Time.day > 10 and self.security.Holdings.Quantity <= 0: quantity = self.CalculateOrderQuantity(self.lii, .5) self.Log("MarketOrder: " + str(quantity)) self.MarketOrder(self.lii, quantity, True) # async needed for partial fill market orders elif self.Time.day > 20 and self.security.Holdings.Quantity >= 0: quantity = self.CalculateOrderQuantity(self.lii, -.5) self.Log("MarketOrder: " + str(quantity)) self.MarketOrder(self.lii, quantity, True) # async needed for partial fill market orders # inherit Immediate Fill Model class CustomFillModel(ImmediateFillModel): def __init__(self, algorithm): self.algorithm = algorithm self.absoluteRemainingByOrderId = {} self.random = Random(1234) def MarketFill(self, asset, order): absoluteRemaining = order.AbsoluteQuantity if order.Id in self.absoluteRemainingByOrderId.keys(): absoluteRemaining = self.absoluteRemainingByOrderId[order.Id] fill = super().MarketFill(asset, order) absoluteFillQuantity = int(min(absoluteRemaining, self.random.Next(0, 2*int(order.AbsoluteQuantity)))) fill.FillQuantity = np.sign(order.Quantity) * absoluteFillQuantity if absoluteRemaining == absoluteFillQuantity: fill.Status = OrderStatus.Filled if self.absoluteRemainingByOrderId.get(order.Id): self.absoluteRemainingByOrderId.pop(order.Id) else: absoluteRemaining = absoluteRemaining - absoluteFillQuantity self.absoluteRemainingByOrderId[order.Id] = absoluteRemaining fill.Status = OrderStatus.PartiallyFilled self.algorithm.Log("CustomFillModel: " + str(fill)) return fill