Hi,
I try to use the covered call example in the Tutorials. It basically just sell monthly covered calls.
The security used is "IBM", from 2020-01-01 to 2020-03-01. I used the "SetFilter" method, which by default only looks at the monthly.
I run into 2 questions which I can't explain.
1. why after the 1st monlty option (200117C00135000) is expired, the next option is submitted on 2020-01-22, which is a Wednesday, but not on 2020-01-21 (that Monday is a holiday I believe)
2. the next monthly option is (IBM 200221C00143000), which is set to expire on 2/21, but there is an assignment on 2/18.
Can anyone explain why? Thanks.
I attached my code here, and also the log file.
Thanks.
from datetime import timedelta
class CoveredCallAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 1)
self.SetEndDate(2020, 3, 1)
self.SetCash(100000)
equity = self.AddEquity("IBM", Resolution.Minute)
option = self.AddOption("IBM", Resolution.Minute)
self.symbol = option.Symbol
# set strike/expiry filter for this option chain
option.SetFilter(-3, +3, timedelta(0), timedelta(30))
# use the underlying equity as the benchmark
self.SetBenchmark(equity.Symbol)
def OnData(self,slice):
if not self.Portfolio["IBM"].Invested:
self.MarketOrder("IBM",100) # buy 100 shares of underlying stocks
self.Log(str(self.Time) + " bought IBM " + "@" + str(self.Securities["IBM"].Price)
+ " Cash balance: " + str(self.Portfolio.Cash)
+ " Equity: " + str(self.Portfolio.HoldStock))
option_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
if len(option_invested) < 1:
self.TradeOptions(slice)
def TradeOptions(self,slice):
for i in slice.OptionChains:
if i.Key != self.symbol: continue
chain = i.Value
# filter the call options contracts
call = [x for x in chain if x.Right == OptionRight.Call]
# sorted the contracts according to their expiration dates and choose the ATM options
contracts = sorted(sorted(call, key = lambda x: abs(chain.Underlying.Price - x.Strike)),
key = lambda x: x.Expiry, reverse=True)
if len(contracts) == 0: return
self.call = contracts[0].Symbol
# short the call options
self.MarketOrder(self.call, -1)
def OnOrderEvent(self, orderEvent):
self.Log(str(orderEvent))
self.Log("Cash balance: " + str(self.Portfolio.Cash))
2020-01-01 00:00:00 Launching analysis for d2d7894f981e5c6562aca1d75163f84b with LEAN Engine v2.4.0.0.8588
2020-01-01 00:00:00 Warning: The IBM equity security was set the raw price normalization mode to work with options.
2020-01-02 09:31:00 Time: 01/02/2020 14:31:00 OrderID: 1 EventID: 1 Symbol: IBM Status: Submitted Quantity 100
2020-01-02 09:31:00 Cash balance: 100000.0
2020-01-02 09:31:00 Time: 01/02/2020 14:31:00 OrderID: 1 EventID: 2 Symbol: IBM Status: Filled Quantity 100 FillQuantity: 100 FillPrice: 135.08 USD OrderFee: 1 USD
2020-01-02 09:31:00 Cash balance: 86491.0
2020-01-02 09:31:00 2020-01-02 09:31:00 bought IBM @135.025 Cash balance: 86491.0 Equity: True
2020-01-02 09:31:00 Time: 01/02/2020 14:31:00 OrderID: 2 EventID: 1 Symbol: IBM 200117C00135000 Status: Submitted Quantity -1
2020-01-02 09:31:00 Cash balance: 86491.0
2020-01-02 09:31:00 Time: 01/02/2020 14:31:00 OrderID: 2 EventID: 2 Symbol: IBM 200117C00135000 Status: Filled Quantity -1 FillQuantity: -1 FillPrice: 1.63 USD OrderFee: 1 USD
2020-01-02 09:31:00 Cash balance: 86653.0
2020-01-17 16:00:00 Time: 01/17/2020 21:00:00 OrderID: 3 EventID: 1 Symbol: IBM 200117C00135000 Status: Submitted Quantity -1
2020-01-17 16:00:00 Cash balance: 86653.0
2020-01-18 00:00:00 Time: 01/18/2020 05:00:00 OrderID: 3 EventID: 2 Symbol: IBM 200117C00135000 Status: Filled Quantity -1 FillQuantity: 1 FillPrice: 0 Message: Adjusting(or removing) the exercised/assigned option
2020-01-18 00:00:00 Cash balance: 86653.0
2020-01-18 00:00:00 Time: 01/18/2020 05:00:00 OrderID: 3 EventID: 3 Symbol: IBM Status: Filled Quantity -1 FillQuantity: -100 FillPrice: 135 Message: Option Exercise/Assignment
2020-01-18 00:00:00 Cash balance: 100153.0
2020-01-18 00:00:00 Time: 01/18/2020 05:00:00 OrderID: 4 EventID: 1 Symbol: IBM Status: Submitted Quantity 100
2020-01-18 00:00:00 Cash balance: 100153.0
2020-01-18 00:00:00 2020-01-18 00:00:00 bought IBM @138.28 Cash balance: 100153.0 Equity: False
2020-01-21 09:31:00 Time: 01/21/2020 14:31:00 OrderID: 4 EventID: 2 Symbol: IBM Status: Filled Quantity 100 FillQuantity: 100 FillPrice: 138.29 USD OrderFee: 1 USD
2020-01-21 09:31:00 Cash balance: 86323.0
? why the option is submitted on 1/22, but not 1/21
2020-01-22 09:31:00 Time: 01/22/2020 14:31:00 OrderID: 5 EventID: 1 Symbol: IBM 200221C00143000 Status: Submitted Quantity -1
2020-01-22 09:31:00 Cash balance: 86323.0
2020-01-22 09:31:00 Time: 01/22/2020 14:31:00 OrderID: 5 EventID: 2 Symbol: IBM 200221C00143000 Status: Filled Quantity -1 FillQuantity: -1 FillPrice: 1.88 USD OrderFee: 1 USD
2020-01-22 09:31:00 Cash balance: 86510.0
? The option is set to expire on 2/21, why there are some many operation on 2/18
2020-02-18 14:04:00 Time: 02/18/2020 19:04:00 OrderID: 6 EventID: 1 Symbol: IBM 200221C00143000 Status: Submitted Quantity -1
2020-02-18 14:04:00 Cash balance: 86672.0
2020-02-18 14:05:00 Time: 02/18/2020 19:05:00 OrderID: 6 EventID: 2 Symbol: IBM 200221C00143000 Status: Filled Quantity -1 FillQuantity: 1 FillPrice: 0 Message: Adjusting(or removing) the exercised/assigned option
2020-02-18 14:05:00 Cash balance: 86672.0
2020-02-18 14:05:00 Time: 02/18/2020 19:05:00 OrderID: 6 EventID: 3 Symbol: IBM Status: Filled Quantity -1 FillQuantity: -100 FillPrice: 143 Message: Option Exercise/Assignment
2020-02-18 14:05:00 Cash balance: 100972.0
2020-02-18 14:05:00 Time: 02/18/2020 19:05:00 OrderID: 7 EventID: 1 Symbol: IBM Status: Submitted Quantity 100
2020-02-18 14:05:00 Cash balance: 100972.0
2020-02-18 14:05:00 Time: 02/18/2020 19:05:00 OrderID: 7 EventID: 2 Symbol: IBM Status: Filled Quantity 100 FillQuantity: 100 FillPrice: 150.67 USD OrderFee: 1 USD
2020-02-18 14:05:00 Cash balance: 85904.0
2020-02-18 14:05:00 2020-02-18 14:05:00 bought IBM @150.67 Cash balance: 85904.0 Equity: True
2020-02-18 14:05:00 Time: 02/18/2020 19:05:00 OrderID: 8 EventID: 1 Symbol: IBM 200221C00150000 Status: Submitted Quantity -1
2020-02-18 14:05:00 Cash balance: 85904.0
2020-02-18 14:05:00 Time: 02/18/2020 19:05:00 OrderID: 8 EventID: 2 Symbol: IBM 200221C00150000 Status: Filled Quantity -1 FillQuantity: -1 FillPrice: 1.51 USD OrderFee: 1 USD
2020-02-18 14:05:00 Cash balance: 86054.0
2020-02-21 16:00:00 Time: 02/21/2020 21:00:00 OrderID: 9 EventID: 1 Symbol: IBM 200221C00150000 Status: Submitted Quantity -1
2020-02-21 16:00:00 Cash balance: 86054.0
2020-02-22 00:00:00 Time: 02/22/2020 05:00:00 OrderID: 9 EventID: 2 Symbol: IBM 200221C00150000 Status: Filled Quantity -1 FillQuantity: 1 FillPrice: 0 Message: Adjusting(or removing) the exercised/assigned option
2020-02-22 00:00:00 Cash balance: 86054.0
2020-02-24 09:31:00 Time: 02/24/2020 14:31:00 OrderID: 10 EventID: 1 Symbol: IBM 200320C00146000 Status: Submitted Quantity -1
2020-02-24 09:31:00 Cash balance: 86054.0
2020-02-24 09:31:00 Time: 02/24/2020 14:31:00 OrderID: 10 EventID: 2 Symbol: IBM 200320C00146000 Status: Filled Quantity -1 FillQuantity: -1 FillPrice: 3.6 USD OrderFee: 1 USD
2020-02-24 09:31:00 Cash balance: 86413.0
2020-02-28 16:00:00 Algorithm Id:(d2d7894f981e5c6562aca1d75163f84b) completed in 15.14 seconds at 1034k data points per second. Processing total of 15,662,196 data points.
Rahul Chowdhury
Hey Danfeng,
1. The algorithm does not trade any IBM options between 01-18-2020 and 01-21-2020 because there is no option chains data for those days. Looking through the data explorer, there seems to be missing options data for IBM for those days.
2. If you look at the Orders tab in the backtest page, you'll see that the exercise on 02-18-2020 is a "Simulated option assignment before expiration" under the tags section.
Best
Rahul
Danfeng Li
Thanks, Rahul,
The Orders tab is very helpful.
A related question, where can I see the snapshot of my portfolio, such as cash and holdings? If not, what is the best way to print it out?
Thanks.
Dan
Rahul Chowdhury
Hey Danfeng,
In live trading, We can see a list of the current holdings in the Holdings tab. However, there isn't any corresponding tab for backtesting. We will need to use Debug/Log statements to view snapshots of our portfolio holdings. The easiest way to do this is
self.Debug(f"Securities Held: {[str(symbol) for symbol in self.Portfolio.Keys if self.Portfolio[symbol].Invested]}")
Keep in mind, there is a 3 MB daily limit on logging/debugging, so you should log strategically.
Best
Rahul
Danfeng Li
Thanks, Rahul.
Dan
Danfeng Li
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!