Refactoring
This commit is contained in:
+13
-116
@@ -4,152 +4,49 @@ interface
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Generics.Collections,
|
||||
Myc.Lazy,
|
||||
Myc.Trade.DataPoint,
|
||||
Myc.Trade.DataSeries,
|
||||
Myc.Signals, // Added for TLatch
|
||||
Myc.Futures; // Added for TFuture
|
||||
Myc.Signals,
|
||||
Myc.Futures;
|
||||
|
||||
type
|
||||
// Represents a generic data server capable of providing sequential data chunks.
|
||||
// The type parameter T specifies the type of data points served.
|
||||
IDataServer<T> = interface
|
||||
['{A6E246A2-E84E-49AB-A63E-333E561E488C}']
|
||||
// Provides a TMutable<Boolean> that indicates if the server is currently
|
||||
// serving live data (true) or historical data (false).
|
||||
function GetIsLiveData: TMutable<Boolean>;
|
||||
// Retrieves a chunk of data into the provided dynamic array.
|
||||
// Returns the number of items successfully read into the array.
|
||||
function GetChunk(var Data: array of T): Integer;
|
||||
property IsLiveData: TMutable<Boolean> read GetIsLiveData;
|
||||
end;
|
||||
|
||||
// Abstract base class for IDataServer implementations.
|
||||
TDataServer<T> = class(TInterfacedObject, IDataServer<T>)
|
||||
protected
|
||||
function GetIsLiveData: TMutable<Boolean>; virtual; abstract;
|
||||
function GetChunk(var Data: array of T): Integer; virtual; abstract;
|
||||
end;
|
||||
|
||||
// Represents a factory for creating IDataServer instances.
|
||||
// The type parameter T specifies the type of data points the created server will provide.
|
||||
IDataServerNode<T> = interface
|
||||
['{DA3531F1-158E-4A63-8E5A-34089C537B1B}']
|
||||
// Creates and returns a new instance of an IDataServer.
|
||||
function CreateDataServer: IDataServer<T>;
|
||||
end;
|
||||
|
||||
// Abstract base class for IDataServerNode implementations.
|
||||
TDataServerNode<T> = class(TInterfacedObject, IDataServerNode<T>)
|
||||
public
|
||||
// Factory method to create the actual data server instance.
|
||||
function CreateDataServer: IDataServer<T>; virtual; abstract;
|
||||
end;
|
||||
|
||||
TTABFileServer = class(TDataServer<TDataPoint<TAskBidItem>>)
|
||||
|
||||
private
|
||||
FFilename: String;
|
||||
FIsLiveData: TMutable<Boolean>.IWriteable;
|
||||
|
||||
// Internal state
|
||||
FCurrentFileName: string;
|
||||
FCurrentData: TFuture<TArray<TAskBid.TTick>>;
|
||||
FNextFileName: string;
|
||||
FNextData: TFuture<TArray<TAskBid.TTick>>;
|
||||
FCurrPosInFile: Int64;
|
||||
FCurrentIdx: Int64;
|
||||
FLastTimeStamp: TDateTime;
|
||||
|
||||
protected
|
||||
function GetChunk(var Data: array of TDataPoint<TAskBidItem>): Integer; override;
|
||||
function GetIsLiveData: TMutable<Boolean>; override;
|
||||
public
|
||||
constructor Create(const AFilename: String);
|
||||
procedure AfterConstruction; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
System.IOUtils;
|
||||
|
||||
{ TTABFileServer<T> }
|
||||
|
||||
constructor TTABFileServer.Create(const AFilename: String);
|
||||
begin
|
||||
inherited Create;
|
||||
FFilename := AFilename;
|
||||
|
||||
FNextData := TFuture<TArray<TAskBid.TTick>>.Null;
|
||||
FIsLiveData := TMutable<Boolean>.CreateWriteable(false);
|
||||
end;
|
||||
|
||||
procedure TTABFileServer.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
FCurrentFileName := FFilename;
|
||||
FCurrentData := TAskBid.LoadDataFile(FCurrentFileName);
|
||||
FCurrPosInFile := 0;
|
||||
FCurrentIdx := 0;
|
||||
FIsLiveData.SetValue(false);
|
||||
FLastTimeStamp := 0;
|
||||
FFilename := '';
|
||||
|
||||
FNextFileName := FindNextDataFile(FCurrentFileName);
|
||||
if FNextFileName <> '' then
|
||||
FNextData := TAskBid.LoadDataFile(FNextFileName);
|
||||
exit;
|
||||
end;
|
||||
|
||||
function TTABFileServer.GetChunk(var Data: array of TDataPoint<TAskBidItem>): Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
|
||||
if FCurrentData.Done.IsSet then
|
||||
begin
|
||||
var maxLen := Length(Data);
|
||||
|
||||
var currData := FCurrentData.Value;
|
||||
while Result < MaxLen do
|
||||
begin
|
||||
if FCurrPosInFile >= Length(currData) then
|
||||
begin
|
||||
// Next File!
|
||||
FCurrentData := FNextData;
|
||||
FCurrentFileName := FNextFileName;
|
||||
FCurrPosInFile := 0;
|
||||
|
||||
FNextFileName := '';
|
||||
FNextData := TFuture<TArray<TAskBid.TTick>>.Null;
|
||||
|
||||
if FCurrentFileName <> '' then
|
||||
begin
|
||||
FNextFileName := FindNextDataFile(FCurrentFileName);
|
||||
if FNextFileName <> '' then
|
||||
FNextData := TAskBid.LoadDataFile(FNextFileName);
|
||||
|
||||
if FCurrentData.Done.IsSet then
|
||||
begin
|
||||
currData := FCurrentData.Value;
|
||||
continue;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// We're done with this series
|
||||
FIsLiveData.SetValue(true);
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
|
||||
var item := currData[FCurrPosInFile];
|
||||
if FLastTimeStamp < item.TimeStamp then
|
||||
begin
|
||||
FLastTimeStamp := item.TimeStamp;
|
||||
Data[Result].Create(FCurrentIdx, FLastTimeStamp, item.Data);
|
||||
inc(Result);
|
||||
inc(FCurrentIdx);
|
||||
end;
|
||||
inc(FCurrPosInFile);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TTABFileServer.GetIsLiveData: TMutable<Boolean>;
|
||||
begin
|
||||
Result := FIsLiveData;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user