Sample SMA strategy

This commit is contained in:
Michael Schimmel
2025-09-03 13:41:24 +02:00
parent 3e4ca283c9
commit 6b9dcee417
9 changed files with 505 additions and 179 deletions
+24 -4
View File
@@ -76,6 +76,7 @@ type
const Title, Details: string;
const InPin, OutPin: String;
IsExec: Boolean;
HasResult: Boolean;
const ChildVisitorProc: TChildVisitorProc
): TAuraNode;
function VisitOperatorNode(
@@ -181,7 +182,8 @@ implementation
uses
System.Math,
System.StrUtils;
System.StrUtils,
Myc.Data.Scalar;
type
// This visitor converts an AST expression subtree into a single string.
@@ -284,7 +286,7 @@ var
begin
sb := TStringBuilder.Create;
try
sb.Append('(');
sb.Append(#$03BB + '(');
if Length(Node.Parameters) > 0 then
begin
for i := 0 to High(Node.Parameters) do
@@ -677,6 +679,7 @@ begin
'',
'',
true,
false,
procedure(const Visitor: IAstVisitor)
var
expression: IExpressionNode;
@@ -715,6 +718,7 @@ function TAstToAuraNodeVisitor.VisitContainerNode(
const Title, Details: string;
const InPin, OutPin: String;
IsExec: Boolean;
HasResult: Boolean;
const ChildVisitorProc: TChildVisitorProc
): TAuraNode;
var
@@ -724,6 +728,7 @@ var
maxRight: Single;
maxBottom: Single;
control: TControl;
childLastResult: TAuraNodeResult;
begin
const pinNodeHeight = cPinSize + cVerticalPadding;
@@ -764,6 +769,9 @@ begin
childVisitor := TAstToAuraNodeVisitor.Create(FWorkspace, containerNode, childStartPos, FConnections, FCurrentExec.ToArray, FMode);
ChildVisitorProc(childVisitor);
// Capture the result from the child visitor.
childLastResult := (childVisitor as TAstToAuraNodeVisitor).FLastResult;
FCurrentExec.Clear;
FCurrentExec.AddRange((childVisitor as TAstToAuraNodeVisitor).FCurrentExec);
@@ -781,7 +789,7 @@ begin
// The width must be at least the title width, and large enough for children.
containerNode.Width := Max(containerNode.Width, maxRight + FSpacing.X);
containerNode.Height := Max(containerNode.Height, maxBottom + FSpacing.Y + IfThen(OutPin <> '', pinNodeHeight, 0));
containerNode.Height := Max(containerNode.Height, maxBottom + FSpacing.Y);
if OutPin <> '' then
begin
@@ -789,8 +797,19 @@ begin
exitNode.Parent := containerNode;
exitNode.Height := pinNodeHeight;
var exitPin := CreateEntry(exitNode);
// Create and connect a data pin if the container returns a value.
if HasResult and Assigned(childLastResult.OutputPin) then
begin
var dataResultPin := CreateInput(exitNode, 'Result');
FConnections.Add(TPinConnection.Create(childLastResult.OutputPin, dataResultPin));
end;
FinalizeNodeLayout(exitNode);
// Enlarge for the exit node
containerNode.Height := Max(containerNode.Height, maxBottom + FSpacing.Y + exitNode.Height);
exitNode.Position.Point := TPointF.Create(containerNode.Width - exitNode.Width, containerNode.Height - exitNode.Height);
if not IsExec then
@@ -1022,11 +1041,12 @@ begin
// Use the helper to create and populate the container node.
lambdaNode :=
VisitContainerNode(
'Lambda',
#$03BB,
paramStr,
'call',
'return',
false,
true,
procedure(const Visitor: IAstVisitor) begin Node.Body.Accept(Visitor); end
);