Implementing first "strategy" for proof of concept
This commit is contained in:
+145
-48
@@ -44,7 +44,9 @@ uses
|
||||
FMX.ImgList,
|
||||
System.Actions,
|
||||
FMX.ActnList,
|
||||
TestChartControl;
|
||||
DynamicFMXControl,
|
||||
FirstStrategy,
|
||||
Myc.FMX.Chart;
|
||||
|
||||
type
|
||||
TForm1 = class(TForm)
|
||||
@@ -69,9 +71,9 @@ type
|
||||
TreeView: TTreeView;
|
||||
TestButton: TSpeedButton;
|
||||
TestAction: TAction;
|
||||
SpeedButton1: TSpeedButton;
|
||||
TestPopup: TPopup;
|
||||
FlowLayout1: TFlowLayout;
|
||||
FlowLayout: TFlowLayout;
|
||||
StrategyButton: TSpeedButton;
|
||||
procedure RandomButtonClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
@@ -82,31 +84,33 @@ type
|
||||
procedure TreeViewDblClick(Sender: TObject);
|
||||
procedure AddWorkspaceActionExecute(Sender: TObject);
|
||||
procedure TestActionExecute(Sender: TObject);
|
||||
procedure SpeedButton1Click(Sender: TObject);
|
||||
procedure StrategyButtonClick(Sender: TObject);
|
||||
private
|
||||
const
|
||||
cnt = 20;
|
||||
type
|
||||
TRndItem = record
|
||||
Stream: IDataStream<TAskBidItem>;
|
||||
Data: TMutable<TDataSeries<TAskBidItem>>;
|
||||
Stream: IDataStream<TAuraAskBidFileItem>;
|
||||
Data: TMutable<TDataSeries<TAuraAskBidFileItem>>;
|
||||
Labl: TLabel;
|
||||
end;
|
||||
private
|
||||
FOnEvent: TNotifyEvent;
|
||||
{ Private declarations }
|
||||
FServer: IDataServer<TAskBidItem>;
|
||||
FServer: IDataServer<TAuraAskBidFileItem>;
|
||||
FSymbols: TFuture<TArray<String>>;
|
||||
FRandom: TList<TRndItem>;
|
||||
FTerminate: TEvent;
|
||||
FLoadDone: TState;
|
||||
FProcessDone: TState;
|
||||
FApplication: IAuraApplication;
|
||||
FModulesItem: TTreeViewItem;
|
||||
function SelectedSymbol: String;
|
||||
function ExecuteStrategy(const Symbol: String; const Processor: IMycProcessor<TArray<TDataPoint<TAskBidItem>>>): TState;
|
||||
|
||||
public
|
||||
procedure NewWorkspace;
|
||||
function CurrLayout: TFlowLayout;
|
||||
function CurrLayout<T: TControl>: T;
|
||||
procedure AlignControl(Control: TControl);
|
||||
published
|
||||
property OnEvent: TNotifyEvent read FOnEvent write FOnEvent;
|
||||
end;
|
||||
@@ -134,10 +138,6 @@ begin
|
||||
scrollbox.Parent := tab;
|
||||
scrollbox.Align := TAlignLayout.Client;
|
||||
|
||||
var flow := TFlowLayout.Create(Self);
|
||||
flow.Parent := tab;
|
||||
flow.Align := TAlignLayout.Client;
|
||||
|
||||
tab.ProcessSignal(ws.Name.Changed, procedure begin tab.Text := ws.Caption; end);
|
||||
end;
|
||||
|
||||
@@ -146,6 +146,68 @@ begin
|
||||
FTerminate.Notify;
|
||||
end;
|
||||
|
||||
procedure TForm1.StrategyButtonClick(Sender: TObject);
|
||||
begin
|
||||
var Layout := CurrLayout<TVertScrollBox>;
|
||||
if Layout = nil then
|
||||
exit;
|
||||
|
||||
var Symbol := SelectedSymbol;
|
||||
if Symbol = '' then
|
||||
exit;
|
||||
|
||||
var stateText := TWriteable<String>.CreateWriteable.Protect;
|
||||
var stateLabel := TLabel.Create(Self);
|
||||
AlignControl( stateLabel );
|
||||
|
||||
stateLabel.Text := 'Initializing...';
|
||||
|
||||
var chart := TMycChart.Create(Self);
|
||||
AlignControl( chart );
|
||||
chart.Height := Layout.ChildrenRect.Width*9/16;
|
||||
|
||||
/////
|
||||
|
||||
var strategy: ITicksToTimeframe := TTicksToTimeframe.Create( D, stateText );
|
||||
|
||||
var Ohlc: IMycIndicator<TDataPoint<TOhlcItem>, TOhlcItem> := TMycGenericIndicator<TDataPoint<TOhlcItem>, TOhlcItem>.Create( 0,
|
||||
function( const Ohlc: TDataPoint<TOhlcItem> ): TOhlcItem
|
||||
begin
|
||||
Result := Ohlc.Data;
|
||||
end );
|
||||
|
||||
strategy.Observers.Link(Ohlc);
|
||||
|
||||
var Closes: IMycIndicator<TOhlcItem, Double> := TMycGenericIndicator<TOhlcItem, Double>.Create( 0,
|
||||
function( const Ohlc: TOhlcItem ): Double
|
||||
begin
|
||||
Result := Ohlc.Close;
|
||||
end );
|
||||
|
||||
Ohlc.Observers.Link( Closes );
|
||||
|
||||
var Hull: IMycIndicator<Double, Double> := THullMovingAverage.Create( 50 );
|
||||
|
||||
Closes.Observers.Link( Hull );
|
||||
|
||||
Hull.Observers.Link(chart.CreateDoubleListener);
|
||||
|
||||
var done := ExecuteStrategy( Symbol, strategy );
|
||||
|
||||
/////
|
||||
|
||||
stateLabel.ProcessSignal(
|
||||
stateText.Changed, done,
|
||||
procedure
|
||||
begin
|
||||
stateLabel.Text := stateText.Value;
|
||||
end );
|
||||
|
||||
FProcessDone := TState.All([FProcessDone, done]);
|
||||
|
||||
strategy.Observers.Link(chart.CreateOhlcListener);
|
||||
end;
|
||||
|
||||
procedure TForm1.TreeViewDblClick(Sender: TObject);
|
||||
begin
|
||||
var sel := TreeView.Selected as TTreeViewItem;
|
||||
@@ -209,6 +271,7 @@ begin
|
||||
// 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;
|
||||
ChartButton.Enabled := false;
|
||||
LoadButton.Enabled := false;
|
||||
@@ -244,7 +307,7 @@ procedure TForm1.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FSymbols.WaitFor;
|
||||
FTerminate.Notify;
|
||||
TaskManager.WaitFor(FLoadDone);
|
||||
TaskManager.WaitFor(FProcessDone);
|
||||
FRandom.Free;
|
||||
end;
|
||||
|
||||
@@ -257,12 +320,12 @@ procedure TForm1.LoadButtonClick(Sender: TObject);
|
||||
begin
|
||||
if SymbolsComboBox.ItemIndex < 0 then
|
||||
exit;
|
||||
var Layout := CurrLayout;
|
||||
var Layout := CurrLayout<TVertScrollBox>;
|
||||
if Layout = nil then
|
||||
exit;
|
||||
|
||||
var Stream := FServer.CreateStream(FSymbols.WaitFor[SymbolsComboBox.ItemIndex]);
|
||||
var Data := TDataStreamProvider.Create<TAskBidItem>(30000, 10000, Stream);
|
||||
var Data := TDataStreamProvider.Create<TAuraAskBidFileItem>(30000, 10000, Stream);
|
||||
|
||||
var path := TPath.Create(Self);
|
||||
path.Parent := Layout;
|
||||
@@ -292,14 +355,14 @@ end;
|
||||
|
||||
procedure TForm1.RandomButtonClick(Sender: TObject);
|
||||
begin
|
||||
var Layout := CurrLayout;
|
||||
var Layout := CurrLayout<TVertScrollBox>;
|
||||
if Layout = nil then
|
||||
exit;
|
||||
|
||||
var rnd: TRndItem;
|
||||
|
||||
rnd.Stream := FServer.CreateStream(FSymbols.WaitFor[Random(Length(FSymbols.WaitFor))]);
|
||||
rnd.Data := TDataStreamProvider.Create<TAskBidItem>(3000, 1000, rnd.Stream);
|
||||
rnd.Data := TDataStreamProvider.Create<TAuraAskBidFileItem>(3000, 1000, rnd.Stream);
|
||||
|
||||
rnd.Labl := TLabel.Create(Self);
|
||||
rnd.Labl.Parent := Layout;
|
||||
@@ -346,9 +409,22 @@ begin
|
||||
NewWorkspace;
|
||||
end;
|
||||
|
||||
procedure TForm1.AlignControl(Control: TControl);
|
||||
begin
|
||||
var Layout := CurrLayout<TVertScrollBox>;
|
||||
if Layout = nil then
|
||||
exit;
|
||||
|
||||
Control.Parent := Layout;
|
||||
Control.Width := Layout.Width;
|
||||
Control.Position.Y := Layout.ChildrenRect.Bottom+1;
|
||||
Control.Anchors := [TAnchorKind.akLeft, TAnchorKind.akRight];
|
||||
Control.Align := TAlignLayout.Top;
|
||||
end;
|
||||
|
||||
procedure TForm1.ChartButtonClick(Sender: TObject);
|
||||
begin
|
||||
var Layout := CurrLayout;
|
||||
var Layout := CurrLayout<TVertScrollBox>;
|
||||
if Layout = nil then
|
||||
exit;
|
||||
|
||||
@@ -361,41 +437,44 @@ begin
|
||||
|
||||
const width = 300;
|
||||
|
||||
var terminated := TFlag.CreateObserver(FTerminate.Signal).State;
|
||||
|
||||
var done :=
|
||||
TaskManager.RunTask(
|
||||
nil,
|
||||
function: TState
|
||||
begin
|
||||
var Prices := TDataSeries<TAskBidItem>.CreateDataSeries(width);
|
||||
var Prices := TDataSeries<TAuraAskBidFileItem>.CreateDataSeries(width);
|
||||
Result :=
|
||||
FServer.ProcessData(
|
||||
Symbol,
|
||||
FTerminate.Signal,
|
||||
procedure(const Values: TArray<TDataPoint<TAskBidItem>>; const Terminated: TState)
|
||||
begin
|
||||
Prices := Prices.Add(Values);
|
||||
currLog.Value := Prices.TotalCount.ToString;
|
||||
|
||||
var PathData := TPathData.Create;
|
||||
if Prices.Count > 0 then
|
||||
terminated,
|
||||
TMycGenericProcessor<TArray<TDataPoint<TAuraAskBidFileItem>>>.Create(
|
||||
procedure(const Values: TArray<TDataPoint<TAuraAskBidFileItem>>)
|
||||
begin
|
||||
var n := Prices.Count;
|
||||
PathData.MoveTo(PointF(n - 1, Prices[0].Data.Ask));
|
||||
for var i := 1 to n - 1 do
|
||||
PathData.LineTo(PointF(n - i - 1, Prices[i].Data.Ask));
|
||||
Prices := Prices.Add(Values);
|
||||
currLog.Value := Prices.TotalCount.ToString;
|
||||
|
||||
for var i := n - 1 downto 0 do
|
||||
PathData.LineTo(PointF(n - i - 1, Prices[i].Data.Bid));
|
||||
end;
|
||||
PathData.ClosePath;
|
||||
var PathData := TPathData.Create;
|
||||
if Prices.Count > 0 then
|
||||
begin
|
||||
var n := Prices.Count;
|
||||
PathData.MoveTo(PointF(n - 1, Prices[0].Data.Ask));
|
||||
for var i := 1 to n - 1 do
|
||||
PathData.LineTo(PointF(n - i - 1, Prices[i].Data.Ask));
|
||||
|
||||
currPathData.Value := TObjectRef<TPathData>.Create(PathData);
|
||||
end
|
||||
for var i := n - 1 downto 0 do
|
||||
PathData.LineTo(PointF(n - i - 1, Prices[i].Data.Bid));
|
||||
end;
|
||||
PathData.ClosePath;
|
||||
|
||||
currPathData.Value := TObjectRef<TPathData>.Create(PathData);
|
||||
end )
|
||||
);
|
||||
end
|
||||
);
|
||||
|
||||
FLoadDone := TState.All([FLoadDone, done]);
|
||||
FProcessDone := TState.All([FProcessDone, done]);
|
||||
|
||||
var path := TPath.Create(Self);
|
||||
path.Parent := Layout;
|
||||
@@ -412,19 +491,19 @@ begin
|
||||
);
|
||||
end;
|
||||
|
||||
function TForm1.CurrLayout: TFlowLayout;
|
||||
function TForm1.CurrLayout<T>: T;
|
||||
begin
|
||||
if TabControl.ActiveTab = nil then
|
||||
exit(nil);
|
||||
|
||||
var Res: TFlowLayout := nil;
|
||||
var Res: T := nil;
|
||||
TabControl.ActiveTab.EnumControls(
|
||||
function(Control: TControl): TEnumControlsResult
|
||||
begin
|
||||
Result := TEnumControlsResult.Continue;
|
||||
if Control is TFlowLayout then
|
||||
if Control is T then
|
||||
begin
|
||||
Res := Control as TFlowLayout;
|
||||
Res := Control as T;
|
||||
Result := TEnumControlsResult.Stop;
|
||||
end;
|
||||
end
|
||||
@@ -433,6 +512,29 @@ begin
|
||||
Result := Res;
|
||||
end;
|
||||
|
||||
function TForm1.ExecuteStrategy(const Symbol: String; const Processor: IMycProcessor<TArray<TDataPoint<TAskBidItem>>>): TState;
|
||||
var
|
||||
dataProvider: IMycConverter<TArray<TDataPoint<TAuraAskBidFileItem>>, TArray<TDataPoint<TAskBidItem>>>;
|
||||
begin
|
||||
var terminated := TFlag.CreateObserver(FTerminate.Signal).State;
|
||||
|
||||
dataProvider := TMycGenericConverter<TArray<TDataPoint<TAuraAskBidFileItem>>, TArray<TDataPoint<TAskBidItem>>>.Create(
|
||||
function( const Values: TArray<TDataPoint<TAuraAskBidFileItem>> ): TArray<TDataPoint<TAskBidItem>>
|
||||
begin
|
||||
SetLength( Result, Length( Values ) );
|
||||
for var i:=0 to High(Result) do
|
||||
begin
|
||||
Result[i].Time := Values[i].Time;
|
||||
Result[i].Data.Ask := Values[i].Data.Ask;
|
||||
Result[i].Data.Bid := Values[i].Data.Bid;
|
||||
end;
|
||||
end );
|
||||
|
||||
dataProvider.Observers.Link( Processor );
|
||||
|
||||
Result := FServer.ProcessData( Symbol, terminated, dataProvider );
|
||||
end;
|
||||
|
||||
function TForm1.SelectedSymbol: String;
|
||||
begin
|
||||
Result := '';
|
||||
@@ -442,9 +544,4 @@ begin
|
||||
Result := FSymbols.WaitFor[SymbolsComboBox.ItemIndex];
|
||||
end;
|
||||
|
||||
procedure TForm1.SpeedButton1Click(Sender: TObject);
|
||||
begin
|
||||
TestChartForm.Visible := true;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user