Files
MycLib/AuraTrader/MainForm.pas
T
2025-06-24 21:40:06 +02:00

283 lines
8.1 KiB
ObjectPascal

unit MainForm;
interface
uses
System.SysUtils,
System.Types,
System.UITypes,
System.Classes,
System.Variants,
System.DateUtils,
System.Generics.Collections,
FMX.Types,
FMX.Controls,
FMX.Forms,
FMX.Graphics,
FMX.Dialogs,
FMX.Controls.Presentation,
FMX.StdCtrls,
FMX.ListView.Types,
FMX.ListView.Appearances,
FMX.ListView.Adapters.Base,
FMX.ListView,
FMX.Memo.Types,
FMX.ScrollBox,
FMX.Memo,
FMX.Objects,
Myc.Futures,
Myc.Trade.DataStream,
Myc.Trade.DataPoint,
Myc.Trade.DataProvider,
Myc.Signals,
Myc.Lazy,
Myc.Signals.FMX,
Myc.TaskManager,
FMX.ListBox,
FMX.Layouts;
type
TForm1 = class(TForm)
LogMemo: TMemo;
Panel1: TPanel;
RandomButton: TButton;
Path1: TPath;
SymbolsComboBox: TComboBox;
LoadButton: TButton;
FlowLayout: TFlowLayout;
Button1: TButton;
Button2: TButton;
procedure RandomButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure LoadButtonClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
const
cnt = 20;
type
TRndItem = record
Stream: IDataStream<TAskBidItem>;
Data: TMutable<TDataSeries<TAskBidItem>>;
Labl: TLabel;
end;
private
FOnEvent: TNotifyEvent;
{ Private declarations }
FServer: IDataServer<TAskBidItem>;
FSymbols: TFuture<TArray<String>>;
FRandom: TList<TRndItem>;
FTerminate: TEvent;
FLoadDone: TState;
public
{ Public declarations }
published
property OnEvent: TNotifyEvent read FOnEvent write FOnEvent;
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.Button1Click(Sender: TObject);
begin
if SymbolsComboBox.ItemIndex < 0 then
exit;
var curr := TWriteable<TDataSeries<TAskBidItem>>.CreateProtected;
var Symbol := FSymbols.WaitFor[SymbolsComboBox.ItemIndex];
var currPathData := TWriteable<IObjectRef<TPathData>>.CreateProtected;
LogMemo.AddIdleHandler(curr.Changed, procedure begin LogMemo.Lines.Add(Symbol + ': ' + curr.Value.TotalCount.ToString); end);
var arr := TDataSeries<TAskBidItem>.CreateArray(3000);
var done :=
FServer.ProcessData(
Symbol,
FTerminate.Signal,
procedure(const Values: TArray<TDataPoint<TAskBidItem>>; const Terminated: TState)
begin
arr.Add(Values);
curr.Value := arr.Copy;
var PathData := TPathData.Create;
var Prices := arr;
if Prices.Count > 0 then
begin
PathData.MoveTo(PointF(Prices.Count - 1, Prices[0].Data.Ask));
for var i := 1 to Prices.Count - 1 do
PathData.LineTo(PointF(Prices.Count - i - 1, Prices[i].Data.Ask));
end;
currPathData.Value := TObjectRef<TPathData>.Create(PathData);
end
);
FLoadDone := TState.All([FLoadDone, done]);
Path1.AddIdleHandler(
currPathData.Changed,
procedure
begin
if currPathData.Value<>nil then
begin
Path1.Data.Assign( currPathData.Value.Obj );
currPathData.Value := nil;
end;
end );
(*
FLoadDone := TState.All([FLoadDone, done]);
Path1.AddIdleHandler(
curr.Changed,
procedure
begin
var Prices := curr.Value;
if Prices.Count > 0 then
begin
Path1.BeginUpdate;
try
Path1.Data.Clear;
Path1.Data.MoveTo(PointF(Path1.Width - 1, Prices[0].Data.Ask));
for var i := 1 to Prices.Count - 1 do
begin
Path1.Data.LineTo(PointF(Path1.Width - i - 1, Prices[i].Data.Ask));
end;
finally
Path1.EndUpdate;
end;
end;
end
);
*)
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FTerminate.Notify;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FTerminate := TEvent.CreateEvent;
FRandom := TList<TRndItem>.Create;
// Create an instance of the TAuraTABFileServer. The server can be reused for multiple stream creations. [364]
FServer := TAuraTABFileServer.Create('\\COFFEE\TickData\Pepperstone');
SymbolsComboBox.Enabled := false;
FSymbols := FServer.EnumerateSymbols;
SymbolsComboBox.AddIdleHandler(
FSymbols.Done.Signal,
procedure
begin
SymbolsComboBox.BeginUpdate;
try
SymbolsComboBox.Items.Clear;
SymbolsComboBox.Items.AddStrings(FSymbols.WaitFor);
if SymbolsComboBox.Items.Count > 0 then
begin
if SymbolsComboBox.ItemIndex < 0 then
SymbolsComboBox.ItemIndex := SymbolsComboBox.Items.IndexOf('GER40');
SymbolsComboBox.Enabled := true;
end;
finally
SymbolsComboBox.EndUpdate;
end;
end
);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FTerminate.Notify;
TaskManager.WaitFor(FLoadDone);
Application.OnIdle := nil;
FRandom.Free;
end;
procedure TForm1.LoadButtonClick(Sender: TObject);
begin
if SymbolsComboBox.ItemIndex < 0 then
exit;
var Stream := FServer.CreateStream(FSymbols.WaitFor[SymbolsComboBox.ItemIndex]);
var Data := TDataStreamProvider.Create<TAskBidItem>(30000, 10000, Stream);
Path1.AddIdleHandler(
Data.Changed,
procedure
begin
var Prices := Data.Value;
if Prices.Count > 0 then
begin
Path1.BeginUpdate;
try
Path1.Data.Clear;
Path1.Data.MoveTo(PointF(Path1.Width - 1, Prices[0].Data.Ask));
for var i := 1 to Prices.Count - 1 do
Path1.Data.LineTo(PointF(Path1.Width - i - 1, Prices[i].Data.Ask));
finally
Path1.EndUpdate;
end;
end;
end
);
end;
procedure TForm1.RandomButtonClick(Sender: TObject);
begin
var rnd: TRndItem;
var ass := FSymbols.WaitFor;
rnd.Stream := FServer.CreateStream(ass[Random(Length(FSymbols.WaitFor))]);
rnd.Data := TDataStreamProvider.Create<TAskBidItem>(3000, 1000, rnd.Stream);
rnd.Labl := TLabel.Create(Self);
rnd.Labl.Parent := FlowLayout;
rnd.Labl.Align := TAlignLayout.None;
rnd.Labl.WordWrap := false;
rnd.Labl.Width := 300;
rnd.Labl.Text := rnd.Stream.Symbol + ' loading...';
FRandom.Add(rnd);
var Proc :=
procedure(idx: Integer)
begin
FRandom[idx]
.Labl
.AddIdleHandler(
FRandom[idx].Data.Changed,
procedure
begin
var data := FRandom[idx].Data.Value;
if data.Count > 0 then
begin
var dp := data[0];
FRandom[idx].Labl.Text :=
FRandom[idx].Stream.Symbol
+ ' '
+ dp.Time.ToString
+ ' '
+ data.TotalCount.ToString
+ ' '
+ dp.Data.Ask.ToString;
end;
end);
end;
Proc(FRandom.Count - 1);
end;
end.