Overall Statistics |
Total Trades 13445 Average Win 0.27% Average Loss -0.07% Compounding Annual Return -10.332% Drawdown 74.600% Expectancy -0.166 Net Profit -62.888% Sharpe Ratio -0.26 Probabilistic Sharpe Ratio 0.000% Loss Rate 82% Win Rate 18% Profit-Loss Ratio 3.57 Alpha -0.077 Beta 0.274 Annual Standard Deviation 0.204 Annual Variance 0.042 Information Ratio -0.618 Tracking Error 0.227 Treynor Ratio -0.193 Total Fees $86686.70 Estimated Strategy Capacity $180000.00 Lowest Capacity Asset TMV UBTUG7D0B7TX |
/// Please refer to Research.ipynb using QuantConnect.Algorithm.Framework.Alphas; using QuantConnect.Algorithm.Framework.Portfolio; using QuantConnect.Algorithm.Framework.Execution; using QuantConnect.Brokerages; using System; using System.Collections.Generic; using System.Linq; using MathNet.Numerics.Distributions; namespace QuantConnect.Algorithm.Csharp { public class MeanReversionDemo : QCAlgorithm { List<string> _asset = new List<string>{"SHY", "TLT", "IEI", "SHV", "TLH", "EDV", "BIL", "SPTL", "TBT", "TMF", "TMV", "TBF", "VGSH", "VGIT", "VGLT", "SCHO", "SCHR", "SPTS", "GOVT"}; public override void Initialize() { // 1. Required: Five years of backtest history SetStartDate(2014, 1, 1); // 2. Required: Alpha Streams Models: SetBrokerageModel(BrokerageName.AlphaStreams); // 3. Required: Significant AUM Capacity SetCash(1000000); // 4. Required: Benchmark to SPY SetBenchmark("SPY"); SetPortfolioConstruction(new InsightWeightingPortfolioConstructionModel()); SetExecution(new ImmediateExecutionModel()); // Add Equity ------------------------------------------------ foreach(var ticker in _asset) { AddEquity(ticker, Resolution.Minute); } // Set Scheduled Event Method For Our Model Schedule.On(DateRules.EveryDay(), TimeRules.BeforeMarketClose("SHY", 5), EveryDayBeforeMarketClose); } private void EveryDayBeforeMarketClose() { // Fetch history on our universe var history = History(Securities.Keys, 30, Resolution.Daily); if (history.Count() < 0) return; // Extract close prices for each Symbol from Slice data var closes = new Dictionary<Symbol, List<Decimal>>(); foreach(var slice in history){ foreach(var symbol in slice.Keys){ if(!closes.ContainsKey(symbol)){ closes.Add(symbol, new List<Decimal>()); } closes[symbol].Add(slice.Bars[symbol].Close); } } // Get the 30-day rolling mean, standard deviation series, z-score and filtration for each Symbol var rollingMean = new Dictionary<string, double>(); var rollingStd = new Dictionary<string, double>(); var filter = new Dictionary<string, bool>(); var zScore = new Dictionary<string, double>(); foreach(var kvp in closes) { var symbol = kvp.Key; if(!rollingMean.ContainsKey(symbol)){ rollingMean.Add(symbol, decimal.ToDouble(kvp.Value.Average())); rollingStd.Add(symbol, Math.Sqrt(kvp.Value.Average(v => Math.Pow(decimal.ToDouble(v-kvp.Value.Average()), 2)))); zScore.Add(symbol, (decimal.ToDouble(kvp.Value.Last()) - rollingMean[symbol]) / rollingStd[symbol]); filter.Add(symbol, zScore[symbol] < -1); } } // Calculate the expected return and its probability, then calculate the weight var magnitude = new Dictionary<Symbol, double>(); var confidence = new Dictionary<Symbol, double>(); var weights = new Dictionary<Symbol, double>(); foreach(var kvp in rollingMean) { var symbol = kvp.Key; if(!magnitude.ContainsKey(symbol)){ magnitude.Add(symbol, -zScore[symbol] * rollingStd[symbol] / decimal.ToDouble(closes[symbol].Last())); confidence.Add(symbol, Normal.CDF(0, 1, -zScore[symbol])); // Filter if trade or not var trade = filter[symbol] ? 1d : 0d; weights.Add(symbol, trade * Math.Max(confidence[symbol] - 1 / (magnitude[symbol] + 1), 0)); } } // Normalize the weights, then emit insights List<Insight> insights = new List<Insight>{}; var sum = weights.Sum(x => x.Value); if (sum == 0) return; foreach(var kvp in weights) { var symbol = kvp.Key; weights[symbol] = kvp.Value / sum; var insight = new Insight(symbol, TimeSpan.FromDays(1), InsightType.Price, InsightDirection.Up, magnitude[symbol], confidence[symbol], null, weights[symbol]); EmitInsights(insight); } } } }