| Overall Statistics |
|
Total Orders 396 Average Win 0.16% Average Loss -0.15% Compounding Annual Return 21.421% Drawdown 4.000% Expectancy 0.090 Start Equity 100000 End Equity 104621.32 Net Profit 4.621% Sharpe Ratio 0.684 Sortino Ratio 0.783 Probabilistic Sharpe Ratio 46.564% Loss Rate 47% Win Rate 53% Profit-Loss Ratio 1.06 Alpha -0.334 Beta 1.035 Annual Standard Deviation 0.137 Annual Variance 0.019 Information Ratio -3.262 Tracking Error 0.098 Treynor Ratio 0.09 Total Fees $500.90 Estimated Strategy Capacity $170000000.00 Lowest Capacity Asset SQ W5OUXC7GJYAT Portfolio Turnover 46.16% Drawdown Recovery 21 |
# region imports
from AlgorithmImports import *
# endregion
class EMAMomentumUniverse(QCAlgorithm):
def Initialize(self):
self.set_start_date(2019, 1, 7)
self.set_end_date(2019, 4, 1)
self.set_cash(100000)
self.universe_settings.resolution = Resolution.DAILY
self.add_universe(self.select)
self.averages = { }
def select(self, fundamental):
selected = []
fundamental = sorted([x for x in fundamental if x.price > 10],
key=lambda x: x.dollar_volume, reverse=True)[:100]
for stock in fundamental:
symbol = stock.symbol
if symbol not in self.averages:
# 1. Call history to get an array of 200 days of history data
history = self.history[TradeBar](symbol, 200, Resolution.DAILY)
#2. Adjust SelectionData to pass in the history result
self.averages[symbol] = SelectionData(history)
self.averages[symbol].update(self.time, stock.adjusted_price)
if self.averages[symbol].is_ready() and self.averages[symbol].fast > self.averages[symbol].slow:
selected.append(symbol)
return selected[:10]
def on_securities_changed(self, changes):
for security in changes.removed_securities:
self.liquidate(security.symbol)
for security in changes.added_securities:
# make sure the secuirty has a price before placing the order
price = self.get_last_known_price(security)
security.set_market_price(price)
self.set_holdings(security.symbol, 0.10)
class SelectionData():
#3. Update the constructor to accept a history array
def __init__(self, history):
self.slow = ExponentialMovingAverage(200)
self.fast = ExponentialMovingAverage(50)
#4. Loop over the history data and update the indicators
for bar in history:
self.update(bar.end_time, bar.close)
def is_ready(self):
return self.slow.is_ready and self.fast.is_ready
def update(self, time, price):
self.fast.update(time, price)
self.slow.update(time, price)