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
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
lo = .5 ; hi = 1.5   # log price discrepancies outside of these multipliers

class PriceScreening(QCAlgorithm):
    def Initialize(c):
        use_security_initializer = 0
        if use_security_initializer:
            c.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
            c.SetSecurityInitializer(
                CustomSecurityInitializer(c.BrokerageModel,
                FuncSecuritySeeder(Func[Security, BaseData](c.GetLastKnownPrice)),
                DataNormalizationMode.Raw)
            )
        c.SetCash(100)
        c.SetStartDate(2017,12,22)
        c.SetEndDate(  2017,12,28)
        c.AddUniverse(c.CoarseSelection)
        c.Schedule.On(c.DateRules.EveryDay(), c.TimeRules.At(9, 30), Action(c.trade))

    def CoarseSelection(c, coarse):
        coarse = [ s for s in coarse if s.Price > .2 and s.Price < .99 and s.HasFundamentalData ]
        #coarse = sorted(coarse, key = lambda s: s.Price)[:40]
        c.prices = {}
        for s in coarse:
            c.prices[str(s.Symbol)] = {
                's.Price': s.Price,
            }
        c.universe = [ s.Symbol for s in coarse ]
        return c.universe

    def trade(c):
        if not len(c.universe): return
        hist = c.History(c.universe, 1, Resolution.Daily)['close']

        hits = []
        for s in c.universe:
            s = str(s)  # by the way, why is this needed?
            try:
                if not c.Securities.ContainsKey(s):
                    continue
                #if s in c.Securities and 'Price' in c.Securities[s] and c.Securities[s].Price:
                #    c.SetHoldings(s, .05)
                # some uniformity, trying to go for two digits and this does rounding
                a = float('%.2f' % c.prices[s]['s.Price']) if c.prices[s]['s.Price'] else 0.0
                b = float('%.2f' % hist[s])
                d = float('%.2f' % c.Securities[s].Price)
                log_zeros = 0
                if log_zeros and not d:  # if c.Securities[s].Price is 0.0
                    c.Debug('    {} {}'.format(d, s))
                if not b:  continue
                if not d:  continue
                # If prices are quite a ways off from each other, queue for logging
                if a / b > hi or \
                   a / b < lo or \
                   a / d > hi or \
                   a / d < lo or \
                   b / d > hi or \
                   b / d < lo:
                      hits.append('{}{}{}{}'.format(s.rjust(20), str(a).rjust(10), str(b).rjust(13), str(d).rjust(18)))
            except Exception as e:
                c.Log('{} {}'.format(s, e))
        if hits:
            c.Debug('{}{}{}{}'.format('Symbol'.ljust(20), 's.Price'.rjust(10), 'Hist Daily'.rjust(13), 'c.Securities[s].Price'.rjust(24)))
            for h in hits:
                c.Debug(h)

class CustomSecurityInitializer(BrokerageModelSecurityInitializer):
    '''custom initializer that will set the data normalization mode.
     sub-class the BrokerageModelSecurityInitializer so can also take advantage of the default model/leverage setting behaviors'''

    def __init__(c, brokerageModel, securitySeeder, dataNormalizationMode):
        '''Initializes a new instance of the CustomSecurityInitializer class with the specified normalization mode
        brokerageModel -- The brokerage model used to get fill/fee/slippage/settlement models
        securitySeeder -- The security seeder to be used
        dataNormalizationMode -- The desired data normalization mode'''
        c.base = BrokerageModelSecurityInitializer(brokerageModel, securitySeeder)
        c.dataNormalizationMode = dataNormalizationMode

    def Initialize(c, security):
        '''Initializes the specified security by setting up the models
        security -- The security to be initialized
        seedSecurity -- True to seed the security, false otherwise'''
        # first call the default implementation
        c.base.Initialize(security)

        # now apply data normalization mode
        security.SetDataNormalizationMode(c.dataNormalizationMode)