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 Probabilistic 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 -4.248 Tracking Error 0.126 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 |
class CustomModelsAlgorithm(QCAlgorithm): '''Demonstration of using custom fee, slippage, fill, and buying power 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(2013,10,1) # Set Start Date self.SetEndDate(2013,10,31) # Set End Date self.security = self.AddEquity("SPY", Resolution.Hour) self.spy = self.security.Symbol # set our models self.security.SetFeeModel(CustomFeeModel(self)) self.security.SetFillModel(CustomFillModel(self)) self.security.SetSlippageModel(CustomSlippageModel(self)) self.security.SetBuyingPowerModel(CustomBuyingPowerModel(self)) def OnData(self, data): open_orders = self.Transactions.GetOpenOrders(self.spy) if len(open_orders) != 0: return if self.Time.day > 10 and self.security.Holdings.Quantity <= 0: quantity = self.CalculateOrderQuantity(self.spy, .5) self.Log(f"MarketOrder: {quantity}") self.MarketOrder(self.spy, quantity, True) # async needed for partial fill market orders elif self.Time.day > 20 and self.security.Holdings.Quantity >= 0: quantity = self.CalculateOrderQuantity(self.spy, -.5) self.Log(f"MarketOrder: {quantity}") self.MarketOrder(self.spy, quantity, True) # async needed for partial fill market orders # If we want to use methods from other models, you need to inherit from one of them class CustomFillModel(ImmediateFillModel): def __init__(self, algorithm): self.algorithm = algorithm self.absoluteRemainingByOrderId = {} self.random = Random(387510346) 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(f"CustomFillModel: {fill}") return fill class CustomFeeModel(FeeModel): def __init__(self, algorithm): self.algorithm = algorithm def GetOrderFee(self, parameters): # custom fee math fee = max(1, parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.00001) self.algorithm.Log(f"CustomFeeModel: {fee}") return OrderFee(CashAmount(fee, "USD")) class CustomSlippageModel: def __init__(self, algorithm): self.algorithm = algorithm def GetSlippageApproximation(self, asset, order): # custom slippage math slippage = asset.Price * 0.0001 * np.log10(2*float(order.AbsoluteQuantity)) self.algorithm.Log(f"CustomSlippageModel: {slippage}") return slippage class CustomBuyingPowerModel(BuyingPowerModel): def __init__(self, algorithm): self.algorithm = algorithm def HasSufficientBuyingPowerForOrder(self, parameters): # custom behavior: this model will assume that there is always enough buying power hasSufficientBuyingPowerForOrderResult = HasSufficientBuyingPowerForOrderResult(True) self.algorithm.Log(f"CustomBuyingPowerModel: {hasSufficientBuyingPowerForOrderResult.IsSufficient}") return hasSufficientBuyingPowerForOrderResult