File: main.pas

package info (click to toggle)
lazarus 2.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 214,460 kB
  • sloc: pascal: 1,862,622; xml: 265,709; cpp: 56,595; sh: 3,008; java: 609; makefile: 535; perl: 297; sql: 222; ansic: 137
file content (199 lines) | stat: -rw-r--r-- 6,255 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
unit main;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, TAGraph, TAMultiSeries, TATools,
  Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, ColorBox, types;

type

  { TMainForm }

  TMainForm = class(TForm)
    cbCandleStickSameColor: TCheckBox;
    cbSeriesType: TComboBox;
    ChartToolset1: TChartToolset;
    cbUpColor: TColorBox;
    cbDownColor: TColorBox;
    DataPointHintTool_Details: TDataPointHintTool;
    DataPointHintTool_All: TDataPointHintTool;
    FinancialChart: TChart;
    Label1: TLabel;
    LblDown: TLabel;
    LblUp: TLabel;
    ohlcSeries: TOpenHighLowCloseSeries;
    BottomPanel: TPanel;
    TopPanel: TPanel;
    procedure cbCandleStickSameColorChange(Sender: TObject);
    procedure cbSeriesTypeChange(Sender: TObject);
    procedure cbColorChange(Sender: TObject);
    procedure DataPointHintTool_AllHint(ATool: TDataPointHintTool;
      const APoint: TPoint; var AHint: String);
    procedure DataPointHintToolHintLocation(ATool: TDataPointHintTool;
      AHintSize: TSize; var APoint: TPoint);
    procedure DataPointHintTool_DetailsHint(ATool: TDataPointHintTool;
      const APoint: TPoint; var AHint: String);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.lfm}

uses
  DateUtils;

const
  DATA_FILE = 'data.txt';

{ TMainForm }

procedure TMainForm.FormCreate(Sender: TObject);
var
  dataList: TStringList;
  lines: TStringList;
  fs: TFormatSettings;
  i: Integer;
  xDate: TDate;
  yOpen, yClose, yHigh, yLow: Double;
begin
  fs := DefaultFormatSettings;
  fs.DateSeparator := '-';
  fs.ShortDateFormat := 'd/mmm/yyyy';
  fs.DecimalSeparator := '.';
  dataList := TStringList.Create;
  try
    dataList.LoadFromFile(DATA_FILE);
    lines := TStringList.Create;
    try
      for i:=1 to dataList.Count-1 do begin   // skip header line
        lines.CommaText := dataList[i];
        xDate := ScanDateTime('yyyy-mm-dd', lines[0]);
        yOpen := StrToFloat(lines[1], fs);
        yHigh := StrToFloat(lines[2], fs);
        yLow := StrToFloat(lines[3], fs);
        yClose := StrToFloat(lines[4], fs);
        // We don't use the date for x because we want to skip the weekends in the chart
        // Therefore, we use the index and add the date as a label. Diplay of
        // the data labels is activated by BottomAxis.Marks.Style = smsLabel.
        ohlcSeries.AddXOHLC(i, yOpen, yHigh, yLow, yClose, DateToStr(xDate));
      end;
    finally
      lines.Free;
    end;
  finally
    dataList.Free;
  end;

  FinancialChart.BottomAxis.Marks.Source := ohlcSeries.ListSource;
end;

{ The combobox switches between OHLC and candle stick display modes. }
procedure TMainForm.cbSeriesTypeChange(Sender: TObject);
begin
  ohlcSeries.Mode := TOHLCMode(CbSeriesType.ItemIndex);
  cbCandleStickSameColor.Visible := cbSeriesType.ItemIndex = 1;
end;

procedure TMainForm.cbColorChange(Sender: TObject);
begin
  ohlcSeries.LinePen.Color := cbUpColor.Selected;
  ohlcSeries.DownLinePen.Color := cbDownColor.Selected;
  ohlcSeries.CandlestickUpBrush.Color := cbUpColor.Selected;
  ohlcSeries.CandleStickDownBrush.Color := cbDownColor.Selected;
end;

procedure TMainForm.cbCandleStickSameColorChange(Sender: TObject);
begin
  if cbCandleStickSameColor.Checked then
    ohlcSeries.CandlestickLinePen.Color := clDefault
  else
    ohlcSeries.CandleStickLinePen.Color := clBlack;
end;

{ This event handler returns the text to be displayed as a mouse-over hint.
  We construct the text from the date, and the open, high, low, close values. }
procedure TMainForm.DataPointHintTool_AllHint(ATool: TDataPointHintTool;
  const APoint: TPoint; var AHint: String);
var
  ser: TOpenHighLowCloseSeries;
begin
  ser := ATool.Series as TOpenHighLowCloseSeries;
  AHint := AnsiToUTF8(Format('Date: %s'#13'  Open: %.2m'#13'  High: %.2m'#13'  Low: %.2m'#13'  Close: %.2m', [
    FormatDateTime('dddddd', StrToDate(ser.ListSource[ATool.PointIndex]^.Text)),
    ser.ListSource[ATool.PointIndex]^.GetY(ser.YIndexOpen),
    ser.ListSource[ATool.PointIndex]^.GetY(ser.YIndexHigh),
    ser.ListSource[ATool.PointIndex]^.GetY(ser.YIndexHigh),
    ser.ListSource[ATool.PointIndex]^.GetY(ser.YIndexClose)
  ]));
end;

{ Similar to the method above. Displays only the date and the value clicked }
procedure TMainForm.DataPointHintTool_DetailsHint(ATool: TDataPointHintTool;
  const APoint: TPoint; var AHint: String);
var
  ser: TOpenHighLowCloseSeries;
  x, y: Integer;
  idx: Integer;
  yidx: Integer;
  ohlcName: String;
begin
  ser := ATool.Series as TOpenHighLowCloseSeries;
  idx := ATool.PointIndex;
  yidx := ATool.YIndex;
  if yidx = ohlcSeries.YIndexClose then
    ohlcName := 'Close'
  else if yidx = ohlcSeries.YIndexHigh then
    ohlcName := 'High'
  else if yidx = ohlcSeries.YIndexLow then
    ohlcName := 'Low'
  else if yidx = ohlcSeries.YIndexOpen then
    ohlcName := 'Open';
  AHint := AnsiToUTF8(Format('Date: %s'#13'  %s: %.2m', [
    FormatDateTime('dddddd', StrToDate(ser.ListSource[idx]^.Text)),
    ohlcName,
    ser.ListSource[idx]^.GetY(yidx)
  ]));
end;

{ This event handler returns the location of the hint on the screen. To enhance
  the assosciation with the data point and to avoid covering of the data point
  we move center the hint window and move it up to the top of a OHLC/candle
  data point.

  Note:
  The tool's UseApplicationHint must be set to FALSE for this even to fire. }
procedure TMainForm.DataPointHintToolHintLocation(ATool: TDataPointHintTool;
  AHintSize: TSize; var APoint: TPoint);
var
  ser: TOpenHighLowCloseSeries;
  x, y: Integer;
begin
  { Calculate screen coordinates of the "high" point }
  ser := ATool.Series as TOpenHighLowCloseSeries;
  x := FinancialChart.XGraphToImage(ser.ListSource[ATool.PointIndex]^.X);
  y := FinancialChart.YGraphToImage(ser.ListSource[ATool.PointIndex]^.YList[2]);
    // "High" value, i.e. max of data point

  // Center hint horizontally relative to data point
  APoint.x := x - AHintSize.CX div 2;

  // Move hint 4 pixels above the "High" data point
  APoint.y := y - AHintSize.CY - 4;

  // Hint coordinates are relative to screen
  APoint := FinancialChart.ClientToScreen(APoint);
end;

end.