| 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)