Overall Statistics |
Total Trades 9 Average Win 0% Average Loss 0% Compounding Annual Return -56.116% Drawdown 0.900% Expectancy 0 Net Profit -0.899% Sharpe Ratio -6.671 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.331 Beta 0.645 Annual Standard Deviation 0.08 Annual Variance 0.006 Information Ratio -3.685 Tracking Error 0.06 Treynor Ratio -0.822 Total Fees $9.00 Estimated Strategy Capacity $66000000.00 Lowest Capacity Asset JAZZ TT3D85SDWEW5 |
from AlgorithmImports import * #lean project-create --language python "Test" #lean cloud backtest "Test" --push --open #lean backtest Test from datetime import timedelta from decimal import Decimal class Test(QCAlgorithm): def Initialize(self): self.SetCash(100000) # Set Strategy Cash self.SetStartDate(2014, 3, 24) self.SetEndDate(2014,3, 27) self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.TestFilter) self.AddAlpha(TestAlphaModel(self)) self.SetPortfolioConstruction(TestPortfolioConstructionModel(portfolioBias = PortfolioBias.Long)) self.Settings.RebalancePortfolioOnInsightChanges = True self.Settings.RebalancePortfolioOnSecurityChanges = False self.SetExecution(TestExecutionModel()) #self.SetRiskManagement(CompositeRiskManagementModel( # TrailingStopRiskManagementModel(0.1), # MaximumDrawdownPercentPerSecurity() #)) def TestFilter(self, universe): selected = [] universe = [c for c in universe if c.HasFundamentalData] universe = sorted(universe, key=lambda c: c.DollarVolume, reverse=True)[100:103] for coarse in universe: selected.append(coarse.Symbol) self.Log(f"[LOG->ADDED] {self.Time}: {coarse.Symbol}") return selected def OnOrderEvent(self, orderEvent: OrderEvent) -> None: order = self.Transactions.GetOrderById(orderEvent.OrderId) if orderEvent.Status == OrderStatus.Filled: self.Log(f"[LOG->ORDER] -> {self.Time}: {order.Type}: {orderEvent}") class TestAlphaModel(AlphaModel): def __init__(self, algo): self.algo = algo def Update(self, algo, slice): insights = [] for symbol in slice.Keys: if slice.ContainsKey(symbol) and slice[symbol] is not None: if (algo.Portfolio[symbol].Invested): insights.append(Insight.Price(symbol, timedelta(days=1), InsightDirection.Flat, None, None, None, 0.05)) algo.Log(f"[LOG->INSIGHT] Flat -> {algo.Time}: {symbol}") else: insights.append(Insight.Price(symbol, timedelta(days=2), InsightDirection.Up, None, None, None, 0.05)) algo.Log(f"[LOG->INSIGHT] Up -> {algo.Time}: {symbol}") return insights def OnSecuritiesChanged(self, algo, changes): algo.Log(f"Changes ({algo.Time}):: {changes}") class TestPortfolioConstructionModel(PortfolioConstructionModel): insightCollection = InsightCollection() def __init__(self, portfolioBias = PortfolioBias.Long): super().__init__() self.portfolioBias = portfolioBias self.SetRebalancingFunc(Resolution.Daily) def CreateTargets(self, algo, insights): targets = [] if (insights.Length > 0): self.insightCollection.AddRange(insights) percents = self.DetermineTargetPercent(insights) for insight in insights: percent = float(percents.get(insight)) algo.Log(f"CreateTargets Add -> {insight.Symbol} {insight.Direction} {percent} ") if (insight.Direction == InsightDirection.Up): target = PortfolioTarget.Percent(algo, insight.Symbol, percents.get(insight)) if target != None: targets.append(target) expiredInsights = self.insightCollection.RemoveExpiredInsights(algo.UtcTime); for insight in expiredInsights: algo.Log(f"CreateTargets Expired -> {insight.Symbol} {insight.Direction} ") target = PortfolioTarget.Percent(algo, insight.Symbol, 0) if target != None and algo.Portfolio[insight.Symbol].Invested: targets.append(target) return targets def DetermineTargetPercent(self, activeInsights): result = {} 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) * insight.Weight return result def RespectPortfolioBias(self, insight): return self.portfolioBias == PortfolioBias.LongShort or insight.Direction == self.portfolioBias class TestExecutionModel(ExecutionModel): def __init__(self): self.targetsCollection = PortfolioTargetCollection() def Execute(self, algo, targets): self.targetsCollection.AddRange(targets) if not self.targetsCollection.IsEmpty: for target in self.targetsCollection.OrderByMarginImpact(algo): security = algo.Securities[target.Symbol] quantity = OrderSizing.GetUnorderedQuantity(algo, target, security) if quantity != 0: aboveMinimumPortfolio = BuyingPowerModelExtensions.AboveMinimumOrderMarginPortfolioPercentage(security.BuyingPowerModel, security, quantity, algo.Portfolio, algo.Settings.MinimumOrderMarginPortfolioPercentage) if aboveMinimumPortfolio: algo.MarketOrder(security, quantity) self.targetsCollection.ClearFulfilled(algo)