Testing TValue as Params
This commit is contained in:
@@ -6,6 +6,7 @@ uses
|
||||
System.SysUtils,
|
||||
System.Math,
|
||||
System.Rtti,
|
||||
Myc.Data.Records,
|
||||
Myc.Data.Pipeline,
|
||||
Myc.Data.Series,
|
||||
Myc.Trade.Types,
|
||||
@@ -147,9 +148,7 @@ type
|
||||
DPeriod: Integer;
|
||||
end;
|
||||
TArgs = record
|
||||
High: Double;
|
||||
Low: Double;
|
||||
Close: Double;
|
||||
Value: TOhlcItem;
|
||||
end;
|
||||
TResult = record
|
||||
K: Double; // %K line
|
||||
@@ -157,12 +156,12 @@ type
|
||||
end;
|
||||
[IndicatorFactory]
|
||||
class function CreateFactory: TIndicatorFactoryProc<TParams, TArgs, TResult>; static;
|
||||
|
||||
class function CreateStochastic(KPeriod, DPeriod: Integer): TConvertFunc<TArgs, TResult>; overload; static;
|
||||
class function CreateStochastic(KPeriod, DPeriod: Integer): TConvertFunc<TOhlcItem, TResult>; overload; static;
|
||||
// Creates a Stochastic Oscillator using an injectable moving average for the %D line.
|
||||
class function CreateStochastic(
|
||||
KPeriod: Integer;
|
||||
const SmaD: TConvertFunc<Double, Double>
|
||||
): TConvertFunc<TArgs, TStochastic.TResult>; overload; static;
|
||||
): TConvertFunc<TOhlcItem, TStochastic.TResult>; overload; static;
|
||||
end;
|
||||
|
||||
[IndicatorName('StdDev', 'Standard Deviation')]
|
||||
@@ -215,17 +214,15 @@ type
|
||||
Period: Integer;
|
||||
end;
|
||||
TArgs = record
|
||||
High: Double;
|
||||
Low: Double;
|
||||
Close: Double;
|
||||
Value: TOhlcItem;
|
||||
end;
|
||||
TResult = record
|
||||
ATR: Double;
|
||||
end;
|
||||
[IndicatorFactory]
|
||||
class function CreateFactory: TIndicatorFactoryProc<TParams, TArgs, TResult>; static;
|
||||
class function CreateATR(Period: Integer): TConvertFunc<TArgs, Double>; overload; static;
|
||||
class function CreateATR(const MovAvgTR: TConvertFunc<Double, Double>): TConvertFunc<TArgs, Double>; overload; static;
|
||||
class function CreateATR(Period: Integer): TConvertFunc<TOhlcItem, Double>; overload; static;
|
||||
class function CreateATR(const MovAvgTR: TConvertFunc<Double, Double>): TConvertFunc<TOhlcItem, Double>; overload; static;
|
||||
end;
|
||||
|
||||
[IndicatorName('KC', 'Keltner Channels')]
|
||||
@@ -238,9 +235,7 @@ type
|
||||
Multiplier: Double;
|
||||
end;
|
||||
TArgs = record
|
||||
High: Double;
|
||||
Low: Double;
|
||||
Close: Double;
|
||||
Value: TOhlcItem;
|
||||
end;
|
||||
TResult = record
|
||||
UpperBand: Double;
|
||||
@@ -249,12 +244,12 @@ type
|
||||
end;
|
||||
[IndicatorFactory]
|
||||
class function CreateFactory: TIndicatorFactoryProc<TParams, TArgs, TResult>; static;
|
||||
class function CreateKeltnerChannels(Period: Integer; Multiplier: Double): TConvertFunc<TArgs, TResult>; overload; static;
|
||||
class function CreateKeltnerChannels(Period: Integer; Multiplier: Double): TConvertFunc<TOhlcItem, TResult>; overload; static;
|
||||
class function CreateKeltnerChannels(
|
||||
const MovAvgMiddle: TConvertFunc<Double, Double>;
|
||||
const AtrFunc: TConvertFunc<TATR.TArgs, Double>;
|
||||
const AtrFunc: TConvertFunc<TOhlcItem, Double>;
|
||||
Multiplier: Double
|
||||
): TConvertFunc<TArgs, TKeltnerChannels.TResult>; overload; static;
|
||||
): TConvertFunc<TOhlcItem, TKeltnerChannels.TResult>; overload; static;
|
||||
end;
|
||||
|
||||
[IndicatorName('Mean', 'Mean Value')]
|
||||
@@ -713,22 +708,25 @@ begin
|
||||
Result :=
|
||||
function(const Params: TParams): TConvertFunc<TArgs, TResult>
|
||||
var
|
||||
stochFunc: TConvertFunc<TArgs, TResult>;
|
||||
stochFunc: TConvertFunc<TOhlcItem, TResult>;
|
||||
begin
|
||||
stochFunc := CreateStochastic(Params.KPeriod, Params.DPeriod);
|
||||
Result := function(const Value: TArgs): TResult begin Result := stochFunc(Value); end;
|
||||
Result := function(const Value: TArgs): TResult begin Result := stochFunc(Value.Value); end;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TStochastic.CreateStochastic(KPeriod, DPeriod: Integer): TConvertFunc<TArgs, TResult>;
|
||||
class function TStochastic.CreateStochastic(KPeriod, DPeriod: Integer): TConvertFunc<TOhlcItem, TStochastic.TResult>;
|
||||
begin
|
||||
Result := CreateStochastic(KPeriod, TSMA.CreateSMA(DPeriod));
|
||||
end;
|
||||
|
||||
// Creates a Stochastic Oscillator using an injectable moving average for the %D line.
|
||||
class function TStochastic.CreateStochastic(KPeriod: Integer; const SmaD: TConvertFunc<Double, Double>): TConvertFunc<TArgs, TResult>;
|
||||
class function TStochastic.CreateStochastic(
|
||||
KPeriod: Integer;
|
||||
const SmaD: TConvertFunc<Double, Double>
|
||||
): TConvertFunc<TOhlcItem, TStochastic.TResult>;
|
||||
var
|
||||
buffer: TArray<TArgs>;
|
||||
buffer: TArray<TOhlcItem>;
|
||||
highDeque: TLightDeque;
|
||||
lowDeque: TLightDeque;
|
||||
valueCount: Int64;
|
||||
@@ -736,7 +734,7 @@ begin
|
||||
if (KPeriod <= 0) then
|
||||
begin
|
||||
Result :=
|
||||
function(const Value: TArgs): TResult
|
||||
function(const Value: TOhlcItem): TResult
|
||||
begin
|
||||
Result.K := Double.NaN;
|
||||
Result.D := Double.NaN;
|
||||
@@ -750,7 +748,7 @@ begin
|
||||
valueCount := 0;
|
||||
|
||||
Result :=
|
||||
function(const Value: TArgs): TStochastic.TResult
|
||||
function(const Value: TOhlcItem): TStochastic.TResult
|
||||
var
|
||||
currentIndex, firstIndex, lastIndex: Integer;
|
||||
highestHigh, lowestLow: Double;
|
||||
@@ -928,25 +926,25 @@ begin
|
||||
Result :=
|
||||
function(const Params: TParams): TConvertFunc<TArgs, TResult>
|
||||
var
|
||||
atrFunc: TConvertFunc<TArgs, Double>;
|
||||
atrFunc: TConvertFunc<TOhlcItem, Double>;
|
||||
begin
|
||||
atrFunc := CreateATR(Params.Period);
|
||||
Result := function(const Value: TArgs): TResult begin Result.ATR := atrFunc(Value); end;
|
||||
Result := function(const Value: TArgs): TResult begin Result.ATR := atrFunc(Value.Value); end;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TATR.CreateATR(Period: Integer): TConvertFunc<TArgs, Double>;
|
||||
class function TATR.CreateATR(Period: Integer): TConvertFunc<TOhlcItem, Double>;
|
||||
begin
|
||||
Result := CreateATR(TEMA.CreateEMA(Period));
|
||||
end;
|
||||
|
||||
// Calculates the Average True Range (ATR) using an injectable moving average.
|
||||
class function TATR.CreateATR(const MovAvgTR: TConvertFunc<Double, Double>): TConvertFunc<TArgs, Double>;
|
||||
class function TATR.CreateATR(const MovAvgTR: TConvertFunc<Double, Double>): TConvertFunc<TOhlcItem, Double>;
|
||||
begin
|
||||
var sourceData: TSeries<TArgs>;
|
||||
var sourceData: TSeries<TOhlcItem>;
|
||||
|
||||
Result :=
|
||||
function(const Value: TArgs): Double
|
||||
function(const Value: TOhlcItem): Double
|
||||
var
|
||||
tr: Double;
|
||||
begin
|
||||
@@ -970,19 +968,20 @@ end;
|
||||
|
||||
{ TKeltnerChannels }
|
||||
|
||||
class function TKeltnerChannels.CreateFactory: TIndicatorFactoryProc<TParams, TArgs, TResult>;
|
||||
class function TKeltnerChannels.CreateFactory:
|
||||
TIndicatorFactoryProc<TKeltnerChannels.TParams, TKeltnerChannels.TArgs, TKeltnerChannels.TResult>;
|
||||
begin
|
||||
Result :=
|
||||
function(const Params: TParams): TConvertFunc<TArgs, TResult>
|
||||
var
|
||||
kcFunc: TConvertFunc<TArgs, TResult>;
|
||||
kcFunc: TConvertFunc<TOhlcItem, TResult>;
|
||||
begin
|
||||
kcFunc := CreateKeltnerChannels(Params.Period, Params.Multiplier);
|
||||
Result := function(const Value: TArgs): TResult begin Result := kcFunc(Value); end;
|
||||
Result := function(const Value: TArgs): TResult begin Result := kcFunc(Value.Value); end;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TKeltnerChannels.CreateKeltnerChannels(Period: Integer; Multiplier: Double): TConvertFunc<TArgs, TResult>;
|
||||
class function TKeltnerChannels.CreateKeltnerChannels(Period: Integer; Multiplier: Double): TConvertFunc<TOhlcItem, TResult>;
|
||||
begin
|
||||
Result := CreateKeltnerChannels(TEMA.CreateEMA(Period), TATR.CreateATR(Period), Multiplier);
|
||||
end;
|
||||
@@ -990,12 +989,12 @@ end;
|
||||
// Calculates Keltner Channels using an injectable ATR and middle band moving average.
|
||||
class function TKeltnerChannels.CreateKeltnerChannels(
|
||||
const MovAvgMiddle: TConvertFunc<Double, Double>;
|
||||
const AtrFunc: TConvertFunc<TATR.TArgs, Double>;
|
||||
const AtrFunc: TConvertFunc<TOhlcItem, Double>;
|
||||
Multiplier: Double
|
||||
): TConvertFunc<TArgs, TKeltnerChannels.TResult>;
|
||||
): TConvertFunc<TOhlcItem, TKeltnerChannels.TResult>;
|
||||
begin
|
||||
Result :=
|
||||
function(const Value: TArgs): TKeltnerChannels.TResult
|
||||
function(const Value: TOhlcItem): TKeltnerChannels.TResult
|
||||
var
|
||||
atrValue, middleValue, typicalPrice: Double;
|
||||
begin
|
||||
@@ -1004,12 +1003,7 @@ begin
|
||||
|
||||
// Get values from the provided indicator functions.
|
||||
middleValue := MovAvgMiddle(typicalPrice);
|
||||
|
||||
var atrArgs: TATR.TArgs;
|
||||
atrArgs.High := Value.High;
|
||||
atrArgs.Low := Value.Low;
|
||||
atrArgs.Close := Value.Close;
|
||||
atrValue := AtrFunc(atrArgs);
|
||||
atrValue := AtrFunc(Value);
|
||||
|
||||
// Set default NaN values for the warm-up period.
|
||||
Result.MiddleBand := middleValue;
|
||||
|
||||
Reference in New Issue
Block a user