Short Availability
Key Concepts
Introduction
To short a security, you need to borrow shares from another investor or organization that owns the shares. A shortable provider is a model that tracks the number of shares that are available for you to borrow. A shortable provider can make your backtest results more realistic because it doesn't let you place a short trade if there are no shares available for you to borrow.
Set Providers
The brokerage model of your algorithm automatically sets the settlement model for each security, but you can override it. To manually set the shortable provider of a security, call the SetShortableProvider
set_shortable_provider
method on the Security
object.
public override void Initialize() { var security = AddEquity("SPY"); // Get shortable stocks and quantity from local disk security.SetShortableProvider(new LocalDiskShortableProvider("axos")); }
def initialize(self) -> None: security = self.add_equity("SPY") # Get shortable stocks and quantity from local disk security.set_shortable_provider(LocalDiskShortableProvider("axos"))
You can also set the shortable provider in a security initializer. If your algorithm has a universe, use the security initializer technique. In order to initialize single security subscriptions with the security initializer, call SetSecurityInitializer
set_security_initializer
before you create the subscriptions.
public override void Initialize() { // Set the security initializer before requesting data to apply to all requested securities afterwards SetSecurityInitializer(CustomSecurityInitializer); AddEquity("SPY"); } private void CustomSecurityInitializer(Security security) { security.SetShortableProvider(new LocalDiskShortableProvider("axos")); }
def initialize(self) -> None: # Set the security initializer before requesting data to apply to all requested securities afterwards self.set_security_initializer(self.custom_security_initializer) self.add_equity("SPY") def custom_security_initializer(self, security: Security) -> None: security.set_shortable_provider(LocalDiskShortableProvider("axos"))
If you call the SetSecurityInitializer
set_security_initializer
method, it overwrites the default security initializer. The default security initializer uses the security-level reality models of the brokerage model to set the following reality models of each security:
To extend upon the default security initializer instead of overwriting it, create a custom BrokerageModelSecurityInitializer
.
public class BrokerageModelExampleAlgorithm : QCAlgorithm { public override void Initialize() { // In the Initialize method, set the security initializer to seed initial the prices and models of assets. SetSecurityInitializer(new MySecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices))); } } public class MySecurityInitializer : BrokerageModelSecurityInitializer { public MySecurityInitializer(IBrokerageModel brokerageModel, ISecuritySeeder securitySeeder) : base(brokerageModel, securitySeeder) {} public override void Initialize(Security security) { // First, call the superclass definition. // This method sets the reality models of each security using the default reality models of the brokerage model. base.Initialize(security); // Next, overwrite some of the reality models security.SetShortableProvider(new LocalDiskShortableProvider("axos")); } }
class BrokerageModelExampleAlgorithm(QCAlgorithm): def initialize(self) -> None: # In the Initialize method, set the security initializer to seed initial the prices and models of assets. self.set_security_initializer(MySecurityInitializer(self.brokerage_model, FuncSecuritySeeder(self.get_last_known_prices))) # Outside of the algorithm class class MySecurityInitializer(BrokerageModelSecurityInitializer): def __init__(self, brokerage_model: IBrokerageModel, security_seeder: ISecuritySeeder) -> None: super().__init__(brokerage_model, security_seeder) def initialize(self, security: Security) -> None: # First, call the superclass definition. # This method sets the reality models of each security using the default reality models of the brokerage model. super().initialize(security) # Next, overwrite some of the reality models security.set_shortable_provider(LocalDiskShortableProvider("axos"))
To view all the pre-built shortable providers, see Supported Providers.
Default Behavior
The brokerage model of your algorithm automatically sets the shortable provider for each security. The default brokerage model is the DefaultBrokerageModel
, which uses the NullShortableProvider.
Provider Structure
Shortable providers must implement the IShortableProvider
interface.
Shortable providers that implement the IShortableProvider
interface must implement the FeeRate
fee_rate
, RebateRate
rebate_rate
, and ShortableQuantity
shortable_quantity
methods.
These methods receives a Symbol and the local time of the algorithm.
The FeeRate
fee_rate
method returns the borrow fee rate.
The RebateRate
rebate_rate
method returns the borrow rebate rate.
The ShortableQuantity
shortable_quantity
returns the shortable quantity.
public class CustomShortableProviderExampleAlgorithm : QCAlgorithm { public override void Initialize() { var security = AddEquity("SPY"); // Provide the selected security with your broker's shortable information security.SetShortableProvider(new MyShortableProvider()); } } // Define the custom shortable provider class MyShortableProvider : IShortableProvider { public decimal FeeRate(Symbol symbol, DateTime localTime) { return 0.0025m; } public decimal RebateRate(Symbol symbol, DateTime localTime) { return 0.0507m; } public long? ShortableQuantity(Symbol symbol, DateTime localTime) { return 10000; } }
class CustomShortableProviderExampleAlgorithm(QCAlgorithm): def initialize(self) -> None: security = self.add_equity("SPY") # Provide the selected security with your broker's shortable information security.set_shortable_provider(MyShortableProvider()) # Define the custom shortable provider class MyShortableProvider(NullShortableProvider): def fee_rate(self, symbol: Symbol, local_time: datetime) -> float: return 0.0025 def rebate_rate(self, symbol: Symbol, local_time: datetime) -> float: return 0.0507 def shortable_quantity(self, symbol: Symbol, local_time: datetime) -> float: return 10000
For a full example algorithm, see this backtestthis backtest.
Borrowing Costs
In live trading, your brokerage charges an interest fee when you borrow shares to short a security. In backtesting, we don't currently simulate short interest fees. You can evaluate the borrowing cost with the FeeRate
fee_rate
and RebateRate
rebate_rate
methods.
To get valid borrowing rates, use the InteractiveBrokersShortableProvider.