Test-Apps für Gemini Api und Blockly

This commit is contained in:
Michael Schimmel
2025-06-10 17:08:09 +02:00
parent 312be15cc8
commit 0e598d595e
8 changed files with 1555 additions and 35 deletions
+36 -35
View File
@@ -5,7 +5,7 @@ unit Myc.Trade.DataStream;
Provides a data server for loading time-series data and streaming it.
This unit contains the core components for handling historical data:
- TDataRecord: A generic record for a single time-stamped data entry.
- TAuraFileDataRecord: A generic record for a single time-stamped data entry.
- IDataServer/TAuraDataServer: A server component responsible for loading and caching
series of data files from disk. Each server instance manages its own cache,
but all instances share a central load gate.
@@ -29,11 +29,6 @@ uses
Myc.Trade.DataPoint;
type
// A generic record for a single time-stamped data entry.
TDataRecord<T: record> = packed record
TimeStamp: TDateTime;
Data: T;
end;
// Represents a generic data stream capable of providing sequential data chunks.
IDataStream<T> = interface
@@ -69,10 +64,16 @@ type
procedure ClearCache;
end;
// A generic record for a single time-stamped data entry.
TAuraFileDataRecord<T: record> = packed record
TimeStamp: TDateTime;
Data: T;
end;
IAuraDataServer<T: record> = interface(IDataServer<T>)
['{481E27DE-DC58-49AF-B8A8-B6316980C423}']
function LoadDataFile(const FileName: string): TFuture<TArray<TDataRecord<T>>>;
function LoadDataSeries(const FileName: string): TFuture<TArray<TDataRecord<T>>>;
function LoadDataFile(const FileName: string): TFuture<TArray<TAuraFileDataRecord<T>>>;
function LoadDataSeries(const FileName: string): TFuture<TArray<TAuraFileDataRecord<T>>>;
function EnumerateAssetFiles: TArray<String>;
end;
@@ -87,7 +88,7 @@ type
Name: String;
Age: TDateTime;
LastUsed: TDateTime;
Data: TFuture<TArray<TDataRecord<T>>>;
Data: TFuture<TArray<TAuraFileDataRecord<T>>>;
end;
private
// The cache is per-instance.
@@ -101,8 +102,8 @@ type
FLoadGate: TLatch;
protected
class function ReadCompressedData(const InputStream: TStream): TArray<TDataRecord<T>>; static;
class function ReadUncompressedData(const InputStream: TStream): TArray<TDataRecord<T>>; static;
class function ReadCompressedData(const InputStream: TStream): TArray<TAuraFileDataRecord<T>>; static;
class function ReadUncompressedData(const InputStream: TStream): TArray<TAuraFileDataRecord<T>>; static;
public
constructor Create(const APath: String);
@@ -123,8 +124,8 @@ type
procedure ClearCache;
function EnumerateAssetFiles: TArray<String>;
function LoadDataFile(const FileName: string): TFuture<TArray<TDataRecord<T>>>;
function LoadDataSeries(const FileName: string): TFuture<TArray<TDataRecord<T>>>;
function LoadDataFile(const FileName: string): TFuture<TArray<TAuraFileDataRecord<T>>>;
function LoadDataSeries(const FileName: string): TFuture<TArray<TAuraFileDataRecord<T>>>;
property Path: String read GetPath;
end;
@@ -135,9 +136,9 @@ type
FDataServer: TAuraDataServer<T>;
FIsLiveData: TMutable<Boolean>.IWriteable;
FCurrentFileName: string;
FCurrentData: TFuture<TArray<TDataRecord<T>>>;
FCurrentData: TFuture<TArray<TAuraFileDataRecord<T>>>;
FNextFileName: string;
FNextData: TFuture<TArray<TDataRecord<T>>>;
FNextData: TFuture<TArray<TAuraFileDataRecord<T>>>;
FCurrPosInFile: Int64;
FCurrentIdx: Int64;
FLastTimeStamp: TDateTime;
@@ -314,12 +315,12 @@ begin
Result := FPath;
end;
function TAuraDataServer<T>.LoadDataFile(const FileName: string): TFuture<TArray<TDataRecord<T>>>;
function TAuraDataServer<T>.LoadDataFile(const FileName: string): TFuture<TArray<TAuraFileDataRecord<T>>>;
var
parsedPath, parsedSymbol: string;
parsedYear, parsedMonth: Integer;
begin
Result := TFuture<TArray<TDataRecord<T>>>.Null;
Result := TFuture<TArray<TAuraFileDataRecord<T>>>.Null;
if not TryParseFileName(FileName, parsedPath, parsedSymbol, parsedYear, parsedMonth) then
exit;
@@ -368,8 +369,8 @@ begin
.Construct(
TLatch.Enqueue(FLoadGate), // Use shared class var FLoadGate
function: TBytes begin Result := TFile.ReadAllBytes(capFileName); end)
.Chain<TArray<TDataRecord<T>>>(
function(bytes: TBytes): TArray<TDataRecord<T>>
.Chain<TArray<TAuraFileDataRecord<T>>>(
function(bytes: TBytes): TArray<TAuraFileDataRecord<T>>
begin
var zipMemoryStream := TBytesStream.Create(bytes);
try
@@ -383,9 +384,9 @@ begin
else if TFile.Exists(FileName) then
begin
Result :=
TFuture<TArray<TDataRecord<T>>>.Construct(
TFuture<TArray<TAuraFileDataRecord<T>>>.Construct(
TLatch.Enqueue(FLoadGate), // Use shared class var FLoadGate
function: TArray<TDataRecord<T>>
function: TArray<TAuraFileDataRecord<T>>
begin
if TFile.Exists(capFileName) then
begin
@@ -418,11 +419,11 @@ begin
end;
end;
function TAuraDataServer<T>.LoadDataSeries(const FileName: string): TFuture<TArray<TDataRecord<T>>>;
function TAuraDataServer<T>.LoadDataSeries(const FileName: string): TFuture<TArray<TAuraFileDataRecord<T>>>;
var
loadedState: TState;
loadedFiles: TArray<TFuture<TArray<TDataRecord<T>>>>;
liveData: TFuture<TArray<TDataRecord<T>>>;
loadedFiles: TArray<TFuture<TArray<TAuraFileDataRecord<T>>>>;
liveData: TFuture<TArray<TAuraFileDataRecord<T>>>;
tabFiles: TList<string>;
currentFile: string;
liveFilePath: string;
@@ -452,7 +453,7 @@ begin
end;
end;
var loadedFileList := TList<TFuture<TArray<TDataRecord<T>>>>.Create;
var loadedFileList := TList<TFuture<TArray<TAuraFileDataRecord<T>>>>.Create;
var loadStates := TList<TState>.Create;
try
for currentFile in tabFiles do
@@ -462,7 +463,7 @@ begin
loadStates.Add(data.Done);
end;
liveData := TFuture<TArray<TDataRecord<T>>>.Null;
liveData := TFuture<TArray<TAuraFileDataRecord<T>>>.Null;
if liveFilePath <> '' then
begin
liveData := LoadDataFile(liveFilePath);
@@ -481,11 +482,11 @@ begin
end;
Result :=
TFuture<TArray<TDataRecord<T>>>.Construct(
TFuture<TArray<TAuraFileDataRecord<T>>>.Construct(
loadedState,
function: TArray<TDataRecord<T>>
function: TArray<TAuraFileDataRecord<T>>
begin
var tickList := TList<TDataRecord<T>>.Create;
var tickList := TList<TAuraFileDataRecord<T>>.Create;
try
var overallLastTabTickTime: TDateTime := 0;
var cnt := 0;
@@ -508,7 +509,7 @@ begin
);
end;
class function TAuraDataServer<T>.ReadCompressedData(const InputStream: TStream): TArray<TDataRecord<T>>;
class function TAuraDataServer<T>.ReadCompressedData(const InputStream: TStream): TArray<TAuraFileDataRecord<T>>;
var
decompressionStream: TStream;
localHeader: TZipHeader;
@@ -547,7 +548,7 @@ begin
end;
end;
class function TAuraDataServer<T>.ReadUncompressedData(const InputStream: TStream): TArray<TDataRecord<T>>;
class function TAuraDataServer<T>.ReadUncompressedData(const InputStream: TStream): TArray<TAuraFileDataRecord<T>>;
var
fileSize: Int64;
recordCount, bytesRead: Integer;
@@ -555,10 +556,10 @@ begin
SetLength(Result, 0);
InputStream.Position := 0;
fileSize := InputStream.Size;
if (fileSize = 0) or ((fileSize mod SizeOf(TDataRecord<T>)) <> 0) then
if (fileSize = 0) or ((fileSize mod SizeOf(TAuraFileDataRecord<T>)) <> 0) then
exit;
recordCount := fileSize div SizeOf(TDataRecord<T>);
recordCount := fileSize div SizeOf(TAuraFileDataRecord<T>);
if recordCount > 0 then
begin
SetLength(Result, recordCount);
@@ -596,8 +597,8 @@ end;
function TAuraFileStream<T>.GetChunk(var Data: array of TDataPoint<T>): Integer;
var
item: TDataRecord<T>;
currData: TArray<TDataRecord<T>>;
item: TAuraFileDataRecord<T>;
currData: TArray<TAuraFileDataRecord<T>>;
begin
Result := 0;
if not FCurrentData.Done.IsSet then