Overall Statistics |
Total Orders 4793 Average Win 0.16% Average Loss -0.17% Compounding Annual Return 7.295% Drawdown 35.400% Expectancy 0.089 Start Equity 100000 End Equity 152598.79 Net Profit 52.599% Sharpe Ratio 0.252 Sortino Ratio 0.26 Probabilistic Sharpe Ratio 3.108% Loss Rate 43% Win Rate 57% Profit-Loss Ratio 0.91 Alpha -0.021 Beta 0.873 Annual Standard Deviation 0.176 Annual Variance 0.031 Information Ratio -0.308 Tracking Error 0.099 Treynor Ratio 0.051 Total Fees $4976.21 Estimated Strategy Capacity $74000000.00 Lowest Capacity Asset CRL RVSAF8UO0M79 Portfolio Turnover 4.98% |
#region imports using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Globalization; using System.Drawing; using QuantConnect; using QuantConnect.Algorithm.Selection; using QuantConnect.Algorithm.Framework; using QuantConnect.Algorithm.Framework.Selection; using QuantConnect.Algorithm.Framework.Alphas; using QuantConnect.Algorithm.Framework.Portfolio; using QuantConnect.Algorithm.Framework.Execution; using QuantConnect.Algorithm.Framework.Risk; using QuantConnect.Parameters; using QuantConnect.Benchmarks; using QuantConnect.Brokerages; using QuantConnect.Util; using QuantConnect.Interfaces; using QuantConnect.Algorithm; using QuantConnect.Indicators; using QuantConnect.Data; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Custom; using QuantConnect.DataSource; using QuantConnect.Data.Fundamental; using QuantConnect.Data.Market; using QuantConnect.Data.UniverseSelection; using QuantConnect.Notifications; using QuantConnect.Orders; using QuantConnect.Orders.Fees; using QuantConnect.Orders.Fills; using QuantConnect.Orders.Slippage; using QuantConnect.Scheduling; using QuantConnect.Securities; using QuantConnect.Securities.Equity; using QuantConnect.Securities.Future; using QuantConnect.Securities.Option; using QuantConnect.Securities.Positions; using QuantConnect.Securities.Forex; using QuantConnect.Securities.Crypto; using QuantConnect.Securities.Interfaces; using QuantConnect.Storage; using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm; using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm; #endregion namespace QuantConnect.Algorithm.CSharp { public class ConservativeRebalancingAlphaModel : AlphaModel { private int _vLookback; private int _mLookback; private List<Symbol> _symbols; private int _month; public ConservativeRebalancingAlphaModel(int vLookback, int mLookback) { _vLookback = vLookback; _mLookback = mLookback; _symbols = new List<Symbol>(); _month = -1; } public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { foreach (var added in changes.AddedSecurities) { _symbols.Add(added.Symbol); } foreach (var removed in changes.RemovedSecurities) { _symbols.Remove(removed.Symbol); algorithm.Liquidate(removed.Symbol); } } public override IEnumerable<Insight> Update(QCAlgorithmFramework algorithm, Slice data) { if (algorithm.Time.Day != 1 || algorithm.Time.Month == _month) { algorithm.Log($"List of constituents: {string.Join(", ", _symbols.Select(s => s.Value))}"); return Enumerable.Empty<Insight>(); } _month = algorithm.Time.Month; var alphas = new Dictionary<Symbol, decimal>(); foreach (var symbol in _symbols) { if (!data.ContainsKey(symbol)) { continue; } var roc = algorithm.ROC(symbol, 1, Resolution.Daily); var std = algorithm.STD(symbol, _vLookback, Resolution.Daily); var momp = algorithm.MOMP(symbol, _mLookback, Resolution.Daily); var history = algorithm.History(symbol, Math.Max(_vLookback, _mLookback)+1, Resolution.Daily); foreach (var row in history) { roc.Update(row.EndTime, row.Close); std.Update(row.EndTime, roc.Current.Value); momp.Update(row.EndTime, row.Close); } // Log the readiness of the indicators algorithm.Log($"Indicators for {symbol} at {algorithm.Time}: ROC ready = {roc.IsReady}, STD ready = {std.IsReady}, MOMP ready = {momp.IsReady}"); alphas[symbol] = momp.Current.Value / std.Current.Value; algorithm.Log($"Alpha value for {symbol}: {alphas[symbol]}"); } var selected = alphas.OrderByDescending(x => x.Value).Take(50).Select(x => x.Key); // Log the selected symbols algorithm.Debug($"Selected symbols at {algorithm.Time}: {string.Join(", ", selected)}"); // int daysInMonth = DateTime.DaysInMonth(algorithm.Time.Year, algorithm.Time.Month); // TimeSpan lifespan = TimeSpan.FromDays(daysInMonth - 1); return selected.Select(symbol => new Insight(symbol, TimeSpan.FromDays(2), InsightType.Price, InsightDirection.Up)); } } }
#region imports using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Globalization; using System.Drawing; using QuantConnect; using QuantConnect.Algorithm.Framework; using QuantConnect.Algorithm.Framework.Selection; using QuantConnect.Algorithm.Framework.Alphas; using QuantConnect.Algorithm.Framework.Portfolio; using QuantConnect.Algorithm.Framework.Execution; using QuantConnect.Algorithm.Framework.Risk; using QuantConnect.Algorithm.Selection; using QuantConnect.Parameters; using QuantConnect.Benchmarks; using QuantConnect.Brokerages; using QuantConnect.Util; using QuantConnect.Interfaces; using QuantConnect.Algorithm; using QuantConnect.Indicators; using QuantConnect.Data; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Custom; using QuantConnect.DataSource; using QuantConnect.Data.Fundamental; using QuantConnect.Data.Market; using QuantConnect.Data.UniverseSelection; using QuantConnect.Notifications; using QuantConnect.Orders; using QuantConnect.Orders.Fees; using QuantConnect.Orders.Fills; using QuantConnect.Orders.Slippage; using QuantConnect.Scheduling; using QuantConnect.Securities; using QuantConnect.Securities.Equity; using QuantConnect.Securities.Future; using QuantConnect.Securities.Option; using QuantConnect.Securities.Forex; using QuantConnect.Securities.Crypto; using QuantConnect.Securities.Interfaces; using QuantConnect.Storage; using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm; using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm; #endregion namespace QuantConnect.Algorithm.CSharp { public class ConservativeAlgorithm : QCAlgorithm { public override void Initialize() { SetStartDate(2018, 1, 1); SetEndDate(2024, 1, 1); SetCash(100000); // Set number days to trace back int vLookback = 36; int mLookback = 12; // SetWarmUp(40); SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin); // SPY 500 companies string spy = "SPY"; SetBenchmark(AddEquity(spy, Resolution.Daily).Symbol); UniverseSettings.Resolution = Resolution.Daily; UniverseSettings.Schedule.On(DateRules.MonthStart()); AddUniverseSelection(new ETFConstituentsUniverseSelectionModel(spy)); SetAlpha(new ConservativeRebalancingAlphaModel(vLookback, mLookback)); // Set the portfolio construction to rebalance on the first trading day of each month Settings.RebalancePortfolioOnInsightChanges = false; Settings.RebalancePortfolioOnSecurityChanges = false; SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel( time => { // Rebalance on the first trading day of each month if (time.Day == 1) { return time; } return null; })); SetRiskManagement(new NullRiskManagementModel()); SetExecution(new ImmediateExecutionModel()); } } }