Adds CustomBuyingPowerModelAlgorithm (#4824)
* Adds CustomBuyingPowerModelAlgorithm This algorithms is an example on how to implement a custom buying power model. In this particular case, it shows how to override `HasSufficientBuyingPowerForOrder` in order to place orders without sufficient buying power according to the default model. * Upgrades CustomModelsAlgorithm to Include CustomBuyingPowerModel The custom buying power model overrides `HasSufficientBuyingPowerForOrderResult` but it doesn't change the trades and, consequently, the regression statistics.
This commit is contained in:
committed by
GitHub
parent
b2ed398687
commit
84264ca7ef
@@ -27,16 +27,17 @@ import numpy as np
|
||||
import random
|
||||
|
||||
### <summary>
|
||||
### Demonstration of using custom fee, slippage and fill models for modelling transactions in backtesting.
|
||||
### 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.
|
||||
### </summary>
|
||||
### <meta name="tag" content="trading and orders" />
|
||||
### <meta name="tag" content="transaction fees and slippage" />
|
||||
### <meta name="tag" content="custom buying power models" />
|
||||
### <meta name="tag" content="custom transaction models" />
|
||||
### <meta name="tag" content="custom slippage models" />
|
||||
### <meta name="tag" content="custom fee models" />
|
||||
class CustomModelsAlgorithm(QCAlgorithm):
|
||||
'''Demonstration of using custom fee, slippage and fill models for modelling transactions in backtesting.
|
||||
'''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):
|
||||
@@ -49,6 +50,7 @@ class CustomModelsAlgorithm(QCAlgorithm):
|
||||
self.security.SetFeeModel(CustomFeeModel(self))
|
||||
self.security.SetFillModel(CustomFillModel(self))
|
||||
self.security.SetSlippageModel(CustomSlippageModel(self))
|
||||
self.security.SetBuyingPowerModel(CustomBuyingPowerModel(self))
|
||||
|
||||
|
||||
def OnData(self, data):
|
||||
@@ -57,12 +59,12 @@ class CustomModelsAlgorithm(QCAlgorithm):
|
||||
|
||||
if self.Time.day > 10 and self.security.Holdings.Quantity <= 0:
|
||||
quantity = self.CalculateOrderQuantity(self.spy, .5)
|
||||
self.Log("MarketOrder: " + str(quantity))
|
||||
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("MarketOrder: " + str(quantity))
|
||||
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
|
||||
@@ -90,7 +92,7 @@ class CustomFillModel(ImmediateFillModel):
|
||||
absoluteRemaining = absoluteRemaining - absoluteFillQuantity
|
||||
self.absoluteRemainingByOrderId[order.Id] = absoluteRemaining
|
||||
fill.Status = OrderStatus.PartiallyFilled
|
||||
self.algorithm.Log("CustomFillModel: " + str(fill))
|
||||
self.algorithm.Log(f"CustomFillModel: {fill}")
|
||||
return fill
|
||||
|
||||
class CustomFeeModel(FeeModel):
|
||||
@@ -102,7 +104,7 @@ class CustomFeeModel(FeeModel):
|
||||
fee = max(1, parameters.Security.Price
|
||||
* parameters.Order.AbsoluteQuantity
|
||||
* 0.00001)
|
||||
self.algorithm.Log("CustomFeeModel: " + str(fee))
|
||||
self.algorithm.Log(f"CustomFeeModel: {fee}")
|
||||
return OrderFee(CashAmount(fee, "USD"))
|
||||
|
||||
class CustomSlippageModel:
|
||||
@@ -112,5 +114,15 @@ class CustomSlippageModel:
|
||||
def GetSlippageApproximation(self, asset, order):
|
||||
# custom slippage math
|
||||
slippage = asset.Price * 0.0001 * np.log10(2*float(order.AbsoluteQuantity))
|
||||
self.algorithm.Log("CustomSlippageModel: " + str(slippage))
|
||||
return slippage
|
||||
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
|
||||
Reference in New Issue
Block a user