diff --git a/AuraTrader/AuraTrader.dproj b/AuraTrader/AuraTrader.dproj
index 18a82b0..0ded5a4 100644
--- a/AuraTrader/AuraTrader.dproj
+++ b/AuraTrader/AuraTrader.dproj
@@ -4,7 +4,7 @@
20.3
FMX
True
- Release
+ Debug
Win64
AuraTrader
3
diff --git a/AuraTrader/MainForm.pas b/AuraTrader/MainForm.pas
index 6d8de84..303241f 100644
--- a/AuraTrader/MainForm.pas
+++ b/AuraTrader/MainForm.pas
@@ -105,13 +105,13 @@ type
FApplication: IAuraApplication;
FModulesItem: TTreeViewItem;
function SelectedSymbol: String;
- procedure ExecuteStrategy(const Symbol: String; Timeframe: TTimeframe; const Processor: IMycProcessor>);
+ procedure ExecuteStrategy(const Symbol: String; Timeframe: TTimeframe; const Consumer: IConsumer>);
public
procedure NewWorkspace;
function CurrLayout: T;
procedure AlignControl(Control: TControl);
- function CreateStrategy2(Timeframe: TTimeframe): IMycProcessor>;
+ function CreateStrategy2(Timeframe: TTimeframe): IConsumer>;
published
property OnEvent: TNotifyEvent read FOnEvent write FOnEvent;
@@ -285,7 +285,7 @@ begin
Control.Align := TAlignLayout.Top;
end;
-function TForm1.CreateStrategy2(Timeframe: TTimeframe): IMycProcessor>;
+function TForm1.CreateStrategy2(Timeframe: TTimeframe): IConsumer>;
type
TSignal = record
Sig: Double;
@@ -297,9 +297,9 @@ var
panel: TMycChart.TPanel;
begin
var ticker := TConverter.CreateIdentity>;
- Result := ticker;
+ Result := ticker.Consumer;
- var OhlcPoint := ticker.DataProvider.Chain>(TConverter.CreateOhlcAggregation(Timeframe));
+ var OhlcPoint := ticker.Producer.Chain>(TConverter.CreateOhlcAggregation(Timeframe));
var Ohlc := OhlcPoint.Field('Data');
@@ -426,7 +426,7 @@ begin
conv.Chain(Signal);
- var pnl := Signal.DataProvider.Field('pnl');
+ var pnl := Signal.Producer.Field('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.DataProvider.Field('Entry'), TAlphaColors.Green, 1);
- panel.AddDoubleSeries(Signal.DataProvider.Field('SL'), TAlphaColors.Red, 2);
+ panel.AddDoubleSeries(Signal.Producer.Field('Entry'), TAlphaColors.Green, 1);
+ panel.AddDoubleSeries(Signal.Producer.Field('SL'), TAlphaColors.Red, 2);
var mean := TConverter, Double>.CreateGeneric(TIndicators.CreateMean());
TConverter.Join([Hull, Sma]).Chain(mean);
- panel.AddDoubleSeries(mean.DataProvider, TAlphaColors.Blue, 5);
+ panel.AddDoubleSeries(mean.Producer, TAlphaColors.Blue, 5);
var pnlChart := TMycChart.Create(Self);
AlignControl(pnlChart);
pnlChart.Height := Layout.ChildrenRect.Width * 9 / 24;
pnlChart.Lookback.Value := 50000;
- pnlChart.SetXAxisCounter(equity.DataProvider);
+ pnlChart.SetXAxisCounter(equity.Producer);
////////////
var EMAFactory := TEMA.Create;
@@ -498,7 +498,7 @@ begin
var equityEMA :=
equity
- .DataProvider
+ .Producer
.Chain(TConverter.FieldToRecord(EMAFactory.Input, 'Price'))
.Chain(EMAConv)
.Chain(TConverter.FieldOfRecord(EMAFactory.Output, 'MA'));
@@ -506,7 +506,7 @@ begin
//////////////
panel := pnlChart.AddPanel;
- panel.AddDoubleSeries(equity.DataProvider, TAlphaColors.Blue, 3);
+ panel.AddDoubleSeries(equity.Producer, TAlphaColors.Blue, 3);
panel.AddDoubleSeries(equityEMA, TAlphaColors.Gray, 2);
/////
@@ -533,7 +533,7 @@ begin
Result := Res;
end;
-procedure TForm1.ExecuteStrategy(const Symbol: String; Timeframe: TTimeframe; const Processor: IMycProcessor>);
+procedure TForm1.ExecuteStrategy(const Symbol: String; Timeframe: TTimeframe; const Consumer: IConsumer>);
begin
var terminated := TFlag.CreateObserver(FTerminate.Signal).State;
@@ -550,9 +550,9 @@ begin
);
var OhlcPoint := lastPrice.Chain>(TConverter.CreateTickAggregation(Timeframe));
- OhlcPoint.DataProvider.Link(Processor);
+ OhlcPoint.Producer.Link(Consumer);
- var dataProvider :=
+ var Producer :=
TConverter>, TArray>>.CreateGeneric(
function(const Values: TArray>): TArray>
begin
@@ -566,16 +566,16 @@ begin
end
);
- dataProvider.DataProvider.Link(ticker);
+ Producer.Producer.Link(ticker);
- FProcessDone := FProcessDone + FServer.ProcessData(Symbol, terminated, dataProvider);
+ FProcessDone := FProcessDone + FServer.ProcessData(Symbol, terminated, Producer);
{$else}
var ticker := TConverter.CreateTicker>;
- ticker.DataProvider.Chain(Processor);
+ ticker.Producer.Chain(Consumer);
- FProcessDone := FProcessDone + FServer.ProcessData(Symbol, terminated, ticker);
+ FProcessDone := FProcessDone + FServer.ProcessData(Symbol, terminated, ticker.Consumer);
{$endif}
end;
@@ -609,7 +609,7 @@ begin
var ticker := TConverter.CreateIdentity>;
- var OhlcPoint := ticker.DataProvider.Chain>(TConverter.CreateOhlcAggregation(timeframe));
+ var OhlcPoint := ticker.Producer.Chain>(TConverter.CreateOhlcAggregation(timeframe));
// var OhlcTicker := TConverter.CreateIdentity>;
// var OhlcPoint := OhlcTicker.Sender;
@@ -674,7 +674,7 @@ begin
}
/////
- ExecuteStrategy(Symbol, timeframe, ticker);
+ ExecuteStrategy(Symbol, timeframe, ticker.Consumer);
end;
procedure TForm1.Strat2ButtonClick(Sender: TObject);
@@ -687,7 +687,7 @@ begin
//ExecuteStrategy(Symbol, timeframe, CreateStrategy2(timeframe));
var tstStrat := StrategyTest.CreateStrategy1(timeframe);
- ExecuteStrategy(Symbol, timeframe, tstStrat);
+ ExecuteStrategy(Symbol, timeframe, tstStrat.Consumer);
var Layout := CurrLayout;
if Layout = nil then
@@ -698,10 +698,10 @@ begin
pnlChart.Height := Layout.ChildrenRect.Width * 9 / 24;
pnlChart.Lookback.Value := 50000;
- pnlChart.SetXAxisCounter(tstStrat.DataProvider);
+ pnlChart.SetXAxisCounter(tstStrat.Producer);
var panel := pnlChart.AddPanel;
- panel.AddDoubleSeries(tstStrat.DataProvider, TAlphaColors.Blue, 3);
+ panel.AddDoubleSeries(tstStrat.Producer, TAlphaColors.Blue, 3);
end;
end.
diff --git a/AuraTrader/StrategyTest.pas b/AuraTrader/StrategyTest.pas
index d82bc80..cff102b 100644
--- a/AuraTrader/StrategyTest.pas
+++ b/AuraTrader/StrategyTest.pas
@@ -30,7 +30,7 @@ type
begin
var ticker := TConverter.CreateIdentity>;
- var OhlcPoint := ticker.DataProvider.Chain>(TConverter.CreateOhlcAggregation(Timeframe));
+ var OhlcPoint := ticker.Producer.Chain>(TConverter.CreateOhlcAggregation(Timeframe));
var Ohlc := OhlcPoint.Field('Data');
@@ -183,7 +183,7 @@ begin
)
);
- Result := TConverter, Double>.Construct(ticker, equity);
+ Result := TConverter, Double>.Construct(ticker.Consumer, equity);
end;
end.
diff --git a/Src/Myc.Fmx.Chart.Series.pas b/Src/Myc.Fmx.Chart.Series.pas
index 4182e57..cb527ae 100644
--- a/Src/Myc.Fmx.Chart.Series.pas
+++ b/Src/Myc.Fmx.Chart.Series.pas
@@ -18,7 +18,7 @@ type
{ TChartCustomLayer }
TChartCustomLayer = class abstract(TMycChart.TDataLayer)
private
- FDataProvider: TDataProvider;
+ FProducer: TProducer;
FReceiver: TLazy>;
FData: TSeries;
protected
@@ -33,7 +33,7 @@ type
const YForm: TFunc
); override; abstract;
public
- constructor Create(AParent: TMycChart.TPanel; const ADataProvider: TDataProvider);
+ constructor Create(AParent: TMycChart.TPanel; const AProducer: TProducer);
property Data: TSeries read FData;
end;
@@ -53,7 +53,7 @@ type
public
constructor Create(
AParent: TMycChart.TPanel;
- const ADataProvider: TDataProvider;
+ const AProducer: TProducer;
const AUpColor, ADownColor: TMutable
);
end;
@@ -74,7 +74,7 @@ type
public
constructor Create(
AParent: TMycChart.TPanel;
- const ADataProvider: TDataProvider;
+ const AProducer: TProducer;
const ALineColor: TAlphaColor;
ALineWidth: Single
);
@@ -83,7 +83,7 @@ type
{ TChartXAxisLayer }
TChartXAxisLayer = class(TMycChart.TXAxisLayer)
private
- FDataProvider: TDataProvider;
+ FProducer: TProducer;
FReceiver: TLazy>;
FData: TSeries;
protected
@@ -92,7 +92,7 @@ type
function GetCount: Int64; override;
function GetTotalCount: Int64; override;
public
- constructor Create(AOwner: TMycChart; const ADataProvider: TDataProvider);
+ constructor Create(AOwner: TMycChart; const AProducer: TProducer);
property Data: TSeries read FData;
end;
@@ -104,7 +104,7 @@ type
// Provide a formatted timestamp string for a given data index.
function GetCaption(Idx: Int64): String; override; final;
public
- constructor Create(AOwner: TMycChart; ATimeframe: TTimeframe; const ADataProvider: TDataProvider);
+ constructor Create(AOwner: TMycChart; ATimeframe: TTimeframe; const AProducer: TProducer);
end;
implementation
@@ -118,12 +118,12 @@ uses
constructor TChartLineLayer.Create(
AParent: TMycChart.TPanel;
- const ADataProvider: TDataProvider;
+ const AProducer: TProducer;
const ALineColor: TAlphaColor;
ALineWidth: Single
);
begin
- inherited Create(AParent, ADataProvider);
+ inherited Create(AParent, AProducer);
FLineColor := ALineColor;
FLineWidth := ALineWidth;
end;
@@ -194,11 +194,11 @@ end;
constructor TChartOhlcLayer.Create(
AParent: TMycChart.TPanel;
- const ADataProvider: TDataProvider;
+ const AProducer: TProducer;
const AUpColor, ADownColor: TMutable
);
begin
- inherited Create(AParent, ADataProvider);
+ inherited Create(AParent, AProducer);
FUpColor := AUpColor;
FDownColor := ADownColor;
@@ -267,12 +267,12 @@ end;
{ TChartCustomLayer }
-constructor TChartCustomLayer.Create(AParent: TMycChart.TPanel; const ADataProvider: TDataProvider);
+constructor TChartCustomLayer.Create(AParent: TMycChart.TPanel; const AProducer: TProducer);
begin
inherited Create(AParent);
- FDataProvider := ADataProvider;
+ FProducer := AProducer;
- FReceiver := FDataProvider.CreateEndpoint(Owner.Lookback.Value);
+ FReceiver := FProducer.CreateEndpoint(Owner.Lookback.Value);
end;
function TChartCustomLayer.GetCount: Int64;
@@ -292,11 +292,11 @@ end;
{ TChartXAxisLayer }
-constructor TChartXAxisLayer.Create(AOwner: TMycChart; const ADataProvider: TDataProvider);
+constructor TChartXAxisLayer.Create(AOwner: TMycChart; const AProducer: TProducer);
begin
inherited Create(AOwner);
- FDataProvider := ADataProvider;
- FReceiver := FDataProvider.CreateEndpoint(Owner.Lookback.Value);
+ FProducer := AProducer;
+ FReceiver := FProducer.CreateEndpoint(Owner.Lookback.Value);
end;
function TChartXAxisLayer.GetCaption(Idx: Int64): String;
@@ -321,9 +321,9 @@ end;
{ TChartXAxisTimestampLayer }
-constructor TChartXAxisTimestampLayer.Create(AOwner: TMycChart; ATimeframe: TTimeframe; const ADataProvider: TDataProvider);
+constructor TChartXAxisTimestampLayer.Create(AOwner: TMycChart; ATimeframe: TTimeframe; const AProducer: TProducer);
begin
- inherited Create(AOwner, ADataProvider);
+ inherited Create(AOwner, AProducer);
FTimeframe := ATimeframe;
end;
diff --git a/Src/Myc.Fmx.Chart.pas b/Src/Myc.Fmx.Chart.pas
index ab334cf..8484cbb 100644
--- a/Src/Myc.Fmx.Chart.pas
+++ b/Src/Myc.Fmx.Chart.pas
@@ -97,13 +97,13 @@ type
destructor Destroy; override;
function AddOhlcSeries(
- const DataProvider: TDataProvider;
+ const Producer: TProducer;
const AUpColor: TAlphaColor = TAlphaColors.Green;
const ADownColor: TAlphaColor = TAlphaColors.Red
): TMycChart.TDataLayer;
function AddDoubleSeries(
- const DataProvider: TDataProvider;
+ const Producer: TProducer;
const ALineColor: TAlphaColor = TAlphaColors.Cornflowerblue;
const ALineWidth: Single = 1.5
): TMycChart.TDataLayer;
@@ -150,8 +150,8 @@ type
function AddPanel: TPanel;
// Sets the master series that defines the time scale (X-axis).
- function SetXAxisSeries(Timeframe: TTimeframe; const DataProvider: TDataProvider): TMycChart.TXAxisLayer; overload;
- function SetXAxisCounter(const DataProvider: TDataProvider): TMycChart.TXAxisLayer; overload;
+ function SetXAxisSeries(Timeframe: TTimeframe; const Producer: TProducer): TMycChart.TXAxisLayer; overload;
+ function SetXAxisCounter(const Producer: TProducer): TMycChart.TXAxisLayer; overload;
property Lookback: TWriteable read FLookback write FLookback;
property NeedRepaint: TFlag read FNeedRepaint;
@@ -632,19 +632,19 @@ begin
Repaint;
end;
-function TMycChart.SetXAxisCounter(const DataProvider: TDataProvider): TMycChart.TXAxisLayer;
+function TMycChart.SetXAxisCounter(const Producer: TProducer): TMycChart.TXAxisLayer;
begin
FXAxisSeries.Free;
- FXAxisSeries := TChartXAxisLayer.Create(Self, DataProvider.Chain(TConverter.CreateCounter));
+ FXAxisSeries := TChartXAxisLayer.Create(Self, Producer.Chain(TConverter.CreateCounter));
Result := FXAxisSeries;
end;
-function TMycChart.SetXAxisSeries(Timeframe: TTimeframe; const DataProvider: TDataProvider): TMycChart.TXAxisLayer;
+function TMycChart.SetXAxisSeries(Timeframe: TTimeframe; const Producer: TProducer): TMycChart.TXAxisLayer;
begin
FXAxisSeries.Free;
- FXAxisSeries := TChartXAxisTimestampLayer.Create(Self, Timeframe, DataProvider);
+ FXAxisSeries := TChartXAxisTimestampLayer.Create(Self, Timeframe, Producer);
Result := FXAxisSeries;
end;
@@ -670,23 +670,22 @@ begin
end;
function TMycChart.TPanel.AddDoubleSeries(
- const DataProvider: TDataProvider;
+ const Producer: TProducer;
const ALineColor: TAlphaColor = TAlphaColors.Cornflowerblue;
const ALineWidth: Single = 1.5
): TMycChart.TDataLayer;
begin
- Result := TChartLineLayer.Create(Self, DataProvider, ALineColor, ALineWidth);
+ Result := TChartLineLayer.Create(Self, Producer, ALineColor, ALineWidth);
FLayers.Add(Result);
end;
function TMycChart.TPanel.AddOhlcSeries(
- const DataProvider: TDataProvider;
+ const Producer: TProducer;
const AUpColor: TAlphaColor = TAlphaColors.Green;
const ADownColor: TAlphaColor = TAlphaColors.Red
): TMycChart.TDataLayer;
begin
- Result :=
- TChartOhlcLayer.Create(Self, DataProvider, TMutable.Constant(AUpColor), TMutable.Constant(ADownColor));
+ Result := TChartOhlcLayer.Create(Self, Producer, TMutable.Constant(AUpColor), TMutable.Constant(ADownColor));
FLayers.Add(Result);
end;
diff --git a/Src/Myc.Trade.DataPoint.Impl.pas b/Src/Myc.Trade.DataPoint.Impl.pas
index 085af95..93a1533 100644
--- a/Src/Myc.Trade.DataPoint.Impl.pas
+++ b/Src/Myc.Trade.DataPoint.Impl.pas
@@ -15,68 +15,91 @@ uses
type
// Abstract base class for data consumers.
- TMycProcessor = class abstract(TInterfacedObject, IMycProcessor)
+ TMycConsumer = class abstract(TContainedObject, IConsumer)
+ strict private
+ type
+ TNull = class(TInterfacedObject, IConsumer)
+ protected
+ function Consume(const Value: T): TState;
+ end;
+ class var
+ FNull: IConsumer;
+ class constructor CreateClass;
protected
- function Execute(const Value: T; const Proc: TConstFunc): TState;
- function ProcessData(const Value: T): TState; virtual; abstract;
- end;
-
- // Concrete data provider that manages a list of processors (listeners).
- TMycContainedDataProvider = class abstract(TContainedObject, IDataProvider)
- private
- FListeners: TMycNotifyList>;
+ function Consume(const Value: T): TState; virtual; abstract;
public
- constructor Create(const Controller: IInterface);
- destructor Destroy; override;
- // Notifies all linked processors.
- function Broadcast(const Value: T): TState;
- // Link a Processor
- function Link(const Processor: IMycProcessor): TTag;
- // Unlink a linked strategy
- procedure Unlink(Tag: TTag);
+ class property Null: IConsumer read FNull;
end;
- TMycSequence = class(TMycProcessor, IMycDataSequence)
+ TMycProducer = class(TInterfacedObject, IProducer)
+ strict private
+ type
+ TNull = class(TInterfacedObject, IProducer)
+ public
+ function Link(const Consumer: IConsumer): TTag;
+ procedure Unlink(Tag: TTag);
+ end;
+ class var
+ FNull: IProducer;
+ class constructor CreateClass;
private
- FDataProviders: TArray>;
- function GetCount: Integer;
- function GetDataProvider(Idx: Integer): TDataProvider;
- protected
- function ProcessData(const Value: T): TState; override;
- function ProcessDataProvider(Idx: Integer; const Value: T): TState;
- public
- constructor Create(ACount: Integer);
- destructor Destroy; override;
- end;
-
- // Null object implementation for IDataProvider.
- TNullDataProvider = class(TInterfacedObject, IDataProvider)
- public
- function Link(const Receiver: IMycProcessor): TTag;
- procedure Unlink(Tag: TTag);
- end;
-
- // Abstract base class for components that process data of type S and provide data of type T.
- TMycConverter = class abstract(TMycProcessor, IConverter)
- private
- FDataProvider: TMycContainedDataProvider;
- function GetDataProvider: IDataProvider;
- protected
- function ProcessData(const Value: S): TState; override; abstract;
- // Broadcasts the given data to all linked processors.
- function Broadcast(const Value: T): TState;
+ FListeners: TMycNotifyList>;
public
constructor Create;
destructor Destroy; override;
- property DataProvider: IDataProvider read GetDataProvider;
+ function Broadcast(const Value: T): TState;
+ function Link(const Consumer: IConsumer): TTag;
+ procedure Unlink(Tag: TTag);
+ class property Null: IProducer read FNull;
end;
- // Null object implementation for IConverter.
- TNullConverter = class(TInterfacedObject, IConverter)
+ // Concrete producer that manages a list of consumers (listeners).
+ TMycContainedProducer = class(TContainedObject, IProducer)
private
- function GetDataProvider: IDataProvider;
+ FListeners: TMycNotifyList>;
public
- function ProcessData(const Value: S): TState;
+ constructor Create(const Controller: IInterface);
+ destructor Destroy; override;
+ function Broadcast(const Value: T): TState;
+ function Link(const Consumer: IConsumer): TTag;
+ procedure Unlink(Tag: TTag);
+ end;
+
+ // Abstract base class for components that now act as a producer and contain a consumer.
+ TMycConverter = class abstract(TMycProducer, IConverter)
+ strict private
+ type
+ TNull = class(TInterfacedObject, IConverter)
+ private
+ function GetConsumer: IConsumer;
+ function Link(const Consumer: IConsumer): TTag;
+ procedure Unlink(Tag: TTag);
+ end;
+ class var
+ FNull: IConverter;
+ class constructor CreateClass;
+ private
+ type
+ TConsumer = class(TMycConsumer)
+ private
+ FOwner: TMycConverter;
+ protected
+ function Consume(const Value: S): TState; override; final;
+ public
+ constructor Create(AOwner: TMycConverter);
+ end;
+
+ private
+ FConsumer: TConsumer;
+ function GetConsumer: IConsumer;
+ protected
+ // To be implemented by descendants to perform the actual conversion.
+ function Consume(const Value: S): TState; virtual; abstract;
+ public
+ constructor Create;
+ destructor Destroy; override;
+
+ class property Null: IConverter read FNull;
end;
// A generic converter that uses a function reference for the conversion logic.
@@ -84,7 +107,7 @@ type
private
FFunc: TConstFunc;
protected
- function ProcessData(const Value: S): TState; override;
+ function Consume(const Value: S): TState; override;
public
constructor Create(const AFunc: TConstFunc);
end;
@@ -93,7 +116,7 @@ type
private
FFunc: TConstFunc.TBroadcastProc, TState>;
protected
- function ProcessData(const Value: S): TState; override;
+ function Consume(const Value: S): TState; override;
public
constructor Create(const AFunc: TConstFunc.TBroadcastProc, TState>);
end;
@@ -103,21 +126,14 @@ type
FFunc: TConstFunc;
FQueue: TState;
protected
- function ProcessData(const Value: S): TState; override;
+ function Consume(const Value: S): TState; override;
public
constructor Create(const AFunc: TConstFunc);
end;
TMycIdentityConverter = class(TMycConverter)
protected
- function ProcessData(const Value: T): TState; override; final;
- end;
-
- // A converter specialized for calculating indicators.
- TMycIndicator = class(TMycConverter)
- protected
- function ProcessData(const Value: S): TState; override; final;
- function Calculate(const Value: S): T; virtual; abstract;
+ function Consume(const Value: T): TState; override; final;
end;
// A converter that counts incoming data points and outputs the current count.
@@ -125,47 +141,40 @@ type
private
FCount: Int64;
protected
- function ProcessData(const Value: T): TState; override;
+ function Consume(const Value: T): TState; override;
public
constructor Create;
end;
// A converter that takes an array and broadcasts each element individually.
TMycTicker = class(TMycConverter, T>)
- public
- function ProcessData(const Values: TArray): TState; override;
+ protected
+ function Consume(const Values: TArray): TState; override;
end;
// A converter that reads a specific field from a record using RTTI.
TMycRecordFieldReader = class(TMycConverter)
private
FOffset: Integer;
+ protected
+ function Consume(const Values: S): TState; override;
public
constructor Create(const AFieldName: String);
- function ProcessData(const Values: S): TState; override;
end;
- // A generic processor implementation that uses a function reference.
- TMycGenericProcessor = class(TMycProcessor)
+ // A consumer implementation that is owned by a controller.
+ TMycGenericConsumer = class(TMycConsumer)
private
FProc: TConstFunc;
protected
- function ProcessData(const Value: T): TState; override; final;
- public
- constructor Create(const AProc: TConstFunc);
- end;
-
- // A processor implementation that is owned by a controller.
- TMycContainedProcessor = class(TContainedObject, IMycProcessor)
- private
- FProc: TConstFunc;
- function ProcessData(const Value: T): TState;
+ function Consume(const Value: T): TState; override;
public
constructor Create(const Controller: IInterface; const AProc: TConstFunc);
end;
// Endpoint that collects data into a series.
TMycDataEndpoint = class(TInterfacedObject, TLazy>.ILazy)
+ private
type
PItem = ^TItem;
TItem = record
@@ -173,18 +182,18 @@ type
Value: T;
end;
private
- FProcessor: TMycContainedProcessor;
+ FConsumer: TMycGenericConsumer;
FTag: TTag;
- FDataProvider: IDataProvider;
+ FProducer: IProducer;
FLookback: Int64;
FChanged: TFlag;
FLock: TLightweightMREW;
FFirst: PItem;
FCount: Integer;
function GetChanged: TState;
- function ProcessData(const Value: T): TState;
+ function Consume(const Value: T): TState;
public
- constructor Create(const ADataProvider: TDataProvider; ALookback: Int64);
+ constructor Create(const AProducer: TProducer; ALookback: Int64);
destructor Destroy; override;
function Update(var Value: TSeries): Boolean;
end;
@@ -196,9 +205,10 @@ type
function GetBarStartTime(const TimeStamp: TDateTime; const Timeframe: TTimeframe): TDateTime;
function GetCurrentBar: TDataPoint;
function GetTimeframe: TTimeframe;
+ protected
+ function Consume(const Value: TDataPoint): TState; override;
public
constructor Create(const ATimeframe: TTimeframe);
- function ProcessData(const Value: TDataPoint): TState; override;
property CurrentBar: TDataPoint read GetCurrentBar;
property Timeframe: TTimeframe read GetTimeframe;
end;
@@ -207,7 +217,7 @@ type
private
FQueue: TState;
protected
- function ProcessData(const Value: T): TState; override; final;
+ function Consume(const Value: T): TState; override; final;
end;
TOhlcAggregation = class(TMycConverter, TDataPoint>)
@@ -217,42 +227,58 @@ type
function GetBarStartTime(const TimeStamp: TDateTime; const Timeframe: TTimeframe): TDateTime;
function GetCurrentBar: TDataPoint;
function GetTimeframe: TTimeframe;
+ protected
+ function Consume(const Value: TDataPoint): TState; override;
public
constructor Create(const ATimeframe: TTimeframe);
- function ProcessData(const Value: TDataPoint): TState; override;
property CurrentBar: TDataPoint read GetCurrentBar;
property Timeframe: TTimeframe read GetTimeframe;
end;
// Endpoint that collects data into a series.
- TMycDataJoin = class(TInterfacedObject, IDataProvider>)
+ TMycDataJoin = class(TInterfacedObject, IProducer>)
private
- FReceivers: array of record
- DataProvider: IDataProvider;
- Processor: TMycContainedProcessor;
+ FConsumers: array of record
+ Producer: IProducer;
+ Consumer: TMycGenericConsumer;
Tag: TTag;
Queue: TQueue;
end;
- FDataProvider: TMycContainedDataProvider>;
+ FContainedProvider: TMycContainedProducer>;
FLock: TSpinLock;
FCount: Integer;
- function ProcessData(Idx: Integer; const Value: T): TState;
+ function Consume(Idx: Integer; const Value: T): TState;
+ function Link(const Consumer: IConsumer>): TTag;
+ procedure Unlink(Tag: TTag);
public
- constructor Create(const ADataProviders: TArray>);
+ constructor Create(const AProducers: TArray>);
destructor Destroy; override;
- property DataProvider: TMycContainedDataProvider> read FDataProvider implements IDataProvider>;
end;
- TMycComposedConverter = class(TMycProcessor, IConverter)
+ TMycComposedConverter = class(TInterfacedObject, IConverter)
private
- FProcessor: IMycProcessor;
- FDataProvider: TDataProvider;
+ FConsumer: IConsumer;
+ FProducer: TProducer;
protected
- function ProcessData(const Value: S): TState; override;
- function GetDataProvider: IDataProvider;
+ function GetConsumer: IConsumer;
+ function Link(const Consumer: IConsumer): TTag;
+ procedure Unlink(Tag: TTag);
public
- constructor Create(const AProcessor: IMycProcessor; const ADataProvider: TDataProvider);
+ constructor Create(const AConsumer: IConsumer; const AProducer: TProducer);
+ end;
+
+ TMycSequence = class(TInterfacedObject, IConsumer)
+ private
+ FProducers: TArray>;
+ protected
+ function Consume(const Value: T): TState;
+ function ProcessProducer(Idx: Integer; const Value: T): TState;
+ public
+ constructor Create(ACount: Integer);
+ destructor Destroy; override;
+
+ class function CreateSequence(Count: Integer; out Producers: TArray