Prompt
Build an algorithm that picks the 10 stocks with the lowest valid PE ratio, then adds front-month at-the-money call options on them. Drop NaN PE ratios in the fundamental filter, sort ascending, and take 10. Chain an option universe on top of the equity universe and restrict it to front-month, calls-only, with strikes within roughly two steps of the ATM strike. Use asynchronous selection and raw data normalization, which is required to compare option strikes fairly. In data handling, iterate each option chain and read each contract's last price. Set $100,000 cash. Backtest from September 1, 2024 to December 31, 2024.
Error
The backtest ended with a runtime error.
Runtime Error: 'OfTypeIterator[FineFundamental]' object has no attribute 'front_month'
at _option_filter
.front_month()
^^^^^^^^^^^
in main.py: line 33
'OfTypeIterator[FineFundamental]' object has no attribute 'front_month'
at _option_filter
.front_month()
^^^^^^^^^^^
in main.py: line 33
Code
main.py
# region imports
from AlgorithmImports import *
# endregion
class LowPECallOptionsAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
self.set_cash(100_000)
self.settings.seed_initial_prices = True
# Add equity universe with option chain
self._universe = self.add_universe(
self._select_fundamentals,
self._option_filter
)
self.universe_settings.asynchronous = True
self.universe_settings.data_normalization_mode = DataNormalizationMode.RAW
def _select_fundamentals(self, fundamentals: List[Fundamental]) -> List[Symbol]:
# Drop NaN PE ratios, sort ascending, take 10
filtered = [f for f in fundamentals if f.valuation_ratios.pe_ratio
and not float('nan') == f.valuation_ratios.pe_ratio
and f.valuation_ratios.pe_ratio > 0]
sorted_by_pe = sorted(filtered, key=lambda f: f.valuation_ratios.pe_ratio)
return [f.symbol for f in sorted_by_pe[:10]]
def _option_filter(self, universe: OptionFilterUniverse) -> OptionFilterUniverse:
# Front-month calls only, strikes within ~2 steps of ATM
return (universe
.front_month()
.calls_only()
.strikes(-2, 2))
def on_data(self, data: Slice) -> None:
pass
def on_securities_changed(self, changes: SecurityChanges) -> None:
# Log added/removed securities
for security in changes.added_securities:
self.log(f"Added: {security.symbol}")
for security in changes.removed_securities:
self.log(f"Removed: {security.symbol}")
def on_option_chain(self, option_chain: OptionChain) -> None:
# Iterate option chain contracts and read last price
for contract in option_chain:
last_price = contract.last_price
self.log(
f"Contract: {contract.symbol} | "
f"Strike: {contract.strike} | "
f"Expiry: {contract.expiry.date()} | "
f"Last: {last_price}"
)
Prompt
Build an algorithm that picks the 10 stocks with the lowest valid PE ratio, then adds front-month at-the-money call options on them. Drop NaN PE ratios in the fundamental filter, sort ascending, and take 10. Chain an option universe on top of the equity universe and restrict it to front-month, calls-only, with strikes within roughly two steps of the ATM strike. Use asynchronous selection and raw data normalization, which is required to compare option strikes fairly. In data handling, iterate each option chain and read each contract's last price. Set $100,000 cash. Backtest from September 1, 2024 to December 31, 2024.
Error
The backtest ended with a runtime error.
Runtime Error: 'OfTypeIterator[FineFundamental]' object has no attribute 'front_month'
at _option_filter
.front_month()
^^^^^^^^^^^
in main.py: line 33
'OfTypeIterator[FineFundamental]' object has no attribute 'front_month'
at _option_filter
.front_month()
^^^^^^^^^^^
in main.py: line 33
Code
main.py