Overall Statistics
import numpy as np
from pprint import pprint
import pandas as pd
from datetime import timedelta

### <summary>
### Basic template algorithm simply initializes the date range and cash. This is a skeleton
### framework you can use for designing an algorithm.
### </summary>
class BasicTemplateAlgorithm(QCAlgorithm):
    '''Basic template algorithm simply initializes the date range and cash'''

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.SetStartDate(2016,10,01)  #Set Start Date
        self.SetEndDate(2016,11,05)    #Set End Date
        self.SetCash(25000)           #Set Strategy Cash
        # Find more symbols here: http://quantconnect.com/data
        self.AddUniverse(self.CoarseSelectionFunction)
        self.should_trade = True

        # option.SetFilter(-2, 2, TimeSpan.FromDays(30), TimeSpan.FromDays(180));
        self.AddEquity("SPY")
        self.Schedule.On(self.DateRules.Every([DayOfWeek.Thursday]), self.TimeRules.BeforeMarketClose("SPY", 45), Action(self.Activate))
    
    def CoarseSelectionFunction(self, coarse):
        '''Take the top 5 by dollar volume using coarse'''
        # sort descending by daily dollar volume
        sortedByDollarVolume = sorted(coarse, \
            key=lambda x: x.DollarVolume, reverse=True) 
    
        # add Options
        for x in sortedByDollarVolume[:5]:
            option = self.AddOption(x.Symbol.Value, Resolution.Minute)
            option.SetFilter(-2, +2, timedelta(0), timedelta(180))
            self.AddEquity(x.Symbol.Value, Resolution.Minute)
    
        # we need to return only the symbol objects
        return [ x.Symbol for x in sortedByDollarVolume[:5] ]
        
    def GetOptionTrades(self, data):
        '''figure out which trades to make, and trade size as well'''
        trades_to_make = []
        return trades_to_make
        
    def Activate(self):
        '''Make Options Trades'''
        self.should_trade = True

    def OnData(self,slice):
        if self.should_trade == False:
            return
        
        k = 0
        for i in slice.OptionChains:
            k += 1
            self.Log(str(k))
            optionchain = i.Value 
            # print out the undelying price
            # self.Log("underlying price:" + str(optionchain.Underlying.Price))
            # create a data frame to show the filtered contracts
            df = pd.DataFrame([[x.Right,float(x.Strike),x.Expiry,float(x.BidPrice), float(x.AskPrice)] for x in optionchain],
                              index=[x.Symbol.Value for x in optionchain],
                              columns=['type(call 0, put 1)', 'strike', 'expiry', 'ask price', 'bid price'])
            
            # self.Log(str(df))

            # we sort the contracts to find at the money (ATM) contract with farthest expiration
            contracts = sorted(sorted(optionchain, key = lambda x: abs(optionchain.Underlying.Price - x.Strike)),key = lambda x: x.Expiry, reverse=True)
            # buy the option with farthest expiration and sell it when the exchange closes
            if len(contracts) == 0: continue
            symbol = contracts[0].Symbol   
            #self.MarketOrder(symbol, 1)
            #self.MarketOnCloseOrder(symbol, -1)
            
        self.should_trade = False