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
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
from clr import AddReference
AddReference("System.Core")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm")

from QuantConnect.Securities.Option import OptionPriceModels
import QuantConnect
import cloudpickle
import json
import math
import numpy as np
import pandas as pd
from scipy.optimize import minimize_scalar
from scipy.stats import linregress

class AutomatonTrade(QCAlgorithm):

    # Constants
    NUMBER_SYMBOLS = 200
    ATR_PERIOD = 15
    SHORT_ATR_PERIOD = 5
    ATR_MULTIPLIER = 1
    BAD_SYMBOLS = [ "|", " ", "ZVZZT", "ZXZZT", "ZWZZT", "TBLT", "MTECW", "SSLJ", "YERR", "CYTXZ", "BRACW", "NFINW", "MDR", "AIKI", "CEI" ]
    WINDOW_SIZE = 15
    BARS_TO_HOLD_ORDERS_FOR = 5
    BID_ADJUSTMENT = 0.01

    def Initialize(self):
        
        # Init
        self.SetStartDate(2020, 1, 1)
        self.SetEndDate(2020, 1, 3)
        self.SetCash(5000)
        
        self.SetTimeZone(TimeZones.NewYork)
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
        self.UniverseSettings.Resolution = Resolution.Minute
        self.SetSecurityInitializer(self.CustomSecurityInitializer)
                
        # Live universe with selection.
        self.AddUniverse(self.CoarseSelectionFunction)

    def CustomSecurityInitializer(self, security):
        '''Initialize the security with raw prices'''
        security.SetDataNormalizationMode(DataNormalizationMode.Raw)

    def CoarseSelectionFunction(self, coarse):

        # Sort by price, dollar volume and volume
        sortedByPrice = sorted(coarse, key = lambda x : (x.Price, x.DollarVolume, x.Volume))
    
        # Volume > 500k so we have liquidity and don't get shitty stocks
        # Any ticker with more than 4 chars is likely a warrant and will crash
        # Eliminate bad symbols
        filtered = [ x.Symbol for x in sortedByPrice if x.Volume > 500000 and len(x.Symbol.Value) < 5 and not any(y in str(x.Symbol.Value) for y in AutomatonTrade.BAD_SYMBOLS) ]

        top = filtered[:AutomatonTrade.NUMBER_SYMBOLS]
        
        self.currentActiveSecurities = top
        self.lastSelectedSymbolsAsCommaSeperatedString = ', '.join(list(map(lambda x : '"' + x.Value + '"', top)))
        self.printLog("------ CoarseSelectionFunction symbols (" + str(len(top)) + "):")
        #self.printLog(self.lastSelectedSymbolsAsCommaSeperatedString)

        # Reset vars
        self.prices = np.zeros([AutomatonTrade.WINDOW_SIZE, AutomatonTrade.NUMBER_SYMBOLS])
        self.lastSelectedSymbolsAsCommaSeperatedString = None
        self.ignoreDaySymbols = []
        self.barCount = 0

        # Store the list as the tickers
        self.lastSelectedSymbols = list(map(lambda x : x.Value, top))
        
        return top
        
    def OnData(self, dataSlice):
        
        # We use the bars (stock) for everything    
        data = dataSlice.Bars

        # Check if we have open orders
        openOrders = self.Transactions.GetOpenOrders()
        if len(openOrders) == 0:
            
            # If nothing is invested, look to buy
            if not self.Portfolio.Invested:

                # See if we can invest in anything
                for i, stock in enumerate(self.currentActiveSecurities):
                    
                    stockSymbol = stock
                    contracts = self.OptionChainProvider.GetOptionContractList(stockSymbol, data.Time)
                    for contract in contracts:
                        option = self.AddOptionContract(contract, Resolution.Minute)
                        option.PriceModel = OptionPriceModels.BlackScholes()
                    
                    optionchain = None
                    for kvp in dataSlice.OptionChains:
                        if str(stockSymbol) in str(kvp.Key):
                            optionchain = kvp.Value
                            break
                    
                    # Ensure we have data for it
                    if data.ContainsKey(stockSymbol) and data[stockSymbol] is not None and optionchain is not None:
                        
                        for contract in optionchain.Contracts:
                            if contract.Value.Greeks.Delta != 0:
                                self.printLog(str(contract.Value.Greeks.Delta))
                                
    def printLog(self, message, symbol = None):
        if symbol is not None:
            message = self.prependMessage(message, symbol)

        message = str(self.Time) + " -- " + message

        if not self.LiveMode:
            self.Debug(message) # This ends up in the log too
        else:
            self.Log(message)