Back

Hedging Equities with Options in a Dynamic Universe

Hello all,

I wanted to share one of the algorithms I have been working on for a while now as I feel it can easily be extended/implemented by other community members. The basic outline of the algorithm is to hedge all of our equity positions (when option data is available) with options of the desired strike and expiration away from the current price and date.

The Universe Selection pulls 25 stocks considered to be stable and the desired put and call options, if available. 

The Alpha Model is a simple reversion to the mean strategy which produces insights on the equities then sends market orders on either the put or call option, depending on the equity's insight. 

Although the performance of the alpha model is weak, the alpha is not the purpose of this algorithm. The purpose of this algorithm is to create a hedging strategy with options using a dynamic universe. 

The reason I think this might be useful is we never have to implement a risk management model that removes options that are expiring too soon or have a strike price( or expiration date) that is no longer desired.  With the dynamic universe, the optimal put and call contracts are always returned. Therefore we do not need to build portfolio construction, or risk management models that take into effect options.

Before I go, I wanted to thank both Jovad Uribe and Alex from QuantConnect for working with me on this project. 

 

Jason Bohne :)

Update Backtest








0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Great post! I hope the community utilizes this implementation.

0

Hi Jason,

Interesting algorithm. Thank you for sharing it with the community. There are a few improvements we can make to it though. I've outlined these below, separated by the containing file.

main.py
We can remove the imports of the PCM and execution models. Doing so automatically imports the C# versions, increasing the backtest speed.


OptionsUniverse.py
We can move the static hard-coded values used throughout this class to the constructor's signature. This creates a single place for us to adjust all the parameters of the class.

We can change the if-tree found in SelectFine so that it uses if-elif-else to increase speed. Also, the last if-condition in the original algorithm above was causing bugs.

We can change the construction of `self.contracts` into a convenient one-liner:

self.contract = [self.GetContract(algorithm, stock) for stock in self.stocks]

Doing this requires us to adjust the signature for the GetContract method so it can receive a `stock` argument.

When sorting and filtering the contracts in GetContract, it's best if we perform all the filtering before sorting. This leads to less looping.

OptionsAlpha.py
In the OnSecuritiesChanged method:

  • There is no need to have `self.removed` as a class variable.
  • We can move the creation of consolidators and indicators for each SymbolData object into the SymbolData constructor.
  • We can use the OptionRight enum when creating OptionData objects instead of the string representation.
  • We don't actually need to create OptionData objects. We can just save a list of options.

In the Update method:

  • Add a stop condition after assigning both `putcontract` and `callcontract` to increase performance.
  • It's most convenient to assign the current value of the indicators as it saves us from typing `Current.Value` multiple times.
std=symbolData.STD.Current.Value
ema=symbolData.EMA.Current.Value

See the attached backtest for reference. All the above modifications have been applied.

Best,
Derek Melchin

1

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Thank you, Derek. 

All of those changes made sense and I will definitely implement those into my program. I appreciate the in-depth assistance.

Jason :)

0

It would be a great help if anyone explains me this block of code in OptionsUniverse.py inside SelectFine() method : 

#Following block of code combines both the symbols of equities and options
res = [i for i in self.contract if i]
self.result=[]
for t in res:
for x in t:
self.result.append(x)
self.newstocks= [x.Symbol for x in self.stocks]

#Returns our equities and hedged options
return [x for x in self.newstocks + self.result]

Basically i would like to know how does the returned list look like. I presumed that self.contract is a list containing put and call contracts of each underlying stock in portfolio. My confusions are: 
what is the reason for using two for loops ?
what is SelectFine returning at the end ? what does the + operator do ?
 

0

"t in res" is iterating over a list of tuples and "x in t" is unpacking the tuple into a list of individual put and call contract symbols, isn't it? Then the return statement concatenates the lists using the '+' operator: the list of stock symbols and the list of individual options contracts.

Splat operator could be used to remove the internal loop, though it is probably not faster.

for t in res:
self.result += [*t]

 

0

Hector Barrio , Thank you so much for the explanation. So the returned list from SelectFine() is a list with stock symbols at the beginning and then put and call contracts, right ? What i am thinking , wouldn't it be efficient if we could generate a dictionary of put/call contracts keyed by stock symbols or, returning a pandas dataframe? 

0

No problem Rayhan, I don´t think SelectFine return data type can be altered, it has to return a symbol list as it is part of the framework and the symbol list will be used to create the universe object.

https://www.quantconnect.com/docs/algorithm-framework/universe-selection

 

0

Hey Rayhan,

Yes, as Hector explained res is the list of tuples containing the selected put and call contracts for each equity in our universe. The loop unpacks it so we can combine it with the list of equities selected. The reasoning for this is so both our equities and put/call contracts can be returned from the universe selection model as the selected assets. 

I chose to return both the contracts and equities to keep it in the framework format. In the alpha model, one can generate insights both on the equities and contracts ( which often helps because we would not know whether we should hedge each equity with a put or call contract until we generate our insight on the equity).

 

By the way, thank you Hector for answering. If anyone has any other questions or suggestions, feel free to let me know. 

Jason 

0

So the AlphaModel doesnot work with OptionsChains? 

0

Thank you Jason Bohne  first of all for sharing such a nice work. Actually i am having more confusions as i dig deeper, i hope the friendly community is going to clear my confusion : 

1. Since the coarse selection is executed once in a month, however, does the finefilter execute with each resolution of the algorithm ? Or the universe selection throws the data to the OptionsAlpha once in a month ?

2. In this tutorial Option Contracts there are two rights on a contract:
x.Right = 0  call option[right to buy] x.Right = 1  put option[right to sell].
which means we can go long on call and write put. Can we not sell call and buy put ? 

3. Does the Insight in alphamodel is a prediction for future trend ? How is it useful in the next time step ?

Pardon me i might sound naive because i'm actually a newbee.

0

Hey Rayhan,

1). The Fine filter executes as often as the Coarse filter, which is on the first of each month. The universe selection class is called as frequently as the algorithm resolution is set which is minute. However, from the following snippet of code, you can see it will ignore both the coarse and fine filter and return the currently selected universe during the current month.

month= algorithm.Time.month
if month == self.lastmonth:
return Universe.Unchanged
self.lastmonth= month

2). You could sell a call and buy a put however that is doubling your hedge. Additionally, there is always more risk associated with shorting assets. I decided that only longing options was sufficient for my algorithm. Feel free to make this change if you want

3). Insight is the direction in which you think a specific asset will go in some future time period. Check out some more documentation on Insights here https://www.quantconnect.com/docs/algorithm-framework/alpha-creation#Alpha-Creation-Creating-Insights

 

Jason

1

I appriciate your answer. I completely get that now. 
Moreover, In the following code from OptionAlpha module, we check if we have call contract in the portfolio and then sell the contract right? Since MarketOrder method will sell an asset at the current market price, what will be the selling price of callcontract in this case?

if callcontract is not None and algorithm.Portfolio[callcontract.Symbol].Invested:
   algorithm.MarketOrder(callcontract.Symbol,-1,True)

If we were selling the callcontract without the condition, would that be going short on callcontract? Can we do that without a Margin Call account ?

 

#if algorithm.Portfolio[callcontract.Symbol].Invested:
algorithm.MarketOrder(callcontract.Symbol,-1,True)

 

 

0

Rayhan

Let's say we originally have a short position on equity XYZ. Then we will also have a call option (if they are available to trade) also in our portfolio. Now let's say we switch our position from a short position to a long position on XYZ. Then we do not want a call contract anymore we would want a put contract. That block of code deals with that scenario. If we are trying to buy a put but we currently have a call contract we will send out a market order to liquidate the call in addition to purchasing the put. 

 

I assume it would sell somewhere in the neighborhood of the current market price but due to slippage, low liquidity this might not always be the case. You can work with reality modeling to try and portray more accurate results in your backtest, found here 

https://www.quantconnect.com/docs/algorithm-reference/reality-modelling

 I know you can *usually* short call/put contracts however I am not sure whether or not one would need a margin account to do so. I  imagine this is a better question for your brokerage. 

 

Jason

0

Hi Rayhan and Jason,

To clarify,

if callcontract is not None and algorithm.Portfolio[callcontract.Symbol].Invested:
algorithm.MarketOrder(callcontract.Symbol,-1,True)

will not flip the direction of an option trade when currently long one call contract. To do that, -2 would need to be passed as the quantity argument. See the attached backtest for reference.

Additionally, the universe selection class is not always called as frequently as the algorithm resolution. By default, regardless of the universe resolution, universe selection is performed daily. To call it more frequently, scheduled universe selection can be used.

Best,
Derek Melchin

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


thanks Derek Melchin . Setting the quantity -2 pretty much makes sense to me as i was thinking that -1 is going to help us to close the position. 

Can anyone share a risk model for option trading as a reference ?

0

Hi Rayhan,

We have several example risk management models in the documentation. They are not tailored to options though.

Best,
Derek Melchin

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Update Backtest





0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Loading...

This discussion is closed