Refactoring identifiers

This commit is contained in:
Michael Schimmel
2025-07-24 07:59:41 +02:00
parent 7b2446b220
commit 6a114f77c5
4 changed files with 70 additions and 65 deletions
+26 -23
View File
@@ -299,7 +299,7 @@ begin
var ticker := TConverter.CreateIdentity<TDataPoint<TOhlcItem>>;
Result := ticker;
var OhlcPoint := ticker.Sender.Chain<TDataPoint<TOhlcItem>>(TConverter.CreateOhlcAggregation(Timeframe));
var OhlcPoint := ticker.DataProvider.Chain<TDataPoint<TOhlcItem>>(TConverter.CreateOhlcAggregation(Timeframe));
var Ohlc := OhlcPoint.Field<TOhlcItem>('Data');
@@ -426,7 +426,7 @@ begin
conv.Chain<TSignal>(Signal);
var pnl := Signal.Sender.Field<Double>('pnl');
var pnl := Signal.DataProvider.Field<Double>('pnl');
var FEquity: Double := 10000;
var FInit: Boolean := false;
@@ -470,21 +470,21 @@ begin
panel.AddOhlcSeries(Ohlc);
panel.AddDoubleSeries(Hull, TAlphaColors.Cornflowerblue, 2);
panel.AddDoubleSeries(Sma, TAlphaColors.Brown, 1.5);
panel.AddDoubleSeries(Signal.Sender.Field<Double>('Entry'), TAlphaColors.Green, 1);
panel.AddDoubleSeries(Signal.Sender.Field<Double>('SL'), TAlphaColors.Red, 2);
panel.AddDoubleSeries(Signal.DataProvider.Field<Double>('Entry'), TAlphaColors.Green, 1);
panel.AddDoubleSeries(Signal.DataProvider.Field<Double>('SL'), TAlphaColors.Red, 2);
var mean := TConverter<TArray<Double>, Double>.CreateGeneric(TIndicators.CreateMean());
TConverter.Join<Double>([Hull, Sma]).Chain<Double>(mean);
panel.AddDoubleSeries(mean.Sender, TAlphaColors.Blue, 5);
panel.AddDoubleSeries(mean.DataProvider, TAlphaColors.Blue, 5);
var pnlChart := TMycChart.Create(Self);
AlignControl(pnlChart);
pnlChart.Height := Layout.ChildrenRect.Width * 9 / 24;
pnlChart.Lookback.Value := 50000;
pnlChart.SetXAxisCounter<Double>(equity.Sender);
pnlChart.SetXAxisCounter<Double>(equity.DataProvider);
////////////
var EMAFactory := TEMA.Create;
@@ -498,7 +498,7 @@ begin
var equityEMA :=
equity
.Sender
.DataProvider
.Chain<TDataRecord>(TConverter.FieldToRecord<Double>(EMAFactory.Input, 'Price'))
.Chain<TDataRecord>(EMAConv)
.Chain<Double>(TConverter.FieldOfRecord<Double>(EMAFactory.Output, 'MA'));
@@ -506,7 +506,7 @@ begin
//////////////
panel := pnlChart.AddPanel;
panel.AddDoubleSeries(equity.Sender, TAlphaColors.Blue, 3);
panel.AddDoubleSeries(equity.DataProvider, TAlphaColors.Blue, 3);
panel.AddDoubleSeries(equityEMA, TAlphaColors.Gray, 2);
/////
@@ -550,7 +550,7 @@ begin
);
var OhlcPoint := lastPrice.Chain<TDataPoint<TOhlcItem>>(TConverter.CreateTickAggregation(Timeframe));
OhlcPoint.Sender.Link(Processor);
OhlcPoint.DataProvider.Link(Processor);
var dataProvider :=
TConverter<TArray<TDataPoint<TAuraAskBidFileItem>>, TArray<TDataPoint<TAskBidItem>>>.CreateGeneric(
@@ -566,14 +566,14 @@ begin
end
);
dataProvider.Sender.Link(ticker);
dataProvider.DataProvider.Link(ticker);
FProcessDone := FProcessDone + FServer.ProcessData(Symbol, terminated, dataProvider);
{$else}
var ticker := TConverter.CreateTicker<TDataPoint<TOhlcItem>>;
ticker.Sender.Chain(Processor);
ticker.DataProvider.Chain(Processor);
FProcessDone := FProcessDone + FServer.ProcessData(Symbol, terminated, ticker);
{$endif}
@@ -605,23 +605,26 @@ begin
/////
var OhlcTicker := TConverter.CreateIdentity<TDataPoint<TOhlcItem>>;
var OhlcPoint := OhlcTicker.Sender;
var timeframe := TTimeframe.H;
var ticker := TConverter.CreateIdentity<TDataPoint<TOhlcItem>>;
var OhlcPoint := ticker.DataProvider.Chain<TDataPoint<TOhlcItem>>(TConverter.CreateOhlcAggregation(timeframe));
// var OhlcTicker := TConverter.CreateIdentity<TDataPoint<TOhlcItem>>;
// var OhlcPoint := OhlcTicker.Sender;
var Timestamps := OhlcPoint.Field<TDateTime>('Time');
var Ohlc := OhlcPoint.Field<TOhlcItem>('Data');
var Closes := Ohlc.Field<Double>('Close');
var Hull := Closes.MakeParallel.Chain<Double>(TIndicators.CreateHMA(150));
var Sma := Closes.MakeParallel.Chain<Double>(TIndicators.CreateSMA(50));
var Ema := Closes.MakeParallel.Chain<Double>(TIndicators.CreateEMA(21));
var Hull := Closes.Chain<Double>(TIndicators.CreateHMA(150));
var Sma := Closes.Chain<Double>(TIndicators.CreateSMA(50));
var Ema := Closes.Chain<Double>(TIndicators.CreateEMA(21));
var Boli := Closes.MakeParallel.Chain<TBollingerBandsResult>(TIndicators.CreateBollingerBands(20, 2.0));
var Rsi := Closes.MakeParallel.Chain<Double>(TIndicators.CreateRSI(14));
var Rsi := Closes.Chain<Double>(TIndicators.CreateRSI(14));
var Macd := Closes.MakeParallel.Chain<TMacdResult>(TIndicators.CreateMACD(12, 26, 9));
var Stoch := Ohlc.MakeParallel.Chain<TStochasticResult>(TIndicators.CreateStochastic(14, 3));
var Stoch := Ohlc.Chain<TStochasticResult>(TIndicators.CreateStochastic(14, 3));
chart.SetXAxisSeries(timeframe, Timestamps);
@@ -671,7 +674,7 @@ begin
}
/////
ExecuteStrategy(Symbol, timeframe, OhlcTicker);
ExecuteStrategy(Symbol, timeframe, ticker);
end;
procedure TForm1.Strat2ButtonClick(Sender: TObject);
@@ -695,10 +698,10 @@ begin
pnlChart.Height := Layout.ChildrenRect.Width * 9 / 24;
pnlChart.Lookback.Value := 50000;
pnlChart.SetXAxisCounter<Double>(tstStrat.Sender);
pnlChart.SetXAxisCounter<Double>(tstStrat.DataProvider);
var panel := pnlChart.AddPanel;
panel.AddDoubleSeries(tstStrat.Sender, TAlphaColors.Blue, 3);
panel.AddDoubleSeries(tstStrat.DataProvider, TAlphaColors.Blue, 3);
end;
end.
+1 -1
View File
@@ -30,7 +30,7 @@ type
begin
var ticker := TConverter.CreateIdentity<TDataPoint<TOhlcItem>>;
var OhlcPoint := ticker.Sender.Chain<TDataPoint<TOhlcItem>>(TConverter.CreateOhlcAggregation(Timeframe));
var OhlcPoint := ticker.DataProvider.Chain<TDataPoint<TOhlcItem>>(TConverter.CreateOhlcAggregation(Timeframe));
var Ohlc := OhlcPoint.Field<TOhlcItem>('Data');
+18 -18
View File
@@ -59,8 +59,8 @@ type
// Abstract base class for components that process data of type S and provide data of type T.
TMycConverter<S, T> = class abstract(TMycProcessor<S>, IConverter<S, T>)
private
FSender: TMycContainedDataProvider<T>;
function GetSender: IDataProvider<T>;
FDataProvider: TMycContainedDataProvider<T>;
function GetDataProvider: IDataProvider<T>;
protected
function ProcessData(const Value: S): TState; override; abstract;
// Broadcasts the given data to all linked processors.
@@ -68,13 +68,13 @@ type
public
constructor Create;
destructor Destroy; override;
property Sender: IDataProvider<T> read GetSender;
property DataProvider: IDataProvider<T> read GetDataProvider;
end;
// Null object implementation for IConverter.
TNullConverter<S, T> = class(TInterfacedObject, IConverter<S, T>)
private
function GetSender: IDataProvider<T>;
function GetDataProvider: IDataProvider<T>;
public
function ProcessData(const Value: S): TState;
end;
@@ -234,14 +234,14 @@ type
Queue: TQueue<T>;
end;
FSender: TMycContainedDataProvider<TArray<T>>;
FDataProvider: TMycContainedDataProvider<TArray<T>>;
FLock: TSpinLock;
FCount: Integer;
function ProcessData(Idx: Integer; const Value: T): TState;
public
constructor Create(const ADataProviders: TArray<TDataProvider<T>>);
destructor Destroy; override;
property Sender: TMycContainedDataProvider<TArray<T>> read FSender implements IDataProvider<TArray<T>>;
property DataProvider: TMycContainedDataProvider<TArray<T>> read FDataProvider implements IDataProvider<TArray<T>>;
end;
TMycComposedConverter<S, T> = class(TMycProcessor<S>, IConverter<S, T>)
@@ -250,7 +250,7 @@ type
FDataProvider: TDataProvider<T>;
protected
function ProcessData(const Value: S): TState; override;
function GetSender: IDataProvider<T>;
function GetDataProvider: IDataProvider<T>;
public
constructor Create(const AProcessor: IMycProcessor<S>; const ADataProvider: TDataProvider<T>);
end;
@@ -352,28 +352,28 @@ end;
constructor TMycConverter<S, T>.Create;
begin
inherited Create;
FSender := TMycContainedDataProvider<T>.Create(Self);
FDataProvider := TMycContainedDataProvider<T>.Create(Self);
end;
destructor TMycConverter<S, T>.Destroy;
begin
FSender.Free;
FDataProvider.Free;
inherited Destroy;
end;
function TMycConverter<S, T>.Broadcast(const Value: T): TState;
begin
Result := FSender.Broadcast(Value);
Result := FDataProvider.Broadcast(Value);
end;
function TMycConverter<S, T>.GetSender: IDataProvider<T>;
function TMycConverter<S, T>.GetDataProvider: IDataProvider<T>;
begin
Result := FSender;
Result := FDataProvider;
end;
{ TNullConverter<S, T> }
function TNullConverter<S, T>.GetSender: IDataProvider<T>;
function TNullConverter<S, T>.GetDataProvider: IDataProvider<T>;
begin
Result := TDataProvider<T>.Null;
end;
@@ -847,7 +847,7 @@ begin
FLock := TSpinLock.Create(false);
FCount := Length(FReceivers);
FSender := TMycContainedDataProvider<TArray<T>>.Create(Self);
FDataProvider := TMycContainedDataProvider<TArray<T>>.Create(Self);
var cFunc :=
function(Idx: Integer): TConstFunc<T, TState>
@@ -875,7 +875,7 @@ begin
Queue.Free;
end;
FSender.Free;
FDataProvider.Free;
inherited;
end;
@@ -908,7 +908,7 @@ begin
end;
if Arr <> nil then
FSender.Broadcast(Arr);
FDataProvider.Broadcast(Arr);
end;
constructor TMycGenericAggregator<S, T>.Create(const AFunc: TConstFunc<S, TConverter<S, T>.TBroadcastProc, TState>);
@@ -919,7 +919,7 @@ end;
function TMycGenericAggregator<S, T>.ProcessData(const Value: S): TState;
begin
Result := FFunc(Value, function(const Value: T): TState begin Result := FSender.Broadcast(Value); end);
Result := FFunc(Value, function(const Value: T): TState begin Result := FDataProvider.Broadcast(Value); end);
end;
constructor TMycComposedConverter<S, T>.Create(const AProcessor: IMycProcessor<S>; const ADataProvider: TDataProvider<T>);
@@ -929,7 +929,7 @@ begin
FDataProvider := ADataProvider;
end;
function TMycComposedConverter<S, T>.GetSender: IDataProvider<T>;
function TMycComposedConverter<S, T>.GetDataProvider: IDataProvider<T>;
begin
Result := FDataProvider;
end;
+25 -23
View File
@@ -22,14 +22,16 @@ type
end;
IConverter<S, T> = interface(IMycProcessor<S>)
function GetSender: IDataProvider<T>;
property Sender: IDataProvider<T> read GetSender;
{$region 'private'}
function GetDataProvider: IDataProvider<T>;
{$endregion}
property DataProvider: IDataProvider<T> read GetDataProvider;
end;
// Interface helper for IDataProvider providing the null object pattern.
TDataProvider<T> = record
type
TLink = record
TSubscription = record
private
FDataProvider: IDataProvider<T>;
FTag: TTag;
@@ -54,7 +56,7 @@ type
class operator Implicit(const A: IDataProvider<T>): TDataProvider<T>; overload;
class operator Implicit(const A: TDataProvider<T>): IDataProvider<T>; overload;
function Link(const Receiver: IMycProcessor<T>): TLink; inline;
function Link(const Receiver: IMycProcessor<T>): TSubscription; inline;
function Chain(const Next: IMycProcessor<T>): IMycProcessor<T>; overload; inline;
function Chain<R>(const Next: IConverter<T, R>): TDataProvider<R>; overload; inline;
@@ -90,7 +92,7 @@ type
class constructor CreateClass;
private
FConverter: IConverter<S, T>;
function GetSender: TDataProvider<T>; inline;
function GetDataProvider: TDataProvider<T>; inline;
public
constructor Create(const AConverter: IConverter<S, T>);
@@ -103,13 +105,13 @@ type
class function CreateGeneric(const Func: TConstFunc<S, T>): TConverter<S, T>; static;
class function CreateAggregation(const Func: TConstFunc<S, TBroadcastProc, TState>): TConverter<S, T>; static;
function Sequence(Count: Integer): IMycDataSequence<T>; overload;
function CreateSequence(Count: Integer): IMycDataSequence<T>; overload;
function Sequence(const Items: TArray<IConverter<S, T>>): IMycDataSequence<S>; overload;
// Provides access to the null object instance.
class property Null: IConverter<S, T> read FNull;
// Wrapper for IConverter.Sender
property Sender: TDataProvider<T> read GetSender;
// Wrapper for IConverter.DataProvider
property DataProvider: TDataProvider<T> read GetDataProvider;
end;
// Factory for creating specific converter instances.
@@ -158,6 +160,15 @@ uses
{ TDataProvider<T> }
procedure TDataProvider<T>.TSubscription.Unlink;
begin
if FTag <> nil then
begin
FDataProvider.Unlink(FTag);
FTag := nil;
end;
end;
class constructor TDataProvider<T>.CreateClass;
begin
// Create the singleton null object instance.
@@ -180,7 +191,7 @@ end;
function TDataProvider<T>.Chain<R>(const Next: IConverter<T, R>): TDataProvider<R>;
begin
FDataProvider.Link(Next);
Result := Next.Sender;
Result := Next.DataProvider;
end;
function TDataProvider<T>.Chain<R>(const Func: TConstFunc<T, R>): TDataProvider<R>;
@@ -213,7 +224,7 @@ begin
Result := A.FDataProvider;
end;
function TDataProvider<T>.Link(const Receiver: IMycProcessor<T>): TLink;
function TDataProvider<T>.Link(const Receiver: IMycProcessor<T>): TSubscription;
begin
Result.FDataProvider := FDataProvider;
Result.FTag := FDataProvider.Link(Receiver);
@@ -253,15 +264,15 @@ begin
Result := TMycGenericConverter<S, T>.Create(Func);
end;
function TConverter<S, T>.GetSender: TDataProvider<T>;
function TConverter<S, T>.GetDataProvider: TDataProvider<T>;
begin
Result := FConverter.Sender;
Result := FConverter.DataProvider;
end;
function TConverter<S, T>.Sequence(Count: Integer): IMycDataSequence<T>;
function TConverter<S, T>.CreateSequence(Count: Integer): IMycDataSequence<T>;
begin
Result := TMycSequence<T>.Create(Count);
FConverter.Sender.Link(Result);
FConverter.DataProvider.Link(Result);
end;
function TConverter<S, T>.Sequence(const Items: TArray<IConverter<S, T>>): IMycDataSequence<S>;
@@ -416,13 +427,4 @@ begin
RecProvider.Link(Result);
end;
procedure TDataProvider<T>.TLink.Unlink;
begin
if FTag <> nil then
begin
FDataProvider.Unlink(FTag);
FTag := nil;
end;
end;
end.