Unit refactoring
Fixed massive heap corruption bug in TDataRecord
This commit is contained in:
@@ -8,8 +8,9 @@ uses
|
||||
System.Generics.Collections,
|
||||
System.Rtti,
|
||||
Myc.Data.Records,
|
||||
Myc.Trade.Types,
|
||||
Myc.Data.Series;
|
||||
Myc.Data.Pipeline,
|
||||
Myc.Data.Series,
|
||||
Myc.Trade.Types;
|
||||
|
||||
type
|
||||
// Result for the Moving Average Convergence Divergence (MACD) indicator.
|
||||
@@ -46,48 +47,48 @@ type
|
||||
class function CalculateWMA(const Series: TSeries<Double>; const Period: Integer): Double; static;
|
||||
public
|
||||
// Simple Moving Average
|
||||
class function CreateSMA(Period: Integer): TConstFunc<Double, Double>; static;
|
||||
class function CreateSMA(Period: Integer): TConvertFunc<Double, Double>; static;
|
||||
// Exponential Moving Average
|
||||
class function CreateEMA(Period: Integer): TConstFunc<Double, Double>; static;
|
||||
class function CreateEMA(Period: Integer): TConvertFunc<Double, Double>; static;
|
||||
// Hull Moving Average
|
||||
class function CreateHMA(Period: Integer): TConstFunc<Double, Double>; static;
|
||||
class function CreateHMA(Period: Integer): TConvertFunc<Double, Double>; static;
|
||||
// Relative Strength Index
|
||||
class function CreateRSI(Period: Integer): TConstFunc<Double, Double>; static;
|
||||
class function CreateRSI(Period: Integer): TConvertFunc<Double, Double>; static;
|
||||
// Moving Average Convergence Divergence
|
||||
class function CreateMACD(FastPeriod, SlowPeriod, SignalPeriod: Integer): TConstFunc<Double, TMacdResult>; overload; static;
|
||||
class function CreateMACD(FastPeriod, SlowPeriod, SignalPeriod: Integer): TConvertFunc<Double, TMacdResult>; overload; static;
|
||||
class function CreateMACD(
|
||||
const EmaFast,
|
||||
EmaSlow,
|
||||
EmaSignal: TConstFunc<Double, Double>
|
||||
): TConstFunc<Double, TMacdResult>; overload; static;
|
||||
EmaSignal: TConvertFunc<Double, Double>
|
||||
): TConvertFunc<Double, TMacdResult>; overload; static;
|
||||
// Stochastic Oscillator
|
||||
class function CreateStochastic(KPeriod, DPeriod: Integer): TConstFunc<TOhlcItem, TStochasticResult>; overload; static;
|
||||
class function CreateStochastic(KPeriod, DPeriod: Integer): TConvertFunc<TOhlcItem, TStochasticResult>; overload; static;
|
||||
class function CreateStochastic(
|
||||
KPeriod: Integer;
|
||||
const SmaD: TConstFunc<Double, Double>
|
||||
): TConstFunc<TOhlcItem, TStochasticResult>; overload; static;
|
||||
const SmaD: TConvertFunc<Double, Double>
|
||||
): TConvertFunc<TOhlcItem, TStochasticResult>; overload; static;
|
||||
// Bollinger Bands
|
||||
class function CreateBollingerBands(Period: Integer; Multiplier: Double): TConstFunc<Double, TBollingerBandsResult>; static;
|
||||
class function CreateBollingerBands(Period: Integer; Multiplier: Double): TConvertFunc<Double, TBollingerBandsResult>; static;
|
||||
// Average True Range
|
||||
class function CreateATR(Period: Integer): TConstFunc<TOhlcItem, Double>; overload; static;
|
||||
class function CreateATR(const MovAvgTR: TConstFunc<Double, Double>): TConstFunc<TOhlcItem, 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;
|
||||
// Keltner Channels
|
||||
class function CreateKeltnerChannels(
|
||||
Period: Integer;
|
||||
Multiplier: Double
|
||||
): TConstFunc<TOhlcItem, TKeltnerChannelsResult>; overload; static;
|
||||
): TConvertFunc<TOhlcItem, TKeltnerChannelsResult>; overload; static;
|
||||
class function CreateKeltnerChannels(
|
||||
const MovAvgMiddle: TConstFunc<Double, Double>;
|
||||
const AtrFunc: TConstFunc<TOhlcItem, Double>;
|
||||
const MovAvgMiddle: TConvertFunc<Double, Double>;
|
||||
const AtrFunc: TConvertFunc<TOhlcItem, Double>;
|
||||
Multiplier: Double
|
||||
): TConstFunc<TOhlcItem, TKeltnerChannelsResult>; overload; static;
|
||||
): TConvertFunc<TOhlcItem, TKeltnerChannelsResult>; overload; static;
|
||||
|
||||
class function CreateMean: TConstFunc<TArray<Double>, Double>; static;
|
||||
class function CreateMean: TConvertFunc<TArray<Double>, Double>; static;
|
||||
end;
|
||||
|
||||
TIndicatorFactory = class
|
||||
type
|
||||
TFunc = TConstFunc<TDataRecord, TDataRecord>;
|
||||
TFunc = TConvertFunc<TDataRecord, TDataRecord>;
|
||||
private
|
||||
FParams: TDataRecord.TLayout;
|
||||
FInput: TDataRecord.TLayout;
|
||||
@@ -125,9 +126,9 @@ type
|
||||
TMACD = class
|
||||
type
|
||||
TParam = record
|
||||
Fast: TConstFunc<Double, Double>;
|
||||
Slow: TConstFunc<Double, Double>;
|
||||
Signal: TConstFunc<Double, Double>;
|
||||
Fast: TConvertFunc<Double, Double>;
|
||||
Slow: TConvertFunc<Double, Double>;
|
||||
Signal: TConvertFunc<Double, Double>;
|
||||
end;
|
||||
|
||||
TInput = record
|
||||
@@ -141,7 +142,7 @@ type
|
||||
end;
|
||||
|
||||
public
|
||||
class function CreateMACD(const Param: TParam): TConstFunc<TInput, TResult>; static;
|
||||
class function CreateMACD(const Param: TParam): TConvertFunc<TInput, TResult>; static;
|
||||
end;
|
||||
|
||||
var
|
||||
@@ -208,7 +209,7 @@ begin
|
||||
Result := numerator / denominator;
|
||||
end;
|
||||
|
||||
class function TIndicators.CreateBollingerBands(Period: Integer; Multiplier: Double): TConstFunc<Double, TBollingerBandsResult>;
|
||||
class function TIndicators.CreateBollingerBands(Period: Integer; Multiplier: Double): TConvertFunc<Double, TBollingerBandsResult>;
|
||||
begin
|
||||
var sourceData: TSeries<Double>;
|
||||
Result :=
|
||||
@@ -231,7 +232,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TIndicators.CreateEMA(Period: Integer): TConstFunc<Double, Double>;
|
||||
class function TIndicators.CreateEMA(Period: Integer): TConvertFunc<Double, Double>;
|
||||
begin
|
||||
var lastEma: Double := Double.NaN;
|
||||
var sourceData: TSeries<Double>;
|
||||
@@ -262,7 +263,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TIndicators.CreateHMA(Period: Integer): TConstFunc<Double, Double>;
|
||||
class function TIndicators.CreateHMA(Period: Integer): TConvertFunc<Double, Double>;
|
||||
begin
|
||||
var periodHalf := Period div 2;
|
||||
var periodSqrt := Round(Sqrt(Period));
|
||||
@@ -305,13 +306,13 @@ begin
|
||||
end;
|
||||
|
||||
// Standard MACD using EMAs.
|
||||
class function TIndicators.CreateMACD(FastPeriod, SlowPeriod, SignalPeriod: Integer): TConstFunc<Double, TMacdResult>;
|
||||
class function TIndicators.CreateMACD(FastPeriod, SlowPeriod, SignalPeriod: Integer): TConvertFunc<Double, TMacdResult>;
|
||||
begin
|
||||
Result := CreateMACD(CreateEMA(FastPeriod), CreateEMA(SlowPeriod), CreateEMA(SignalPeriod));
|
||||
end;
|
||||
|
||||
// Creates a MACD indicator from three provided moving average functions.
|
||||
class function TIndicators.CreateMACD(const EmaFast, EmaSlow, EmaSignal: TConstFunc<Double, Double>): TConstFunc<Double, TMacdResult>;
|
||||
class function TIndicators.CreateMACD(const EmaFast, EmaSlow, EmaSignal: TConvertFunc<Double, Double>): TConvertFunc<Double, TMacdResult>;
|
||||
begin
|
||||
Result :=
|
||||
function(const Value: Double): TMacdResult
|
||||
@@ -339,7 +340,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TIndicators.CreateRSI(Period: Integer): TConstFunc<Double, Double>;
|
||||
class function TIndicators.CreateRSI(Period: Integer): TConvertFunc<Double, Double>;
|
||||
begin
|
||||
var avgGain: Double := Double.NaN;
|
||||
var avgLoss: Double := Double.NaN;
|
||||
@@ -398,7 +399,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TIndicators.CreateSMA(Period: Integer): TConstFunc<Double, Double>;
|
||||
class function TIndicators.CreateSMA(Period: Integer): TConvertFunc<Double, Double>;
|
||||
begin
|
||||
var sourceData: TSeries<Double>;
|
||||
Result :=
|
||||
@@ -413,7 +414,7 @@ begin
|
||||
end;
|
||||
|
||||
// Standard Stochastic Oscillator using an SMA for the %D line.
|
||||
class function TIndicators.CreateStochastic(KPeriod, DPeriod: Integer): TConstFunc<TOhlcItem, TStochasticResult>;
|
||||
class function TIndicators.CreateStochastic(KPeriod, DPeriod: Integer): TConvertFunc<TOhlcItem, TStochasticResult>;
|
||||
begin
|
||||
Result := CreateStochastic(KPeriod, CreateSMA(DPeriod));
|
||||
end;
|
||||
@@ -421,8 +422,8 @@ end;
|
||||
// Creates a Stochastic Oscillator using an injectable moving average for the %D line.
|
||||
class function TIndicators.CreateStochastic(
|
||||
KPeriod: Integer;
|
||||
const SmaD: TConstFunc<Double, Double>
|
||||
): TConstFunc<TOhlcItem, TStochasticResult>;
|
||||
const SmaD: TConvertFunc<Double, Double>
|
||||
): TConvertFunc<TOhlcItem, TStochasticResult>;
|
||||
begin
|
||||
var sourceData: TSeries<TOhlcItem>;
|
||||
|
||||
@@ -461,13 +462,13 @@ begin
|
||||
end;
|
||||
|
||||
// Standard ATR using an EMA for smoothing.
|
||||
class function TIndicators.CreateATR(Period: Integer): TConstFunc<TOhlcItem, Double>;
|
||||
class function TIndicators.CreateATR(Period: Integer): TConvertFunc<TOhlcItem, Double>;
|
||||
begin
|
||||
Result := CreateATR(CreateEMA(Period));
|
||||
end;
|
||||
|
||||
// Calculates the Average True Range (ATR) using an injectable moving average.
|
||||
class function TIndicators.CreateATR(const MovAvgTR: TConstFunc<Double, Double>): TConstFunc<TOhlcItem, Double>;
|
||||
class function TIndicators.CreateATR(const MovAvgTR: TConvertFunc<Double, Double>): TConvertFunc<TOhlcItem, Double>;
|
||||
begin
|
||||
var sourceData: TSeries<TOhlcItem>;
|
||||
|
||||
@@ -495,17 +496,17 @@ begin
|
||||
end;
|
||||
|
||||
// Standard Keltner Channels using an EMA for the middle line and an EMA-based ATR.
|
||||
class function TIndicators.CreateKeltnerChannels(Period: Integer; Multiplier: Double): TConstFunc<TOhlcItem, TKeltnerChannelsResult>;
|
||||
class function TIndicators.CreateKeltnerChannels(Period: Integer; Multiplier: Double): TConvertFunc<TOhlcItem, TKeltnerChannelsResult>;
|
||||
begin
|
||||
Result := CreateKeltnerChannels(CreateEMA(Period), CreateATR(Period), Multiplier);
|
||||
end;
|
||||
|
||||
// Calculates Keltner Channels using an injectable ATR and middle band moving average.
|
||||
class function TIndicators.CreateKeltnerChannels(
|
||||
const MovAvgMiddle: TConstFunc<Double, Double>;
|
||||
const AtrFunc: TConstFunc<TOhlcItem, Double>;
|
||||
const MovAvgMiddle: TConvertFunc<Double, Double>;
|
||||
const AtrFunc: TConvertFunc<TOhlcItem, Double>;
|
||||
Multiplier: Double
|
||||
): TConstFunc<TOhlcItem, TKeltnerChannelsResult>;
|
||||
): TConvertFunc<TOhlcItem, TKeltnerChannelsResult>;
|
||||
begin
|
||||
Result :=
|
||||
function(const Value: TOhlcItem): TKeltnerChannelsResult
|
||||
@@ -533,7 +534,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TIndicators.CreateMean: TConstFunc<TArray<Double>, Double>;
|
||||
class function TIndicators.CreateMean: TConvertFunc<TArray<Double>, Double>;
|
||||
begin
|
||||
Result :=
|
||||
function(const Value: TArray<Double>): Double
|
||||
@@ -548,7 +549,7 @@ begin
|
||||
end;
|
||||
|
||||
// Creates a MACD indicator from three provided moving average functions.
|
||||
class function TMACD.CreateMACD(const Param: TParam): TConstFunc<TInput, TResult>;
|
||||
class function TMACD.CreateMACD(const Param: TParam): TConvertFunc<TInput, TResult>;
|
||||
begin
|
||||
Result :=
|
||||
function(const Input: TInput): TResult
|
||||
|
||||
Reference in New Issue
Block a user