Refactoring DataFlow, 1st Generic Data records working
This commit is contained in:
+243
-11
@@ -50,7 +50,9 @@ uses
|
||||
System.Actions,
|
||||
FMX.ActnList,
|
||||
DynamicFMXControl,
|
||||
Myc.FMX.Chart;
|
||||
Myc.FMX.Chart,
|
||||
Myc.Trade.Indicators,
|
||||
Myc.DataRecord;
|
||||
|
||||
type
|
||||
TForm1 = class(TForm)
|
||||
@@ -108,6 +110,7 @@ type
|
||||
procedure NewWorkspace;
|
||||
function CurrLayout<T: TControl>: T;
|
||||
procedure AlignControl(Control: TControl);
|
||||
function CreateStrategy1(Timeframe: TTimeframe): IMycProcessor<TDataPoint<TOhlcItem>>;
|
||||
function CreateStrategy2(Timeframe: TTimeframe): IMycProcessor<TDataPoint<TOhlcItem>>;
|
||||
|
||||
published
|
||||
@@ -124,29 +127,24 @@ type
|
||||
constructor Create(AEquity: Double);
|
||||
end;
|
||||
|
||||
type
|
||||
TStaget1Result = record
|
||||
ATR, Hull, SMA, O, H, L, C: Double
|
||||
end;
|
||||
|
||||
var
|
||||
Form1: TForm1;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
TestModule,
|
||||
Myc.Trade.Indicators,
|
||||
Myc.DataRecord;
|
||||
TestModule;
|
||||
|
||||
{$R *.fmx}
|
||||
|
||||
procedure TForm1.NewWorkspace;
|
||||
var
|
||||
tab: TTabItem;
|
||||
begin
|
||||
var ws: IAuraWorkspace := TMycAuraWorkspace.Create('New workspace', tmTesting);
|
||||
FApplication.Workspaces.Insert(-1, ws);
|
||||
|
||||
var tab := TabControl.Add;
|
||||
tab := TabControl.Add;
|
||||
tab.Text := ws.Caption;
|
||||
tab.Tag := NativeInt(ws);
|
||||
|
||||
@@ -297,7 +295,7 @@ begin
|
||||
Control.Align := TAlignLayout.Top;
|
||||
end;
|
||||
|
||||
function TForm1.CreateStrategy2(Timeframe: TTimeframe): IMycProcessor<TDataPoint<TOhlcItem>>;
|
||||
function TForm1.CreateStrategy1(Timeframe: TTimeframe): IMycProcessor<TDataPoint<TOhlcItem>>;
|
||||
type
|
||||
TSignal = record
|
||||
Sig: Double;
|
||||
@@ -453,6 +451,12 @@ begin
|
||||
panel.AddDoubleSeries(Signal.Field<Double>('Entry').Sender, TAlphaColors.Green, 1);
|
||||
panel.AddDoubleSeries(Signal.Field<Double>('SL').Sender, TAlphaColors.Red, 2);
|
||||
|
||||
var mean := TConverter<TArray<Double>, Double>.CreateGeneric(TIndicators.CreateMean());
|
||||
|
||||
TConverter.Join<Double>([Hull.Sender, Sma.Sender]).Link(mean);
|
||||
|
||||
panel.AddDoubleSeries(mean.Sender, TAlphaColors.Blue, 5);
|
||||
|
||||
var pnlChart := TMycChart.Create(Self);
|
||||
AlignControl(pnlChart);
|
||||
pnlChart.Height := Layout.ChildrenRect.Width * 9 / 24;
|
||||
@@ -460,8 +464,236 @@ begin
|
||||
|
||||
pnlChart.SetXAxisCounter<Double>(equity.Sender);
|
||||
|
||||
////////////
|
||||
var EMAFactory := TEMA.Create;
|
||||
|
||||
var Params := TDataRecord.CreateFrom(EMAFactory.Params);
|
||||
Params.SetValue<Integer>('Period', 20);
|
||||
|
||||
var indi := EMAFActory.CreateIndicator(Params);
|
||||
|
||||
var EMAConv := TConverter<TDataRecord, TDataRecord>.CreateGeneric(indi);
|
||||
|
||||
var equityEMA :=
|
||||
equity
|
||||
.Chain<TDataRecord>(TConverter.FieldToRecord<Double>(EMAFactory.Input, 'Price'))
|
||||
.Chain<TDataRecord>(EMAConv)
|
||||
.Chain<Double>(TConverter.FieldOfRecord<Double>(EMAFactory.Output, 'MA'));
|
||||
|
||||
//////////////
|
||||
|
||||
panel := pnlChart.AddPanel;
|
||||
panel.AddDoubleSeries(equity.Sender, TAlphaColors.Blue, 3);
|
||||
panel.AddDoubleSeries(equityEMA.Sender, TAlphaColors.Gray, 2);
|
||||
|
||||
/////
|
||||
end;
|
||||
|
||||
function TForm1.CreateStrategy2(Timeframe: TTimeframe): IMycProcessor<TDataPoint<TOhlcItem>>;
|
||||
type
|
||||
TSignal = record
|
||||
Sig: Double;
|
||||
SL: Double;
|
||||
Entry: Double;
|
||||
pnl: Double;
|
||||
end;
|
||||
var
|
||||
panel: TMycChart.TPanel;
|
||||
begin
|
||||
var ticker := TConverter.CreateIdentity<TDataPoint<TOhlcItem>>;
|
||||
Result := ticker;
|
||||
|
||||
var OhlcPoint := ticker.Chain<TDataPoint<TOhlcItem>>(TConverter.CreateOhlcAggregation(Timeframe));
|
||||
|
||||
var Ohlc := OhlcPoint.Field<TOhlcItem>('Data');
|
||||
|
||||
var Closes := Ohlc.Field<Double>('Close');
|
||||
|
||||
var Hull := Closes.Chain<Double>(TIndicators.CreateHMA(250)).MakeParallel;
|
||||
var Sma := Closes.Chain<Double>(TIndicators.CreateSMA(200)).MakeParallel;
|
||||
|
||||
var Lowest: Double := Double.MaxValue;
|
||||
var Highest: Double := Double.MinValue;
|
||||
|
||||
var ATR := Ohlc.Chain<Double>(TIndicators.CreateATR(50)).MakeParallel;
|
||||
|
||||
// next stage
|
||||
|
||||
var ATREndPoint := TConverter.CreateEndpoint<Double>(ATR.Sender, 5);
|
||||
var ATRSeries: TSeries<Double>;
|
||||
|
||||
var HullEndPoint := TConverter.CreateEndpoint<Double>(Hull.Sender, 5);
|
||||
var HullSeries: TSeries<Double>;
|
||||
|
||||
var SmaEndPoint := TConverter.CreateEndpoint<Double>(Sma.Sender, 5);
|
||||
var SmaSeries: TSeries<Double>;
|
||||
|
||||
var curr: TSignal;
|
||||
curr.SL := Double.NaN;
|
||||
curr.Entry := Double.NaN;
|
||||
|
||||
var lastHull, lastSma: Double;
|
||||
|
||||
var conv :=
|
||||
TConverter.Join<Double>(
|
||||
[Ohlc.Field<Double>('Low').Sender, Ohlc.Field<Double>('High').Sender, Closes.Sender, ATR.Sender, Hull.Sender, Sma.Sender]
|
||||
);
|
||||
|
||||
var Signal :=
|
||||
TConverter<TArray<Double>, TSignal>.CreateGeneric(
|
||||
function(const Values: TArray<Double>): TSignal
|
||||
begin
|
||||
var low := Values[0];
|
||||
var high := Values[1];
|
||||
var close := Values[2];
|
||||
var atr := Values[3];
|
||||
var hull := Values[4];
|
||||
var sma := Values[5];
|
||||
|
||||
if low < Lowest then
|
||||
Lowest := low;
|
||||
if high > Highest then
|
||||
Highest := high;
|
||||
|
||||
Result := curr;
|
||||
Result.Sig := 0;
|
||||
var pnl: double := NaN;
|
||||
|
||||
if (hull < sma) and (lastHull >= lastSma) then
|
||||
begin
|
||||
if curr.Sig > 0 then
|
||||
pnl := close - curr.Entry;
|
||||
|
||||
curr.Sig := -1;
|
||||
curr.SL := Highest;
|
||||
curr.Entry := close;
|
||||
Result := curr;
|
||||
end
|
||||
else if (hull > sma) and (lastHull <= lastSma) then
|
||||
begin
|
||||
if curr.Sig < 0 then
|
||||
pnl := curr.Entry - close;
|
||||
|
||||
curr.Sig := 1;
|
||||
curr.SL := Lowest;
|
||||
curr.Entry := close;
|
||||
Result := curr;
|
||||
end;
|
||||
|
||||
atr := 15 * atr;
|
||||
if curr.Sig > 0 then
|
||||
begin
|
||||
if close > curr.SL then
|
||||
begin
|
||||
if curr.SL < close - atr then
|
||||
curr.SL := close - atr;
|
||||
Result.SL := curr.SL;
|
||||
end;
|
||||
|
||||
if low <= curr.SL then
|
||||
begin
|
||||
pnl := curr.SL - curr.Entry;
|
||||
curr.Sig := 0;
|
||||
Result.Sig := 0;
|
||||
curr.SL := NaN;
|
||||
end;
|
||||
end
|
||||
else if curr.Sig < 0 then
|
||||
begin
|
||||
if close < curr.SL then
|
||||
begin
|
||||
if curr.SL > close + atr then
|
||||
curr.SL := close + atr;
|
||||
Result.SL := curr.SL;
|
||||
end;
|
||||
|
||||
if high >= curr.SL then
|
||||
begin
|
||||
pnl := curr.Entry - curr.SL;
|
||||
curr.Sig := 0;
|
||||
Result.Sig := 0;
|
||||
curr.SL := NaN;
|
||||
end;
|
||||
end;
|
||||
|
||||
if Result.Sig <> 0 then
|
||||
begin
|
||||
Lowest := Double.MaxValue;
|
||||
Highest := Double.MinValue;
|
||||
Result.SL := Double.NaN;
|
||||
Result.Entry := Double.NaN;
|
||||
end;
|
||||
|
||||
Result.pnl := pnl;
|
||||
|
||||
lastHull := hull;
|
||||
lastSma := sma;
|
||||
end
|
||||
);
|
||||
|
||||
conv.Link(Signal);
|
||||
|
||||
var pnl := Signal.Field<Double>('pnl');
|
||||
|
||||
var equity: TConverter<Double, Double> := TEquitySum.Create(10000);
|
||||
pnl.Sender.Link(equity);
|
||||
|
||||
var Layout := CurrLayout<TVertScrollBox>;
|
||||
if Layout = nil then
|
||||
exit;
|
||||
|
||||
var Symbol := SelectedSymbol;
|
||||
if Symbol = '' then
|
||||
exit;
|
||||
|
||||
var chart := TMycChart.Create(Self);
|
||||
AlignControl(chart);
|
||||
chart.Height := Layout.ChildrenRect.Width * 9 / 16;
|
||||
chart.Lookback.Value := 50000;
|
||||
|
||||
chart.SetXAxisSeries(M15, OhlcPoint.Field<TDateTime>('Time').Sender);
|
||||
|
||||
panel := chart.AddPanel;
|
||||
panel.AddOhlcSeries(Ohlc.Sender);
|
||||
panel.AddDoubleSeries(Hull.Sender, TAlphaColors.Cornflowerblue, 2);
|
||||
panel.AddDoubleSeries(Sma.Sender, TAlphaColors.Brown, 1.5);
|
||||
panel.AddDoubleSeries(Signal.Field<Double>('Entry').Sender, TAlphaColors.Green, 1);
|
||||
panel.AddDoubleSeries(Signal.Field<Double>('SL').Sender, TAlphaColors.Red, 2);
|
||||
|
||||
var mean := TConverter<TArray<Double>, Double>.CreateGeneric(TIndicators.CreateMean());
|
||||
|
||||
TConverter.Join<Double>([Hull.Sender, Sma.Sender]).Link(mean);
|
||||
|
||||
panel.AddDoubleSeries(mean.Sender, 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);
|
||||
|
||||
////////////
|
||||
var EMAFactory := TEMA.Create;
|
||||
|
||||
var Params := TDataRecord.CreateFrom(EMAFactory.Params);
|
||||
Params.SetValue<Integer>('Period', 20);
|
||||
|
||||
var indi := EMAFActory.CreateIndicator(Params);
|
||||
|
||||
var EMAConv := TConverter<TDataRecord, TDataRecord>.CreateGeneric(indi);
|
||||
|
||||
var equityEMA :=
|
||||
equity
|
||||
.Chain<TDataRecord>(TConverter.FieldToRecord<Double>(EMAFactory.Input, 'Price'))
|
||||
.Chain<TDataRecord>(EMAConv)
|
||||
.Chain<Double>(TConverter.FieldOfRecord<Double>(EMAFactory.Output, 'MA'));
|
||||
|
||||
//////////////
|
||||
|
||||
panel := pnlChart.AddPanel;
|
||||
panel.AddDoubleSeries(equity.Sender, TAlphaColors.Blue, 3);
|
||||
panel.AddDoubleSeries(equityEMA.Sender, TAlphaColors.Gray, 2);
|
||||
|
||||
/////
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user