Sample SMA strategy
This commit is contained in:
+70
-33
@@ -21,7 +21,8 @@ type
|
||||
end;
|
||||
|
||||
// Added avkMemberSeries to represent a TScalarMemberSeries value.
|
||||
TAstValueKind = (avkUndefined, avkScalar, avkClosure, avkText, avkRecordSeries, avkRecord, avkMemberSeries);
|
||||
// Added avkSeries to represent a TScalarSeries value.
|
||||
TAstValueKind = (avkUndefined, avkScalar, avkClosure, avkText, avkSeries, avkRecordSeries, avkRecord, avkMemberSeries);
|
||||
|
||||
// --- Forward Declarations to break cycles ---
|
||||
IExecutionScope = interface;
|
||||
@@ -40,8 +41,10 @@ type
|
||||
IVariableDeclarationNode = interface;
|
||||
IAssignmentNode = interface;
|
||||
IIndexerNode = interface;
|
||||
// Added forward declaration for the new member access node.
|
||||
IMemberAccessNode = interface;
|
||||
ICreateSeriesNode = interface;
|
||||
IAddSeriesItemNode = interface;
|
||||
ISeriesLengthNode = interface;
|
||||
IEvaluatorClosure = interface;
|
||||
|
||||
// --- Concrete Type Definitions ---
|
||||
@@ -60,17 +63,8 @@ type
|
||||
TAstValue = record
|
||||
private
|
||||
type
|
||||
IVal<T> = interface
|
||||
['{7D5AD675-A008-4007-B1A4-CF7A05749510}'] // needed, do not remove
|
||||
function GetValue: T;
|
||||
property Value: T read GetValue;
|
||||
end;
|
||||
|
||||
TVal<T> = class(TInterfacedObject, IVal<T>)
|
||||
private
|
||||
FValue: T;
|
||||
function GetValue: T;
|
||||
public
|
||||
TVal<T> = class(TInterfacedObject)
|
||||
Value: T;
|
||||
constructor Create(const AValue: T);
|
||||
end;
|
||||
|
||||
@@ -86,15 +80,17 @@ type
|
||||
class function FromScalar(const AValue: TScalar): TAstValue; inline; static;
|
||||
class function FromClosure(const AValue: IEvaluatorClosure): TAstValue; inline; static;
|
||||
class function FromText(const AValue: String): TAstValue; inline; static;
|
||||
class function FromRecordSeries(const AValue: TScalarRecordSeries): TAstValue; inline; static;
|
||||
class function FromRecord(const AValue: TScalarRecord): TAstValue; inline; static;
|
||||
class function FromMemberSeries(const AValue: TScalarMemberSeries): TAstValue; inline; static;
|
||||
class function FromSeries(const [ref] AValue: TScalarSeries): TAstValue; static; inline;
|
||||
class function FromRecordSeries(const [ref] AValue: TScalarRecordSeries): TAstValue; static; inline;
|
||||
class function FromRecord(const [ref] AValue: TScalarRecord): TAstValue; static; inline;
|
||||
class function FromMemberSeries(const [ref] AValue: TScalarMemberSeries): TAstValue; static; inline;
|
||||
function AsScalar: TScalar; inline;
|
||||
function AsClosure: IEvaluatorClosure; inline;
|
||||
function AsText: String; inline;
|
||||
function AsRecordSeries: TScalarRecordSeries; inline;
|
||||
function AsRecordSeries: TVal<TScalarRecordSeries>; inline;
|
||||
function AsRecord: TScalarRecord; inline;
|
||||
function AsMemberSeries: TScalarMemberSeries; inline;
|
||||
function AsMemberSeries: TVal<TScalarMemberSeries>; inline;
|
||||
function AsSeries: TVal<TScalarSeries>; inline;
|
||||
function ToString: String;
|
||||
property IsVoid: Boolean read GetIsVoid;
|
||||
property Kind: TAstValueKind read GetKind;
|
||||
@@ -126,6 +122,9 @@ type
|
||||
function VisitAssignment(const Node: IAssignmentNode): TAstValue;
|
||||
function VisitIndexer(const Node: IIndexerNode): TAstValue;
|
||||
function VisitMemberAccess(const Node: IMemberAccessNode): TAstValue;
|
||||
function VisitCreateSeries(const Node: ICreateSeriesNode): TAstValue;
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TAstValue;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): TAstValue;
|
||||
end;
|
||||
|
||||
IAstNode = interface(IInterface)
|
||||
@@ -256,6 +255,33 @@ type
|
||||
property Member: IIdentifierNode read GetMember;
|
||||
end;
|
||||
|
||||
// Represents creating a new, empty series (e.g., new series(int)).
|
||||
ICreateSeriesNode = interface(IExpressionNode)
|
||||
{$region 'private'}
|
||||
function GetDefinition: String;
|
||||
{$endregion}
|
||||
property Definition: String read GetDefinition;
|
||||
end;
|
||||
|
||||
// Represents adding a value to a series (e.g., my_series.add(value, 100)).
|
||||
IAddSeriesItemNode = interface(IExpressionNode)
|
||||
{$region 'private'}
|
||||
function GetSeries: IIdentifierNode;
|
||||
function GetValue: IExpressionNode;
|
||||
function GetLookback: IExpressionNode;
|
||||
{$endregion}
|
||||
property Series: IIdentifierNode read GetSeries;
|
||||
property Value: IExpressionNode read GetValue;
|
||||
property Lookback: IExpressionNode read GetLookback;
|
||||
end;
|
||||
|
||||
ISeriesLengthNode = interface(IExpressionNode)
|
||||
{$region 'private'}
|
||||
function GetSeries: IIdentifierNode;
|
||||
{$endregion}
|
||||
property Series: IIdentifierNode read GetSeries;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@@ -266,12 +292,7 @@ uses
|
||||
constructor TAstValue.TVal<T>.Create(const AValue: T);
|
||||
begin
|
||||
inherited Create;
|
||||
FValue := AValue;
|
||||
end;
|
||||
|
||||
function TAstValue.TVal<T>.GetValue: T;
|
||||
begin
|
||||
Result := FValue;
|
||||
Value := AValue;
|
||||
end;
|
||||
|
||||
{ TAstValue }
|
||||
@@ -289,25 +310,25 @@ begin
|
||||
Result := IEvaluatorClosure(FInterface);
|
||||
end;
|
||||
|
||||
function TAstValue.AsMemberSeries: TScalarMemberSeries;
|
||||
function TAstValue.AsMemberSeries: TVal<TScalarMemberSeries>;
|
||||
begin
|
||||
if (FKind <> avkMemberSeries) then
|
||||
raise EInvalidCast.Create('Cannot read value as MemberSeries.');
|
||||
Result := (FInterface as IVal<TScalarMemberSeries>).Value;
|
||||
Result := TVal<TScalarMemberSeries>(FInterface);
|
||||
end;
|
||||
|
||||
function TAstValue.AsRecord: TScalarRecord;
|
||||
begin
|
||||
if (FKind <> avkRecord) then
|
||||
raise EInvalidCast.Create('Cannot read value as Record.');
|
||||
Result := (FInterface as IVal<TScalarRecord>).Value;
|
||||
Result := (FInterface as TVal<TScalarRecord>).Value;
|
||||
end;
|
||||
|
||||
function TAstValue.AsRecordSeries: TScalarRecordSeries;
|
||||
function TAstValue.AsRecordSeries: TVal<TScalarRecordSeries>;
|
||||
begin
|
||||
if (FKind <> avkRecordSeries) then
|
||||
raise EInvalidCast.Create('Cannot read value as RecordSeries.');
|
||||
Result := (FInterface as IVal<TScalarRecordSeries>).Value;
|
||||
Result := TVal<TScalarRecordSeries>(FInterface);
|
||||
end;
|
||||
|
||||
function TAstValue.AsScalar: TScalar;
|
||||
@@ -317,12 +338,20 @@ begin
|
||||
Result := FScalar;
|
||||
end;
|
||||
|
||||
// Added support for TScalarSeries
|
||||
function TAstValue.AsSeries: TVal<TScalarSeries>;
|
||||
begin
|
||||
if (FKind <> avkSeries) then
|
||||
raise EInvalidCast.Create('Cannot read value as Series.');
|
||||
Result := TVal<TScalarSeries>(FInterface);
|
||||
end;
|
||||
|
||||
function TAstValue.AsText: String;
|
||||
begin
|
||||
if (FKind <> avkText) then
|
||||
raise EInvalidCast.Create('Cannot read value as Text.');
|
||||
|
||||
Result := (FInterface as IVal<String>).Value;
|
||||
Result := (FInterface as TVal<String>).Value;
|
||||
end;
|
||||
|
||||
class function TAstValue.FromClosure(const AValue: IEvaluatorClosure): TAstValue;
|
||||
@@ -332,21 +361,21 @@ begin
|
||||
Result.FScalar := Default(TScalar);
|
||||
end;
|
||||
|
||||
class function TAstValue.FromMemberSeries(const AValue: TScalarMemberSeries): TAstValue;
|
||||
class function TAstValue.FromMemberSeries(const [ref] AValue: TScalarMemberSeries): TAstValue;
|
||||
begin
|
||||
Result.FKind := avkMemberSeries;
|
||||
Result.FInterface := TVal<TScalarMemberSeries>.Create(AValue);
|
||||
Result.FScalar := Default(TScalar);
|
||||
end;
|
||||
|
||||
class function TAstValue.FromRecord(const AValue: TScalarRecord): TAstValue;
|
||||
class function TAstValue.FromRecord(const [ref] AValue: TScalarRecord): TAstValue;
|
||||
begin
|
||||
Result.FKind := avkRecord;
|
||||
Result.FInterface := TVal<TScalarRecord>.Create(AValue);
|
||||
Result.FScalar := Default(TScalar);
|
||||
end;
|
||||
|
||||
class function TAstValue.FromRecordSeries(const AValue: TScalarRecordSeries): TAstValue;
|
||||
class function TAstValue.FromRecordSeries(const [ref] AValue: TScalarRecordSeries): TAstValue;
|
||||
begin
|
||||
Result.FKind := avkRecordSeries;
|
||||
Result.FInterface := TVal<TScalarRecordSeries>.Create(AValue);
|
||||
@@ -360,6 +389,13 @@ begin
|
||||
Result.FInterface := nil;
|
||||
end;
|
||||
|
||||
class function TAstValue.FromSeries(const [ref] AValue: TScalarSeries): TAstValue;
|
||||
begin
|
||||
Result.FKind := avkSeries;
|
||||
Result.FInterface := TVal<TScalarSeries>.Create(AValue);
|
||||
Result.FScalar := Default(TScalar);
|
||||
end;
|
||||
|
||||
class function TAstValue.FromText(const AValue: String): TAstValue;
|
||||
begin
|
||||
Result.FKind := avkText;
|
||||
@@ -383,6 +419,7 @@ begin
|
||||
avkScalar: Result := FScalar.ToString;
|
||||
avkClosure: Result := '<closure>';
|
||||
avkText: Result := AsText;
|
||||
avkSeries: Result := '<series>';
|
||||
avkRecordSeries: Result := '<record_series>';
|
||||
avkRecord: Result := '<record>';
|
||||
avkMemberSeries: Result := '<member_series>';
|
||||
|
||||
Reference in New Issue
Block a user