Streamlining main app
Bugfix in Chart -> StrokeJoint set to Bevel
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<ProjectVersion>20.3</ProjectVersion>
|
||||
<FrameworkType>FMX</FrameworkType>
|
||||
<Base>True</Base>
|
||||
<Config Condition="'$(Config)'==''">Release</Config>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<Platform Condition="'$(Platform)'==''">Win64</Platform>
|
||||
<ProjectName Condition="'$(ProjectName)'==''">AuraTrader</ProjectName>
|
||||
<TargetedPlatforms>3</TargetedPlatforms>
|
||||
|
||||
@@ -42,17 +42,13 @@ type
|
||||
TTicksToBars = class(TMycConverter<TDataPoint<TAskBidItem>, TDataPoint<TOhlcItem>>)
|
||||
private
|
||||
FTimeframe: TTimeframe;
|
||||
// Stores the currently aggregating OHLC data.
|
||||
FCurrentBar: TDataPoint<TOhlcItem>;
|
||||
function GetBarStartTime(const TimeStamp: TDateTime; const Timeframe: TTimeframe): TDateTime;
|
||||
function GetCurrentBar: TDataPoint<TOhlcItem>;
|
||||
function GetTimeframe: TTimeframe;
|
||||
public
|
||||
constructor Create(const ATimeframe: TTimeframe);
|
||||
|
||||
// Process new data. This is called concurrently and must not have side effects out of the scope of this class!
|
||||
function ProcessData(const Value: TDataPoint<TAskBidItem>): TState; override;
|
||||
|
||||
property CurrentBar: TDataPoint<TOhlcItem> read GetCurrentBar;
|
||||
property Timeframe: TTimeframe read GetTimeframe;
|
||||
end;
|
||||
|
||||
+47
-39
@@ -3,7 +3,7 @@ object Form1: TForm1
|
||||
Top = 0
|
||||
Caption = 'Form1'
|
||||
ClientHeight = 840
|
||||
ClientWidth = 796
|
||||
ClientWidth = 1017
|
||||
FormFactor.Width = 320
|
||||
FormFactor.Height = 480
|
||||
FormFactor.Devices = [Desktop]
|
||||
@@ -12,7 +12,7 @@ object Form1: TForm1
|
||||
DesignerMasterStyle = 0
|
||||
object MainPanel: TPanel
|
||||
Align = Client
|
||||
Size.Width = 796.000000000000000000
|
||||
Size.Width = 1017.000000000000000000
|
||||
Size.Height = 712.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabOrder = 2
|
||||
@@ -27,30 +27,30 @@ object Form1: TForm1
|
||||
end
|
||||
object WorkspacePanel: TPanel
|
||||
Align = Client
|
||||
Size.Width = 619.000000000000000000
|
||||
Size.Width = 840.000000000000000000
|
||||
Size.Height = 712.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabOrder = 3
|
||||
object TabControl: TTabControl
|
||||
Align = Client
|
||||
Size.Width = 619.000000000000000000
|
||||
Size.Height = 672.000000000000000000
|
||||
Size.Width = 840.000000000000000000
|
||||
Size.Height = 678.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabIndex = 0
|
||||
TabOrder = 10
|
||||
TabPosition = PlatformDefault
|
||||
end
|
||||
object ToolBar: TToolBar
|
||||
Size.Width = 619.000000000000000000
|
||||
Size.Height = 40.000000000000000000
|
||||
Size.Width = 840.000000000000000000
|
||||
Size.Height = 34.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabOrder = 3
|
||||
object AddWorkspaceButton: TSpeedButton
|
||||
Action = AddWorkspaceAction
|
||||
Align = FitLeft
|
||||
ImageIndex = -1
|
||||
Size.Width = 145.454589843750000000
|
||||
Size.Height = 40.000000000000000000
|
||||
Size.Width = 123.636383056640600000
|
||||
Size.Height = 34.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
Text = 'Add'
|
||||
TextSettings.Trimming = None
|
||||
@@ -59,9 +59,9 @@ object Form1: TForm1
|
||||
Action = TestAction
|
||||
Align = FitLeft
|
||||
ImageIndex = -1
|
||||
Position.X = 145.454589843750000000
|
||||
Size.Width = 145.454544067382800000
|
||||
Size.Height = 40.000000000000000000
|
||||
Position.X = 123.636383056640600000
|
||||
Size.Width = 123.636322021484400000
|
||||
Size.Height = 34.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TextSettings.Trimming = None
|
||||
object TestPopup: TPopup
|
||||
@@ -88,10 +88,9 @@ object Form1: TForm1
|
||||
Size.Width = 47.000000000000000000
|
||||
Size.Height = 22.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabOrder = 5
|
||||
TabOrder = 4
|
||||
Text = 'Load'
|
||||
TextSettings.Trimming = None
|
||||
OnClick = LoadButtonClick
|
||||
end
|
||||
object RandomButton: TButton
|
||||
Anchors = [akTop, akRight]
|
||||
@@ -99,45 +98,54 @@ object Form1: TForm1
|
||||
TabOrder = 2
|
||||
Text = 'Random'
|
||||
TextSettings.Trimming = None
|
||||
OnClick = RandomButtonClick
|
||||
end
|
||||
object StopButton: TButton
|
||||
Anchors = [akTop, akRight]
|
||||
Position.Y = 63.000000000000000000
|
||||
TabOrder = 8
|
||||
Text = 'StopButton'
|
||||
TextSettings.Trimming = None
|
||||
OnClick = StopButtonClick
|
||||
end
|
||||
object ChartButton: TButton
|
||||
Anchors = [akTop, akRight]
|
||||
Position.Y = 85.000000000000000000
|
||||
TabOrder = 7
|
||||
Position.Y = 63.000000000000000000
|
||||
TabOrder = 6
|
||||
Text = 'ChartButton'
|
||||
TextSettings.Trimming = None
|
||||
OnClick = ChartButtonClick
|
||||
end
|
||||
object SymbolsComboBox: TComboBox
|
||||
Anchors = [akTop, akRight]
|
||||
Position.Y = 107.000000000000000000
|
||||
Size.Width = 177.000000000000000000
|
||||
Size.Height = 22.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabOrder = 4
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
object StrategyButton: TSpeedButton
|
||||
Align = FitLeft
|
||||
Position.X = 290.909118652343800000
|
||||
Size.Width = 145.454467773437500000
|
||||
Size.Height = 40.000000000000000000
|
||||
Position.X = 247.272705078125000000
|
||||
Size.Width = 123.250000000000000000
|
||||
Size.Height = 34.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
Text = 'Strategy'
|
||||
TextSettings.Trimming = None
|
||||
OnClick = StrategyButtonClick
|
||||
end
|
||||
object SymbolsComboBox: TComboBox
|
||||
Align = FitLeft
|
||||
Margins.Top = 4.000000000000000000
|
||||
Margins.Bottom = 4.000000000000000000
|
||||
Position.X = 370.522735595703100000
|
||||
Position.Y = 4.000000000000000000
|
||||
Size.Width = 141.192199707031300000
|
||||
Size.Height = 26.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabOrder = 3
|
||||
end
|
||||
object StopButton: TButton
|
||||
Align = FitLeft
|
||||
Margins.Left = 8.000000000000000000
|
||||
Margins.Top = 4.000000000000000000
|
||||
Margins.Right = 8.000000000000000000
|
||||
Margins.Bottom = 4.000000000000000000
|
||||
Position.X = 519.714965820312500000
|
||||
Position.Y = 4.000000000000000000
|
||||
Size.Width = 111.404327392578100000
|
||||
Size.Height = 26.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabOrder = 7
|
||||
Text = 'StopButton'
|
||||
TextSettings.Trimming = None
|
||||
OnClick = StopButtonClick
|
||||
end
|
||||
end
|
||||
end
|
||||
object ObjectsPanel: TPanel
|
||||
@@ -191,11 +199,11 @@ object Form1: TForm1
|
||||
DataDetectorTypes = []
|
||||
Align = Bottom
|
||||
Position.Y = 712.000000000000000000
|
||||
Size.Width = 796.000000000000000000
|
||||
Size.Width = 1017.000000000000000000
|
||||
Size.Height = 128.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabOrder = 1
|
||||
Viewport.Width = 792.000000000000000000
|
||||
Viewport.Width = 1013.000000000000000000
|
||||
Viewport.Height = 124.000000000000000000
|
||||
end
|
||||
object ActionList: TActionList
|
||||
|
||||
+214
-356
@@ -75,32 +75,18 @@ type
|
||||
TestPopup: TPopup;
|
||||
FlowLayout: TFlowLayout;
|
||||
StrategyButton: TSpeedButton;
|
||||
procedure RandomButtonClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure LoadButtonClick(Sender: TObject);
|
||||
procedure ChartButtonClick(Sender: TObject);
|
||||
procedure StopButtonClick(Sender: TObject);
|
||||
procedure LayoutResized(Sender: TObject);
|
||||
procedure TreeViewDblClick(Sender: TObject);
|
||||
procedure AddWorkspaceActionExecute(Sender: TObject);
|
||||
procedure TestActionExecute(Sender: TObject);
|
||||
procedure StrategyButtonClick(Sender: TObject);
|
||||
private
|
||||
const
|
||||
cnt = 20;
|
||||
type
|
||||
TRndItem = record
|
||||
Stream: IDataStream<TAuraAskBidFileItem>;
|
||||
Data: TMutable<TDataSeries<TAuraAskBidFileItem>>;
|
||||
Labl: TLabel;
|
||||
end;
|
||||
private
|
||||
FOnEvent: TNotifyEvent;
|
||||
{ Private declarations }
|
||||
FServer: IDataServer<TAuraAskBidFileItem>;
|
||||
FSymbols: TFuture<TArray<String>>;
|
||||
FRandom: TList<TRndItem>;
|
||||
FTerminate: TEvent;
|
||||
FProcessDone: TState;
|
||||
FApplication: IAuraApplication;
|
||||
@@ -148,6 +134,184 @@ begin
|
||||
FTerminate.Notify;
|
||||
end;
|
||||
|
||||
procedure TForm1.TreeViewDblClick(Sender: TObject);
|
||||
begin
|
||||
var sel := TreeView.Selected as TTreeViewItem;
|
||||
|
||||
var parent := sel.ParentItem;
|
||||
if parent = nil then
|
||||
exit;
|
||||
|
||||
if parent = FModulesItem then
|
||||
begin
|
||||
if (TabControl.ActiveTab <> nil) and (TabControl.ActiveTab.Tag <> 0) then
|
||||
begin
|
||||
var ws := IAuraWorkspace(TabControl.ActiveTab.Tag);
|
||||
var module := FApplication.Modules[sel.TagString];
|
||||
if (ws <> nil) and (module <> nil) then
|
||||
module.SetupWorkspace(ws);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
begin
|
||||
FApplication := TMycAuraApplication.Create;
|
||||
|
||||
FModulesItem := TTreeViewItem.Create(Self);
|
||||
FModulesItem.Text := 'Modules';
|
||||
|
||||
const modName = 'Test_Module';
|
||||
|
||||
FApplication.RegisterModule(modName, TTestModule.Create('Test-Module', 1));
|
||||
|
||||
TreeView.AddObject(FModulesItem);
|
||||
FModulesItem.ProcessSignal(
|
||||
FApplication.ModuleNames.Changed,
|
||||
procedure
|
||||
begin
|
||||
FModulesItem.BeginUpdate;
|
||||
try
|
||||
while FModulesItem.Count > 0 do
|
||||
FModulesItem[0].Free;
|
||||
var mods := FApplication.ModuleNames.Value;
|
||||
for var i := 0 to High(mods) do
|
||||
begin
|
||||
var ModItem := TTreeViewItem.Create(Self);
|
||||
ModItem.Text := mods[i];
|
||||
ModItem.DragMode := TDragMode.dmAutomatic;
|
||||
ModItem.Text := 'Module-' + mods[i];
|
||||
ModItem.TagString := mods[i];
|
||||
FModulesItem.AddObject(ModItem);
|
||||
end;
|
||||
FModulesItem.ExpandAll;
|
||||
finally
|
||||
FModulesItem.EndUpdate;
|
||||
end;
|
||||
end
|
||||
);
|
||||
|
||||
FTerminate := TEvent.CreateEvent;
|
||||
|
||||
// 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;
|
||||
|
||||
FSymbols := FServer.EnumerateSymbols;
|
||||
|
||||
SymbolsComboBox.ProcessSignal(
|
||||
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;
|
||||
ChartButton.Enabled := true;
|
||||
LoadButton.Enabled := true;
|
||||
end;
|
||||
finally
|
||||
SymbolsComboBox.EndUpdate;
|
||||
end;
|
||||
end
|
||||
);
|
||||
|
||||
NewWorkspace;
|
||||
end;
|
||||
|
||||
procedure TForm1.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FSymbols.WaitFor;
|
||||
FTerminate.Notify;
|
||||
TaskManager.WaitFor(FProcessDone);
|
||||
end;
|
||||
|
||||
procedure TForm1.TestActionExecute(Sender: TObject);
|
||||
begin
|
||||
TestPopup.IsOpen := TestAction.Checked;
|
||||
end;
|
||||
|
||||
procedure TForm1.AddWorkspaceActionExecute(Sender: TObject);
|
||||
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;
|
||||
|
||||
function TForm1.CurrLayout<T>: T;
|
||||
begin
|
||||
if TabControl.ActiveTab = nil then
|
||||
exit(nil);
|
||||
|
||||
var Res: T := nil;
|
||||
TabControl.ActiveTab.EnumControls(
|
||||
function(Control: TControl): TEnumControlsResult
|
||||
begin
|
||||
Result := TEnumControlsResult.Continue;
|
||||
if Control is T then
|
||||
begin
|
||||
Res := Control as T;
|
||||
Result := TEnumControlsResult.Stop;
|
||||
end;
|
||||
end
|
||||
);
|
||||
|
||||
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.Sender.Link(Processor);
|
||||
|
||||
Result := FServer.ProcessData(Symbol, terminated, dataProvider);
|
||||
end;
|
||||
|
||||
function TForm1.SelectedSymbol: String;
|
||||
begin
|
||||
Result := '';
|
||||
if RandomBox.IsChecked then
|
||||
Result := FSymbols.WaitFor[Random(Length(FSymbols.WaitFor))]
|
||||
else if SymbolsComboBox.ItemIndex >= 0 then
|
||||
Result := FSymbols.WaitFor[SymbolsComboBox.ItemIndex];
|
||||
end;
|
||||
|
||||
procedure TForm1.StrategyButtonClick(Sender: TObject);
|
||||
begin
|
||||
var Layout := CurrLayout<TVertScrollBox>;
|
||||
@@ -179,7 +343,7 @@ begin
|
||||
OhlcPoint.Sender.Link(TimeStamps);
|
||||
chart.SetXAxisSeries(timeframe, Timestamps.Sender);
|
||||
|
||||
var Panel := chart.Panels[0];
|
||||
var Panel := chart.AddPanel;
|
||||
|
||||
var Ohlc: IMycConverter<TDataPoint<TOhlcItem>, TOhlcItem> :=
|
||||
TMycGenericConverter<TDataPoint<TOhlcItem>, TOhlcItem>
|
||||
@@ -275,351 +439,45 @@ begin
|
||||
Stoch.Sender.Link(StochD);
|
||||
Panel.AddDoubleSeries(StochD.Sender, TAlphaColors.Red);
|
||||
|
||||
var done := ExecuteStrategy(Symbol, ticker);
|
||||
/////
|
||||
|
||||
var tickChart := TMycChart.Create(Self);
|
||||
tickChart.Height := Layout.ChildrenRect.Width * 9 / 16;
|
||||
AlignControl(tickChart);
|
||||
tickChart.Lookback.Value := 1000000;
|
||||
|
||||
var TickTime: IMycConverter<TDataPoint<TAskBidItem>, TDateTime> :=
|
||||
TMycGenericConverter<TDataPoint<TAskBidItem>, TDateTime>
|
||||
.Create(function(const Tick: TDataPoint<TAskBidItem>): TDateTime begin Result := Tick.Time; end);
|
||||
|
||||
var TickAsk: IMycConverter<TDataPoint<TAskBidItem>, Double> :=
|
||||
TMycGenericConverter<TDataPoint<TAskBidItem>, Double>
|
||||
.Create(function(const Tick: TDataPoint<TAskBidItem>): Double begin Result := Tick.Data.Ask; end);
|
||||
|
||||
var TickBid: IMycConverter<TDataPoint<TAskBidItem>, Double> :=
|
||||
TMycGenericConverter<TDataPoint<TAskBidItem>, Double>
|
||||
.Create(function(const Tick: TDataPoint<TAskBidItem>): Double begin Result := Tick.Data.Bid; end);
|
||||
|
||||
var TickSpread: IMycConverter<TDataPoint<TAskBidItem>, Double> :=
|
||||
TMycGenericConverter<TDataPoint<TAskBidItem>, Double>
|
||||
.Create(function(const Tick: TDataPoint<TAskBidItem>): Double begin Result := Tick.Data.Bid-Tick.Data.Ask; end);
|
||||
|
||||
ticker.Sender.Link( TickTime );
|
||||
ticker.Sender.Link( TickAsk );
|
||||
ticker.Sender.Link( TickBid );
|
||||
ticker.Sender.Link( TickSpread );
|
||||
|
||||
tickChart.SetXAxisSeries( TTimeframe.S, TickTime.Sender );
|
||||
panel := tickChart.AddPanel;
|
||||
panel.AddDoubleSeries(TickAsk.Sender, TAlphaColors.Blue);
|
||||
panel.AddDoubleSeries(TickBid.Sender, TAlphaColors.Red);
|
||||
panel := tickChart.AddPanel;
|
||||
panel.AddDoubleSeries(TickSpread.Sender);
|
||||
|
||||
/////
|
||||
|
||||
var done := ExecuteStrategy(Symbol, ticker);
|
||||
FProcessDone := TState.All([FProcessDone, done]);
|
||||
end;
|
||||
|
||||
procedure TForm1.TreeViewDblClick(Sender: TObject);
|
||||
begin
|
||||
var sel := TreeView.Selected as TTreeViewItem;
|
||||
|
||||
var parent := sel.ParentItem;
|
||||
if parent = nil then
|
||||
exit;
|
||||
|
||||
if parent = FModulesItem then
|
||||
begin
|
||||
if (TabControl.ActiveTab <> nil) and (TabControl.ActiveTab.Tag <> 0) then
|
||||
begin
|
||||
var ws := IAuraWorkspace(TabControl.ActiveTab.Tag);
|
||||
var module := FApplication.Modules[sel.TagString];
|
||||
if (ws <> nil) and (module <> nil) then
|
||||
module.SetupWorkspace(ws);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
begin
|
||||
FApplication := TMycAuraApplication.Create;
|
||||
|
||||
FModulesItem := TTreeViewItem.Create(Self);
|
||||
FModulesItem.Text := 'Modules';
|
||||
|
||||
const modName = 'Test_Module';
|
||||
|
||||
FApplication.RegisterModule(modName, TTestModule.Create('Test-Module', 1));
|
||||
|
||||
TreeView.AddObject(FModulesItem);
|
||||
FModulesItem.ProcessSignal(
|
||||
FApplication.ModuleNames.Changed,
|
||||
procedure
|
||||
begin
|
||||
FModulesItem.BeginUpdate;
|
||||
try
|
||||
while FModulesItem.Count > 0 do
|
||||
FModulesItem[0].Free;
|
||||
var mods := FApplication.ModuleNames.Value;
|
||||
for var i := 0 to High(mods) do
|
||||
begin
|
||||
var ModItem := TTreeViewItem.Create(Self);
|
||||
ModItem.Text := mods[i];
|
||||
ModItem.DragMode := TDragMode.dmAutomatic;
|
||||
ModItem.Text := 'Module-' + mods[i];
|
||||
ModItem.TagString := mods[i];
|
||||
FModulesItem.AddObject(ModItem);
|
||||
end;
|
||||
FModulesItem.ExpandAll;
|
||||
finally
|
||||
FModulesItem.EndUpdate;
|
||||
end;
|
||||
end
|
||||
);
|
||||
|
||||
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;
|
||||
ChartButton.Enabled := false;
|
||||
LoadButton.Enabled := false;
|
||||
|
||||
FSymbols := FServer.EnumerateSymbols;
|
||||
|
||||
SymbolsComboBox.ProcessSignal(
|
||||
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;
|
||||
ChartButton.Enabled := true;
|
||||
LoadButton.Enabled := true;
|
||||
end;
|
||||
finally
|
||||
SymbolsComboBox.EndUpdate;
|
||||
end;
|
||||
end
|
||||
);
|
||||
|
||||
NewWorkspace;
|
||||
end;
|
||||
|
||||
procedure TForm1.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FSymbols.WaitFor;
|
||||
FTerminate.Notify;
|
||||
TaskManager.WaitFor(FProcessDone);
|
||||
FRandom.Free;
|
||||
end;
|
||||
|
||||
procedure TForm1.LayoutResized(Sender: TObject);
|
||||
begin
|
||||
LogMemo.Lines.Add('resize');
|
||||
end;
|
||||
|
||||
procedure TForm1.LoadButtonClick(Sender: TObject);
|
||||
begin
|
||||
if SymbolsComboBox.ItemIndex < 0 then
|
||||
exit;
|
||||
var Layout := CurrLayout<TVertScrollBox>;
|
||||
if Layout = nil then
|
||||
exit;
|
||||
|
||||
var Stream := FServer.CreateStream(FSymbols.WaitFor[SymbolsComboBox.ItemIndex]);
|
||||
var Data := TDataStreamProvider.Create<TAuraAskBidFileItem>(30000, 10000, Stream);
|
||||
|
||||
var path := TPath.Create(Self);
|
||||
path.Parent := Layout;
|
||||
path.Align := TAlignLayout.None;
|
||||
|
||||
path.ProcessSignal(
|
||||
Data.Changed,
|
||||
procedure
|
||||
begin
|
||||
var Prices := Data.Value;
|
||||
|
||||
if Prices.Count > 0 then
|
||||
begin
|
||||
path.BeginUpdate;
|
||||
try
|
||||
path.Data.Clear;
|
||||
path.Data.MoveTo(PointF(path.Width - 1, Prices[0].Data.Ask));
|
||||
for var i := 1 to Prices.Count - 1 do
|
||||
path.Data.LineTo(PointF(path.Width - i - 1, Prices[i].Data.Ask));
|
||||
finally
|
||||
path.EndUpdate;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
);
|
||||
end;
|
||||
|
||||
procedure TForm1.RandomButtonClick(Sender: TObject);
|
||||
begin
|
||||
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<TAuraAskBidFileItem>(3000, 1000, rnd.Stream);
|
||||
|
||||
rnd.Labl := TLabel.Create(Self);
|
||||
rnd.Labl.Parent := Layout;
|
||||
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
|
||||
.ProcessSignal(
|
||||
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;
|
||||
|
||||
procedure TForm1.TestActionExecute(Sender: TObject);
|
||||
begin
|
||||
TestPopup.IsOpen := TestAction.Checked;
|
||||
end;
|
||||
|
||||
procedure TForm1.AddWorkspaceActionExecute(Sender: TObject);
|
||||
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<TVertScrollBox>;
|
||||
if Layout = nil then
|
||||
exit;
|
||||
|
||||
var Symbol := SelectedSymbol;
|
||||
if Symbol = '' then
|
||||
exit;
|
||||
|
||||
var currPathData := TWriteable<IObjectRef<TPathData>>.CreateWriteable.Protect;
|
||||
var currLog := TWriteable<String>.CreateWriteable.Protect;
|
||||
|
||||
const width = 300;
|
||||
|
||||
var terminated := TFlag.CreateObserver(FTerminate.Signal).State;
|
||||
|
||||
var done :=
|
||||
TaskManager.RunTask(
|
||||
nil,
|
||||
function: TState
|
||||
begin
|
||||
var Prices := TDataSeries<TAuraAskBidFileItem>.CreateDataSeries(width);
|
||||
Result :=
|
||||
FServer.ProcessData(
|
||||
Symbol,
|
||||
terminated,
|
||||
TMycGenericProcessor<TArray<TDataPoint<TAuraAskBidFileItem>>>.Create(
|
||||
function(const Values: TArray<TDataPoint<TAuraAskBidFileItem>>): TState
|
||||
begin
|
||||
Result := TState.Null;
|
||||
|
||||
Prices := Prices.Add(Values);
|
||||
currLog.Value := Prices.TotalCount.ToString;
|
||||
|
||||
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));
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
FProcessDone := TState.All([FProcessDone, done]);
|
||||
|
||||
var path := TPath.Create(Self);
|
||||
path.Parent := Layout;
|
||||
path.Align := TAlignLayout.None;
|
||||
|
||||
path.ProcessSignal(
|
||||
currPathData.Changed,
|
||||
procedure(out IsDone: Boolean)
|
||||
begin
|
||||
if currPathData.Value <> nil then
|
||||
path.Data.Assign(currPathData.Value.Obj);
|
||||
IsDone := done.IsSet;
|
||||
end
|
||||
);
|
||||
end;
|
||||
|
||||
function TForm1.CurrLayout<T>: T;
|
||||
begin
|
||||
if TabControl.ActiveTab = nil then
|
||||
exit(nil);
|
||||
|
||||
var Res: T := nil;
|
||||
TabControl.ActiveTab.EnumControls(
|
||||
function(Control: TControl): TEnumControlsResult
|
||||
begin
|
||||
Result := TEnumControlsResult.Continue;
|
||||
if Control is T then
|
||||
begin
|
||||
Res := Control as T;
|
||||
Result := TEnumControlsResult.Stop;
|
||||
end;
|
||||
end
|
||||
);
|
||||
|
||||
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.Sender.Link(Processor);
|
||||
|
||||
Result := FServer.ProcessData(Symbol, terminated, dataProvider);
|
||||
end;
|
||||
|
||||
function TForm1.SelectedSymbol: String;
|
||||
begin
|
||||
Result := '';
|
||||
if RandomBox.IsChecked then
|
||||
Result := FSymbols.WaitFor[Random(Length(FSymbols.WaitFor))]
|
||||
else if SymbolsComboBox.ItemIndex >= 0 then
|
||||
Result := FSymbols.WaitFor[SymbolsComboBox.ItemIndex];
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user