| Overall Statistics |
|
Total Trades 208 Average Win 0.83% Average Loss -0.54% Compounding Annual Return -76.282% Drawdown 13.600% Expectancy -0.090 Net Profit -5.370% Sharpe Ratio -1.064 Probabilistic Sharpe Ratio 28.301% Loss Rate 64% Win Rate 36% Profit-Loss Ratio 1.53 Alpha -1 Beta 2.371 Annual Standard Deviation 0.592 Annual Variance 0.351 Information Ratio -1.399 Tracking Error 0.562 Treynor Ratio -0.266 Total Fees $270.53 Estimated Strategy Capacity $97000.00 |
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Algorithm.Framework")
from QuantConnect.Data.UniverseSelection import *
from QuantConnect.Indicators import ExponentialMovingAverage
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
class TopGainersUniverseSelectionModel(FundamentalUniverseSelectionModel):
def __init__(self,
Period = 1,
universeCount = 10,
universeSettings = None,
securityInitializer = None):
super().__init__(False, universeSettings, securityInitializer)
self.universeCount = universeCount
self.stateData = { }
def SelectCoarse(self, algorithm, coarse):
for c in coarse:
if c.Symbol not in self.stateData:
self.stateData[c.Symbol] = self.SelectionData(c.Symbol, 1)
avg = self.stateData[c.Symbol]
avg.update(c.EndTime, c.Price, c.Volume)
values = [x for x in self.stateData.values() if x.is_roc_positive and x.volume > 100000 and x.price > 1]
values.sort(key=lambda x: x.roc, reverse=True)
for x in values[:self.universeCount]:
algorithm.Log('-symbol: ' + str(x.symbol.Value) + ' -Price:' + str(x.price) + ' -ROC: ' + str(x.roc))
return [ x.symbol for x in values[:self.universeCount] ]
class SelectionData:
def __init__(self, symbol, period):
self.symbol = symbol
self.roc = RateOfChangePercent(period)
self.is_roc_positive = False
self.volume = 0
self.price = 0
def update(self, time, price, volume):
self.volume = volume
self.price = price
if self.roc.Update(time, price):
self.is_roc_positive = self.roc.Current.Value > 0from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Common")
from AlphaCreation import ConstantAlphaModel
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from RiskManagement import MaximumDrawdownPercentPerSecurity
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
from UniverseSelection import TopGainersUniverseSelectionModel
from System import *
from QuantConnect import *
from QuantConnect.Data import *
from QuantConnect.Algorithm import *
from QuantConnect.Indicators import *
from QuantConnect.Algorithm.Framework.Portfolio import *
from System.Collections.Generic import List
class TopGainersUniverseSelect(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021,4,16)
#self.SetEndDate(2021, 4, 23) #Set End Date
self.SetCash(10000) #Set Strategy Cash
self.UniverseSettings.Resolution = Resolution.Minute
self.SetUniverseSelection(TopGainersUniverseSelectionModel())
self.SetAlpha(ConstantAlphaModel())
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
self.SetExecution(ImmediateExecutionModel())
self.SetRiskManagement(MaximumDrawdownPercentPerSecurity())
self.AddEquity("SPY")
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 5), self.rebalance)
def rebalance(self):
self.Liquidate()from clr import AddReference
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Algorithm.Framework")
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Algorithm.Framework import *
from datetime import timedelta
from QuantConnect.Algorithm.Framework.Alphas import AlphaModel, Insight, InsightType, InsightDirection
class ConstantAlphaModel(AlphaModel):
def __init__(self):
self.period = timedelta(hours=6, minutes=30)
self.securities = []
self.insightsTimeBySymbol = {}
self.ShouldEmitInsight = True
self.Name = 'ConstantAlphaModel'
self.symbols_by_time = {}
def Update(self, algorithm, data):
insights = []
if self.ShouldEmitInsight:
purchased_symbols = []
for security in self.securities:
if algorithm.Securities[security.Symbol].Price == 0:
continue
if security.Symbol.Value == "SPY":
continue
# If security bought two days in a row
days_purchased = [security.Symbol in symbols for time, symbols in self.symbols_by_time.items()]
if days_purchased and all(days_purchased):
algorithm.Debug(f"Skipping {security.Symbol} because it's been purchased 2 days in a row")
continue
purchased_symbols.append(security.Symbol)
if purchased_symbols:
# Create insights
for symbol in purchased_symbols:
insights.append(Insight.Price(symbol, self.period, InsightDirection.Up))
self.ShouldEmitInsight = False
# Delete old keys
sorted_times = sorted(self.symbols_by_time.keys())
for time in sorted_times[:-2]:
self.symbols_by_time.pop(time)
self.symbols_by_time[data.Time] = purchased_symbols
return insights
def OnSecuritiesChanged(self, algorithm, changes):
self.removedSecurities = []
for added in changes.AddedSecurities:
self.securities.append(added)
self.ShouldEmitInsight = True
# This will allow the insight to be re-sent when the security re-joins the universe
for removed in changes.RemovedSecurities:
self.removedSecurities.append(removed)
self.ShouldEmitInsight = True
if removed in self.securities:
self.securities.remove(removed)
if removed.Symbol in self.insightsTimeBySymbol:
self.insightsTimeBySymbol.pop(removed.Symbol)from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Algorithm.Framework")
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Algorithm.Framework import *
from QuantConnect.Algorithm.Framework.Portfolio import PortfolioTarget
from QuantConnect.Algorithm.Framework.Risk import RiskManagementModel
class MaximumDrawdownPercentPerSecurity(RiskManagementModel):
def __init__(self, maximumDrawdownPercent = 0.5):
self.maximumDrawdownPercent = -abs(maximumDrawdownPercent)
def ManageRisk(self, algorithm, targets):
StartTime = algorithm.Time.replace(hour=9, minute=30, second=0)
targets = []
for kvp in algorithm.Securities:
security = kvp.Value
if not security.Invested:
continue
if algorithm.Time > StartTime:
pnl = security.Holdings.UnrealizedProfitPercent
if pnl <= self.maximumDrawdownPercent:
algorithm.Log(str(algorithm.Time) + 'Liquidating Due To MaxDrawdown: ' + str(security))
targets.append(PortfolioTarget(security.Symbol, 0))
return targetsfrom clr import AddReference
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm.Framework")
from QuantConnect import Resolution, Extensions
from QuantConnect.Algorithm.Framework.Alphas import *
from QuantConnect.Algorithm.Framework.Portfolio import *
from itertools import groupby
from datetime import datetime, timedelta
class EqualWeightingPortfolioConstructionModel(PortfolioConstructionModel):
def __init__(self, rebalance = Resolution.Daily, portfolioBias = PortfolioBias.Long):
self.portfolioBias = portfolioBias
# If the argument is an instance of Resolution or Timedelta
# Redefine rebalancingFunc
rebalancingFunc = rebalance
if isinstance(rebalance, int):
rebalance = Extensions.ToTimeSpan(rebalance)
if isinstance(rebalance, timedelta):
rebalancingFunc = lambda dt: dt + rebalance
if rebalancingFunc:
self.SetRebalancingFunc(rebalancingFunc)
def DetermineTargetPercent(self, activeInsights):
result = {}
# give equal weighting to each security
count = sum(x.Direction != InsightDirection.Flat and self.RespectPortfolioBias(x) for x in activeInsights)
percent = 0 if count == 0 else 1.0 / count
for insight in activeInsights:
result[insight] = (insight.Direction if self.RespectPortfolioBias(insight) else InsightDirection.Flat) * percent
return result
def RespectPortfolioBias(self, insight):
return self.portfolioBias == PortfolioBias.Long or insight.Direction == self.portfolioBias