Exemplo n.º 1
0
        /// <summary>
        /// Truncates the chart and order data in the result packet to within the specified time frame
        /// </summary>
        private static void Truncate(LiveResult result, DateTime start, DateTime stop)
        {
            var unixDateStart = Time.DateTimeToUnixTimeStamp(start);
            var unixDateStop  = Time.DateTimeToUnixTimeStamp(stop);

            var charts = new Dictionary <string, Chart>();

            foreach (var chart in result.Charts.Values)
            {
                var newChart = new Chart(chart.Name, chart.ChartType);
                charts.Add(newChart.Name, newChart);
                foreach (var series in chart.Series.Values)
                {
                    var newSeries = new Series(series.Name, series.SeriesType);
                    newSeries.Values.AddRange(series.Values.Where(chartPoint => chartPoint.x >= unixDateStart && chartPoint.x <= unixDateStop));
                    newChart.AddSeries(newSeries);
                }
            }
            result.Charts = charts;
            result.Orders = result.Orders.Values.Where(x => x.Time >= start && x.Time <= stop).ToDictionary(x => x.Id);

            //For live charting convert to UTC
            foreach (var order in result.Orders)
            {
                order.Value.Time = order.Value.Time.ToUniversalTime();
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Estimate the kelly estimate of the strategy.
 /// </summary>
 /// <param name="name">Name of the widget</param>
 /// <param name="key">Location of injection</param>
 /// <param name="backtest">Backtest result object</param>
 /// <param name="live">Live result object</param>
 public KellyEstimateReportElement(string name, string key, BacktestResult backtest, LiveResult live)
 {
     _live     = live;
     _backtest = backtest;
     Name      = name;
     Key       = key;
 }
Exemplo n.º 3
0
 /// <summary>
 /// Estimate the max drawdown of the strategy.
 /// </summary>
 /// <param name="name">Name of the widget</param>
 /// <param name="key">Location of injection</param>
 /// <param name="backtest">Backtest result object</param>
 /// <param name="live">Live result object</param>
 public MaxDrawdownReportElement(string name, string key, BacktestResult backtest, LiveResult live)
 {
     _live     = live;
     _backtest = backtest;
     Name      = name;
     Key       = key;
 }
Exemplo n.º 4
0
 /// <summary>
 /// Estimate the information ratio of the strategy.
 /// </summary>
 /// <param name="name">Name of the widget</param>
 /// <param name="key">Location of injection</param>
 /// <param name="backtest">Backtest result object</param>
 /// <param name="live">Live result object</param>
 public InformationRatioReportElement(string name, string key, BacktestResult backtest, LiveResult live)
 {
     _live     = live;
     _backtest = backtest;
     Name      = name;
     Key       = key;
 }
Exemplo n.º 5
0
 /// <summary>
 /// Create a new plot of the daily returns in bar chart format
 /// </summary>
 /// <param name="name">Name of the widget</param>
 /// <param name="key">Location of injection</param>
 /// <param name="backtest">Backtest result object</param>
 /// <param name="live">Live result object</param>
 public DailyReturnsReportElement(string name, string key, BacktestResult backtest, LiveResult live)
 {
     _live     = live;
     _backtest = backtest;
     Name      = name;
     Key       = key;
 }
Exemplo n.º 6
0
 /// <summary>
 /// Create a new plot of the rolling sharpe ratio
 /// </summary>
 /// <param name="name">Name of the widget</param>
 /// <param name="key">Location of injection</param>
 /// <param name="backtest">Backtest result object</param>
 /// <param name="live">Live result object</param>
 public RollingSharpeReportElement(string name, string key, BacktestResult backtest, LiveResult live)
 {
     _live     = live;
     _backtest = backtest;
     Name      = name;
     Key       = key;
 }
Exemplo n.º 7
0
        /// <summary>
        /// Truncates the chart and order data in the result packet to within the specified time frame
        /// </summary>
        private static void Truncate(LiveResult result, DateTime start, DateTime stop)
        {
            var unixDateStart = Time.DateTimeToUnixTimeStamp(start);
            var unixDateStop  = Time.DateTimeToUnixTimeStamp(stop);

            //Log.Trace("LiveTradingResultHandler.Truncate: Start: " + start.ToString("u") + " Stop : " + stop.ToString("u"));
            //Log.Trace("LiveTradingResultHandler.Truncate: Truncate Delta: " + (unixDateStop - unixDateStart) + " Incoming Points: " + result.Charts["Strategy Equity"].Series["Equity"].Values.Count);

            var charts = new Dictionary <string, Chart>();

            foreach (var kvp in result.Charts)
            {
                var chart    = kvp.Value;
                var newChart = new Chart(chart.Name, chart.ChartType);
                charts.Add(kvp.Key, newChart);
                foreach (var series in chart.Series.Values)
                {
                    var newSeries = new Series(series.Name, series.SeriesType);
                    newSeries.Values.AddRange(series.Values.Where(chartPoint => chartPoint.x >= unixDateStart && chartPoint.x <= unixDateStop));
                    newChart.AddSeries(newSeries);
                }
            }
            result.Charts = charts;
            result.Orders = result.Orders.Values.Where(x => x.Time >= start && x.Time <= stop).ToDictionary(x => x.Id);

            //Log.Trace("LiveTradingResultHandler.Truncate: Truncate Outgoing: " + result.Charts["Strategy Equity"].Series["Equity"].Values.Count);

            //For live charting convert to UTC
            foreach (var order in result.Orders)
            {
                order.Value.Time = order.Value.Time.ToUniversalTime();
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Estimate the trades per day of the strategy.
 /// </summary>
 /// <param name="name">Name of the widget</param>
 /// <param name="key">Location of injection</param>
 /// <param name="backtest">Backtest result object</param>
 /// <param name="live">Live result object</param>
 public TradesPerDayReportElement(string name, string key, BacktestResult backtest, LiveResult live)
 {
     _live     = live;
     _backtest = backtest;
     Name      = name;
     Key       = key;
 }
 /// <summary>
 /// Create a new array of crisis event plots
 /// </summary>
 /// <param name="name">Name of the widget</param>
 /// <param name="key">Location of injection</param>
 /// <param name="backtest">Backtest result object</param>
 /// <param name="live">Live result object</param>
 public CrisisReportElement(string name, string key, BacktestResult backtest, LiveResult live)
 {
     _live     = live;
     _backtest = backtest;
     _template = File.ReadAllText("template.crisis.html");
     Name      = name;
     Key       = key;
 }
Exemplo n.º 10
0
        static void Main(string[] args)
        {
            // Adds the current working directory to the PYTHONPATH env var.
            PythonInitializer.SetPythonPathEnvironmentVariable();

            // Parse report arguments and merge with config to use in report creator:
            if (args.Length > 0)
            {
                Config.MergeCommandLineArgumentsWithConfiguration(ReportArgumentParser.ParseArguments(args));
            }
            var name             = Config.Get("strategy-name");
            var description      = Config.Get("strategy-description");
            var version          = Config.Get("strategy-version");
            var backtestDataFile = Config.Get("backtest-data-source-file");
            var liveDataFile     = Config.Get("live-data-source-file");
            var destination      = Config.Get("report-destination");

            //Set the Order Parser For JSON:
            JsonConvert.DefaultSettings = () => new JsonSerializerSettings
            {
                Converters = { new OrderJsonConverter() }
            };

            // Parse content from source files into result objects
            Log.Trace($"QuantConnect.Report.Main(): Parsing source files...{backtestDataFile}, {liveDataFile}");
            var backtest = JsonConvert.DeserializeObject <BacktestResult>(File.ReadAllText(backtestDataFile));

            LiveResult live = null;

            if (liveDataFile != string.Empty)
            {
                live = JsonConvert.DeserializeObject <LiveResult>(File.ReadAllText(liveDataFile), new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore
                });
            }

            //Create a new report
            Log.Trace("QuantConnect.Report.Main(): Instantiating report...");
            var report = new Report(name, description, version, backtest, live);

            // Generate the html content
            Log.Trace("QuantConnect.Report.Main(): Starting content compile...");
            var html = report.Compile();

            //Write it to target destination.
            if (destination != string.Empty)
            {
                Log.Trace($"QuantConnect.Report.Main(): Writing content to file {destination}");
                File.WriteAllText(destination, html);
            }
            else
            {
                Console.Write(html);
            }
            Log.Trace("QuantConnect.Report.Main(): Completed.");
            Console.ReadKey();
        }
Exemplo n.º 11
0
        /// <summary>
        /// Create a new capacity estimate
        /// </summary>
        /// <param name="name">Name of the widget</param>
        /// <param name="key">Location of injection</param>
        /// <param name="backtest">Backtest result object</param>
        /// <param name="live">Live result object</param>
        public EstimatedCapacityReportElement(string name, string key, BacktestResult backtest, LiveResult live)
        {
            _live     = live;
            _backtest = backtest;
            Name      = name;
            Key       = key;

            _capacityEstimator = new StrategyCapacity();
        }
Exemplo n.º 12
0
 public Result FromLiveResult(LiveResult liveResult)
 {
     return(new Result
     {
         ResultType = ResultType.Live,
         Charts = new Dictionary <string, Chart>(liveResult.Charts),
         Orders = new Dictionary <int, Order>(liveResult.Orders),
         ProfitLoss = new Dictionary <DateTime, decimal>(liveResult.ProfitLoss),
         Statistics = new Dictionary <string, string>(liveResult.Statistics),
         RuntimeStatistics = new Dictionary <string, string>(liveResult.RuntimeStatistics)
     });
 }
 /// <summary>
 /// Create a new plot of the asset allocation over time
 /// </summary>
 /// <param name="name">Name of the widget</param>
 /// <param name="key">Location of injection</param>
 /// <param name="backtest">Backtest result object</param>
 /// <param name="live">Live result object</param>
 /// <param name="backtestPortfolios">Backtest point in time portfolios</param>
 /// <param name="livePortfolios">Live point in time portfolios</param>
 public AssetAllocationReportElement(
     string name,
     string key,
     BacktestResult backtest,
     LiveResult live,
     List <PointInTimePortfolio> backtestPortfolios,
     List <PointInTimePortfolio> livePortfolios)
 {
     _backtest           = backtest;
     _backtestPortfolios = backtestPortfolios;
     _live           = live;
     _livePortfolios = livePortfolios;
     Name            = name;
     Key             = key;
 }
Exemplo n.º 14
0
        /// <summary>
        /// Saves the Live Results per two seconds iterations
        /// </summary>
        /// <param name="game"></param>
        private void saveLiveGameResults(Game game)
        {
            LiveResult _liveResult = new LiveResult
            {
                BetServiceMatchNo = game.ShortCode,
                ResultMinute      = game.Minutes,
                HomeScore         = game.LocalTeamScore,
                AwayScore         = game.AwayTeamScore,
                TimeUpdated       = DateTime.Now,
            };

            try
            {
                BetDatabase.LiveResults.AddOrUpdate(lmr => lmr.LiveResultId, _liveResult);
                BetDatabase.SaveChanges();
            }
            catch (Exception ex)
            {
            }
        }
Exemplo n.º 15
0
        public void JsonRoundTrip()
        {
            var cashBook = new CashBook {
                AccountCurrency = Currencies.EUR
            };

            cashBook.Add(Currencies.USD, 10, 1.2m);
            cashBook.Add(Currencies.EUR, 10, 1m);

            var expected = new LiveResult {
                CashBook = cashBook
            };

            var serialized = JsonConvert.SerializeObject(expected);
            var result     = JsonConvert.DeserializeObject <LiveResult>(serialized);

            Assert.AreEqual(expected.AccountCurrency, result.AccountCurrency);
            Assert.AreEqual(expected.AccountCurrencySymbol, result.AccountCurrencySymbol);
            Assert.AreEqual(expected.Cash.Count, result.Cash.Count);
            Assert.AreEqual(expected.Cash[Currencies.USD].Amount, result.Cash[Currencies.USD].Amount);
            Assert.AreEqual(expected.Cash[Currencies.USD].ConversionRate, result.Cash[Currencies.USD].ConversionRate);
            Assert.AreEqual(expected.Cash[Currencies.EUR].Amount, result.Cash[Currencies.EUR].Amount);
            Assert.AreEqual(expected.Cash[Currencies.EUR].ConversionRate, result.Cash[Currencies.EUR].ConversionRate);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Create beautiful HTML and PDF Reports based on backtest and live data.
        /// </summary>
        /// <param name="name">Name of the strategy</param>
        /// <param name="description">Description of the strategy</param>
        /// <param name="version">Version number of the strategy</param>
        /// <param name="backtest">Backtest result object</param>
        /// <param name="live">Live result object</param>
        /// <param name="pointInTimePortfolioDestination">Point in time portfolio json output base filename</param>
        public Report(string name, string description, string version, BacktestResult backtest, LiveResult live, string pointInTimePortfolioDestination = null)
        {
            var backtestCurve = new Series <DateTime, double>(ResultsUtil.EquityPoints(backtest));
            var liveCurve     = new Series <DateTime, double>(ResultsUtil.EquityPoints(live));

            var backtestOrders = backtest?.Orders?.Values.ToList() ?? new List <Order>();
            var liveOrders     = live?.Orders?.Values.ToList() ?? new List <Order>();

            Log.Trace($"QuantConnect.Report.Report(): Processing backtesting orders");
            var backtestPortfolioInTime = PortfolioLooper.FromOrders(backtestCurve, backtestOrders).ToList();

            Log.Trace($"QuantConnect.Report.Report(): Processing live orders");
            var livePortfolioInTime = PortfolioLooper.FromOrders(liveCurve, liveOrders, liveSeries: true).ToList();

            var destination = pointInTimePortfolioDestination ?? Config.Get("report-destination");

            if (!string.IsNullOrWhiteSpace(destination))
            {
                if (backtestPortfolioInTime.Count != 0)
                {
                    var dailyBacktestPortfolioInTime = backtestPortfolioInTime
                                                       .Select(x => new PointInTimePortfolio(x, x.Time.Date).NoEmptyHoldings())
                                                       .GroupBy(x => x.Time.Date)
                                                       .Select(kvp => kvp.Last())
                                                       .OrderBy(x => x.Time)
                                                       .ToList();

                    var outputFile = destination.Replace(".html", string.Empty) + "-backtesting-portfolio.json";
                    Log.Trace($"Report.Report(): Writing backtest point-in-time portfolios to JSON file: {outputFile}");
                    var backtestPortfolioOutput = JsonConvert.SerializeObject(dailyBacktestPortfolioInTime);
                    File.WriteAllText(outputFile, backtestPortfolioOutput);
                }
                if (livePortfolioInTime.Count != 0)
                {
                    var dailyLivePortfolioInTime = livePortfolioInTime
                                                   .Select(x => new PointInTimePortfolio(x, x.Time.Date).NoEmptyHoldings())
                                                   .GroupBy(x => x.Time.Date)
                                                   .Select(kvp => kvp.Last())
                                                   .OrderBy(x => x.Time)
                                                   .ToList();

                    var outputFile = destination.Replace(".html", string.Empty) + "-live-portfolio.json";
                    Log.Trace($"Report.Report(): Writing live point-in-time portfolios to JSON file: {outputFile}");
                    var livePortfolioOutput = JsonConvert.SerializeObject(dailyLivePortfolioInTime);
                    File.WriteAllText(outputFile, livePortfolioOutput);
                }
            }

            _elements = new List <IReportElement>
            {
                //Basics
                new TextReportElement("strategy name", ReportKey.StrategyName, name),
                new TextReportElement("description", ReportKey.StrategyDescription, description),
                new TextReportElement("version", ReportKey.StrategyVersion, version),
                new TextReportElement("stylesheet", ReportKey.Stylesheet, File.ReadAllText("css/report.css")),
                new TextReportElement("live marker key", ReportKey.LiveMarker, live == null ? string.Empty : "Live "),

                //KPI's Backtest:
                new DaysLiveReportElement("days live kpi", ReportKey.DaysLive, live),
                new CAGRReportElement("cagr kpi", ReportKey.CAGR, backtest, live),
                new TurnoverReportElement("turnover kpi", ReportKey.Turnover, backtest, live),
                new MaxDrawdownReportElement("max drawdown kpi", ReportKey.MaxDrawdown, backtest, live),
                new KellyEstimateReportElement("kelly estimate kpi", ReportKey.KellyEstimate, backtest, live),
                new SharpeRatioReportElement("sharpe kpi", ReportKey.SharpeRatio, backtest, live),
                new PSRReportElement("psr kpi", ReportKey.PSR, backtest, live),
                new InformationRatioReportElement("ir kpi", ReportKey.InformationRatio, backtest, live),
                new MarketsReportElement("markets kpi", ReportKey.Markets, backtest, live),
                new TradesPerDayReportElement("trades per day kpi", ReportKey.TradesPerDay, backtest, live),

                // Generate and insert plots MonthlyReturnsReportElement
                new MonthlyReturnsReportElement("monthly return plot", ReportKey.MonthlyReturns, backtest, live),
                new CumulativeReturnsReportElement("cumulative returns", ReportKey.CumulativeReturns, backtest, live),
                new AnnualReturnsReportElement("annual returns", ReportKey.AnnualReturns, backtest, live),
                new ReturnsPerTradeReportElement("returns per trade", ReportKey.ReturnsPerTrade, backtest, live),
                new AssetAllocationReportElement("asset allocation over time pie chart", ReportKey.AssetAllocation, backtest, live, backtestPortfolioInTime, livePortfolioInTime),
                new DrawdownReportElement("drawdown plot", ReportKey.Drawdown, backtest, live),
                new DailyReturnsReportElement("daily returns plot", ReportKey.DailyReturns, backtest, live),
                new RollingPortfolioBetaReportElement("rolling beta to equities plot", ReportKey.RollingBeta, backtest, live),
                new RollingSharpeReportElement("rolling sharpe ratio plot", ReportKey.RollingSharpe, backtest, live),
                new LeverageUtilizationReportElement("leverage plot", ReportKey.LeverageUtilization, backtest, live, backtestPortfolioInTime, livePortfolioInTime),
                new ExposureReportElement("exposure plot", ReportKey.Exposure, backtest, live, backtestPortfolioInTime, livePortfolioInTime),

                // Array of Crisis Plots:
                new CrisisReportElement("crisis page", ReportKey.CrisisPageStyle, backtest, live),
                new CrisisReportElement("crisis plots", ReportKey.CrisisPlots, backtest, live)
            };
        }
Exemplo n.º 17
0
 /// <summary>
 /// Generate a new instance of DrawdownCollection from backtest and live <see cref="Result"/> derived instances
 /// </summary>
 /// <param name="backtestResult">Backtest result packet</param>
 /// <param name="liveResult">Live result packet</param>
 /// <param name="periods">Top N drawdown periods to get</param>
 /// <returns>DrawdownCollection instance</returns>
 public static DrawdownCollection FromResult(BacktestResult backtestResult = null, LiveResult liveResult = null, int periods = 5)
 {
     return(new DrawdownCollection(NormalizeResults(backtestResult, liveResult), periods));
 }
Exemplo n.º 18
0
        /// <summary>
        /// Normalizes the Series used to calculate the drawdown plots and charts
        /// </summary>
        /// <param name="backtestResult">Backtest result packet</param>
        /// <param name="liveResult">Live result packet</param>
        /// <returns></returns>
        public static Series <DateTime, double> NormalizeResults(BacktestResult backtestResult, LiveResult liveResult)
        {
            var backtestPoints = ResultsUtil.EquityPoints(backtestResult);
            var livePoints     = ResultsUtil.EquityPoints(liveResult);

            if (backtestPoints.Count < 2 && livePoints.Count < 2)
            {
                return(new Series <DateTime, double>(new DateTime[] { }, new double[] { }));
            }

            var startingEquity = backtestPoints.Count == 0 ? livePoints.First().Value : backtestPoints.First().Value;

            // Note: these calculations are *incorrect* for getting the cumulative returns. However, since we're just
            // trying to normalize these two series with each other, it's a good candidate for it since the original
            // values can easily be recalculated from this point
            var backtestSeries = new Series <DateTime, double>(backtestPoints).PercentChange().Where(kvp => !double.IsInfinity(kvp.Value)).CumulativeSum();
            var liveSeries     = new Series <DateTime, double>(livePoints).PercentChange().Where(kvp => !double.IsInfinity(kvp.Value)).CumulativeSum();

            // Get the last key of the backtest series if our series is empty to avoid issues with empty frames
            var firstLiveKey = liveSeries.IsEmpty ? backtestSeries.LastKey().AddDays(1) : liveSeries.FirstKey();

            // Add the final non-overlapping point of the backtest equity curve to the entire live series to keep continuity.
            if (!backtestSeries.IsEmpty)
            {
                var filtered = backtestSeries.Where(kvp => kvp.Key < firstLiveKey);
                liveSeries = filtered.IsEmpty ? liveSeries : liveSeries + filtered.LastValue();
            }

            // Prefer the live values as we don't care about backtest once we've deployed into live.
            // All in all, this is a normalized equity curve, though it's been normalized
            // so that there are no discontinuous jumps in equity value if we only used equity cash
            // to add the last value of the backtest series to the live series.
            //
            // Pandas equivalent:
            //
            // ```
            // pd.concat([backtestSeries, liveSeries], axis=1).fillna(method='ffill').dropna().diff().add(1).cumprod().mul(startingEquity)
            // ```
            return(backtestSeries.Merge(liveSeries, UnionBehavior.PreferRight)
                   .FillMissing(Direction.Forward)
                   .DropMissing()
                   .Diff(1)
                   .SelectValues(x => x + 1)
                   .CumulativeProduct()
                   .SelectValues(x => x * startingEquity));
        }
Exemplo n.º 19
0
        static void Main(string[] args)
        {
            // Parse report arguments and merge with config to use in report creator:
            if (args.Length > 0)
            {
                Config.MergeCommandLineArgumentsWithConfiguration(ReportArgumentParser.ParseArguments(args));
            }
            var name             = Config.Get("strategy-name");
            var description      = Config.Get("strategy-description");
            var version          = Config.Get("strategy-version");
            var backtestDataFile = Config.Get("backtest-data-source-file");
            var liveDataFile     = Config.Get("live-data-source-file");
            var destination      = Config.Get("report-destination");

            // Parse content from source files into result objects
            Log.Trace($"QuantConnect.Report.Main(): Parsing source files...{backtestDataFile}, {liveDataFile}");
            var backtestSettings = new JsonSerializerSettings
            {
                Converters = new List <JsonConverter> {
                    new NullResultValueTypeJsonConverter <BacktestResult>()
                },
                FloatParseHandling = FloatParseHandling.Decimal
            };

            var        backtest = JsonConvert.DeserializeObject <BacktestResult>(File.ReadAllText(backtestDataFile), backtestSettings);
            LiveResult live     = null;

            if (liveDataFile != string.Empty)
            {
                var settings = new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    Converters        = new List <JsonConverter> {
                        new NullResultValueTypeJsonConverter <LiveResult>()
                    }
                };

                live = JsonConvert.DeserializeObject <LiveResult>(File.ReadAllText(liveDataFile), settings);
            }

            //Create a new report
            Log.Trace("QuantConnect.Report.Main(): Instantiating report...");
            var report = new Report(name, description, version, backtest, live);

            // Generate the html content
            Log.Trace("QuantConnect.Report.Main(): Starting content compile...");
            string html;
            string _;

            report.Compile(out html, out _);

            //Write it to target destination.
            if (destination != string.Empty)
            {
                Log.Trace($"QuantConnect.Report.Main(): Writing content to file {destination}");
                File.WriteAllText(destination, html);
            }
            else
            {
                Console.Write(html);
            }

            Log.Trace("QuantConnect.Report.Main(): Completed.");

            if (!Console.IsInputRedirected)
            {
                Console.ReadKey();
            }
        }
Exemplo n.º 20
0
 /// <summary>
 /// Create a new metric describing the number of days an algorithm has been live.
 /// </summary>
 /// <param name="name">Name of the widget</param>
 /// <param name="key">Location of injection</param>
 /// <param name="backtest">Backtest result object</param>
 /// <param name="live">Live result object</param>
 public DaysLiveReportElement(string name, string key, LiveResult live)
 {
     _live = live;
     Name  = name;
     Key   = key;
 }
Exemplo n.º 21
0
        /// <summary>
        /// Create beautiful HTML and PDF Reports based on backtest and live data.
        /// </summary>
        /// <param name="name">Name of the strategy</param>
        /// <param name="description">Description of the strategy</param>
        /// <param name="version">Version number of the strategy</param>
        /// <param name="backtest">Backtest result object</param>
        /// <param name="live">Live result object</param>
        public Report(string name, string description, string version, BacktestResult backtest, LiveResult live)
        {
            var backtestCurve = new Series <DateTime, double>(ResultsUtil.EquityPoints(backtest));
            var liveCurve     = new Series <DateTime, double>(ResultsUtil.EquityPoints(live));

            var backtestOrders = backtest?.Orders?.Values.ToList() ?? new List <Order>();
            var liveOrders     = live?.Orders?.Values.ToList() ?? new List <Order>();

            Log.Trace($"QuantConnect.Report.Report(): Processing backtesting orders");
            var backtestPortfolioInTime = PortfolioLooper.FromOrders(backtestCurve, backtestOrders).ToList();

            Log.Trace($"QuantConnect.Report.Report(): Processing live orders");
            var livePortfolioInTime = PortfolioLooper.FromOrders(liveCurve, liveOrders, liveSeries: true).ToList();

            _elements = new List <ReportElement>
            {
                //Basics
                new TextReportElement("strategy name", ReportKey.StrategyName, name),
                new TextReportElement("description", ReportKey.StrategyDescription, description),
                new TextReportElement("version", ReportKey.StrategyVersion, version),
                new TextReportElement("stylesheet", ReportKey.Stylesheet, File.ReadAllText("css/report.css")),

                //KPI's Backtest:
                new EstimatedCapacityReportElement("estimated capacity kpi", ReportKey.EstimatedCapacity, backtest, live),
                new CAGRReportElement("cagr kpi", ReportKey.CAGR, backtest, live),
                new TurnoverReportElement("turnover kpi", ReportKey.Turnover, backtest, live),
                new MaxDrawdownReportElement("max drawdown kpi", ReportKey.MaxDrawdown, backtest, live),
                new KellyEstimateReportElement("kelly estimate kpi", ReportKey.KellyEstimate, backtest, live),
                new SharpeRatioReportElement("sharpe kpi", ReportKey.SharpeRatio, backtest, live),
                new PSRReportElement("psr kpi", ReportKey.PSR, backtest, live),
                new InformationRatioReportElement("ir kpi", ReportKey.InformationRatio, backtest, live),
                new MarketsReportElement("markets kpi", ReportKey.Markets, backtest, live),
                new TradesPerDayReportElement("trades per day kpi", ReportKey.TradesPerDay, backtest, live),

                // Generate and insert plots MonthlyReturnsReportElement
                new MonthlyReturnsReportElement("monthly return plot", ReportKey.MonthlyReturns, backtest, live),
                new CumulativeReturnsReportElement("cumulative returns", ReportKey.CumulativeReturns, backtest, live),
                new AnnualReturnsReportElement("annual returns", ReportKey.AnnualReturns, backtest, live),
                new ReturnsPerTradeReportElement("returns per trade", ReportKey.ReturnsPerTrade, backtest, live),
                new AssetAllocationReportElement("asset allocation over time pie chart", ReportKey.AssetAllocation, backtest, live, backtestPortfolioInTime, livePortfolioInTime),
                new DrawdownReportElement("drawdown plot", ReportKey.Drawdown, backtest, live),
                //new DailyReturnsReportElement("daily returns plot", ReportKey.DailyReturns, backtest, live),
                //new RollingPortfolioBetaReportElement("rolling beta to equities plot", ReportKey.RollingBeta, backtest, live),
                //new RollingSharpeReportElement("rolling sharpe ratio plot", ReportKey.RollingSharpe, backtest, live),
                //new LeverageUtilizationReportElement("leverage plot", ReportKey.LeverageUtilization, backtest, live, backtestPortfolioInTime, livePortfolioInTime),
                //new ExposureReportElement("exposure plot", ReportKey.Exposure, backtest, live, backtestPortfolioInTime, livePortfolioInTime),

                // Array of Crisis Plots:
                new CrisisReportElement("crisis page", ReportKey.CrisisPageStyle, backtest, live),
                new CrisisReportElement("crisis plots", ReportKey.CrisisPlots, backtest, live)
            };
        }
Exemplo n.º 22
0
        /// <summary>
        /// Save the snapshot of the total results to storage.
        /// </summary>
        /// <param name="packet">Packet to store.</param>
        /// <param name="async">Store the packet asyncronously to speed up the thread.</param>
        /// <remarks>
        ///     Async creates crashes in Mono 3.10 if the thread disappears before the upload is complete so it is disabled for now.
        ///     For live trading we're making assumption its a long running task and safe to async save large files.
        /// </remarks>
        public void StoreResult(Packet packet, bool async = true)
        {
            // this will hold all the serialized data and the keys to be stored
            var data_keys = Enumerable.Range(0, 0).Select(x => new
            {
                Key        = (string)null,
                Serialized = (string)null
            }).ToList();

            try
            {
                Log.Debug("LiveTradingResultHandler.StoreResult(): Begin store result sampling");
                lock (_chartLock)
                {
                    // Make sure this is the right type of packet:
                    if (packet.Type != PacketType.LiveResult)
                    {
                        return;
                    }

                    // Port to packet format:
                    var live = packet as LiveResultPacket;

                    if (live != null)
                    {
                        // we need to down sample
                        var start = DateTime.UtcNow.Date;
                        var stop  = start.AddDays(1);

                        // truncate to just today, we don't need more than this for anyone
                        Truncate(live.Results, start, stop);

                        var highResolutionCharts = new Dictionary <string, Chart>(live.Results.Charts);

                        // 10 minute resolution data, save today
                        var tenminuteSampler = new SeriesSampler(TimeSpan.FromMinutes(10));
                        var tenminuteCharts  = tenminuteSampler.SampleCharts(live.Results.Charts, start, stop);

                        live.Results.Charts = tenminuteCharts;
                        data_keys.Add(new
                        {
                            Key        = CreateKey("10minute"),
                            Serialized = JsonConvert.SerializeObject(live.Results)
                        });

                        // minute resoluton data, save today
                        var minuteSampler = new SeriesSampler(TimeSpan.FromMinutes(1));
                        var minuteCharts  = minuteSampler.SampleCharts(live.Results.Charts, start, stop);

                        // swap out our charts with the sampeld data
                        live.Results.Charts = minuteCharts;
                        data_keys.Add(new
                        {
                            Key        = CreateKey("minute"),
                            Serialized = JsonConvert.SerializeObject(live.Results)
                        });

                        // high resolution data, we only want to save an hour
                        live.Results.Charts = highResolutionCharts;
                        start = DateTime.UtcNow.RoundDown(TimeSpan.FromHours(1));
                        stop  = DateTime.UtcNow.RoundUp(TimeSpan.FromHours(1));

                        Truncate(live.Results, start, stop);

                        foreach (var name in live.Results.Charts.Keys)
                        {
                            var newPacket = new LiveResult();
                            newPacket.Orders   = new Dictionary <int, Order>(live.Results.Orders);
                            newPacket.Holdings = new Dictionary <string, Holding>(live.Results.Holdings);
                            newPacket.Charts   = new Dictionary <string, Chart>();
                            newPacket.Charts.Add(name, live.Results.Charts[name]);

                            data_keys.Add(new
                            {
                                Key        = CreateKey("second_" + Uri.EscapeUriString(name), "yyyy-MM-dd-HH"),
                                Serialized = JsonConvert.SerializeObject(newPacket)
                            });
                        }
                    }
                    else
                    {
                        Log.Error("LiveResultHandler.StoreResult(): Result Null.");
                    }
                }
                Log.Debug("LiveTradingResultHandler.StoreResult(): End store result sampling");

                // Upload Results Portion
                foreach (var dataKey in data_keys)
                {
                    _api.Store(dataKey.Serialized, dataKey.Key, StoragePermissions.Authenticated, async);
                }
            }
            catch (Exception err)
            {
                Log.Error(err);
            }
        }