Skip to content
All library documents

EMA Crossover Signals for Trading an SPX Call Option

Article Strategy library · Author: QuantConnect

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.