Overall Statistics |
Total Trades 28803 Average Win 0.06% Average Loss -0.06% Compounding Annual Return -3.321% Drawdown 20.200% Expectancy -0.021 Net Profit -18.275% Sharpe Ratio -0.335 Probabilistic Sharpe Ratio 0.005% Loss Rate 52% Win Rate 48% Profit-Loss Ratio 1.06 Alpha -0.021 Beta -0.003 Annual Standard Deviation 0.063 Annual Variance 0.004 Information Ratio -0.89 Tracking Error 0.163 Treynor Ratio 7.366 Total Fees $53974.34 Estimated Strategy Capacity $250000000.00 Lowest Capacity Asset AXP R735QTJ8XC9X |
#region imports from AlgorithmImports import * import math #endregion class MeanReversion(AlphaModel): def __init__(self): self.symbolData = [] self.lastDay = -1 def Update(self, algorithm, data): time = algorithm.Time day = algorithm.Time.day insights = [] #Near the market close of each day for symbol in self.symbolData: isClosingSoon = algorithm.Securities[symbol].Exchange.IsClosingSoon(1) if isClosingSoon == True: break else: return insights if algorithm.Time.day == self.lastDay: return insights self.lastDay = algorithm.Time.day startdate = time-timedelta(days=1) enddate = time history = algorithm.History(self.symbolData, startdate, enddate, Resolution.Minute) #Hvis vi får nul data, så returnerer vi if history.empty: return insights #Vi får vores tickers tickers = history.index.levels[0] returns = {} #Looper over vores tickers, hvis nogle af dem har tomme data eller close ikke er der, så dropper vi dem for ticker in tickers: ticker_history = history.loc[ticker] symbol = SymbolCache.GetSymbol(ticker) if ticker_history.empty or "close" not in ticker_history or ticker_history.close.isnull().values.any() == True or algorithm.Securities[symbol].HasData == False or algorithm.Securities[symbol].Price == 0: history.drop(ticker, level=0) continue ticker_history = ticker_history.close dailyreturn = ticker_history[-2]-ticker_history[0] if math.isnan(dailyreturn) == True: continue returns[symbol] = dailyreturn #algorithm.Securities[symbol].IsTradable rj = sum(returns.values())/len(returns.keys()) weights = {} sum123 = 0 for key, value in returns.items(): sum123 += abs(value-rj) for key, value in returns.items(): weight = -(value-rj)/sum123 weights[key] = weight for key,value in weights.items(): if value > 0: direction = InsightDirection.Up else: direction = InsightDirection.Down insights.append(Insight.Price(key, Expiry.EndOfDay(time+timedelta(days=1)), direction, weight = value)) return insights def OnSecuritiesChanged(self, algorithm, changes): for added in changes.AddedSecurities: self.symbolData.append(added.Symbol) for removed in changes.RemovedSecurities: self.symbolData.remove(removed.Symbol) # Your New Python File
#region imports from AlgorithmImports import * 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 from pytz import utc UTCMIN = datetime.min.replace(tzinfo=utc) #endregion class WeightedPortfolio(PortfolioConstructionModel): def __init__(self): self.insightCollection = InsightCollection() self.removedSymbols = [] self.nextRebalance = None def CreateTargets(self, algorithm, insights): targets = [] if len(insights) == 0: return targets # here we get the new insights and add them to our insight collection for insight in insights: self.insightCollection.Add(insight) # create flatten target for each security that was removed from the universe if len(self.removedSymbols) > 0: universeDeselectionTargets = [ PortfolioTarget(symbol, 0) for symbol in self.removedSymbols ] targets.extend(universeDeselectionTargets) algorithm.Log('(Portfolio module) liquidating: ' + str([x.Value for x in self.removedSymbols]) + ' if they are active, due to not being in the universe') self.removedSymbols = [] expiredInsights = self.insightCollection.RemoveExpiredInsights(algorithm.UtcTime) expiredTargetsLog = [] expiredTargets = [] for symbol, f in groupby(expiredInsights, lambda x: x.Symbol): if not self.insightCollection.HasActiveInsights(symbol, algorithm.UtcTime): expiredTargets.append(PortfolioTarget(symbol, 0)) expiredTargetsLog.append(symbol) continue algorithm.Log(f'(Portfolio module) sold {expiredTargetsLog} due to insight being expired') targets.extend(expiredTargets) # get insight that have not expired of each symbol that is still in the universe activeInsights = self.insightCollection.GetActiveInsights(algorithm.UtcTime) # get the last generated active insight for each symbol lastActiveInsights = [] for symbol, g in groupby(activeInsights, lambda x: x.Symbol): lastActiveInsights.append(sorted(g, key = lambda x: x.GeneratedTimeUtc)[-1]) # determine target percent for the given insights boughtTargetsLog = [] for insight in lastActiveInsights: allocationPercent = insight.Weight * abs(insight.Direction) target = PortfolioTarget.Percent(algorithm, insight.Symbol, allocationPercent) boughtTargetsLog.append(insight.Symbol) targets.append(target) algorithm.Log(f'(Portfolio module) Bought {boughtTargetsLog} stocks, that expires at {Expiry.EndOfMonth}') return targets def OnSecuritiesChanged(self, algorithm, changes): newRemovedSymbols = [x.Symbol for x in changes.RemovedSecurities if x.Symbol not in self.removedSymbols] # get removed symbol and invalidate them in the insight collection self.removedSymbols.extend(newRemovedSymbols) self.insightCollection.Clear(self.removedSymbols) removedList = [x.Value for x in self.removedSymbols] algorithm.Log('(Portfolio module) securities removed from Universe: ' + str(removedList))
# region imports from AlgorithmImports import * from MeanReversionAlpha import MeanReversion from WeightedPortfolioConstructionModel import WeightedPortfolio # endregion class EmotionalYellowGull(QCAlgorithm): def Initialize(self): self.SetStartDate(2016, 1, 1) # Set Start Date' self.SetEndDate(2021, 12, 20) self.SetCash(500000) # Set Strategy Cash self.UniverseSettings.Resolution = Resolution.Minute self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) seeder = FuncSecuritySeeder(self.GetLastKnownPrices) self.SetSecurityInitializer(lambda security: seeder.SeedSecurity(security)) self.SetBenchmark('SPY') etf_symbol = "XLF" universe = self.Universe.ETF(etf_symbol, Market.USA, self.UniverseSettings, self.ETFConstituentsFilter) self.AddUniverse(universe) self.AddAlpha(MeanReversion()) self.SetPortfolioConstruction(WeightedPortfolio()) self.SetExecution(ImmediateExecutionModel()) self.lastMonth = -1 self.num_coarse = 20 def ETFConstituentsFilter(self, constituents: List[ETFConstituentData]) -> List[Symbol]: if self.Time.month == self.lastMonth: return Universe.Unchanged self.lastMonth = self.Time.month selected = sorted([c for c in constituents if c.Weight], key=lambda c: c.Weight, reverse=True)[:self.num_coarse] return [c.Symbol for c in selected]