| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -3.832 Tracking Error 0.088 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
#region imports
from AlgorithmImports import *
#endregion
from QuantConnect import *
from QuantConnect.Algorithm import *
from datetime import timedelta
from QuantConnect.Securities.Option import OptionPriceModels
class BasicTemplateOptionsAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 1)
self.SetEndDate(2020, 1, 8)
self.SetCash(10000)
option = self.AddOption("SPY", Resolution.Minute)
self.spy = self.AddEquity("SPY", Resolution.Minute)
self.option_symbol = option.Symbol
self.spy_symbol = self.spy.Symbol
self.callcontract = None
self.putcontract = None
self.uNos = {'calls' : {self.spy_symbol : self.callcontract},
'puts' : {self.spy_symbol : self.putcontract}
}
self.data = None
option.PriceModel = OptionPriceModels.CrankNicolsonFD() # both European & American, automatically
# set our strike/expiry filter for this option chain
self.SetWarmUp(7)
#Scheduled Events
self.oldDelta = 0
self.newDeltas = 0
self.callexpiry = 0
self.putexpiry = 0
self.Schedule.On(self.DateRules.WeekStart("SPY"),
self.TimeRules.AfterMarketOpen(self.spy.Symbol, 10),
Action(self.getGreeks))
def OnData(self, slice):
self.data = slice
self.getContracts()
self.timeDecayCheck()
self.setContracts()
#self.profitTake()
def getContracts(self):
if self.IsWarmingUp:
return
for right,_ in self.uNos.items():
if right == 'calls':
for underlying, contract in self.uNos[right].items():
if contract is None:
# ATM call option
targetStrike = (self.Securities[underlying].Price *1) - (self.Securities[underlying].Price * 1)%5
xcontracts = self.OptionChainProvider.GetOptionContractList("SPY", self.Time)
'''
ERROR:
When I am debugging this algorithm, on line 69, xcontracts is a list of option contracts, but when I reach line 74, the xcontracts variable
becomes and error and watch window says NameError ("name 'xcontracts' is not defined")
'''
if self.CurrentSlice.Bars.ContainsKey(underlying):
calls = [x for x in xcontracts if x.ID.OptionRight == OptionRight.Call]
calls = sorted( sorted(calls, key = lambda x: x.ID.Date, reverse = True),
key = lambda x: x.ID.StrikePrice)
calls = [x for x in calls if x.ID.StrikePrice == targetStrike]
calls = [x for x in calls if 50 < (x.ID.Date - self.Time).days <= 60]
if len(calls) == 0:
calls = sorted(calls, key = lambda x: x.ID.Date, reverse=True)
if len(calls) == 0:
return None
self.AddOptionContract(calls[0], Resolution.Minute)
self.uNos[right][underlying] = calls[0]
if right == 'puts':
for underlying, contract in self.uNos[right].items():
if contract is None:
#40% OTM call option
targetStrike = (self.Securities[underlying].Price *1) - (self.Securities[underlying].Price *1)%5
xcontracts = self.OptionChainProvider.GetOptionContractList("SPY", self.Time)
if self.CurrentSlice.Bars.ContainsKey(underlying):
puts = [x for x in xcontracts if x.ID.OptionRight == OptionRight.Put]
puts = sorted( sorted(puts, key = lambda x: x.ID.Date, reverse = True),
key = lambda x: x.ID.StrikePrice)
puts = [x for x in puts if x.ID.StrikePrice == targetStrike]
puts = [x for x in puts if 50 < (x.ID.Date - self.Time).days <= 60]
if len(puts) == 0:
return None
self.AddOptionContract(puts[0], Resolution.Minute)
self.uNos[right][underlying] = puts[0]
self.Log("Delta: " + str(puts[0].Greeks.Delta))
def getGreeks(self):
if self.IsWarmingUp:
return
#if self.callcontract or self.putcontract is None: return
#Get invested Option Values
for symbol, chain in self.data.OptionChains.items():
for contract in chain:
if self.Portfolio[contract.Symbol].Invested:
#self.MarketOrder("SPY", int((contract.Greeks.Delta)*100))
#Get Latest Delta
x = int((contract.Greeks.Delta)*100)
#self.Log(int((contract.Greeks.Delta)*100))
self.newDeltas += x
#self.newDeltas = int((contract.Greeks.Delta) * 100)
#See quantity of hedging
#self.newDeltas = sum(self.newDeltas)
adjDelta = int(self.oldDelta) - int(self.newDeltas)
#Perform Hedges
self.MarketOrder("SPY", adjDelta)
#Make Store delta value for next hedge
self.oldDelta = self.newDeltas
def timeDecayCheck(self):
#Need to fix my time decay check method
if self.IsWarmingUp:
return
#Liquidating on Expiration
for right,cluster in self.uNos.items():
if right == 'calls':
#continue
for underlying, contract in self.uNos[right].items():
if contract is None:
continue
if (contract.ID.Date - self.Time).days < 1:
self.Liquidate(contract)
self.callcontract = None
if right == 'puts':
#continue
for underlying, contract in self.uNos[right].items():
if contract is None:
continue
if (contract.ID.Date - self.Time).days < 1:
self.Liquidate(contract)
self.putcontract = None
def profitTake(self):
return
if self.IsWarmingUp:
return
for right,cluster in self.uNos.items():
if right == 'puts':
for underlying,contract in self.uNos[right].items():
if self.Portfolio[contract].UnrealizedProfitPercent > 1:
self.Liquidate(contract)
self.uNos[right][underlying] = None
def setContracts(self):
for right, cluster in self.uNos.items():
if right == 'calls':
for underlying, contract in self.uNos[right].items():
if contract is None:
continue
if not self.Portfolio[contract].Invested:
if self.CurrentSlice.Bars.ContainsKey(underlying):
if self.Securities[contract].Price != 0:
self.MarketOrder(contract, 1)
if right == 'puts':
for underlying, contract in self.uNos[right].items():
if contract is None:
continue
if (self.purchasedTRH == True):
continue
if not self.Portfolio[contract].Invested:
if self.CurrentSlice.Bars.ContainsKey(underlying):
#self.SetHoldings(contract, 0.03)
if self.Securities[contract].Price != 0:
# SHILE: PUT ADDITIONAL CHECKS HERE
self.MarketOrder(contract, 1)