Work in Progress
This commit is contained in:
@@ -48,6 +48,13 @@ type
|
||||
class property Null: IDataProvider read FNull;
|
||||
end;
|
||||
|
||||
IMycDataSequence<T> = interface(IMycProcessor<T>)
|
||||
function GetCount: Integer;
|
||||
function GetDataProvider(Idx: Integer): TDataProvider<T>;
|
||||
property Count: Integer read GetCount;
|
||||
property DataProvider[Idx: Integer]: TDataProvider<T> read GetDataProvider; default;
|
||||
end;
|
||||
|
||||
// Interface helper for IConverter<S,T> providing the null object pattern.
|
||||
TConverter<S, T> = record
|
||||
public
|
||||
@@ -59,7 +66,6 @@ type
|
||||
property Sender: TDataProvider<T>.IDataProvider read GetSender;
|
||||
end;
|
||||
|
||||
{$region 'private'}
|
||||
strict private
|
||||
class var
|
||||
FNull: IConverter;
|
||||
@@ -67,7 +73,6 @@ type
|
||||
private
|
||||
FConverter: IConverter;
|
||||
function GetSender: TDataProvider<T>; inline;
|
||||
{$endregion}
|
||||
public
|
||||
constructor Create(const AConverter: IConverter);
|
||||
|
||||
@@ -78,15 +83,15 @@ type
|
||||
|
||||
class function CreateGeneric(const Func: TConstFunc<S, T>): TConverter<S, T>; static;
|
||||
|
||||
// Wrapper for IMycProcessor.ProcessData
|
||||
function ProcessData(const Value: S): TState; inline;
|
||||
|
||||
function Chain<R>(const Next: TConverter<T, R>): TConverter<T, R>; overload; inline;
|
||||
function Chain<R>(const Func: TConstFunc<T, R>): TConverter<T, R>; overload; inline;
|
||||
|
||||
// Extracts the field of a record by it's name (using RTTI).
|
||||
function Field<R>(const FieldName: String): TConverter<T, R>; overload; inline;
|
||||
|
||||
function Sequence(Count: Integer): IMycDataSequence<T>; overload;
|
||||
function Sequence(const Items: TArray<IConverter>): IMycDataSequence<S>; overload;
|
||||
|
||||
// Provides access to the null object instance.
|
||||
class property Null: IConverter read FNull;
|
||||
// Wrapper for IConverter.Sender
|
||||
@@ -95,10 +100,18 @@ type
|
||||
|
||||
// Factory for creating specific converter instances.
|
||||
TConverter = record
|
||||
class function CreateEndpoint<T>(const DataProvider: TDataProvider<T>; Lookback: Int64): TMutable<TSeries<T>>; static;
|
||||
|
||||
class function CreateCounter<T>: TConverter<T, Int64>; static;
|
||||
class function CreateTicker<T>: TConverter<TArray<T>, T>; static;
|
||||
class function CreateRecordField<S, T>(const FieldName: String): TConverter<S, T>; static;
|
||||
class function CreateEndpoint<T>(const DataProvider: TDataProvider<T>; Lookback: Int64): TMutable<TSeries<T>>; static;
|
||||
class function CreateIdentity<T>: TConverter<T, T>; static;
|
||||
|
||||
class function CreateAggregation(Timeframe: TTimeframe): TConverter<TDataPoint<Double>, TDataPoint<TOhlcItem>>; static;
|
||||
|
||||
class function CreateDataPointConverter<S, T>(const Func: TConstFunc<S, T>): TConverter<TDataPoint<S>, TDataPoint<T>>; static;
|
||||
|
||||
class function CreateSequence<T>(Count: Integer; const Parent: TDataProvider<T>): TArray<TConverter<T, T>>; overload; static;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@@ -186,6 +199,22 @@ begin
|
||||
Result := FConverter.Sender;
|
||||
end;
|
||||
|
||||
function TConverter<S, T>.Sequence(Count: Integer): IMycDataSequence<T>;
|
||||
begin
|
||||
Result := TMycSequence<T>.Create(Count);
|
||||
FConverter.Sender.Link(Result);
|
||||
end;
|
||||
|
||||
function TConverter<S, T>.Sequence(const Items: TArray<IConverter>): IMycDataSequence<S>;
|
||||
begin
|
||||
var seq: IMycDataSequence<S> := TMycSequence<S>.Create(Length(Items));
|
||||
|
||||
for var i := 0 to High(Items) do
|
||||
seq[i].Link(Items[i]);
|
||||
|
||||
Result := seq;
|
||||
end;
|
||||
|
||||
class operator TConverter<S, T>.Initialize(out Dest: TConverter<S, T>);
|
||||
begin
|
||||
Dest.FConverter := FNull;
|
||||
@@ -201,9 +230,9 @@ begin
|
||||
Result := A.FConverter;
|
||||
end;
|
||||
|
||||
function TConverter<S, T>.ProcessData(const Value: S): TState;
|
||||
class function TConverter.CreateAggregation(Timeframe: TTimeframe): TConverter<TDataPoint<Double>, TDataPoint<TOhlcItem>>;
|
||||
begin
|
||||
Result := FConverter.ProcessData(Value);
|
||||
Result := TTickAggregation.Create(Timeframe);
|
||||
end;
|
||||
|
||||
{ TConverter }
|
||||
@@ -213,11 +242,29 @@ begin
|
||||
Result := TMycDataCounter<T>.Create;
|
||||
end;
|
||||
|
||||
class function TConverter.CreateDataPointConverter<S, T>(const Func: TConstFunc<S, T>): TConverter<TDataPoint<S>, TDataPoint<T>>;
|
||||
begin
|
||||
var cFunc: TConstFunc<S, T> := Func;
|
||||
Result :=
|
||||
TMycGenericConverter<TDataPoint<S>, TDataPoint<T>>.Create(
|
||||
function(const Value: TDataPoint<S>): TDataPoint<T>
|
||||
begin
|
||||
Result.Time := Value.Time;
|
||||
Result.Data := cFunc(Value.Data);
|
||||
end
|
||||
);
|
||||
end;
|
||||
|
||||
class function TConverter.CreateEndpoint<T>(const DataProvider: TDataProvider<T>; Lookback: Int64): TMutable<TSeries<T>>;
|
||||
begin
|
||||
Result := TMycDataEndpoint<T>.Create(DataProvider, Lookback);
|
||||
end;
|
||||
|
||||
class function TConverter.CreateIdentity<T>: TConverter<T, T>;
|
||||
begin
|
||||
Result := TMycIdentityConverter<T>.Create;
|
||||
end;
|
||||
|
||||
class function TConverter.CreateRecordField<S, T>(const FieldName: String): TConverter<S, T>;
|
||||
begin
|
||||
Result := TMycRecordFieldReader<S, T>.Create(FieldName);
|
||||
@@ -228,4 +275,17 @@ begin
|
||||
Result := TMycTicker<T>.Create;
|
||||
end;
|
||||
|
||||
class function TConverter.CreateSequence<T>(Count: Integer; const Parent: TDataProvider<T>): TArray<TConverter<T, T>>;
|
||||
begin
|
||||
var seq: IMycDataSequence<T> := TMycSequence<T>.Create(Count);
|
||||
|
||||
SetLength(Result, Count);
|
||||
for var i := 0 to High(Result) do
|
||||
begin
|
||||
Result[i] := TMycIdentityConverter<T>.Create;
|
||||
seq[i].Link(Result[i]);
|
||||
end;
|
||||
Parent.Link(seq);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user