EMA Crossover Signals for Trading an SPX Call Option
Summary
This QuantConnect example uses the S&P 500 index as a signal source and trades a specified European-style call option on the index. The index itself is added as minute-resolution data but is treated as non-tradable. The algorithm compares two exponential moving averages and holds the option when the slower average is above the faster one; otherwise, it liquidates. It also checks that the index was not traded directly.
The example specifies a short January 2021 date window, initial cash, a fixed option strike and expiration, and minute-resolution data. It demonstrates how an index indicator can inform option orders, rather than presenting a general-purpose options strategy. No performance results, rationale for the chosen contract, option Greeks, or risk controls are provided, and the code’s brief sample is not evidence of profitability. The unusual fast and slow labels and periods should be checked before interpreting the signal as a conventional trend filter.
Key ideas
- The index price supplies signals while the option contract is the traded instrument.
- The algorithm compares 80-period and 200-period exponential moving averages on minute data.
- It holds the specified call when the 200-period average exceeds the 80-period average and liquidates otherwise.
- The example checks that no index position was created, but reports no strategy performance.
Tags
Full text
# BasicTemplateIndexAlgorithm
# BasicTemplateIndexAlgorithm
## Source (Apache-2.0)
```python
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License
from AlgorithmImports import *
class BasicTemplateIndexAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2021, 1, 4)
self.set_end_date(2021, 1, 18)
self.set_cash(1000000)
# Use indicator for signal; but it cannot be traded
self.spx = self.add_index("SPX", Resolution.MINUTE).symbol
# Trade on SPX ITM calls
self.spx_option = Symbol.create_option(
self.spx,
Market.USA,
OptionStyle.EUROPEAN,
OptionRight.CALL,
3200,
datetime(2021, 1, 15)
)
self.add_index_option_contract(self.spx_option, Resolution.MINUTE)
self.ema_slow = self.ema(self.spx, 80)
self.ema_fast = self.ema(self.spx, 200)
def on_data(self, data: Slice):
if self.spx not in data.bars or self.spx_option not in data.bars:
return
if not self.ema_slow.is_ready:
return
if self.ema_fast > self.ema_slow:
self.set_holdings(self.spx_option, 1)
else:
self.liquidate()
def on_end_of_algorithm(self) -> None:
if self.portfolio[self.spx].total_sale_volume > 0:
raise AssertionError("Index is not tradable.")
```Shown in full with attribution under the source's licence. Licence: Apache-2.0
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.