mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-04 19:58:25 +02:00
199 lines
6.1 KiB
ObjectPascal
199 lines
6.1 KiB
ObjectPascal
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 {%H-}APoint: TPoint; var AHint: String);
|
|
procedure DataPointHintToolHintLocation(ATool: TDataPointHintTool;
|
|
AHintSize: TSize; var APoint: TPoint);
|
|
procedure DataPointHintTool_DetailsHint(ATool: TDataPointHintTool;
|
|
const {%H-}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;
|
|
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.
|
|
|