| Overall Statistics |
|
Total Trades 30 Average Win 0.21% Average Loss -0.31% Compounding Annual Return -12.871% Drawdown 1.300% Expectancy -0.278 Net Profit -1.238% Sharpe Ratio -4.092 Probabilistic Sharpe Ratio 3.724% Loss Rate 57% Win Rate 43% Profit-Loss Ratio 0.69 Alpha -0.047 Beta -0.038 Annual Standard Deviation 0.022 Annual Variance 0 Information Ratio -2.996 Tracking Error 0.399 Treynor Ratio 2.321 Total Fees $30.00 Estimated Strategy Capacity $50000.00 Lowest Capacity Asset MSFT 31EL5FBC61VMU|MSFT R735QTJ8XC9X |
#region imports
from AlgorithmImports import *
#endregion
from datetime import timedelta
from random import random
import random
import pandas as pd
import numpy as np
import scipy
import matplotlib as mpl
import matplotlib.pyplot as plt
import math
class LongStrangleAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 3, 30)
self.SetEndDate(2020, 5, 1)
self.SetCash(100000)
option = self.AddOption("MSFT", Resolution.Minute)
self.symbol = option.Symbol
# set our strike/expiry filter for this option chain
option.SetFilter(0, +5, timedelta(0), timedelta(60))
# use the underlying equity GOOG as the benchmark
self.SetBenchmark("MSFT")
self.UniverseSettings.Resolution = Resolution.Daily
self.AddUniverseSelection(FineFundamentalUniverseSelectionModel(self.SelectCoarse, self.SelectFine))
self.Averages()
#Calculate mean of four numbers and add them into self.days
def Averages(self):
self.days = []
for i in range(0, 4):
x = random.randrange(30)
self.days.append(x)
average2 = [i for i in self.days if i != 0]
average2 = sum(average2)/len(average2)
global day
day = math.ceil(average2)
self.Log(str(day))
self.Log(str(self.days))
#Add ticker MSFT(for testing) into the universe
def SelectCoarse(self, coarse):
tickers = ["MSFT"]
return [Symbol.Create(x, SecurityType.Equity, Market.USA) for x in tickers]
#Define when ticker gets to trade(x days before announcement)
def SelectFine(self, fine):
for x in fine:
self.Debug("Symbol:" + x.SecurityReference.SecuritySymbol +", Filling date:" + x.EarningReports.FileDate.strftime("%m/%d/%Y, %H:%M:%S"))
self.Log("the day value is: " + str(day))
return [x for x in fine if self.Time >= x.EarningReports.FileDate - timedelta(days=day) and self.Time < x.EarningReports.FileDate]
def OnData(self,slice):
if self._changes is None: return
optionchain = slice.OptionChains
for i in slice.OptionChains:
if i.Key != self.symbol: continue
chains = i.Value
contract_list = [x for x in chains]
# if there is no contracts in this optionchain, pass the instance
if (slice.OptionChains.Count == 0) or (len(contract_list) == 0): return
# if there is no securities in portfolio, trade the options
for security in self._changes.AddedSecurities:
if self.Portfolio.Invested: return
self.TradeOptions(optionchain)
for security in self._changes.RemovedSecurities:
if security.Invested:
self.Sell(self.call.Symbol ,1)
self.Sell(self.put.Symbol ,1)
self.Debug("sold" + str(self.Time))
self._changes = None
def TradeOptions(self,optionchain):
for i in optionchain:
if i.Key != self.symbol: continue
chain = i.Value
# sorted the optionchain by expiration date and choose the furthest date
expiry = sorted(chain,key = lambda x: x.Expiry, reverse=True)[0].Expiry
# filter the call options from the contracts expires on that date
call = [i for i in chain if i.Expiry == expiry and i.Right == 0]
# sorted the contracts according to their strike prices
call_contracts = sorted(call,key = lambda x: x.Strike)
if len(call_contracts) == 0: continue
# choose the deep OTM call option
self.call = call_contracts[-1]
# select the put options which have the same expiration date with the call option
# sort the put options by strike price
put_contracts = sorted([i for i in chain if i.Expiry == expiry and i.Right == 1], key = lambda x: x.Strike)
# choose the deep OTM put option
self.put = put_contracts[0]
self.Buy(self.call.Symbol ,1)
self.Buy(self.put.Symbol ,1)
self.Debug("Bought" + str(self.Time))
def OnOrderEvent(self, orderEvent):
#self.Log(str(orderEvent))
pass
def OnSecuritiesChanged(self, changes):
self._changes = changes