Hello,
I'm having a hard time figuring out how to add stocks a few days before an announcement and then removing them from the universe the day before the announcement. I came up with something, but it's not really working atm. I'm truly sorry if there are more faults in my code, but I'm still a newbie and trying to learn. Also, how do I solve the issue with self.days.append(x).
Idea: I calculate the mean of 4 random numbers(1-30), this will be the amount of days entering a Straddle Position before the next announcement. Then one day or the day before the announcement is made the position close.
Thanks in advance!
#region imports
from AlgorithmImports import *
#endregion
from datetime import timedelta
from random import random
import random
import pandas as pd
import numpy as np
import scipy
import matplotlib as mpl
import matplotlib.pyplot as plt
import math
class LongStrangleAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 1)
self.SetEndDate(2021, 1, 1)
self.SetCash(100000)
option = self.AddOption("MSFT", Resolution.Minute)
self.symbol = option.Symbol
# set our strike/expiry filter for this option chain
option.SetFilter(0, +5, timedelta(0), timedelta(60))
# use the underlying equity GOOG as the benchmark
self.SetBenchmark("MSFT")
self.UniverseSettings.Resolution = Resolution.Daily
self.AddUniverseSelection(FineFundamentalUniverseSelectionModel(self.SelectCoarse, self.SelectFine))
self.days = []
self.Averages()
#Calculate mean of four numbers and add them into self.days
def Averages(self):
for i in range(0, 4):
x = random.randrange(30)
self.days.append(x)
average2 = [i for i in self.days if i != 0]
average2 = sum(average2)/len(average2)
global day
day = math.ceil(average2)
self.Debug(str(day))
#Add ticker MSFT(for testing) into the universe
def SelectCoarse(self, coarse):
tickers = ["MSFT"]
return [Symbol.Create(x, SecurityType.Equity, Market.USA) for x in tickers]
#Define when ticker gets to trade(x days before announcement)
def SelectFine(self, fine):
for x in fine:
self.Debug("Symbol:" + x.SecurityReference.SecuritySymbol +", Filling date:" + x.EarningReports.FileDate.strftime("%m/%d/%Y, %H:%M:%S"))
return [x for x in fine if self.Time <= x.EarningReports.FileDate - timedelta(days=day)
and x.EarningReports.FileDate != datetime.time()]
def OnData(self,slice):
if self._changes is None: return
optionchain = slice.OptionChains
for i in slice.OptionChains:
if i.Key != self.symbol: continue
chains = i.Value
contract_list = [x for x in chains]
# if there is no contracts in this optionchain, pass the instance
if (slice.OptionChains.Count == 0) or (len(contract_list) == 0): return
# if there is no securities in portfolio, trade the options
for security in self._changes.AddedSecurities:
if self.Portfolio.Invested: return
self.TradeOptions(optionchain)
for security in self._changes.RemovedSecurities:
if security.Invested:
self.SellOptions()
self._changes = None
def TradeOptions(self,optionchain):
for i in optionchain:
if i.Key != self.symbol: continue
chain = i.Value
# sorted the optionchain by expiration date and choose the furthest date
expiry = sorted(chain,key = lambda x: x.Expiry, reverse=True)[0].Expiry
# filter the call options from the contracts expires on that date
call = [i for i in chain if i.Expiry == expiry and i.Right == 0]
# sorted the contracts according to their strike prices
call_contracts = sorted(call,key = lambda x: x.Strike)
if len(call_contracts) == 0: continue
# choose the deep OTM call option
self.call = call_contracts[-1]
# select the put options which have the same expiration date with the call option
# sort the put options by strike price
put_contracts = sorted([i for i in chain if i.Expiry == expiry and i.Right == 1], key = lambda x: x.Strike)
# choose the deep OTM put option
self.put = put_contracts[0]
self.Buy(self.call.Symbol ,1)
self.Buy(self.put.Symbol ,1)
def OnOrderEvent(self, orderEvent):
self.Log(str(orderEvent))
def SellOptions(self):
self.Sell(self.call.Symbol ,1)
self.Sell(self.put.Symbol ,1)
def OnSecuritiesChanged(self, changes):
self._changes = changes
Nico Xenox
I solved the problem with self.days.append by adding self.days into the function.
I also changed this part of the code:
to this here:
But there seems to be another problem somewhere because the first time it buys is at the start date, then it buys and sells it a few times, and it also buys one at the end date.
Why is it selling and buying straddles multiple times at different occasions? How can I change that?
Newoptionz
Hi,
I see the earnings date is outside of the range that the test is being run
self.SetStartDate(2020, 3, 30)
self.SetEndDate(2020, 5, 1)
2020-03-30 00:00:00 : Symbol:MSFT, Filling date:01/29/2020, 00:00:00
MSFT had earnings on the 2020-01-29 2020-04-29 - so it is not getting 2020-04-29
Newoptionz
I know there is an online group that trade a stratergy called the double eagle, which sells a straddle above and below the current price of a security about 30days before earnings and then they close the straddles when they hit a certain profit target or in the week before earnings. They also adjust the straddles if the price moves past their straddle entries. I think that would be a good method to test out here.
Nico Xenox
Hi Newoptionz
I changed the dates from 2020-1-1 to 2021-1-1 but it still shows the same problem(Symbol:MSFT, Filling date:10/23/2019, 00:00:00), I dont understand why it is looking at past filling dates and not at the upcoming ones.
Thank you I will check that out.
Newoptionz
Hi
I don't think they can show the upcomming dates - as these would just be estimates. The quantconnect documents say filedate is the date the report was ‘released’, so past tense. We could put in estimated future dates, and maybe services like ‘Estimize’ would provide them.
Nico Xenox
Hey Newoptionz
Thanks for telling me that, otherwise I would have spent a lot of time trying to figure out why it doesnt work xD. I guess Estimize is for now the simplest method to get what I want, I will have to do some research on that first and understand how to implement it. *sigh*
Nico Xenox
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.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!