Overall Statistics
Total Trades
29
Average Win
1.77%
Average Loss
-0.39%
Compounding Annual Return
53670.962%
Drawdown
4.000%
Expectancy
3.878
Net Profit
14.775%
Sharpe Ratio
281.199
Probabilistic Sharpe Ratio
99.960%
Loss Rate
11%
Win Rate
89%
Profit-Loss Ratio
4.49
Alpha
0
Beta
0
Annual Standard Deviation
0.502
Annual Variance
0.252
Information Ratio
281.199
Tracking Error
0.502
Treynor Ratio
0
Total Fees
$118.10
Estimated Strategy Capacity
$2800000.00
Lowest Capacity Asset
FXI T2O7DUFBZLUT
# working sort of ema universe 2022-06-24

from AlgorithmImports import *
import numpy as np
# --------------------
SL = -0.02; TP = 0.02;
# --------------------
class UglyBrownDolphin(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2022, 6, 17)
        self.SetEndDate(2022, 6, 24)
        self.SetCash(100000) 
        self.UniverseSettings.Resolution = Resolution.Minute
        self.AddUniverse(self.CoarseSelectionFunction)    
        self.SetCash(100000)
        self.SetTimeZone("America/New_York")
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)   
        self.averages = {}
        self.symbolData = {}           
        
       
#####################################################################
# 100 stocks 10$ and up, highest dollar volume
    
    def CoarseSelectionFunction(self, universe):
        selected = []
        universe = sorted(universe, key = lambda c: c.DollarVolume, reverse=True)
        universe = [c for c in universe if c.Price > 10][:100]

        self.Plot("Universe", "top_dv_symbols", len(universe))  
        
        for sec in universe:
            selectionSymbol = sec.Symbol
            
            if selectionSymbol not in self.averages:
            
                history = self.History(selectionSymbol, 30, Resolution.Daily)
                self.averages[selectionSymbol] = SelectionData(history)
            
            self.averages[selectionSymbol].update(self.Time, sec.AdjustedPrice)
        
            if self.averages[selectionSymbol].fast > self.averages[selectionSymbol].slow:
                if self.averages[selectionSymbol].is_ready():
                    selected.append(selectionSymbol)

        self.Plot("Universe", "fast > slow", len(selected))  

        return selected
    
    
#####################################################################
# Create SymbolData object for each stock added to universe
    
    def OnSecuritiesChanged(self, changes):
        for x in changes.RemovedSecurities:
            self.Liquidate(x.Symbol)
            if x.Symbol in self.symbolData:
                del self.symbolData[x.Symbol]
        
        for ticker in changes.AddedSecurities:
            symbol = ticker.Symbol
            if symbol not in self.symbolData:
                indicatorHistory = self.History(symbol, 91, Resolution.Minute)
                self.symbolData[symbol] = SymbolData(self, symbol, indicatorHistory)

                
#####################################################################        
        
    def OnData(self, slice):  
        if not (self.Time.hour == 10 and self.Time.minute == 31): return
        selected = []
        for symbol, data in self.symbolData.items():
            if not (self.Securities[symbol].Exchange.DateTimeIsOpen(self.Time)): continue
            price = self.Securities[symbol].Price            
            if not data.indicator.IsReady: continue                  
            if data.indicator.Current.Value > 1 :
                selected.append(symbol)

        for sec in self.Portfolio.Keys:
            if not (self.Securities[symbol].Exchange.DateTimeIsOpen(self.Time)): continue
            pnl = self.Securities[sec].Holdings.UnrealizedProfitPercent
            if sec not in selected:
                self.Liquidate(sec)
            elif pnl < SL:
                self.Liquidate(sec, "Stop Loss")
            elif pnl > TP:
                self.Liquidate(sec, "Take Profit") 

        for sec in selected:
            if not (self.Securities[symbol].Exchange.DateTimeIsOpen(self.Time)): continue
            self.SetHoldings(sec, 1/len(selected))

        self.Plot("Universe", "indicator > 1", len(selected))      
    

#####################################################################        
# instantiate and initialize symbols, feed with history request             
            
class SymbolData:
    def __init__(self, algorithm, symbol, indicatorHistory):  
        
        self.indicator = MomentumPercent(90)
        if indicatorHistory.empty:
            return      
    
        for bar in indicatorHistory.itertuples():
            self.indicator.Update(bar.Index[1], bar.close)
                
        def is__ready(self):
            return self.indicator.IsReady
            
        def update_(self, time, price):
            self.indicator.Update(time, price)
        
        self.RegisterIndicator = algorithm.RegisterIndicator(symbol, self.indicator, Resolution.Minute) 

        
#####################################################################        
# Only add stocks to universe that are trending up the past 10 days
class SelectionData:
    
    def __init__(self, history):
        self.slow = ExponentialMovingAverage(30)
        self.fast = ExponentialMovingAverage(10)
        
        for bar in history.itertuples():
            self.slow.Update(bar.Index[1], bar.close)
            self.fast.Update(bar.Index[1], bar.close)
    def is_ready(self):
        return self.slow.IsReady and self.fast.IsReady
        
    def update(self, time, price):
        self.fast.Update(time, price)
        self.slow.Update(time, price)