from AlgorithmImports import *
class SellCallWeekkly(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 2, 1)
self.SetEndDate(2022, 3, 30)
self.SetCash(10000000000)
self.SetName("Sell Call Strategy")
self.equity = self.AddEquity("APPL", Resolution.Hour)
self.option = self.AddOption("APPL", Resolution.Hour)
self.option.SetFilter(self.UniverseFunc)
chart = Chart("Stock Info Chart")
chart.AddSeries(Series("Price", SeriesType.Line, 0))
# chart.AddSeries(Series("IV", SeriesType.Line, 1))
self.AddChart(chart)
def UniverseFunc(self, universe):
return universe.include_weeklys().calls_only().Expiration(0, 10)
def get_holding_option(self):
holding_options = []
for kvp in self.Portfolio.Securities:
security = kvp.Value
# 确认这是一个期权且持仓不为零
if security.Type == SecurityType.Option and security.Holdings.Quantity != 0:
# 获取期权合约的详细信息
symbol = security.Symbol
quantity = security.Holdings.Quantity
# # self.Debug(f"持仓期权:{symbol}, 持仓数量:{quantity}")
# # 解析合约细节
# self.Debug(f"标的资产:{symbol.Underlying}, 到期日:{symbol.ID.Date}, "
# f"行权价:{symbol.ID.StrikePrice}, 类型:{symbol.ID.OptionRight}")
holding_options.append(security)
return holding_options
def get_holding_stock(self):
holding_stocks = []
for kvp in self.Portfolio.Securities:
security = kvp.Value
# 确认这是一个股票且持仓不为零
if security.Type == SecurityType.Equity and security.Holdings.Quantity != 0:
# 获取股票合约的详细信息
symbol = security.Symbol
quantity = security.Holdings.Quantity
# self.Debug(f"持仓股票:{symbol}, 持仓数量:{quantity}")
holding_stocks.append(security)
return holding_stocks
def get_target_strike_price_option(self,slice,traget_strike_price):
target_strike = traget_strike_price
chain_value = slice.OptionChains[self.option.Symbol]
contracts = sorted(chain_value.Contracts.Values,
key=lambda x: (abs(x.Strike - target_strike), -x.Expiry.timestamp()))
selected_contract = contracts[0]
return selected_contract
def sell_option_at_115price(self,slice):
self.Debug(f"当前时间:{self.Time}")
stock_price = self.Securities[self.equity.Symbol].Price
target_strike = stock_price * 1.15
contract = self.get_target_strike_price_option(slice,target_strike)
self.Debug(f"当前股票价格: {stock_price:.2f}, 目标行权价: {target_strike:.2f},当前时间:{self.Time},选中期权行权价: {contract.Strike:.2f}, 到期日: {contract.Expiry}")
quantity = 10
self.MarketOrder(contract.Symbol, -quantity)
self.Debug(f"提交卖出订单: {contract.Symbol}, 数量: {quantity}")
def sell_on_monday(self,slice):
if self.Time.weekday() != 0: # only monday
return
#先平仓所有正股
self.Liquidate(self.equity.Symbol)
self.sell_option_at_115price(slice)
def check_to_buy_back(self,slice,hodling_options,holding_stocks):
stock_price = self.Securities[self.equity.Symbol].Price
option_security = hodling_options[0]
symbol = option_security.Symbol
strike_price = symbol.ID.StrikePrice
if stock_price<=strike_price:
return
self.debug(f"stock_price{stock_price},strike_price{strike_price}")
# self.MarketOrder(symbol, abs(security.Holdings.Quantity))
#购买期权对应的股票
if len(holding_stocks)==0:
self.debug(f"buy stock {option_security.Holdings.Quantity}")
self.MarketOrder(self.equity.Symbol, abs(option_security.Holdings.Quantity)*100)
self.sell_option_at_115price(slice)
def OnData(self, slice):
current_time = self.Time
exchange_hours = self.Securities[self.equity.Symbol].Exchange.Hours
# 检查当前时间是否在市场开放时间内
if not exchange_hours.IsOpen(current_time, False):
self.Debug(f"{current_time},Market is not open.")
return
self.Plot("Performance Chart", "Price", self.Securities[self.equity.Symbol].Price)
stock_price = self.Securities[self.equity.Symbol].Price
# iv = self.get_target_strike_price_option(slice,stock_price).impliedVolatility
# self.Plot("Stock Info Chart", "IV", iv)
# self.Debug(f"coming data...{self.time}")
holding_options = self.get_holding_option()
holding_stocks = self.get_holding_stock()
# self.debug(f"holding optins:{holding_options},size:{len(holding_options)}")
if len(holding_options)==0:
self.sell_on_monday(slice)
return
else:
self.check_to_buy_back(slice,holding_options,holding_stocks)
# pass
def OnOrderEvent(self, orderEvent):
if orderEvent.Status == OrderStatus.Filled:
self.Debug(f"Order Filled: {orderEvent.Symbol} - Quantity: {orderEvent.FillQuantity}")