Overall Statistics
Total Trades
12
Average Win
0.01%
Average Loss
-0.01%
Compounding Annual Return
-60.381%
Drawdown
6.400%
Expectancy
-0.171
Net Profit
-2.463%
Sharpe Ratio
-3.503
Probabilistic Sharpe Ratio
13.798%
Loss Rate
60%
Win Rate
40%
Profit-Loss Ratio
1.07
Alpha
-0.004
Beta
1.156
Annual Standard Deviation
0.142
Annual Variance
0.02
Information Ratio
-1.037
Tracking Error
0.068
Treynor Ratio
-0.431
Total Fees
$29.42
Estimated Strategy Capacity
$130000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from AlgorithmImports import *

### <summary>
### Example algorithm for using SymbolData class
### </summary>
class BasicTemplateSymbolDataAlgorithm(QCAlgorithm):

    ### <summary>
    ### Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
    ### </summary>
    def Initialize(self):
        self.SetStartDate(2022, 1, 1)
        self.SetEndDate(2022, 1, 10)
        self.SetCash(1000000)

        self.symbol_data_by_symbol = {}
        
        equities = [
            "SPY", "AAPL"
        ]

        for ticker in equities:
            # Requesting data
            equity = self.AddEquity(ticker,
                resolution = Resolution.Minute,
                extendedMarketHours = True
            )
            
            symbol_data = SymbolData(self, equity)
            self.symbol_data_by_symbol[equity.Symbol] = symbol_data

    ### <summary>
    ### OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
    ### </summary>
    ### <param name="slice">Slice object keyed by symbol containing the stock data</param>
    def OnData(self, slice):
        for symbol, symbol_data in self.symbol_data_by_symbol.items():
            # Call SymbolData.Update() method to handle new data slice received
            is_market_open = symbol_data.Update(slice)
            
            # Get premarket volume for trading and reset the volume counter if market is open
            if is_market_open:
                if not symbol_data.IsReady:
                    self.Log(f"{self.Time}:: Pre-market volume for {symbol} - {symbol_data.PremarketVolume}")

                    if symbol_data.PremarketVolume > 1e6:
                        self.SetHoldings(symbol, 0.5)
                    else:
                        self.SetHoldings(symbol, 0)
                    
                    symbol_data.Reset()
                    symbol_data.IsReady = True

            else:
                symbol_data.IsReady = False
    
### <summary>
### Abstracted class object to hold information (state, indicators, methods, etc.) from a Symbol/Security in a multi-security algorithm
### </summary>
class SymbolData:
    
    ### <summary>
    ### Constructor to instantiate the information needed to be hold
    ### </summary>
    def __init__(self, algorithm, equity):
        self._algorithm = algorithm
        self.Equity = equity
        self.PremarketVolume = 0
        self.IsReady = False
    
    ### <summary>
    ### Handler of new slice of data received
    ### </summary>
    ### <return>If the market is open for the equity</return>
    def Update(self, slice):
        is_market_open = self._algorithm.IsMarketOpen(self.Equity.Symbol)

        if slice.Bars.ContainsKey(self.Equity.Symbol) and not is_market_open:
            self.PremarketVolume += slice.Bars[self.Equity.Symbol].Volume
        
        return is_market_open
        
    def Reset(self):
        self.PremarketVolume = 0