Hello my intelligent friends!
I have a simple question for you all today.
Does anyone know how to do a transfer from trading equities to trading options? Here is some code for example:
# region imports
from AlgorithmImports import *
import pandas as pd
import numpy as np
from datetime import time, datetime, timedelta
# endregion
class CombinedAlgorithm(QCAlgorithm):
def Initialize(self):
# INITIALIZE
self.SetStartDate(2022, 1, 1) # Set Start Date
self.SetEndDate(2022, 10, 5)
self.SetCash(10000) # Set Strategy Cash
self.symbol = self.AddEquity('AAPL', Resolution.Minute)
self.symbol.SetDataNormalizationMode(DataNormalizationMode.SplitAdjusted)
# SCHEDULED EVENTS
self.Schedule.On(self.DateRules.EveryDay(self.symbol.Symbol), self.TimeRules.AfterMarketOpen(self.symbol.Symbol, 120), self.TradingOn)
self.Schedule.On(self.DateRules.EveryDay(self.symbol.Symbol), self.TimeRules.BeforeMarketClose(self.symbol.Symbol, 10), self.TradingOff)
self.Schedule.On(self.DateRules.EveryDay(self.symbol.Symbol), self.TimeRules.BeforeMarketClose(self.symbol.Symbol, 2), self.LiquidateCheck)
self.Schedule.On(self.DateRules.EveryDay(self.symbol.Symbol), self.TimeRules.BeforeMarketClose(self.symbol.Symbol), self.DayEnd)
# TOGGLES
self.thirty_min_reversal_sell = False
self.initial_thirty_min_stop_sell = False
self.initial_stop_sell = False
self.target_sell = False
self.target_hit = False
self.short = False
self.trading = False
self.break_even = False
self.liquidate_toggle = False
self.invest_hour = False
self.hour_trigger = False
# VARIABLES
self.symbol_price = 0
self.initial_stop_price = 0
self.initial_target_price = 0
self.entry_price = 0
self.trigger_thirty_min_high = 0
self.open_thirty_high = 0
self.open_thirty_low = 0
self.initial_thirty_min_stop_price = 0
self.trigger_hour_open = 0
self.trigger_hour_close = 0
self.trigger_hour_high = 0
self.trigger_hour_low = 0
self.previous_hour_high = 0
self.previous_hour_low = 0
self.trigger_hour_timer = 0
self.SetWarmUp(timedelta(days = 70))
self.ema = self.EMA(self.symbol.Symbol, 15, Resolution.Daily)
# CONSOLIDATED DATA
# 30-Minute Bars
thirty_min_consolidator = TradeBarConsolidator(timedelta(minutes=30))
self.SubscriptionManager.AddConsolidator(self.symbol.Symbol, thirty_min_consolidator)
thirty_min_consolidator.DataConsolidated += self.OnThirtyMinBar
self.thirtyMinBarWindow = RollingWindow[TradeBar](4)
def OnData(self, data):
if self.IsWarmingUp:
return
# VARIABLES
self.symbol_price = self.Securities[self.symbol.Symbol].Price
held_stocks = self.Portfolio[self.symbol.Symbol].Quantity
shares_to_buy = int(self.Portfolio.Cash / self.Securities[self.symbol.Symbol].Price)
# ENTRY (SHORT) (HOUR TRIGGERING HOUR - FIRST TRADE OTD)
if self.trading and self.thirty_min_trigger and not self.short:
if (self.symbol_price < self.trigger_thirty_min_low) and self.invest_thirty_min and not self.Portfolio.Invested:
self.ticket = self.MarketOrder(self.symbol.Symbol, -(shares_to_buy))
self.invest_thirty_min = False
self.thirty_min_trigger = False
self.initial_thirty_min_stop_sell = True
self.initial_stop_sell = True
self.initial_thirty_min_stop_price = self.trigger_thirty_min_high
self.thirty_min_reversal_sell = True
self.short = True
self.target_sell = True
self.entry_price = self.symbol_price
self.initial_target_price = self.entry_price * 0.99
self.Log(f'SHORT ENTRY (HOURLY TRIGGERING HOURLY) {self.symbol_price}')
# EXIT (INITIAL TARGET)
if self.Portfolio.Invested and self.short and self.target_sell and (self.symbol_price < self.initial_target_price):
self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
self.target_sell = False
self.target_hit = True
self.Log(f'EXIT (INITIAL TARGET) {self.symbol_price}')
# EXIT (INITIAL STOP)
if not self.target_hit and self.Portfolio.Invested and self.short and self.initial_thirty_min_stop_sell and (self.symbol_price > self.initial_thirty_min_stop_price):
self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
self.initial_thirty_min_stop_sell = False
self.thirty_min_reversal_sell = False
self.short = False
self.Log(f'EXIT (INITIAL STOP before target hit) {self.symbol_price}')
if not self.target_hit and self.Portfolio.Invested and self.short and self.initial_stop_sell and (self.symbol_price > self.initial_stop_price):
self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
self.initial_stop_sell = False
self.thirty_min_reversal_sell = False
self.short = False
self.Log(f'EXIT (INITIAL STOP before target hit) {self.symbol_price}')
if (self.target_hit or self.break_even) and self.Portfolio.Invested and self.short and self.initial_thirty_min_stop_sell and (self.symbol_price > self.entry_price):
self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
self.initial_thirty_min_stop_sell = False
self.thirty_min_reversal_sell = False
self.short = False
self.Log(f'EXIT (INITIAL STOP after target hit) {self.symbol_price}')
# EXIT (60-MIN TRAILING STOP)
if self.short and self.Portfolio.Invested and self.thirty_min_reversal_sell and (self.symbol_price > (self.trigger_hour_high)):
self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
self.thirty_min_reversal_sell = False
self.initial_stop_sell = False
self.short = False
self.Log(f'EXIT (30-MIN REVERSAL) {self.symbol_price} and {self.trigger_thirty_min_high}')
# EXIT (LIQUIDATE AT THE END OF THE DAY)
if self.liquidate_toggle:
self.MarketOrder(self.ticket.Symbol, (self.Securities[self.ticket.Symbol].Holdings.AbsoluteQuantity))
self.liquidate_toggle = False
self.short = False
self.Log(f'EXIT (LIQUIDATE AT THE END OF THE DAY) {self.symbol_price}')
# CONSOLILDATED FUNCTIONS
def OnThirtyMinBar(self, sender, bar):
self.thirtyMinBarWindow.Add(bar)
if not self.thirtyMinBarWindow.IsReady:
return
if self.IsWarmingUp:
return
# VARIABLES
trigger_thirty_min = self.thirtyMinBarWindow[0]
previous_thirty_min = self.thirtyMinBarWindow[1]
prev_trigger_thirty_min = self.thirtyMinBarWindow[2]
prev_previous_thirty_min = self.thirtyMinBarWindow[3]
trigger_thirty_min_close = trigger_thirty_min.Close
self.trigger_thirty_min_high = trigger_thirty_min.High
trigger_thirty_min_low = trigger_thirty_min.Low
previous_thirty_min_high = previous_thirty_min.High
previous_thirty_min_low = previous_thirty_min.Low
previous_thirty_min_open = previous_thirty_min.Open
prev_trigger_thirty_min_high = prev_trigger_thirty_min.High
prev_trigger_thirty_min_low = prev_trigger_thirty_min.Low
prev_previous_thirty_min_high = prev_previous_thirty_min.High
prev_previous_thirty_min_low = prev_previous_thirty_min.Low
if (self.trigger_thirty_min_high > previous_thirty_min_high) and (trigger_thirty_min_low > previous_thirty_min_low):
self.invest_thirty_min = True
self.thirty_min_trigger = True
# SCHEDULED EVENTS
def TradingOn(self): # 2 hours after market open
self.trading = True
def TradingOff(self): # 1 hour before market close
self.trading = False
def LiquidateCheck(self): # 2 mins before market close
if self.Portfolio.Invested:
self.liquidate_toggle = True
if not self.Portfolio.Invested:
return
def DayEnd(self):
self.trading = False
self.short = False
self.trigger_hour_high = 0
self.trigger_hour_low = 0
In conclusion,
as you can see, there are scheduled events, consolidated data, and some entry and exit parameters, how does all this square up with transferring the trades over to options? Does anyone have insight on this?
Thank you so much for your time, guys
Looking forward to hearing back from you,
Best,
Jesse
Derek Melchin
Hi Jesse,
We can keep the algorithm buy/sell logic the same but just change the orders to be Option contracts instead of the underlying Equity. We can subscribe to individual Option contracts or to a universe of Option contracts.
Best,
Derek Melchin
Want to invest in QuantConnect as we build the Linux of quant finance? Checkout our Wefunder campaign to join the revolution.
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.
Jesse Fleming
Hey Derek! Thank you for your usual timely response.
That makes sense! Sounds as easy as changing the order lines of code.
Do you know of a way to filter by premium prices in regards to options?
Thank you for your time,
Best,
Jesse
Derek Melchin
Hi Jesse,
We can access the premium prices from the OptionChain. See the attached backtest for reference.
Best,
Derek Melchin
Want to invest in QuantConnect as we build the Linux of quant finance? Checkout our Wefunder campaign to join the revolution.
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.
Jesse Fleming
Absolutely amazing. Thank you, sir.
Jesse Fleming
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!