#region License Information
/* HeuristicLab
* Copyright (C) 2002-2013 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.Collections.Generic;
using System.Linq;
using System.Windows.Forms.DataVisualization.Charting;
using HeuristicLab.DataImporter.Data;
using HeuristicLab.DataImporter.Data.CommandBase;
using HeuristicLab.DataImporter.Data.Model;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
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;
[StorableConstructor]
protected CreateTimeSeriesColumnsCommand(bool deserializing) : base(deserializing) { }
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();
}
}
}