Overall Statistics |
Total Trades 500 Average Win 0.08% Average Loss -0.08% Compounding Annual Return 0.831% Drawdown 2.000% Expectancy 0.023 Net Profit 0.414% Sharpe Ratio 0.329 Probabilistic Sharpe Ratio 31.750% Loss Rate 49% Win Rate 51% Profit-Loss Ratio 1.00 Alpha -0.006 Beta 0.05 Annual Standard Deviation 0.026 Annual Variance 0.001 Information Ratio -2.194 Tracking Error 0.131 Treynor Ratio 0.171 Total Fees $560.00 Estimated Strategy Capacity $21000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X |
from CustomInsightWeightingPortfolioConstructionModel import CustomInsightWeightingPortfolioConstructionModel class JumpingRedPenguin(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 1, 18) self.SetCash(100000) self.AddEquity("SPY", Resolution.Minute) self.AddAlpha(Alpha1()) self.AddAlpha(Alpha2()) self.SetPortfolioConstruction(CustomInsightWeightingPortfolioConstructionModel()) class Alpha1(AlphaModel): def __init__(self): self.Name = "Long" def Update(self, algorithm, data): if algorithm.Time.hour == 9 and algorithm.Time.minute == 31: return [Insight.Price("SPY", timedelta(minutes = 20), InsightDirection.Up, None, None, None, 0.5)] return [] class Alpha2(AlphaModel): def __init__(self): self.Name = "Short" def Update(self, algorithm, data): if algorithm.Time.hour == 10 and algorithm.Time.minute == 31: return [Insight.Price("SPY", timedelta(minutes = 20), InsightDirection.Up, None, None, None, 1.)] return []
from clr import AddReference AddReference("QuantConnect.Common") AddReference("QuantConnect.Algorithm.Framework") from QuantConnect import * from QuantConnect.Algorithm.Framework.Alphas import * from EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel, PortfolioBias class CustomInsightWeightingPortfolioConstructionModel(EqualWeightingPortfolioConstructionModel): def __init__(self, rebalance = Resolution.Daily, portfolioBias = PortfolioBias.LongShort): super().__init__(rebalance, portfolioBias) def ShouldCreateTargetForInsight(self, insight): # Ignore insights that don't have Weight value return insight.Weight is not None def DetermineTargetPercent(self, activeInsights): result = {} # We will adjust weights proportionally in case the sum is > 1 so it sums to 1. weightSums = sum(self.GetValue(insight) for insight in activeInsights if self.RespectPortfolioBias(insight)) weightFactor = 1.0 if weightSums > 1: weightFactor = 1 / weightSums for insight in activeInsights: result[insight] = (insight.Direction if self.RespectPortfolioBias(insight) else InsightDirection.Flat) * self.GetValue(insight) * weightFactor return result def GetValue(self, insight): # adjust by alpha model if insight.SourceModel == "Long": factor = 0.5 elif insight.SourceModel == "Short": factor = 2 return insight.Weight * factor
from clr import AddReference AddReference("QuantConnect.Common") AddReference("QuantConnect.Algorithm.Framework") from QuantConnect import * from QuantConnect.Algorithm.Framework.Alphas import * from QuantConnect.Algorithm.Framework.Portfolio import * from itertools import groupby from datetime import datetime, timedelta class EqualWeightingPortfolioConstructionModel(PortfolioConstructionModel): '''Provides an implementation of IPortfolioConstructionModel that gives equal weighting to all securities. The target percent holdings of each security is 1/N where N is the number of securities. For insights of direction InsightDirection.Up, long targets are returned and for insights of direction InsightDirection.Down, short targets are returned.''' def __init__(self, rebalance = Resolution.Daily, portfolioBias = PortfolioBias.LongShort): '''Initialize a new instance of EqualWeightingPortfolioConstructionModel Args: rebalance: Rebalancing parameter. If it is a timedelta, date rules or Resolution, it will be converted into a function. If None will be ignored. The function returns the next expected rebalance time for a given algorithm UTC DateTime. The function returns null if unknown, in which case the function will be called again in the next loop. Returning current time will trigger rebalance. portfolioBias: Specifies the bias of the portfolio (Short, Long/Short, 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): '''Will determine the target percent for each insight Args: activeInsights: The active insights to generate a target for''' 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): '''Method that will determine if a given insight respects the portfolio bias Args: insight: The insight to create a target for ''' return self.portfolioBias == PortfolioBias.LongShort or insight.Direction == self.portfolioBias