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.
|