File: main.pas

package info (click to toggle)
lazarus 1.6.2%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 172,444 kB
  • ctags: 124,173
  • sloc: pascal: 1,528,777; xml: 260,232; sh: 3,008; java: 603; makefile: 512; perl: 297; sql: 222; ansic: 137
file content (175 lines) | stat: -rw-r--r-- 5,264 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
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: TDataPointHintTool;
    FinancialChart: TChart;
    LblDown: TLabel;
    LblUp: TLabel;
    ohlcSeries: TOpenHighLowCloseSeries;
    BottomPanel: TPanel;
    TopPanel: TPanel;
    procedure cbCandleStickSameColorChange(Sender: TObject);
    procedure cbSeriesTypeChange(Sender: TObject);
    procedure cbColorChange(Sender: TObject);
    procedure DataPointHintToolHint(ATool: TDataPointHintTool;
      const APoint: TPoint; var AHint: String);
    procedure DataPointHintToolHintLocation(ATool: TDataPointHintTool;
      AHintSize: TSize; var APoint: TPoint);
    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
  case ohlcSeries.Mode of
    mOHLC:
      begin
        ohlcSeries.LinePen.Color := cbUpColor.Selected;
        ohlcSeries.DownLinePen.Color := cbDownColor.Selected;
      end;
    mCandleStick:
      begin
        ohlcSeries.CandlestickUpBrush.Color := cbUpColor.Selected;
        ohlcSeries.CandleStickDownBrush.Color := cbDownColor.Selected;
      end;
  end;
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.DataPointHintToolHint(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]^.YList[0],
    ser.ListSource[ATool.PointIndex]^.YList[2],
    ser.ListSource[ATool.PointIndex]^.Y,
    ser.ListSource[ATool.PointIndex]^.YList[1]
  ]));
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.