Back

Entry on long straddles to anticipate earnings surprises

Hi there,

I'm trying to create code that identifies those underlyings that are having earnings days in 7 days, add them to my universe to buy a long straddle, then sell those positions on earnings day.

With my code it seems to be identifying those items in the universe that are having earnings days in 7 days and adding them, however:

                if (data.OptionChains.TryGetValue(OptionSymbol, out chain))

this is never evaluating to true (and I'm thus never executing a trade). I've debuged the OptionSymbol object and it's not undefined or anything, thoughts? According to this file: http://data.quantconnect.com/option/usa/options.txt 'fb,' for instance, should have options data.

My code is attached.

Thanks for the help!

Update Backtest








As a note, 

public override void OnData(Slice data) {
...
}

was originally

public override void OnData(TradeBars data) {
...
}

in the example for coarse/fine universe filtering I stole. Is my Slice data incorrect in my code?

Moreover, is there a way to build an OptionChains chain other than:

if (data.OptionChains.TryGetValue(OptionSymbol, out chain))

which could be the answer that'll work in my case?

0

After I get this entering orders, I'll need to fix a few other things I would need help with, too:

1) Get it to buy chains that are 30-45 days out from today;

2) Get it to buy a % of the buying power in the account's worth of straddles at a time (instead of just 1).

0

We are attaching an example that may put you in the right direction.
We limit it to only trade SPY options:

public IEnumerable<Symbol> FineSelectionFunction(IEnumerable<FineFundamental> fine)
{
// Only return SPY for testing purposes
return fine.Where(x=> x.Symbol.Value == "SPY").Select(x => x.Symbol);
}

Once the symbols are added to the universe, you should use OnSecuritiesChanged to add the options:

public override void OnSecuritiesChanged(SecurityChanges changes)
{
// Add option for every added security
foreach (var security in changes.AddedSecurities)
{
if (security is Option) continue;

var option = AddOption(security.Symbol);
option.SetFilter(-2, 2, TimeSpan.Zero, TimeSpan.FromDays(45));
}
}

And the trading logic will remain in the OnData event handler like it would if you had used AddOption in Initialize.

Now you will have to add logic to avoid buying straddles when you already have one in your portfolio. After that, you can modify the Fine Universe Selection to allow more symbols.  

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 for your help!

I can't seem to attach a new backtest because of the below error. If I remove:

// Add option for every added security
foreach (var security in changes.AddedSecurities) {
if (security is Option) continue;
                
    var option = AddOption(security.Symbol);
    option.SetFilter(-2, 2, TimeSpan.Zero, TimeSpan.FromDays(45));
}

from 'OnSecuritiesChanged,' the backtest appears to work and consider multiple securities and also doesn't give the error.

I see the occasional error `Runtime Error: System.InvalidCastException: Specified cast is not valid` in OnSecuritiesChanged, thoughts?

When I switched back to universe selection, the code seems to only be considering SPY, here's some output from the line:

Debug("Securities added: " + string.Join(",", changes.AddedSecurities.Select(x => x.Symbol.Value)));

 

973 | 20:03:35: Securities added: SPY
974 | 20:03:39: Securities added: SPY 160318C00194500, SPY 160318C00195000, SPY 160318C00195500,SPY 160318C00196000,SPY 160318P00194500, SPY 160318P00195000, SPY 160318P00195500,SPY 160318P00196000,SPY ...
975 | 20:03:39: Securities added: SPY 160318C00194000, SPY 160318P00194000, SPY 160415C00194000,SPY 160415P00194000
976 | 20:03:40: Securities added: SPY 160318C00196500, SPY 160318P00196500
977 | 20:03:40: Securities added: SPY 160318C00197000, SPY 160318P00197000, SPY 160415C00197000, SPY 160415P00197000
978 | 20:03:41: Securities added: SPY 160318C00197500, SPY 160318P00197500
979 | 20:03:42: Securities added: SPY 160318C00198000, SPY 160318P00198000, SPY 160415C00198000, SPY 160415P00198000
980 | 20:03:43: Securities added: SPY 160318C00198500, SPY 160318P00198500

 

0


Please checkout the attached project, where we use buy straddles of 5 stocks that fall under our universe selection criteria. The algorithm is explained in my previous commment. We only added a List of Symbols to keep track of straddles that were bought.

The "Runtime Error: System.InvalidCastException: Specified cast is not valid" was due to using a wrong value for the first parameter of AddOption:

var option = AddOption(security.Symbol); // Wrong
var option = AddOption(security.Symbol.Value); // Right


 

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!

That's helpful.

I've added in the Liquidate code for when the equities leave the universe - which I hoped would be 7 days later, according to:

Time >= x.EarningReports.FileDate.AddDays(-7) && 
                    Time >= x.EarningReports.FileDate.AddDays(0) && 

 

However it seems my straddles are being immediately resold back to market :(

Thanks for all your help so far!

 

0


I've implemented a SL/TP on my trades instead of trying to resell the straddles on earnings days, but it appears my fine universe selection is adding way more securities than I would have wanted :( 

How can I get it to add just those equities who have earnings days in exactly 7 days to the universe?

Also, is there a way to define this behavior in the coarse universe selection (so that we're not always dealing with the same underlyings)? 

In the same month they're re-entering straddles for multiple stocks mulitple times (ie. immediately after reselling those straddles). The intended effect is that it only enters a straddle 9 days before the earnings date, as defined by:

return fine
                .Where(x => 
        
                    Time >= x.EarningReports.FileDate.AddDays(-9) && 
                    Time >= x.EarningReports.FileDate.AddDays(0) && 
            
                    x.EarningReports.FileDate != new DateTime())

                .Select(x => x.Symbol).Take(5);

0

Here's the backtest:

0


Moreover, is there a way to enable intraday trading for options? that would have avoideded that enormous pitfall in the recent backtest with a smaller SL.

0

The problem lies within the data :) EarningsDate is the most recent earnings date before the Time, which means we can't use it (as I thought it was the next earnings date). The best I can hope for is to add a quarter's worth of time to PeriodEndingDate (then 20-30 days for them to release earnings).

Can we somehow allow it for next earnings date to be available to be pulled, if available?

2

Unfortunatelly the next earnings data is not available. Please checkout the available Fundamentals data here.
Maybe you could make some research to determine whether earnings file dates are consistent (they don't vart much, e.g., always the second Monday of the quarter). It may be a good estimate for backtesting. For live trading, you will be able to rely on Nasdaq's Earnings Calendar.

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.


Hey Bao,

I ended up coding this entire algorithm using a Questrade API demo account (using live data from the day before):

https://github.com/DunnCreativeSS/QuestradePythonLongStraddleEarningDays

The issue is that sometimes the code would buy some straddles that would then have both the call and the put turn worthless - which broke the strategy :( from what I understand you can still sell them to market by setting a limit price you 'think' might be acceptable, but given the automated nature I'm unsure how to calculate that - I'm sure I could create a limit order in a live environment and then if it doesn't sell, update the order to be less advantageous? But altogether the uncertainty made it not worth the effort in the end.

I'd still very much like to be able to backtest the strategy, though. 5 month's data isn't necessarily ideal... all you'd need to do is do some math on the current date (somehow in C#) 

https://stackoverflow.com/questions/1607336/calculate-difference-between-two-dates-number-of-days

 

0

Jarett Dunn ,

I crawled the earning report data from nasdaq which goes back from 2012-Now. I didn't clean the data so some discrepancy in Symbols & Company Name but it seems 99% accurate. Definitely needs some cleaning still. I'll take it down the link after today. 

Thanks for the tip! Let me know if the data helps.
Edited by Jared: Cannot share data obtained illegally.

0

Hey Bao Huynh,

I think a simple implementation will be something like this:

In the Initialize method:

  1. Read all the earning dates as a collection. The final object can be a List<Tuples<DateTime, String>>
  2. Every day check if 7 or 15 days later there is some earning. You can use the Schelude for that.
  3. Make your move.
public override void Initialize()
{
List<Tuple<DateTime, string>> earnings = ReadEarningData();

Schedule.On(DateRules.EveryDay(), TimeRules.At(9, 0), () =>
{
// Check the next earnings.
var nextEarnings = earnings.Where(x => x.Item1.Date == Time.Date.AddDays(7)).ToArray();
foreach (var nextEarning in nextEarnings)
{
// Just an example, implement your logic here.
MarketOrder(nextEarning.Item2, 100);
}
}
);
}

Hope it helps.

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.


Hey,

Thanksf for the help.

Anyone know why the attached backtest is only working with SPY? 

Log(nextEarning.ticker); is logging:

 

2012-02-01 09:00:00 EGHT
2012-02-01 09:00:00 APH
2012-02-01 09:00:00 ASML
2012-02-01 09:00:00 The
2012-02-01 09:00:00 CTBI
2012-02-01 09:00:00 CVBF
2012-02-01 09:00:00 EBAY
2012-02-01 09:00:00 FFIV
2012-02-01 09:00:00 FFKT
2012-02-01 09:00:00 FAST
2012-02-01 09:00:00 ME
2012-02-01 09:00:00 FCCO

etc...

 

0


This line tells it to add daily data. Is this what you intended? "UniverseSettings.Resolution = Resolution.Daily;" 

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.


I believe so :) I'm no pro at QuantConnect or even C#.

In FineSelectionFunction I was trying to load the CSV, load next earners via Schedule.On(DateRules.EveryDay(), TimeRules.At(9, 0), () => (which I think is working, as I have logs from Log(nextEarning.ticker); in my output log) . . . I'm just unsure why that fine universe isn't being picked up on by OnSecuritiesChanged?

0

Got it :) You can call 'AddSecurity' anywhere and it triggers OnSecuritiesChanged.

Issue is I'm breaking the emulator :)

Memory Usage Maxed Out - 1024MB max, with last sample of 2012MB.

Can I clone QuantConnect via GitHub and run it on one of my servers in Ubuntu?

0

You can if you buy your own financial data ($'000) -- or you can increase your backtesting RAM allocation through the subscription page.

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 Jared.

Can you or someone review my code and figure out where the memory leak is, or why it seems to stop processing the backtest after the 16th or so of Jan? It just comes to a dead halt. I put in a limit to not have more than 3 options open at a given point in time, and the last time I tried to run the backtest from Jan - May it gave me an error akin to 'maximum execution time of (however many) seconds has occured, look for any recursive for loops.' Also, where does it get the idea to buy SPY straddle immediately upon launch? Backtest attached.

0


@Alexandre Catarino, in your example of OnSecuritiesChanged what would happen with options that are currently in the universe? Wouldn't they automatically get included in RemovedSecurities next time CoarseSelection function runs, since it only returns underlying equities? So even if your equity ticker remains in the universe it seems its Options will be removed.

0

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