Implementing first "strategy" for proof of concept

This commit is contained in:
Michael Schimmel
2025-07-11 11:06:18 +02:00
parent 644b6074d6
commit 487169afe0
20 changed files with 1761 additions and 274 deletions
+41 -33
View File
@@ -54,14 +54,12 @@ type
function IsHistory: Boolean; virtual; abstract;
end;
TDataProc<T> = reference to procedure(const Values: TArray<TDataPoint<T>>; const Terminated: TState);
// Interface for an instantiable data server.
IDataServer<T: record> = interface
['{1F8E5A9D-E92A-44C1-9F3F-C4B82A6E94B3}']
function CreateStream(const Symbol: String): IDataStream<T>;
procedure ClearCache;
function ProcessData(const Symbol: String; const Terminate: TSignal; const Proc: TDataProc<T>): TState;
function ProcessData(const Symbol: String; const Terminated: TState; const Processor: IMycProcessor<TArray<TDataPoint<T>>>): TState;
function EnumerateSymbols: TFuture<TArray<String>>;
end;
@@ -104,8 +102,8 @@ type
function ProcessFile(
FileInfo: TAuraDataFile;
const DataFile: TFuture<TArray<TDataPoint<T>>>;
Terminated: TState;
Proc: TDataProc<T>
const Terminated: TState;
Processor: IMycProcessor<TArray<TDataPoint<T>>>
): TState;
strict private
@@ -129,7 +127,7 @@ type
function EnumerateSymbols: TFuture<TArray<String>>;
function LoadDataFile(const DataFile: TAuraDataFile): TFuture<TArray<TDataPoint<T>>>;
function ProcessData(const Symbol: String; const Terminate: TSignal; const Proc: TDataProc<T>): TState;
function ProcessData(const Symbol: String; const Terminated: TState; const Processor: IMycProcessor<TArray<TDataPoint<T>>>): TState;
property Path: String read GetPath;
end;
@@ -166,14 +164,19 @@ type
// Aura tick data file Ask-Bid
TAuraTABFileServer = class(TAuraDataServer<TAskBidItem>)
TAuraAskBidFileItem = packed record
Ask: Single;
Bid: Single;
end;
TAuraTABFileServer = class(TAuraDataServer<TAuraAskBidFileItem>)
protected
// Scans a directory and returns the oldest file found for each symbol.
class function ReadCompressedData(const InputStream: TStream): TArray<TDataPoint<TAskBidItem>>; override;
class function ReadUncompressedData(const InputStream: TStream): TArray<TDataPoint<TAskBidItem>>; override;
class function ReadCompressedData(const InputStream: TStream): TArray<TDataPoint<TAuraAskBidFileItem>>; override;
class function ReadUncompressedData(const InputStream: TStream): TArray<TDataPoint<TAuraAskBidFileItem>>; override;
public
function CreateStream(const Symbol: String): IDataStream<TAskBidItem>; override;
function LoadDataSeries(const InitialFile: TAuraDataFile): TFuture<TArray<TDataPoint<TAskBidItem>>>;
function CreateStream(const Symbol: String): IDataStream<TAuraAskBidFileItem>; override;
function LoadDataSeries(const InitialFile: TAuraDataFile): TFuture<TArray<TDataPoint<TAuraAskBidFileItem>>>;
function ParseFileName(const FileName: string): TAuraDataFile; override;
end;
@@ -390,17 +393,21 @@ begin
Result := FPath;
end;
function TAuraDataServer<T>.ProcessData(const Symbol: String; const Terminate: TSignal; const Proc: TDataProc<T>): TState;
function TAuraDataServer<T>.ProcessData(
const Symbol: String;
const Terminated: TState;
const Processor: IMycProcessor<TArray<TDataPoint<T>>>
): TState;
begin
var capProc := Proc;
var terminated := TFlag.CreateObserver(Terminate).State;
var cProc := Processor;
var cTerminated := Terminated;
Result :=
FindFirstFile(Symbol)
.Chain(
function(const FirstFileInfo: TAuraDataFile): TState
begin
Result := ProcessFile(FirstFileInfo, LoadDataFile(FirstFileInfo), terminated, capProc);
Result := ProcessFile(FirstFileInfo, LoadDataFile(FirstFileInfo), cTerminated, cProc);
end);
end;
@@ -413,23 +420,24 @@ end;
function TAuraDataServer<T>.ProcessFile(
FileInfo: TAuraDataFile;
const DataFile: TFuture<TArray<TDataPoint<T>>>;
Terminated: TState;
Proc: TDataProc<T>
const Terminated: TState;
Processor: IMycProcessor<TArray<TDataPoint<T>>>
): TState;
begin
if not FileInfo.IsValid or Terminated.IsSet then
exit(TState.Null);
exit(DataFile.Done);
// Read ahead the next file, while processing the current one
var nextFileInfo := FileInfo.GetNextFile;
var nextFile := LoadDataFile(nextFileInfo);
var cTerminated := Terminated;
Result :=
DataFile.Chain(
function(const Data: TArray<TDataPoint<T>>): TState
begin
Proc(Data, Terminated);
Result := ProcessFile(nextFileInfo, nextFile, Terminated, Proc);
Processor.ProcessData(Data);
Result := ProcessFile(nextFileInfo, nextFile, cTerminated, Processor);
end
);
end;
@@ -574,16 +582,16 @@ end;
{ TAuraTABFileServer }
function TAuraTABFileServer.CreateStream(const Symbol: String): IDataStream<TAskBidItem>;
function TAuraTABFileServer.CreateStream(const Symbol: String): IDataStream<TAuraAskBidFileItem>;
begin
Result := TAuraFileStream<TAskBidItem>.Create(Self, Symbol);
Result := TAuraFileStream<TAuraAskBidFileItem>.Create(Self, Symbol);
end;
function TAuraTABFileServer.LoadDataSeries(const InitialFile: TAuraDataFile): TFuture<TArray<TDataPoint<TAskBidItem>>>;
function TAuraTABFileServer.LoadDataSeries(const InitialFile: TAuraDataFile): TFuture<TArray<TDataPoint<TAuraAskBidFileItem>>>;
var
loadedState: TState;
loadedFiles: TArray<TFuture<TArray<TDataPoint<TAskBidItem>>>>;
liveData: TFuture<TArray<TDataPoint<TAskBidItem>>>;
loadedFiles: TArray<TFuture<TArray<TDataPoint<TAuraAskBidFileItem>>>>;
liveData: TFuture<TArray<TDataPoint<TAuraAskBidFileItem>>>;
tabFiles: TList<TAuraDataFile>;
liveFile: TAuraDataFile;
currentFileInfo: TAuraDataFile;
@@ -607,7 +615,7 @@ begin
liveFile := ParseFileName(potentialLivePath);
end;
var loadedFileList := TList<TFuture<TArray<TDataPoint<TAskBidItem>>>>.Create;
var loadedFileList := TList<TFuture<TArray<TDataPoint<TAuraAskBidFileItem>>>>.Create;
var loadStates := TList<TState>.Create;
try
for var fileInfo in tabFiles do
@@ -617,7 +625,7 @@ begin
loadStates.Add(data.Done);
end;
liveData := TFuture<TArray<TDataPoint<TAskBidItem>>>.Null;
liveData := TFuture<TArray<TDataPoint<TAuraAskBidFileItem>>>.Null;
if liveFile.IsValid then
begin
liveData := LoadDataFile(liveFile);
@@ -636,11 +644,11 @@ begin
end;
Result :=
TFuture<TArray<TDataPoint<TAskBidItem>>>.Construct(
TFuture<TArray<TDataPoint<TAuraAskBidFileItem>>>.Construct(
loadedState,
function: TArray<TDataPoint<TAskBidItem>>
function: TArray<TDataPoint<TAuraAskBidFileItem>>
begin
var tickList := TList<TDataPoint<TAskBidItem>>.Create;
var tickList := TList<TDataPoint<TAuraAskBidFileItem>>.Create;
try
var overallLastTabTickTime: TDateTime := 0;
var cnt := 0;
@@ -710,7 +718,7 @@ begin
Result := TAuraDataFile.Create(path, symbol, fileExt, year, month);
end;
class function TAuraTABFileServer.ReadCompressedData(const InputStream: TStream): TArray<TDataPoint<TAskBidItem>>;
class function TAuraTABFileServer.ReadCompressedData(const InputStream: TStream): TArray<TDataPoint<TAuraAskBidFileItem>>;
var
decompressionStream: TStream;
localHeader: TZipHeader;
@@ -749,11 +757,11 @@ begin
end;
end;
class function TAuraTABFileServer.ReadUncompressedData(const InputStream: TStream): TArray<TDataPoint<TAskBidItem>>;
class function TAuraTABFileServer.ReadUncompressedData(const InputStream: TStream): TArray<TDataPoint<TAuraAskBidFileItem>>;
type
TFileRecord = packed record
TimeStamp: TDateTime;
Data: TAskBidItem;
Data: TAuraAskBidFileItem;
end;
var
fileSize: Int64;