| Overall Statistics |
|
Total Orders 561 Average Win 1.46% Average Loss -1.50% Compounding Annual Return 9.381% Drawdown 36.000% Expectancy 0.129 Start Equity 100000 End Equity 171300.04 Net Profit 71.300% Sharpe Ratio 0.314 Sortino Ratio 0.324 Probabilistic Sharpe Ratio 3.980% Loss Rate 43% Win Rate 57% Profit-Loss Ratio 0.97 Alpha 0 Beta 0 Annual Standard Deviation 0.207 Annual Variance 0.043 Information Ratio 0.42 Tracking Error 0.207 Treynor Ratio 0 Total Fees $1412.10 Estimated Strategy Capacity $20000000.00 Lowest Capacity Asset CE T5JLBNU20TPH Portfolio Turnover 5.48% |
#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(5).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";
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());
}
}
}