#region License Information /* HeuristicLab * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.DataImporter.Data.CommandBase; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.DataImporter.Data; using HeuristicLab.DataImporter.Data.Model; using System.Windows.Forms.DataVisualization.Charting; using System.Drawing; namespace HeuristicLab.DataImporter.Command { [StorableClass] [ViewableCommandInfo("Create time series columns", 1, ColumnGroupState.DoubleColumnSelected, "Column Commands", Position = 16, SelectedColumns = 4)] public class CreateTimeSeriesColumnsCommand : ColumnGroupCommandWithAffectedColumnsBase { private int addedColumnsCount; public CreateTimeSeriesColumnsCommand(DataSet dataSet, string columnGroupName, int[] affectedColumns) : base(dataSet, columnGroupName, affectedColumns) { } public override string Description { get { return "Create time series columns"; } } public override void Execute() { base.Execute(); if (AffectedColumns.Length != 4) throw new CommandExecutionException("The selected columns must include high, low, open, and close price.", this); string[] seriesNames = { "high", "low", "open", "close" }; Chart chart1 = new Chart(); // Y = high // Y2 = low // Y3 = open // Y4 = close List columns = new List(); for (int i = 0; i < 4; i++) { int columnIndex = AffectedColumns[i]; DoubleColumn doubleColumn = ColumnGroup.GetColumn(columnIndex) as DoubleColumn; if (doubleColumn == null) throw new CommandExecutionException("The selection column does not contain double columns.", this); columns.Add(doubleColumn); } Series series = new Series(); series.ChartArea = "Default"; series.ChartType = SeriesChartType.Stock; series.Name = "Input"; series.YValuesPerPoint = 4; for (int i = 0; i < columns[0].TotalValuesCount; i++) { DataPoint point = new DataPoint(); List values = new List(); for (int j = 0; j < 4; j++) { double? v = (double?)columns[j].GetValue(i); if (!v.HasValue) throw new CommandExecutionException("Columns must not contain missing values.", this); values.Add(v.Value); } point.YValues = values.ToArray(); series.Points.AddXY(i, values[0]); series.Points[i].YValues[1] = values[1]; series.Points[i].YValues[2] = values[2]; series.Points[i].YValues[3] = values[3]; } chart1.Series.Add(series); DoubleColumn firstAffectedColumn = (DoubleColumn)ColumnGroup.GetColumn(AffectedColumns[0]); int lastAffectedColumn = AffectedColumns[3]; // formulas using only the close price FinancialFormula[] formulae = new FinancialFormula[] { FinancialFormula.DetrendedPriceOscillator, FinancialFormula.MovingAverageConvergenceDivergence, FinancialFormula.Performance, FinancialFormula.RateOfChange, FinancialFormula.RelativeStrengthIndex, FinancialFormula.StandardDeviation }; int currentColumnIndex = lastAffectedColumn + 1; addedColumnsCount = 0; foreach (var formula in formulae) { chart1.DataManipulator.FinancialFormula(formula, "10", "Input:Y4", "Indicators"); DoubleColumn newColumn = (DoubleColumn)firstAffectedColumn.CreateCopyOfColumnWithoutValues(); newColumn.Name = formula + "(" + firstAffectedColumn.Name + ")"; for (int i = 0; i < chart1.Series["Indicators"].Points.First().XValue; i++) { newColumn.AddValue(null); } foreach (var value in chart1.Series["Indicators"].Points) { newColumn.AddValue(value.YValues[0]); } this.ColumnGroup.InsertColumn(currentColumnIndex, newColumn); currentColumnIndex++; addedColumnsCount++; } // Formulas with two input value formulae = new FinancialFormula[] { FinancialFormula.MassIndex, FinancialFormula.VolatilityChaikins }; foreach (var formula in formulae) { chart1.DataManipulator.FinancialFormula(formula, "20", "Input:Y,Input:Y2", "Indicators"); DoubleColumn newColumn = (DoubleColumn)firstAffectedColumn.CreateCopyOfColumnWithoutValues(); newColumn.Name = formula + "(" + firstAffectedColumn.Name + ")"; for (int i = 0; i < chart1.Series["Indicators"].Points.First().XValue; i++) { newColumn.AddValue(null); } foreach (var value in chart1.Series["Indicators"].Points) { newColumn.AddValue(value.YValues[0]); } this.ColumnGroup.InsertColumn(currentColumnIndex, newColumn); currentColumnIndex++; addedColumnsCount++; } // Williams %R { chart1.DataManipulator.FinancialFormula(FinancialFormula.WilliamsR, "Input:Y,Input:Y2,Input:Y4", "Indicators"); DoubleColumn newColumn = (DoubleColumn)firstAffectedColumn.CreateCopyOfColumnWithoutValues(); newColumn.Name = "WilliamsR(" + firstAffectedColumn.Name + ")"; for (int i = 0; i < chart1.Series["Indicators"].Points.First().XValue; i++) { newColumn.AddValue(null); } foreach (var value in chart1.Series["Indicators"].Points) { newColumn.AddValue(value.YValues[0]); } this.ColumnGroup.InsertColumn(currentColumnIndex, newColumn); currentColumnIndex++; addedColumnsCount++; } // StochasticIndicator { chart1.DataManipulator.FinancialFormula(FinancialFormula.StochasticIndicator, "15", "Input:Y,Input:Y2,Input:Y4", "Indicators,SMA"); DoubleColumn newColumn = (DoubleColumn)firstAffectedColumn.CreateCopyOfColumnWithoutValues(); newColumn.Name = "StochasticIndicator(" + firstAffectedColumn.Name + ")"; for (int i = 0; i < chart1.Series["Indicators"].Points.First().XValue; i++) { newColumn.AddValue(null); } foreach (var value in chart1.Series["Indicators"].Points) { newColumn.AddValue(value.YValues[0]); } this.ColumnGroup.InsertColumn(currentColumnIndex, newColumn); currentColumnIndex++; addedColumnsCount++; DoubleColumn newColumnSma = (DoubleColumn)firstAffectedColumn.CreateCopyOfColumnWithoutValues(); newColumnSma.Name = "StochasticIndicator-SMA(" + firstAffectedColumn.Name + ")"; for (int i = 0; i < chart1.Series["SMA"].Points.First().XValue; i++) { newColumnSma.AddValue(null); } foreach (var value in chart1.Series["SMA"].Points) { newColumnSma.AddValue(value.YValues[0]); } this.ColumnGroup.InsertColumn(currentColumnIndex, newColumnSma); currentColumnIndex++; addedColumnsCount++; } // All other formulas. formulae = new FinancialFormula[] { FinancialFormula.AverageTrueRange, FinancialFormula.CommodityChannelIndex, }; foreach (var formula in formulae) { chart1.DataManipulator.FinancialFormula(formula, "Input:Y,Input:Y2,Input:Y4", "Indicators"); DoubleColumn newColumn = (DoubleColumn)firstAffectedColumn.CreateCopyOfColumnWithoutValues(); newColumn.Name = formula + "(" + firstAffectedColumn.Name + ")"; for (int i = 0; i < chart1.Series["Indicators"].Points.First().XValue; i++) { newColumn.AddValue(null); } foreach (var value in chart1.Series["Indicators"].Points) { newColumn.AddValue(value.YValues[0]); } this.ColumnGroup.InsertColumn(currentColumnIndex, newColumn); currentColumnIndex++; addedColumnsCount++; } // moving averages. formulae = new FinancialFormula[] { FinancialFormula.ExponentialMovingAverage, FinancialFormula.MovingAverage, FinancialFormula.TriangularMovingAverage, FinancialFormula.TripleExponentialMovingAverage, FinancialFormula.WeightedMovingAverage, }; foreach (var formula in formulae) { chart1.DataManipulator.FinancialFormula(formula, "15", "Input:Y4", "Indicators"); DoubleColumn newColumn = (DoubleColumn)firstAffectedColumn.CreateCopyOfColumnWithoutValues(); newColumn.Name = formula + "(" + firstAffectedColumn.Name + ")"; for (int i = 0; i < chart1.Series["Indicators"].Points.First().XValue; i++) { newColumn.AddValue(null); } foreach (var value in chart1.Series["Indicators"].Points) { newColumn.AddValue(value.YValues[0]); } this.ColumnGroup.InsertColumn(currentColumnIndex, newColumn); currentColumnIndex++; addedColumnsCount++; } ColumnGroup.FireChanged(); } public override void UndoExecute() { base.UndoExecute(); int lastAffectedColumnIndex = AffectedColumns[3]; for (int i = 0; i < addedColumnsCount; i++) this.ColumnGroup.RemoveColumn(lastAffectedColumnIndex + 1); addedColumnsCount = 0; ColumnGroup.FireChanged(); } } }