Ast Refactoring
This commit is contained in:
+45
-33
@@ -21,7 +21,6 @@ uses
|
||||
FMX.ScrollBox,
|
||||
FMX.Memo,
|
||||
FMX.Controls.Presentation,
|
||||
DraggablePanel,
|
||||
Myc.Ast.Visualizer,
|
||||
Myc.Data.Scalar,
|
||||
Myc.Ast.Nodes,
|
||||
@@ -691,51 +690,55 @@ begin
|
||||
recordDef := TRttiAstHelper.JsonToRecordDefinition(TRttiAstHelper.RecordDefinitionToJson(TypeInfo(TOHLCV)));
|
||||
series := TScalarRecordSeries.Create(recordDef);
|
||||
|
||||
// 2. Create the setup AST with O(1) SMA implementation
|
||||
// 2. Create the setup AST with the optimized O(1) SMA implementation
|
||||
setupAst :=
|
||||
TAst.Block(
|
||||
[
|
||||
// This factory is now much simpler. It only manages sum and a counter.
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('CreateSMA_O1'),
|
||||
TAst.Identifier('CreateSMA'),
|
||||
TAst.LambdaExpr(
|
||||
[TAst.Identifier('len')],
|
||||
TAst.Block(
|
||||
[
|
||||
TAst.VarDecl(TAst.Identifier('sum'), TAst.Constant(TScalar.FromDouble(0.0))),
|
||||
TAst.VarDecl(TAst.Identifier('values'), TAst.CreateSeries('double')),
|
||||
TAst.VarDecl(TAst.Identifier('count'), TAst.Constant(TScalar.FromInt64(0))),
|
||||
// The returned closure now takes the full series and the new value.
|
||||
TAst.LambdaExpr(
|
||||
[TAst.Identifier('val')],
|
||||
[TAst.Identifier('series'), TAst.Identifier('val')],
|
||||
TAst.Block(
|
||||
[
|
||||
TAst.Assign(
|
||||
TAst.Identifier('sum'),
|
||||
TAst.BinaryExpr(TAst.Identifier('sum'), boAdd, TAst.Identifier('val'))
|
||||
),
|
||||
TAst.Assign(
|
||||
TAst.Identifier('count'),
|
||||
TAst.BinaryExpr(TAst.Identifier('count'), boAdd, TAst.Constant(TScalar.FromInt64(1)))
|
||||
),
|
||||
// If the indicator is "full", subtract the value that just fell out of the window (at index 'len').
|
||||
TAst.IfExpr(
|
||||
TAst.BinaryExpr(
|
||||
TAst.SeriesLength(TAst.Identifier('values')),
|
||||
boGreaterOrEqual,
|
||||
TAst.Identifier('len')
|
||||
),
|
||||
TAst.BinaryExpr(TAst.Identifier('count'), boGreater, TAst.Identifier('len')),
|
||||
TAst.Assign(
|
||||
TAst.Identifier('sum'),
|
||||
TAst.BinaryExpr(
|
||||
TAst.Identifier('sum'),
|
||||
boSubtract,
|
||||
TAst.Indexer(
|
||||
TAst.Identifier('values'),
|
||||
TAst.BinaryExpr(
|
||||
TAst.Identifier('len'),
|
||||
boSubtract,
|
||||
TAst.Constant(TScalar.FromInt64(1))
|
||||
)
|
||||
)
|
||||
TAst.Indexer(TAst.Identifier('series'), TAst.Identifier('len'))
|
||||
)
|
||||
),
|
||||
nil
|
||||
),
|
||||
TAst.Assign(
|
||||
// Calculate and return the average. Divisor is capped at 'len'.
|
||||
TAst.BinaryExpr(
|
||||
TAst.Identifier('sum'),
|
||||
TAst.BinaryExpr(TAst.Identifier('sum'), boAdd, TAst.Identifier('val'))
|
||||
),
|
||||
TAst.AddSeriesItem(TAst.Identifier('values'), TAst.Identifier('val'), TAst.Identifier('len')),
|
||||
TAst.BinaryExpr(TAst.Identifier('sum'), boDivide, TAst.SeriesLength(TAst.Identifier('values')))
|
||||
boDivide,
|
||||
TAst.TernaryExpr(
|
||||
TAst.BinaryExpr(TAst.Identifier('count'), boLess, TAst.Identifier('len')),
|
||||
TAst.Identifier('count'),
|
||||
TAst.Identifier('len')
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
@@ -743,34 +746,43 @@ begin
|
||||
)
|
||||
)
|
||||
),
|
||||
// Instantiation remains the same.
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('smaFast'),
|
||||
TAst.FunctionCall(TAst.Identifier('CreateSMA_O1'), [TAst.Constant(TScalar.FromInt64(smaFastLength))])
|
||||
TAst.FunctionCall(TAst.Identifier('CreateSMA'), [TAst.Constant(TScalar.FromInt64(smaFastLength))])
|
||||
),
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('smaSlow'),
|
||||
TAst.FunctionCall(TAst.Identifier('CreateSMA_O1'), [TAst.Constant(TScalar.FromInt64(smaSlowLength))])
|
||||
TAst.FunctionCall(TAst.Identifier('CreateSMA'), [TAst.Constant(TScalar.FromInt64(smaSlowLength))])
|
||||
),
|
||||
// The main strategy now passes the full close series to the indicators.
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('maCrossStrategy'),
|
||||
TAst.LambdaExpr(
|
||||
[TAst.Identifier('ohlcv')],
|
||||
TAst.Block(
|
||||
[
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('closeSeries'),
|
||||
TAst.MemberAccess(TAst.Identifier('ohlcv'), TAst.Identifier('Close'))
|
||||
),
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('currentClose'),
|
||||
TAst.MemberAccess(
|
||||
TAst.Indexer(TAst.Identifier('ohlcv'), TAst.Constant(TScalar.FromInt64(0))),
|
||||
TAst.Identifier('Close')
|
||||
)
|
||||
TAst.Indexer(TAst.Identifier('closeSeries'), TAst.Constant(TScalar.FromInt64(0)))
|
||||
),
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('valSmaFast'),
|
||||
TAst.FunctionCall(TAst.Identifier('smaFast'), [TAst.Identifier('currentClose')])
|
||||
TAst.FunctionCall(
|
||||
TAst.Identifier('smaFast'),
|
||||
[TAst.Identifier('closeSeries'), TAst.Identifier('currentClose')]
|
||||
)
|
||||
),
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('valSmaSlow'),
|
||||
TAst.FunctionCall(TAst.Identifier('smaSlow'), [TAst.Identifier('currentClose')])
|
||||
TAst.FunctionCall(
|
||||
TAst.Identifier('smaSlow'),
|
||||
[TAst.Identifier('closeSeries'), TAst.Identifier('currentClose')]
|
||||
)
|
||||
),
|
||||
TAst.TernaryExpr(
|
||||
TAst.BinaryExpr(TAst.Identifier('valSmaFast'), boGreater, TAst.Identifier('valSmaSlow')),
|
||||
@@ -827,8 +839,8 @@ begin
|
||||
FGScope.SetValue('current_series', TAstValue.FromRecordSeries(series));
|
||||
resultValue := callAst.Accept(visitor);
|
||||
|
||||
// Memo1.Lines.Add(Format('Tick %d/%d: Close = %.2f, Signal = %s', [i, numRecs, ohlcvRec.Close, resultValue.ToString]));
|
||||
// Application.ProcessMessages;
|
||||
Memo1.Lines.Add(Format('Tick %d/%d: Close = %.2f, Signal = %s', [i, numRecs, ohlcvRec.Close, resultValue.ToString]));
|
||||
Application.ProcessMessages;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user