Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/Views/TradingSolutionLineChartView.cs @ 9743

Last change on this file since 9743 was 9743, checked in by gkronber, 11 years ago

#1508 updated classes in trading branch to work with current trunk version of HL.

File size: 9.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21using System;
22using System.Collections.Generic;
23using System.Drawing;
24using System.Linq;
25using System.Windows.Forms;
26using System.Windows.Forms.DataVisualization.Charting;
27using HeuristicLab.Common;
28using HeuristicLab.MainForm;
29using HeuristicLab.MainForm.WindowsForms;
30using HeuristicLab.Problems.DataAnalysis.Views;
31
32namespace HeuristicLab.Problems.DataAnalysis.Trading.Views {
33  [View("Line Chart")]
34  [Content(typeof(ITradingSolution))]
35  public partial class TradingSolutionLineChartView : DataAnalysisSolutionEvaluationView, ITradingSolutionEvaluationView {
36    private const string PRICEVARIABLE_SERIES_NAME = "Price";
37    private const string SIGNALS_SERIES_NAME = "Signals";
38    private const string ASSET_SERIES_NAME = "Asset";
39
40
41    public new ITradingSolution Content {
42      get { return (ITradingSolution)base.Content; }
43      set { base.Content = value; }
44    }
45
46    public TradingSolutionLineChartView()
47      : base() {
48      InitializeComponent();
49      //configure axis
50      this.chart.CustomizeAllChartAreas();
51      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
52      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
53      this.chart.ChartAreas[0].CursorX.Interval = 1;
54
55      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
56      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
57      this.chart.ChartAreas[0].CursorY.Interval = 0;
58    }
59
60    private void RedrawChart() {
61      this.chart.Series.Clear();
62      if (Content != null) {
63        //this.chart.Series.Add(PRICEVARIABLE_SERIES_NAME);
64        //this.chart.Series[PRICEVARIABLE_SERIES_NAME].LegendText = Content.ProblemData.PriceVariable;
65        //this.chart.Series[PRICEVARIABLE_SERIES_NAME].ChartType = SeriesChartType.FastLine;
66        //this.chart.Series[PRICEVARIABLE_SERIES_NAME].Points.DataBindY(Content.ProblemData.Dataset.GetVariableValues(Content.ProblemData.PriceVariable));
67
68
69        this.chart.Series.Add(SIGNALS_SERIES_NAME);
70        this.chart.Series[SIGNALS_SERIES_NAME].LegendText = SIGNALS_SERIES_NAME;
71        this.chart.Series[SIGNALS_SERIES_NAME].ChartType = SeriesChartType.FastLine;
72        this.chart.Series[SIGNALS_SERIES_NAME].Points.DataBindY(Content.Signals.ToArray());
73        this.chart.Series[SIGNALS_SERIES_NAME].Tag = Content;
74
75        IEnumerable<double> accumulatedPrice = GetAccumulatedPrices(Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.PriceVariable));
76        this.chart.Series.Add(PRICEVARIABLE_SERIES_NAME);
77        this.chart.Series[PRICEVARIABLE_SERIES_NAME].LegendText = PRICEVARIABLE_SERIES_NAME;
78        this.chart.Series[PRICEVARIABLE_SERIES_NAME].ChartType = SeriesChartType.FastLine;
79        this.chart.Series[PRICEVARIABLE_SERIES_NAME].Points.DataBindY(accumulatedPrice.ToArray());
80        this.chart.Series[PRICEVARIABLE_SERIES_NAME].Tag = Content;
81
82        IEnumerable<double> profit = GetProfits(Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.PriceVariable), Content.Signals, Content.ProblemData.TransactionCosts);
83        IEnumerable<double> accumulatedProfits = GetAccumulatedPrices(profit);
84        this.chart.Series.Add(ASSET_SERIES_NAME);
85        this.chart.Series[ASSET_SERIES_NAME].LegendText = ASSET_SERIES_NAME;
86        this.chart.Series[ASSET_SERIES_NAME].ChartType = SeriesChartType.FastLine;
87        this.chart.Series[ASSET_SERIES_NAME].Points.DataBindY(accumulatedProfits.ToArray());
88        this.chart.Series[ASSET_SERIES_NAME].Tag = Content;
89
90        this.UpdateStripLines();
91
92        // UpdateCursorInterval();
93      }
94    }
95
96    private IEnumerable<double> GetProfits(IEnumerable<double> returns, IEnumerable<double> signals, double transactionCost) {
97      int p = (int)signals.First();
98      yield return 0.0;
99      foreach (var signalReturn in returns.Skip(1).Zip(signals.Skip(1), (r, s) => new { Return = r, Signal = s })) {
100        double iterationReturn = 0;
101        double signal = signalReturn.Signal;
102        double actualReturn = signalReturn.Return;
103        if (p == 0 && signal.IsAlmost(0)) {
104        } else if (p == 0 && signal.IsAlmost(1)) {
105          iterationReturn = 0;
106          p = 1;
107        } else if (p == 0 && signal.IsAlmost(-1)) {
108          iterationReturn = 0;
109          p = -1;
110        } else if (p == 1 && signal.IsAlmost(1)) {
111          iterationReturn = actualReturn;
112        } else if (p == 1 && signal.IsAlmost(0)) {
113          iterationReturn = actualReturn - transactionCost;
114          p = 0;
115        } else if (p == 1 && signal.IsAlmost(-1)) {
116          iterationReturn = actualReturn - transactionCost;
117          p = -1;
118        } else if (p == -1 && signal.IsAlmost(-1)) {
119          iterationReturn = -actualReturn;
120        } else if (p == -1 && signal.IsAlmost(0)) {
121          iterationReturn = -actualReturn - transactionCost;
122          p = 0;
123        } else if (p == -1 && signal.IsAlmost(1)) {
124          iterationReturn = -actualReturn - transactionCost;
125          p = 1;
126        }
127        yield return iterationReturn;
128      }
129    }
130
131    private IEnumerable<double> GetAccumulatedPrices(IEnumerable<double> xs) {
132      double sum = 0;
133      foreach (var x in xs) {
134        sum += x;
135        yield return sum;
136      }
137    }
138
139    //private void UpdateCursorInterval() {
140    //  var estimatedValues = this.chart.Series[SIGNALS_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
141    //  var targetValues = this.chart.Series[PRICEVARIABLE_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
142    //  double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();
143    //  double targetValuesRange = targetValues.Max() - targetValues.Min();
144    //  double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));
145    //  double digits = (int)Math.Log10(interestingValuesRange) - 3;
146    //  double yZoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
147    //  this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
148    //}
149
150    #region events
151    protected override void RegisterContentEvents() {
152      base.RegisterContentEvents();
153      Content.ModelChanged += new EventHandler(Content_ModelChanged);
154      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
155    }
156    protected override void DeregisterContentEvents() {
157      base.DeregisterContentEvents();
158      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
159      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
160    }
161
162    private void Content_ProblemDataChanged(object sender, EventArgs e) {
163      RedrawChart();
164    }
165
166    private void Content_ModelChanged(object sender, EventArgs e) {
167      RedrawChart();
168    }
169
170    protected override void OnContentChanged() {
171      base.OnContentChanged();
172      RedrawChart();
173    }
174
175    private void Chart_MouseDoubleClick(object sender, MouseEventArgs e) {
176      HitTestResult result = chart.HitTest(e.X, e.Y);
177      if (result.ChartArea != null && (result.ChartElementType == ChartElementType.PlottingArea ||
178                                       result.ChartElementType == ChartElementType.Gridlines) ||
179                                       result.ChartElementType == ChartElementType.StripLines) {
180        foreach (var axis in result.ChartArea.Axes)
181          axis.ScaleView.ZoomReset(int.MaxValue);
182      }
183    }
184    #endregion
185
186    private void UpdateStripLines() {
187      this.chart.ChartAreas[0].AxisX.StripLines.Clear();
188      this.CreateAndAddStripLine("Training", Color.FromArgb(20, Color.Green),
189        Content.ProblemData.TrainingPartition.Start,
190        Content.ProblemData.TrainingPartition.End);
191      this.CreateAndAddStripLine("Test", Color.FromArgb(20, Color.Red),
192        Content.ProblemData.TestPartition.Start,
193        Content.ProblemData.TestPartition.End);
194    }
195
196    private void CreateAndAddStripLine(string title, Color c, int start, int end) {
197      StripLine stripLine = new StripLine();
198      stripLine.BackColor = c;
199      stripLine.Text = title;
200      stripLine.Font = new Font("Times New Roman", 12, FontStyle.Bold);
201      stripLine.StripWidth = end - start;
202      stripLine.IntervalOffset = start;
203      this.chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
204    }
205  }
206}
Note: See TracBrowser for help on using the repository browser.