diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json
index feff693..771498a 100644
--- a/ASTPlayground/ASTPlayground.delphilsp.json
+++ b/ASTPlayground/ASTPlayground.delphilsp.json
@@ -1 +1 @@
-{ "settings": { "project": "file:///T%3A/Myc/ASTPlayground/ASTPlayground.dpr", "dllname": "dcc64370.dll", "dccOptions": "-$O- -$W+ --inline:off -$R+ -$Q+ --no-config -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG;;FRAMEWORK_FMX -E.\\Win64\\Debug -I\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -LEC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Bpl\\Win64 -LNC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NU.\\Win64\\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -OT:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -R\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -U\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -V -VN -VR -NBC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NHC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\hpp\\Win64 -NO.\\Win64\\Debug -LU" , "projectFiles":[ { "name": "MainForm", "file": "file:///T%3A/Myc/ASTPlayground/MainForm.pas" }, { "name": "Myc.Ast.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Nodes.pas" }, { "name": "Myc.Ast.Scope", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Scope.pas" }, { "name": "Myc.Data.Value", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Data.Value.pas" }, { "name": "Myc.Ast.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Compiler.TCO", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TCO.pas" }, { "name": "Myc.Ast.Compiler.Binder", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Binder.pas" }, { "name": "Myc.Ast.Compiler.Lowering", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Lowering.pas" }, { "name": "Myc.Ast.Compiler.TypeChecker", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TypeChecker.pas" }, { "name": "Myc.Ast.Compiler.Macros", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Macros.pas" }, { "name": "Myc.Ast.Compiler.Specializer", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Specializer.pas" }, { "name": "Myc.Ast.Environment", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Environment.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Analysis.Purity", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Analysis.Purity.pas" }, { "name": "Myc.Ast.Identities", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Identities.pas" }, { "name": "Myc.Fmx.AstEditor.Visualizer", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Layout", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Layout.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Ast.Refactoring.Remove", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Refactoring.Remove.pas" }, { "name": "Myc.Fmx.AstEditor.Render", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Render.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Lists", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Lists.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Primitives", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Primitives.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Control", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Data", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Data.pas" }, { "name": "Myc.Ast.RTL.TypeRegistry", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.TypeRegistry.pas" }, { "name": "Myc.Trade.Broker", "file": "file:///T%3A/Myc/Src/Myc.Trade.Broker.pas" }, { "name": "Myc.Data.Stream.Pipes", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.Pipes.pas" }, { "name": "Myc.Data.Stream", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Pipes", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Pipes.pas" }, { "name": "Demo.Finance", "file": "file:///T%3A/Myc/Test/Demo.Finance.pas" }, { "name": "Myc.Ast.Script.Print", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.Print.pas" }, { "name": "Myc.Ast.Json.Schema.Old", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.Old.pas" }, { "name": "Myc.Ast.Attributes", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Ast.Attributes.pas" }, { "name": "Myc.Ast.Json.Schema", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.pas" }, { "name": "Myc.Ast.RTL.Math", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Math.pas" }, { "name": "Myc.Ast.RTL.DateTime", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.DateTime.pas" }, { "name": "Myc.Ast.RTL.Series", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Series.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": false, "browsingPaths": [ "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/OCX/Servers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/VCL","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/RTL/SYS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win/winrt","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/ToolsAPI","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/IBX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Internet","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/PROPERTY%20EDITORS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/XML","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Core","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/System","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Protocols","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/fmx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/components","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/engine","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/graph","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ado","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/cloud","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dbx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dsnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/vclctrls","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/connectors","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/proxygen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DataExplorer","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/src","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/tests","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Experts","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/abstraction","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/implementation","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indyimpl","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Property%20Editors/Indy10","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap/wsdlimporter","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Visualizers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XMLReporting","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XPGen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/rest","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/firedac","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/tethering","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnitX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ems","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/net","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/FlatBox2D","file:///C%3A/Users/Public/Documents/Embarcadero/Studio/37.0/Dcp/%25PLATFORM%25","file:///%25TP%25/runtime/vcl","file:///S%3A/sc_famos_src/svn_vcl/cpxedits","file:///S%3A/sc_famos_src/svn_vcl/dzChart","file:///S%3A/sc_famos_src/svn_vcl/eaeditor","file:///S%3A/sc_famos_src/svn_vcl/FamosEvents","file:///S%3A/sc_famos_src/svn_vcl/HTML_Viewer/source","file:///S%3A/sc_famos_src/svn_vcl/Myc_ChartEdit","file:///S%3A/sc_famos_src/svn_vcl/Myc_HemiDrag","file:///S%3A/sc_famos_src/svn_vcl/Myc_SplitControl","file:///S%3A/sc_famos_src/svn_vcl/NiceChart","file:///S%3A/sc_famos_src/svn_vcl/plotter","file:///S%3A/sc_famos_src/svn_vcl/SimpleIPC","file:///S%3A/sc_famos_src/svn_vcl/SynEdit-master/Source","file:///S%3A/sc_famos_src/svn_vcl/ValEdits","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib/win32","file:///S%3A/sc_famos_src/svn_vcl/Virtual-TreeView/Source","file:///S%3A/sc_famos_src/svn_common/caHelpSys","file:///S%3A/sc_famos_src/svn_common/Misc","file:///S%3A/sc_famos_src/svn_common/Myc_VecMath","file:///S%3A/sc_famos_src/svn_common/PascalScript/source","file:///S%3A/sc_famos_src/svn_common/TreeBase","file:///S%3A/sc_famos_src/svn_common/TreeBase/Medien","file:///S%3A/3rdParty/spring4d/Source","file:///S%3A/3rdParty/spring4d/Source/Base","file:///S%3A/3rdParty/spring4d/Source/Base/Collections","file:///S%3A/3rdParty/spring4d/Source/Base/Logging","file:///S%3A/3rdParty/spring4d/Source/Base/Patches","file:///S%3A/3rdParty/spring4d/Source/Core/Container","file:///S%3A/3rdParty/spring4d/Source/Core/Interception","file:///S%3A/3rdParty/spring4d/Source/Core/Logging","file:///S%3A/3rdParty/spring4d/Source/Core/Mocking","file:///S%3A/3rdParty/spring4d/Source/Core/Services","file:///S%3A/3rdParty/spring4d/Source/Extensions/Cryptography","file:///S%3A/3rdParty/spring4d/Source/Extensions/Utils","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCommon%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressGDI%2B%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLibrary/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/XP%20Theme%20Manager/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLayout%20Control/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressPageControl/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressEditors%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDocking%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressBars/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressOfficeCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressMemData/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDataController/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressNavBar/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressSkins%20Library/Sources","file:///T%3A/Myc/Src","file:///T%3A/Myc/Src/Data","file:///T%3A/Myc/Src/AST" ] , "CommonAppData": "file:///C%3A/Users/Brummel/AppData/Roaming/Embarcadero/BDS/37.0/" , "Templates": "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/ObjRepos/" } }
\ No newline at end of file
+{ "settings": { "project": "file:///T%3A/Myc/ASTPlayground/ASTPlayground.dpr", "dllname": "dcc64370.dll", "dccOptions": "-$O- -$W+ --inline:off -$R+ -$Q+ --no-config -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG;;FRAMEWORK_FMX -E.\\Win64\\Debug -I\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -LEC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Bpl\\Win64 -LNC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NU.\\Win64\\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -OT:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -R\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -U\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -V -VN -VR -NBC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NHC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\hpp\\Win64 -NO.\\Win64\\Debug -LU" , "projectFiles":[ { "name": "MainForm", "file": "file:///T%3A/Myc/ASTPlayground/MainForm.pas" }, { "name": "Myc.Ast.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Nodes.pas" }, { "name": "Myc.Ast.Scope", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Scope.pas" }, { "name": "Myc.Data.Value", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Data.Value.pas" }, { "name": "Myc.Ast.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Compiler.TCO", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TCO.pas" }, { "name": "Myc.Ast.Compiler.Binder", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Binder.pas" }, { "name": "Myc.Ast.Compiler.Lowering", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Lowering.pas" }, { "name": "Myc.Ast.Compiler.TypeChecker", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TypeChecker.pas" }, { "name": "Myc.Ast.Compiler.Macros", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Macros.pas" }, { "name": "Myc.Ast.Compiler.Specializer", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Specializer.pas" }, { "name": "Myc.Ast.Environment", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Environment.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Analysis.Purity", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Analysis.Purity.pas" }, { "name": "Myc.Ast.Identities", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Identities.pas" }, { "name": "Myc.Fmx.AstEditor.Visualizer", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Layout", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Layout.pas" }, { "name": "Myc.Fmx.AstEditor.Node", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Node.pas" }, { "name": "Myc.Ast.Refactoring.Remove", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Refactoring.Remove.pas" }, { "name": "Myc.Fmx.AstEditor.Render", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Render.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Lists", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Lists.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Primitives", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Primitives.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Control", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Control.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Data", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Data.pas" }, { "name": "Myc.Ast.RTL.TypeRegistry", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.TypeRegistry.pas" }, { "name": "Myc.Trade.Broker", "file": "file:///T%3A/Myc/Src/Myc.Trade.Broker.pas" }, { "name": "Myc.Data.Stream.Pipes", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.Pipes.pas" }, { "name": "Myc.Data.Stream", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Stream.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers.Pipes", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.Pipes.pas" }, { "name": "Demo.Finance", "file": "file:///T%3A/Myc/Test/Demo.Finance.pas" }, { "name": "Myc.Ast.Script.Print", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.Print.pas" }, { "name": "Myc.Ast.Json.Schema.Old", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.Old.pas" }, { "name": "Myc.Ast.Attributes", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Ast.Attributes.pas" }, { "name": "Myc.Ast.Json.Schema", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Json.Schema.pas" }, { "name": "Myc.Ast.RTL.Math", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Math.pas" }, { "name": "Myc.Ast.RTL.DateTime", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.DateTime.pas" }, { "name": "Myc.Ast.RTL.Series", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Series.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": true, "browsingPaths": [ "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/OCX/Servers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/VCL","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/RTL/SYS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win/winrt","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/ToolsAPI","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/IBX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Internet","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/PROPERTY%20EDITORS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/XML","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Core","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/System","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Protocols","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/fmx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/components","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/engine","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/graph","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ado","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/cloud","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dbx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dsnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/vclctrls","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/connectors","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/proxygen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DataExplorer","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/src","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/tests","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Experts","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/abstraction","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/implementation","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indyimpl","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Property%20Editors/Indy10","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap/wsdlimporter","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Visualizers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XMLReporting","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XPGen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/rest","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/firedac","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/tethering","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnitX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ems","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/net","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/FlatBox2D","file:///C%3A/Users/Public/Documents/Embarcadero/Studio/37.0/Dcp/%25PLATFORM%25","file:///%25TP%25/runtime/vcl","file:///S%3A/sc_famos_src/svn_vcl/cpxedits","file:///S%3A/sc_famos_src/svn_vcl/dzChart","file:///S%3A/sc_famos_src/svn_vcl/eaeditor","file:///S%3A/sc_famos_src/svn_vcl/FamosEvents","file:///S%3A/sc_famos_src/svn_vcl/HTML_Viewer/source","file:///S%3A/sc_famos_src/svn_vcl/Myc_ChartEdit","file:///S%3A/sc_famos_src/svn_vcl/Myc_HemiDrag","file:///S%3A/sc_famos_src/svn_vcl/Myc_SplitControl","file:///S%3A/sc_famos_src/svn_vcl/NiceChart","file:///S%3A/sc_famos_src/svn_vcl/plotter","file:///S%3A/sc_famos_src/svn_vcl/SimpleIPC","file:///S%3A/sc_famos_src/svn_vcl/SynEdit-master/Source","file:///S%3A/sc_famos_src/svn_vcl/ValEdits","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib/win32","file:///S%3A/sc_famos_src/svn_vcl/Virtual-TreeView/Source","file:///S%3A/sc_famos_src/svn_common/caHelpSys","file:///S%3A/sc_famos_src/svn_common/Misc","file:///S%3A/sc_famos_src/svn_common/Myc_VecMath","file:///S%3A/sc_famos_src/svn_common/PascalScript/source","file:///S%3A/sc_famos_src/svn_common/TreeBase","file:///S%3A/sc_famos_src/svn_common/TreeBase/Medien","file:///S%3A/3rdParty/spring4d/Source","file:///S%3A/3rdParty/spring4d/Source/Base","file:///S%3A/3rdParty/spring4d/Source/Base/Collections","file:///S%3A/3rdParty/spring4d/Source/Base/Logging","file:///S%3A/3rdParty/spring4d/Source/Base/Patches","file:///S%3A/3rdParty/spring4d/Source/Core/Container","file:///S%3A/3rdParty/spring4d/Source/Core/Interception","file:///S%3A/3rdParty/spring4d/Source/Core/Logging","file:///S%3A/3rdParty/spring4d/Source/Core/Mocking","file:///S%3A/3rdParty/spring4d/Source/Core/Services","file:///S%3A/3rdParty/spring4d/Source/Extensions/Cryptography","file:///S%3A/3rdParty/spring4d/Source/Extensions/Utils","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCommon%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressGDI%2B%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLibrary/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/XP%20Theme%20Manager/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLayout%20Control/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressPageControl/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressEditors%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDocking%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressBars/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressOfficeCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressMemData/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDataController/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressNavBar/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressSkins%20Library/Sources","file:///T%3A/Myc/Src","file:///T%3A/Myc/Src/Data","file:///T%3A/Myc/Src/AST" ] , "CommonAppData": "file:///C%3A/Users/Brummel/AppData/Roaming/Embarcadero/BDS/37.0/" , "Templates": "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/ObjRepos/" } }
\ No newline at end of file
diff --git a/AuraTrader/AuraTrader.dpr b/AuraTrader/AuraTrader.dpr
index 479440b..0c6aa76 100644
--- a/AuraTrader/AuraTrader.dpr
+++ b/AuraTrader/AuraTrader.dpr
@@ -9,8 +9,7 @@ uses
DynamicFMXControl in 'DynamicFMXControl.pas',
Myc.Trade.Pipeline.Impl in '..\Src\Myc.Trade.Pipeline.Impl.pas',
Myc.Trade.Indicators_v2 in '..\Src\Myc.Trade.Indicators_v2.pas',
- Strategy2 in 'Strategy2.pas',
- Myc.Trade.DataFeed in '..\Src\Myc.Trade.DataFeed.pas';
+ Strategy2 in 'Strategy2.pas';
{$R *.res}
diff --git a/AuraTrader/AuraTrader.dproj b/AuraTrader/AuraTrader.dproj
index 08ef546..96c3b37 100644
--- a/AuraTrader/AuraTrader.dproj
+++ b/AuraTrader/AuraTrader.dproj
@@ -4,7 +4,7 @@
20.3
FMX
True
- Debug
+ Release
Win64
AuraTrader
3
@@ -140,7 +140,6 @@
-
Base
@@ -190,12 +189,6 @@
true
-
-
- AuraTrader.rsm
- true
-
-
AuraTrader.exe
diff --git a/AuraTrader/MainForm.fmx b/AuraTrader/MainForm.fmx
index b6df951..2b5b9f6 100644
--- a/AuraTrader/MainForm.fmx
+++ b/AuraTrader/MainForm.fmx
@@ -204,13 +204,6 @@ object Form1: TForm1
Text = 'Button2'
OnClick = Button2Click
end
- object Button3: TButton
- Position.X = 64.000000000000000000
- Position.Y = 152.000000000000000000
- TabOrder = 2
- Text = 'Button3'
- OnClick = Button3Click
- end
end
end
end
diff --git a/AuraTrader/MainForm.pas b/AuraTrader/MainForm.pas
index 613b64e..d766d67 100644
--- a/AuraTrader/MainForm.pas
+++ b/AuraTrader/MainForm.pas
@@ -56,7 +56,6 @@ uses
Myc.Trade.Indicators,
Myc.Trade.Indicators.Common,
Myc.Core.FileCache,
- Myc.Trade.DataFeed,
StrategyTest,
TestMethodCallFromRecordParams;
@@ -89,7 +88,6 @@ type
Strat2Button: TSpeedButton;
Button1: TButton;
Button2: TButton;
- Button3: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure StopButtonClick(Sender: TObject);
@@ -97,7 +95,6 @@ type
procedure AddWorkspaceActionExecute(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
- procedure Button3Click(Sender: TObject);
procedure LogMemoChange(Sender: TObject);
procedure Strat2ButtonClick(Sender: TObject);
procedure TestActionExecute(Sender: TObject);
@@ -115,8 +112,6 @@ type
FProcessDone: TState;
FApplication: IAuraApplication;
FModulesItem: TTreeViewItem;
- FFileCache: IDataFileCache>;
- FFeed: IScalarBatchLoader;
function SelectedSymbol: String;
procedure ExecuteStrategy(const Symbol: String; Timeframe: TTimeframe; const Consumer: IConsumer>);
@@ -197,8 +192,6 @@ procedure TForm1.FormCreate(Sender: TObject);
begin
FApplication := TMycAuraApplication.Create;
- FFileCache := TDataFileCache>.Create;
-
FModulesItem := TTreeViewItem.Create(Self);
FModulesItem.Text := 'Modules';
@@ -350,99 +343,6 @@ begin
end;
-procedure TForm1.Button3Click(Sender: TObject);
-begin
- var symbol := SelectedSymbol;
- if symbol = '' then
- exit;
-
- var layout := CurrLayout;
- if layout = nil then
- exit;
-
- // 1. Setup Chart
- var chart := TMycChart.Create(Self);
- AlignControl(chart);
- chart.Height := layout.ChildrenRect.Width * 9 / 16;
- chart.Lookback.Value := 500000;
-
- // 2. Define Schema (Keywords & Layout)
- var kTime := TKeywordRegistry.Intern('Time');
- var kClose := TKeywordRegistry.Intern('Close');
-
- var def :=
- TScalarRecord.TRegistry.Intern(
- [
- TPair.Create(kTime, TScalar.TKind.DateTime),
- TPair.Create(kClose, TScalar.TKind.Float)
- ]
- );
-
- // 3. Build Pipeline
-
- var iTime := def.IndexOf(kTime);
- var iClose := def.IndexOf(kClose);
-
- var terminated := TFlag.CreateObserver(FTerminate.Signal).State;
- var path := '\\COFFEE\TickData\Pepperstone'; // Or FServer.Path if compatible
-
- FFeed :=
- TScalarBatchLoader.Create(
- FFileCache,
- path,
- '.m1',
- true,
- SizeOf(TM1FileItem),
- procedure(const Src: Pointer; Dst: TScalar.PValue)
- var
- Item: ^TM1FileItem;
- begin
- Item := Src;
-
- // Field 0: Time (DateTime is stored as Double/OADate in TScalar)
- Dst.AsDouble := Item.OADateTime;
-
- // Move to next field in destination (TScalar values are contiguous)
- Inc(Dst);
-
- // Field 1: Close (Float)
- // Convert Int64 price to Double using Digits: Price / 10^Digits
- if Item.Digits > 0 then
- Dst.AsDouble := Item.Close / Power(10, Item.Digits)
- else
- Dst.AsDouble := Item.Close;
- end
- );
-
- // Converter: Transforms raw IRecordSeries (Columns) into TArray
-
- var unpacker := TScalarBatchLoader.CreateTicker(def);
-
- var ticker :=
- unpacker.Producer.Chain>(
- function(const Tick: IScalarRecord): TDataPoint
- begin
- Result.Time := Tick[iTime].Value.Value.AsDouble;
- Result.Data := Tick[iClose].Value.Value.AsDouble;
- end
- );
-
- FFeed.BatchProducer.Chain(unpacker.Consumer);
-
- // Link Chart to Ticker
- chart
- .SetXAxisSeries(TTimeframe.M, ticker.Chain(function(const p: TDataPoint): TDateTime begin Result := p.Time end));
-
- var panel := chart.AddPanel;
- panel.AddDoubleSeries(
- ticker.Chain(function(const p: TDataPoint): Double begin Result := p.Data end),
- TAlphaColors.Orange
- );
-
- // Connect pipeline: Server -> Converter
- FProcessDone := FFeed.ProcessData(symbol, terminated);
-end;
-
function TForm1.CreateStrategy2(Timeframe: TTimeframe): IConsumer>;
type
TSignal = record
diff --git a/Src/Data/Myc.Data.Decimal.pas b/Src/Data/Myc.Data.Decimal.pas
index a355506..422b5f3 100644
--- a/Src/Data/Myc.Data.Decimal.pas
+++ b/Src/Data/Myc.Data.Decimal.pas
@@ -86,17 +86,12 @@ begin
var newValue := AValue.GetValue;
var scaleDiff := ANewScale - oldScale;
- if scaleDiff > 0 then
+ if (scaleDiff > 0) then
begin
- // Increasing scale: multiply by 10^scaleDiff, checking for overflow at each step.
- for var i := 1 to scaleDiff do
- begin
- if newValue > (MAX_VALUE_61BIT div 10) then
- raise EOverflow.Create('Decimal scale up resulted in an overflow.');
- if newValue < (MIN_VALUE_61BIT div 10) then
- raise EOverflow.Create('Decimal scale up resulted in an overflow.');
- newValue := newValue * 10;
- end;
+ var multiplier := PowersOf10[scaleDiff];
+ if (newValue > (MAX_VALUE_61BIT div multiplier)) or (newValue < (MIN_VALUE_61BIT div multiplier)) then
+ raise EOverflow.Create('Decimal scale up resulted in an overflow.');
+ newValue := newValue * multiplier;
end
else
begin
@@ -380,7 +375,7 @@ begin
if val < 0 then
exit(-1);
if val > 0 then
- exit(-1);
+ exit(1);
exit(0);
end;
diff --git a/Src/Data/Myc.Data.Pipeline.pas b/Src/Data/Myc.Data.Pipeline.pas
index dc60ea6..5e19b65 100644
--- a/Src/Data/Myc.Data.Pipeline.pas
+++ b/Src/Data/Myc.Data.Pipeline.pas
@@ -7,16 +7,18 @@ uses
Myc.Mutable,
Myc.Data.Series;
+{$M+}
+
type
TTag = Pointer;
// A generic interface for components that consume data of type T.
- IConsumer = interface(IInvokable)
+ IConsumer = interface
function Consume(const Value: T): TState;
end;
// A producer generates data and distributes it to linked consumers.
- IProducer = interface(IInvokable)
+ IProducer = interface
function Link(const Consumer: IConsumer): TTag;
procedure Unlink(Tag: TTag);
end;
diff --git a/Src/Myc.Trade.DataFeed.pas b/Src/Myc.Trade.DataFeed.pas
deleted file mode 100644
index e5cd915..0000000
--- a/Src/Myc.Trade.DataFeed.pas
+++ /dev/null
@@ -1,697 +0,0 @@
-unit Myc.Trade.DataFeed;
-
-interface
-
-uses
- System.SysUtils,
- System.Classes,
- System.Generics.Collections,
- System.Generics.Defaults,
- System.IOUtils,
- System.TimeSpan,
- Myc.Futures,
- Myc.Signals,
- Myc.Mutable,
- Myc.Data.Scalar,
- Myc.Data.Keyword,
- Myc.Data.Pipeline,
- Myc.Data.Pipeline.Impl,
- Myc.Core.FileCache;
-
-type
- // Callback to convert raw bytes from a file into a TScalar.TValue sequence
- TImportConverter = reference to procedure(const Src: Pointer; Dst: TScalar.PValue);
-
- // Represents a raw block of data read from disk
- TScalarBatch = record
- Data: TArray;
- RecCount: Integer;
- end;
-
- IBroker = interface
- function GetEquity: Double;
- procedure Buy(Count: Integer);
- procedure Sell(Count: Integer);
- property Equity: Double read GetEquity;
- end;
-
- IScalarBatchLoader = interface
- {$region 'private'}
- function GetBatchProducer: TProducer;
- {$endregion}
-
- function EnumerateSymbols: TFuture>;
-
- // Streaming processing: Reads data from disk and broadcasts it via BatchProducer
- function ProcessData(const Symbol: String; const Terminated: TState): TState;
-
- // Provides raw TScalarBatch events
- property BatchProducer: TProducer read GetBatchProducer;
- end;
-
- TScalarBatchLoader = class(TInterfacedObject, IScalarBatchLoader)
- public
- type
- TDataFile = record
- private
- FExtension: String;
- FPath: String;
- FSymbol: String;
- FYear: Integer;
- FMonth: Integer;
- FBasename: String;
- function GetIsValid: Boolean;
- public
- constructor Create(const APath, ASymbol, AExtension: String; AYear, AMonth: Integer; const ABasename: String);
- function GetFullFileName: string;
- property BaseFileName: string read FBasename;
- property IsValid: Boolean read GetIsValid;
- property Extension: String read FExtension;
- property Path: String read FPath;
- property Symbol: String read FSymbol;
- property Year: Integer read FYear;
- property Month: Integer read FMonth;
- end;
-
- var
- FPath: String;
- FLookback: Int64;
- FFileExtension: String;
- FIsCompressed: Boolean;
-
- FCachedFiles: IDataFileCache>;
- FSymbols: TFuture>>;
-
- // Internal producer for raw batches
- FBatchProducer: TMycContainedProducer;
-
- class var
- FLoadGate: TLatch;
-
- function GetPath: String;
-
- // Loading Logic
- function DoLoad(const FileName: string; const Gate: TLatch): TFuture>;
- function LoadDataFile(const DataFile: TDataFile): TFuture>;
-
- // Processing Logic
- function ProcessFile(
- const Files: TArray;
- Index: Integer;
- const DataFile: TFuture>;
- const Terminated: TState
- ): TState;
-
- function ProcessChunks(const Batches: TArray; Terminated: TState): TState;
-
- // Binary I/O
- function ReadCompressedData(const InputStream: TStream): TArray;
- function ReadUncompressedData(const InputStream: TStream): TArray;
-
- // Helpers
- function ParseFileName(const FileName: string): TDataFile;
- procedure UpdateSymbols;
-
- private
- FRecordSize: Integer;
- FConverter: TImportConverter;
-
- function GetBatchProducer: TProducer;
-
- public
- constructor Create(
- const ACachedFiles: IDataFileCache>;
- const APath, AExtension: String;
- IsCompressed: Boolean;
- // RecordSize defines both the input bytes per record AND the output TValues per record
- ARecordSize: Integer;
- const AConverter: TImportConverter
- );
- destructor Destroy; override;
- procedure AfterConstruction; override;
-
- function EnumerateSymbols: TFuture>;
-
- // Streaming processing: Reads data from disk and broadcasts it via BatchTicker
- function ProcessData(const Symbol: String; const Terminated: TState): TState;
-
- class function CreateTicker(const Def: IScalarRecordDefinition): TConverter; static;
-
- property Path: String read GetPath;
- property FileExtension: String read FFileExtension;
- property IsCompressed: Boolean read FIsCompressed;
- property Lookback: Int64 read FLookback write FLookback;
- property BatchProducer: TProducer read GetBatchProducer;
- end;
-
-implementation
-
-uses
- System.Zip,
- System.Math,
- System.StrUtils,
- Myc.TaskManager;
-
-const
- BatchSize = 1024;
-
-type
- // Private implementation of the view logic (Cursor Pattern).
- // This object is reused to avoid allocations per tick.
- TScalarRecordView = class(TInterfacedObject, IScalarRecord)
- private
- FDef: IScalarRecordDefinition;
- FData: TScalar.PValue;
-
- // IKeywordMapping implementation
- function IndexOf(const Key: IKeyword): Integer;
- function GetCount: Integer;
- function GetItems(Idx: Integer): TPair;
- function GetFields(const Key: IKeyword): TScalar;
- function GetDef: IScalarRecordDefinition;
- public
- constructor Create(const ADef: IScalarRecordDefinition);
- procedure SetData(const AData: TScalar.PValue); inline;
- end;
-
-{ TScalarRecordView }
-
-constructor TScalarRecordView.Create(const ADef: IScalarRecordDefinition);
-begin
- inherited Create;
- FDef := ADef;
-end;
-
-procedure TScalarRecordView.SetData(const AData: TScalar.PValue);
-begin
- FData := AData;
-end;
-
-function TScalarRecordView.GetCount: Integer;
-begin
- Result := FDef.Count;
-end;
-
-function TScalarRecordView.GetDef: IScalarRecordDefinition;
-begin
- Result := FDef;
-end;
-
-function TScalarRecordView.GetFields(const Key: IKeyword): TScalar;
-var
- idx: Integer;
-begin
- idx := FDef.IndexOf(Key);
- if idx < 0 then
- exit(Default(TScalar));
-
- // Return the raw TValue at the offset
- Result.Kind := FDef[idx].Value;
- Result.Value := TScalar.PValue(NativeUInt(FData) + NativeUInt(idx * SizeOf(TScalar.TValue)))^;
-end;
-
-function TScalarRecordView.GetItems(Idx: Integer): TPair;
-begin
- Result.Key := FDef[Idx].Key;
- Result.Value.Kind := FDef[idx].Value;
- Result.Value.Value := TScalar.PValue(NativeUInt(FData) + NativeUInt(Idx * SizeOf(TScalar.TValue)))^;
-end;
-
-function TScalarRecordView.IndexOf(const Key: IKeyword): Integer;
-begin
- Result := FDef.IndexOf(Key);
-end;
-
-{ TScalarBatchLoader.TDataFile }
-
-constructor TScalarBatchLoader.TDataFile.Create(const APath, ASymbol, AExtension: String; AYear, AMonth: Integer; const ABasename: String);
-begin
- FPath := APath;
- FSymbol := ASymbol;
- FExtension := AExtension;
- FYear := AYear;
- FMonth := AMonth;
- FBasename := ABasename;
-end;
-
-function TScalarBatchLoader.TDataFile.GetFullFileName: string;
-begin
- Result := TPath.Combine(FPath, FBasename + FExtension);
-end;
-
-function TScalarBatchLoader.TDataFile.GetIsValid: Boolean;
-begin
- Result := (FSymbol <> '') and (FYear > 0);
-end;
-
-{ TScalarBatchLoader }
-
-constructor TScalarBatchLoader.Create(
- const ACachedFiles: IDataFileCache>;
- const APath, AExtension: String;
- IsCompressed: Boolean;
- ARecordSize: Integer;
- const AConverter: TImportConverter
-);
-begin
- inherited Create;
- FPath := APath;
- FCachedFiles := ACachedFiles;
- FFileExtension := AExtension;
- FIsCompressed := IsCompressed;
- FLookback := -1;
-
- // RecordSize is used for both Input Bytes Stride AND Output TValues Count
- FRecordSize := ARecordSize;
- FConverter := AConverter;
-
- Assert(FRecordSize > 0);
- Assert(Assigned(FConverter));
-
- FBatchProducer := TMycContainedProducer.Create(Self);
- FCachedFiles := TDataFileCache>.Create;
-end;
-
-destructor TScalarBatchLoader.Destroy;
-begin
- FCachedFiles.Clear;
- FBatchProducer.Free;
- inherited Destroy;
-end;
-
-procedure TScalarBatchLoader.AfterConstruction;
-begin
- inherited;
- UpdateSymbols;
-end;
-
-class function TScalarBatchLoader.CreateTicker(const Def: IScalarRecordDefinition): TConverter;
-var
- viewObj: TScalarRecordView;
- view: IScalarRecord;
-begin
- Result :=
- TConverter.CreateAggregation(
- function(const Value: TScalarBatch; const Broadcast: TBroadcastFunc): TState
- begin
- if (Length(Value.Data) > 0) and (Value.RecCount > 0) then
- begin
- var Stride := Length(Value.Data) div Value.RecCount;
- var pCursor: TScalar.PValue := @Value.Data[0];
-
- for var i := 0 to Value.RecCount - 1 do
- begin
- if view = nil then
- begin
- // Initialize reused View object (Cursor Pattern)
- // This object implements IScalarRecord and is updated for each tick.
- viewObj := TScalarRecordView.Create(Def);
- view := viewObj as IScalarRecord;
- end;
-
- var rc := viewObj._AddRef;
- try
- // Broadcast tick
- viewObj.SetData(pCursor);
- Broadcast(view);
- finally
- // If client picked it up, we release it
- if viewObj._Release >= rc then
- view := nil;
- end;
-
- Inc(pCursor, Stride);
- end;
- end;
- Result := TState.Null;
- end
- );
-end;
-
-function TScalarBatchLoader.GetPath: String;
-begin
- Result := FPath;
-end;
-
-function TScalarBatchLoader.GetBatchProducer: TProducer;
-begin
- Result := FBatchProducer;
-end;
-
-procedure TScalarBatchLoader.UpdateSymbols;
-begin
- FSymbols :=
- TFuture>>.Construct(
- FSymbols.Done,
- function: TDictionary>
- var
- fileNames: TArray;
- tempSymbolMap: TDictionary>;
- dataFile: TDataFile;
- symbolList: TList;
- begin
- Result := TDictionary>.Create;
- tempSymbolMap := TDictionary>.Create;
- try
- if not TDirectory.Exists(FPath) then
- exit;
-
- fileNames := TDirectory.GetFiles(FPath);
- for var currentFile in fileNames do
- begin
- dataFile := ParseFileName(currentFile);
- if dataFile.IsValid then
- begin
- if not tempSymbolMap.TryGetValue(dataFile.Symbol, symbolList) then
- begin
- symbolList := TList.Create;
- tempSymbolMap.Add(dataFile.Symbol, symbolList);
- end;
- symbolList.Add(dataFile);
- end;
- end;
-
- for var kvp in tempSymbolMap do
- begin
- symbolList := kvp.Value;
- symbolList.Sort(
- TComparer.Construct(
- function(const Left, Right: TDataFile): Integer
- begin
- if Left.Year < Right.Year then
- Result := -1
- else if Left.Year > Right.Year then
- Result := 1
- else
- Result := Left.Month - Right.Month;
- end
- )
- );
- Result.Add(kvp.Key, symbolList.ToArray);
- end;
- finally
- for var kvp in tempSymbolMap do
- kvp.Value.Free;
- tempSymbolMap.Free;
- end;
- end
- );
- FSymbols.Manage;
-end;
-
-function TScalarBatchLoader.EnumerateSymbols: TFuture>;
-begin
- Result :=
- FSymbols.Chain>(
- function(const Symbols: TDictionary>): TArray begin Result := Symbols.Keys.ToArray; end
- );
-end;
-
-function TScalarBatchLoader.ParseFileName(const FileName: string): TDataFile;
-var
- path, fileNameNoPath, baseName, ext, symbol: string;
- year, month: Integer;
- parts, dateParts: TArray;
-begin
- Result := Default(TDataFile);
- path := TPath.GetDirectoryName(FileName);
- fileNameNoPath := TPath.GetFileName(FileName);
-
- ext := TPath.GetExtension(fileNameNoPath);
-
- if not fileNameNoPath.EndsWith(FFileExtension, True) then
- exit;
-
- baseName := TPath.GetFileNameWithoutExtension(fileNameNoPath);
-
- parts := baseName.Split(['_']);
- if Length(parts) < 3 then
- exit;
-
- var startDatePart := parts[High(parts) - 1];
- dateParts := startDatePart.Split(['-']);
- if Length(dateParts) <> 2 then
- exit;
-
- if not TryStrToInt(dateParts[0], year) then
- exit;
- if not TryStrToInt(dateParts[1], month) then
- exit;
-
- if (month < 1) or (month > 12) or (year <= 0) then
- exit;
-
- symbol := string.Join('_', Copy(parts, 0, Length(parts) - 2));
- if symbol = '' then
- exit;
-
- Result := TDataFile.Create(path, symbol, ext, year, month, baseName);
-end;
-
-function TScalarBatchLoader.LoadDataFile(const DataFile: TDataFile): TFuture>;
-begin
- if DataFile.IsValid then
- Result :=
- FCachedFiles.GetOrAdd(
- DataFile.GetFullFileName,
- function(const Filename: String): TFuture> begin Result := DoLoad(Filename, FLoadGate); end
- )
- else
- Result := TFuture>.Construct(TArray(nil));
-end;
-
-function TScalarBatchLoader.DoLoad(const FileName: string; const Gate: TLatch): TFuture>;
-begin
- Result := TFuture>.Null;
- if not TFile.Exists(FileName) then
- exit;
-
- var capFileName := FileName;
-
- if FIsCompressed then
- begin
- Result :=
- TFuture
- .Construct(Gate.Enqueue, function: TBytes begin Result := TFile.ReadAllBytes(capFileName); end)
- .Chain>(
- function(bytes: TBytes): TArray
- begin
- var ms := TBytesStream.Create(bytes);
- try
- Result := ReadCompressedData(ms);
- finally
- ms.Free;
- end;
- end);
- end
- else
- begin
- Result :=
- TFuture>.Construct(
- Gate.Enqueue,
- function: TArray
- begin
- var fs := TFileStream.Create(capFileName, fmOpenRead or fmShareDenyWrite);
- try
- Result := ReadUncompressedData(fs);
- finally
- fs.Free;
- end;
- end
- );
- end;
-end;
-
-function TScalarBatchLoader.ReadCompressedData(const InputStream: TStream): TArray;
-var
- decompressionStream: TStream;
- localHeader: TZipHeader;
- entryIndex, i: Integer;
- zip: TZipFile;
-begin
- Result := nil;
- decompressionStream := nil;
- zip := nil;
-
- if not Assigned(InputStream) or (InputStream.Size = 0) then
- exit;
-
- try
- InputStream.Position := 0;
- zip := TZipFile.Create;
- zip.Open(InputStream, TZipMode.zmRead);
-
- if zip.FileCount = 0 then
- exit;
-
- entryIndex := -1;
- for i := 0 to zip.FileCount - 1 do
- begin
- if zip.FileNames[i].EndsWith(FFileExtension, True) then
- begin
- entryIndex := i;
- break;
- end;
- end;
-
- if entryIndex = -1 then
- entryIndex := 0;
-
- zip.Read(entryIndex, decompressionStream, localHeader);
- if not Assigned(decompressionStream) then
- exit;
-
- Result := ReadUncompressedData(decompressionStream);
- finally
- decompressionStream.Free;
- zip.Free;
- end;
-end;
-
-function TScalarBatchLoader.ReadUncompressedData(const InputStream: TStream): TArray;
-var
- fileSize, totalRecords: Int64;
- numBatches, batchIdx, k: Integer;
- bytesToRead, valuesToWrite: Integer;
- tempBuffer: TBytes;
- pSrc: PByte;
- pDst: TScalar.PValue;
-begin
- Result := nil;
- InputStream.Position := 0;
- fileSize := InputStream.Size;
-
- if (fileSize = 0) or ((fileSize mod FRecordSize) <> 0) then
- exit;
-
- totalRecords := fileSize div FRecordSize;
- if totalRecords = 0 then
- exit;
-
- numBatches := (totalRecords + BatchSize - 1) div BatchSize;
- SetLength(Result, numBatches);
-
- // Buffer for reading raw data chunks before conversion
- SetLength(tempBuffer, BatchSize * FRecordSize);
-
- for batchIdx := 0 to numBatches - 1 do
- begin
- var recordsInBatch := Min(BatchSize, totalRecords - (batchIdx * BatchSize));
- Result[batchIdx].RecCount := recordsInBatch;
-
- // FRecordSize determines both allocation count and input byte stride
- valuesToWrite := recordsInBatch * FRecordSize;
- SetLength(Result[batchIdx].Data, valuesToWrite);
-
- bytesToRead := recordsInBatch * FRecordSize;
- if InputStream.Read(tempBuffer, 0, bytesToRead) <> bytesToRead then
- raise EReadError.Create('Unexpected end of stream');
-
- pSrc := @tempBuffer[0];
- pDst := @Result[batchIdx].Data[0];
-
- // Always use the converter to transform raw bytes to TValues
- for k := 0 to recordsInBatch - 1 do
- begin
- FConverter(pSrc, pDst);
- Inc(pSrc, FRecordSize);
- Inc(pDst, FRecordSize);
- end;
- end;
-end;
-
-function TScalarBatchLoader.ProcessData(const Symbol: String; const Terminated: TState): TState;
-begin
- var cTerminated := Terminated;
- var cSymbol := Symbol;
-
- // We fetch the list once, then iterate by index.
- Result :=
- FSymbols.Chain(
- function(const AllSymbols: TDictionary>): TState
- var
- files: TArray;
- begin
- if AllSymbols.TryGetValue(cSymbol, files) and (Length(files) > 0) then
- begin
- // Start with Index 0
- Result := ProcessFile(files, 0, LoadDataFile(files[0]), cTerminated);
- end
- else
- begin
- Result := TState.Null;
- end;
- end
- );
-end;
-
-function TScalarBatchLoader.ProcessFile(
- const Files: TArray;
- Index: Integer;
- const DataFile: TFuture>;
- const Terminated: TState
-): TState;
-begin
- // Check bounds and termination
- if (Index < 0) or (Index > High(Files)) or Terminated.IsSet then
- exit(DataFile.Done);
-
- var currentInfo := Files[Index];
- if not currentInfo.IsValid then
- exit(DataFile.Done);
-
- // Prefetch logic: Prepare the next file immediately (if available)
- var nextIndex := Index + 1;
- var nextFuture: TFuture>;
-
- if nextIndex <= High(Files) then
- nextFuture := LoadDataFile(Files[nextIndex])
- else
- nextFuture := TFuture>.Construct(TArray(nil)); // End of stream
-
- var cTerminated := Terminated;
-
- // Process current data, then recurse to next index
- Result :=
- DataFile.Chain(
- function(const Batches: TArray): TState
- begin
- var done := ProcessChunks(Batches, Terminated);
-
- // Recurse with Index + 1
- Result :=
- TaskManager.RunTask(done, function: TState begin Result := ProcessFile(Files, nextIndex, nextFuture, cTerminated); end);
- end
- );
-end;
-
-function TScalarBatchLoader.ProcessChunks(const Batches: TArray; Terminated: TState): TState;
-begin
- var callProcess :=
- function(Idx: Integer): TFunc
- begin
- var cBatch := Batches[Idx];
-
- Result :=
- function: TState
- begin
- if not Terminated.IsSet then
- begin
- // Broadcast the raw batch.
- FBatchProducer.Broadcast(cBatch);
- Result := TState.Null;
- end;
- end;
- end;
-
- Result := TState.Null;
-
- for var i := 0 to High(Batches) do
- if not Terminated.IsSet then
- begin
- var queue := TaskManager.RunTask(Result, callProcess(i));
- Result := queue;
- end;
-end;
-
-end.
diff --git a/Src/Myc.Trade.DataStream.pas b/Src/Myc.Trade.DataStream.pas
index 9c16278..6eff592 100644
--- a/Src/Myc.Trade.DataStream.pas
+++ b/Src/Myc.Trade.DataStream.pas
@@ -16,6 +16,24 @@ uses
Myc.Core.FileCache;
type
+ // Match C# M1Record (Pack = 1, 48 Bytes)
+ TM1Record = packed record
+ Time: Double;
+ Open: Double;
+ High: Double;
+ Low: Double;
+ Close: Double;
+ Spread: Single;
+ Volume: Integer;
+ end;
+
+ // Match C# TickRecord (Pack = 1, 24 Bytes)
+ TTickRecord = packed record
+ Time: Double;
+ Ask: Double;
+ Bid: Double;
+ end;
+
// Interface for an instantiable data server.
IDataServer = interface
procedure ClearCache;
@@ -23,7 +41,7 @@ type
function EnumerateSymbols: TFuture>;
end;
- // Represents metadata for a single data file.
+ // Metadata for a monthly data file (SYMBOL_YYYY_MM.EXT)
TDataFile = record
private
FExtension: String;
@@ -45,12 +63,11 @@ type
property Month: Integer read FMonth;
end;
- // Generic server for loading and managing sequential time-series data from files.
- TDataServer = class(TInterfacedObject, IDataServer)
+ // Generic server base handling the pipeline and preloading.
+ TDataServer = class(TInterfacedObject, IDataServer)
private
FCachedFiles: TDataFileCache>>>;
FPath: String;
- // The cache now holds a sorted array of all files for each symbol.
FSymbols: TFuture>>;
function GetPath: String;
@@ -72,10 +89,12 @@ type
FLoadGate: TLatch;
protected
- // Used by cache to actually load an uncached file. Now virtual and abstract.
- function DoLoad(const FileName: string; const Gate: TLatch): TFuture>>>; virtual; abstract;
- // Gets the next consecutive data file from the cached, sorted list.
+ // Maps the raw file record to the internal TDataPoint
+ function MapRecord(const RecordBuffer: R): TDataPoint; virtual; abstract;
+ function DoLoad(const FileName: string; const Gate: TLatch): TFuture>>>;
function GetNextFile(const Curr: TDataFile): TDataFile; virtual;
+ function ReadCompressedData(const InputStream: TStream): TArray>>;
+ function ReadUncompressedData(const InputStream: TStream): TArray>>;
public
constructor Create(const APath: String);
@@ -83,58 +102,27 @@ type
procedure AfterConstruction; override;
procedure ClearCache;
procedure UpdateSymbols;
- // Scans a directory to find the oldest file for a specific symbol.
function FindFirstFile(const Symbol: string): TFuture;
- function ParseFileName(const FileName: string): TDataFile; virtual; abstract;
+ function ParseFileName(const FileName: string): TDataFile;
function EnumerateSymbols: TFuture>;
-
- // Load data file and split content into chunks.
function LoadDataFile(const DataFile: TDataFile): TFuture>>>;
-
function ProcessData(const Symbol: String; const Terminated: TState; const Processor: IConsumer>>): TState;
property Path: String read GetPath;
end;
- TAskBidFileItem = packed record
- Ask: Single;
- Bid: Single;
- end;
-
- TAskBidFileServer = class(TDataServer)
- private
- class function ReadCompressedData(const InputStream: TStream): TArray>>;
- class function ReadUncompressedData(const InputStream: TStream): TArray>>;
+ TTickFileServer = class(TDataServer)
protected
- function DoLoad(const FileName: string; const Gate: TLatch): TFuture>>>; override;
- public
- function ParseFileName(const FileName: string): TDataFile; override;
+ function MapRecord(const RecordBuffer: TTickRecord): TDataPoint; override;
end;
- TM1FileItem = packed record
- OADateTime: Double;
- Open: Int64;
- High: Int64;
- Low: Int64;
- Close: Int64;
- Spread: Int64;
- TickVolume: Integer;
- Digits: Integer;
- end;
-
- // File server for cTrader M1 data. Note that the generic type is TOhlcItem,
- // as the server converts the file data into standard OHLC items.
- TM1FileServer = class(TDataServer)
- private
- class function ReadCompressedData(const InputStream: TStream): TArray>>;
- class function ReadUncompressedData(const InputStream: TStream): TArray>>;
+ TM1FileServer = class(TDataServer)
protected
- function DoLoad(const FileName: string; const Gate: TLatch): TFuture>>>; override;
- public
- function ParseFileName(const FileName: string): TDataFile; override;
+ function MapRecord(const RecordBuffer: TM1Record): TDataPoint; override;
end;
implementation
+
uses
System.Zip,
System.ZLib,
@@ -143,8 +131,7 @@ uses
Myc.TaskManager;
const
- // The number of records per data chunk when loading files.
- ChunkSize = 512;
+ ChunkSize = 1024;
{ TDataFile }
@@ -165,43 +152,42 @@ end;
function TDataFile.GetFullFileName: string;
begin
- Result := TPath.Combine(FPath, GetBaseFileName + FExtension);
+ Result := TPath.Combine(FPath, FBasename + FExtension);
end;
function TDataFile.GetIsValid: Boolean;
begin
- Result := (FSymbol <> '') and (FYear > 0);
+ Result := (FSymbol <> '') and (FYear > 0) and (FMonth >= 1) and (FMonth <= 12);
end;
-{ TDataServer }
+{ TDataServer }
-constructor TDataServer.Create(const APath: String);
+constructor TDataServer.Create(const APath: String);
begin
inherited Create;
FPath := APath;
-
FCachedFiles := TDataFileCache>>>.Create;
end;
-destructor TDataServer.Destroy;
+destructor TDataServer.Destroy;
begin
ClearCache;
FCachedFiles.Free;
inherited Destroy;
end;
-procedure TDataServer.AfterConstruction;
+procedure TDataServer.AfterConstruction;
begin
inherited;
UpdateSymbols;
end;
-procedure TDataServer.ClearCache;
+procedure TDataServer.ClearCache;
begin
FCachedFiles.Clear;
end;
-procedure TDataServer.UpdateSymbols;
+procedure TDataServer.UpdateSymbols;
begin
FSymbols :=
TFuture>>.Construct(
@@ -241,10 +227,8 @@ begin
TComparer.Construct(
function(const Left, Right: TDataFile): Integer
begin
- if Left.Year < Right.Year then
- Result := -1
- else if Left.Year > Right.Year then
- Result := 1
+ if Left.Year <> Right.Year then
+ Result := Left.Year - Right.Year
else
Result := Left.Month - Right.Month;
end
@@ -263,7 +247,7 @@ begin
FSymbols.Manage;
end;
-function TDataServer.EnumerateSymbols: TFuture>;
+function TDataServer.EnumerateSymbols: TFuture>;
begin
Result :=
FSymbols.Chain>(
@@ -271,7 +255,7 @@ begin
);
end;
-function TDataServer.FindFirstFile(const Symbol: string): TFuture;
+function TDataServer.FindFirstFile(const Symbol: string): TFuture;
begin
var symName := Symbol;
Result :=
@@ -288,13 +272,13 @@ begin
);
end;
-function TDataServer.GetNextFile(const Curr: TDataFile): TDataFile;
+function TDataServer.GetNextFile(const Curr: TDataFile): TDataFile;
var
allSymbolFiles: TArray;
foundIndex: Integer;
begin
Result := Default(TDataFile);
- if not Curr.IsValid or not FSymbols.Done.IsSet then
+ if (not Curr.IsValid) or (not FSymbols.Done.IsSet) then
exit;
if not FSymbols.Value.TryGetValue(Curr.Symbol, allSymbolFiles) then
@@ -303,7 +287,7 @@ begin
foundIndex := -1;
for var i := 0 to High(allSymbolFiles) do
begin
- if allSymbolFiles[i].GetBaseFileName() = Curr.GetBaseFileName() then
+ if allSymbolFiles[i].GetBaseFileName = Curr.GetBaseFileName then
begin
foundIndex := i;
break;
@@ -311,51 +295,137 @@ begin
end;
if (foundIndex <> -1) and (foundIndex < High(allSymbolFiles)) then
- begin
Result := allSymbolFiles[foundIndex + 1];
- end;
end;
-function TDataServer.GetPath: String;
+function TDataServer.GetPath: String;
begin
Result := FPath;
end;
-function TDataServer.ProcessData(
- const Symbol: String;
- const Terminated: TState;
- const Processor: IConsumer>>
-): TState;
+function TDataServer.ParseFileName(const FileName: string): TDataFile;
+var
+ fileNameNoPath, baseName, symbol, ext: string;
+ parts: TArray;
+ year, month: Integer;
begin
- var cProc := Processor;
- var cTerminated := Terminated;
+ Result := Default(TDataFile);
+ fileNameNoPath := TPath.GetFileName(FileName);
+ ext := TPath.GetExtension(fileNameNoPath);
+ baseName := TPath.GetFileNameWithoutExtension(fileNameNoPath);
- Result :=
- FindFirstFile(Symbol)
- .Chain(
- function(const FirstFileInfo: TDataFile): TState
- begin
- Result := ProcessFile(FirstFileInfo, LoadDataFile(FirstFileInfo), cTerminated, cProc);
- end);
+ // Format: SYMBOL_YYYY_MM
+ parts := baseName.Split(['_']);
+ if Length(parts) < 3 then
+ exit;
+
+ // Use reverse indexing for year and month
+ if (not TryStrToInt(parts[High(parts)], month)) or (not TryStrToInt(parts[High(parts) - 1], year)) then
+ exit;
+
+ symbol := string.Join('_', Copy(parts, 0, Length(parts) - 2));
+ Result := TDataFile.Create(TPath.GetDirectoryName(FileName), symbol, ext, year, month, baseName);
end;
-function TDataServer.LoadDataFile(const DataFile: TDataFile): TFuture>>>;
+function TDataServer.LoadDataFile(const DataFile: TDataFile): TFuture>>>;
begin
if DataFile.IsValid then
Result :=
FCachedFiles.GetOrAdd(
DataFile.GetFullFileName,
- function(const Filename: String): TFuture>>>
- begin
- // Pass the private load gate to the virtual DoLoad method.
- Result := DoLoad(Filename, FLoadGate);
- end
+ function(const Filename: String): TFuture>>> begin Result := DoLoad(Filename, FLoadGate); end
)
else
Result := TFuture>>>.Construct(TArray>>(nil));
end;
-function TDataServer.ProcessChunks(
+function TDataServer.DoLoad(const FileName: string; const Gate: TLatch): TFuture>>>;
+begin
+ var capFileName := FileName;
+ Result :=
+ TFuture
+ .Construct(Gate.Enqueue, function: TBytes begin Result := TFile.ReadAllBytes(capFileName); end)
+ .Chain>>>(
+ function(Bytes: TBytes): TArray>>
+ var
+ compStream: TBytesStream;
+ begin
+ compStream := TBytesStream.Create(Bytes);
+ try
+ Result := ReadCompressedData(compStream);
+ finally
+ compStream.Free;
+ end;
+ end);
+end;
+
+function TDataServer.ReadCompressedData(const InputStream: TStream): TArray>>;
+var
+ zip: TZipFile;
+ decompStream: TStream;
+ header: TZipHeader;
+ entryIdx: Integer;
+begin
+ Result := nil;
+ InputStream.Position := 0;
+ zip := TZipFile.Create;
+ try
+ zip.Open(InputStream, TZipMode.zmRead);
+ entryIdx := -1;
+ // Search for the .bin entry created by C#
+ for var i := 0 to zip.FileCount - 1 do
+ begin
+ if zip.FileNames[i].EndsWith('.bin', true) then
+ begin
+ entryIdx := i;
+ break;
+ end;
+ end;
+
+ if entryIdx = -1 then
+ exit;
+
+ zip.Read(entryIdx, decompStream, header);
+ try
+ Result := ReadUncompressedData(decompStream);
+ finally
+ decompStream.Free;
+ end;
+ finally
+ zip.Free;
+ end;
+end;
+
+function TDataServer.ReadUncompressedData(const InputStream: TStream): TArray>>;
+var
+ totalRecords, chunkCount, i, j, recsInChunk: Integer;
+ rawBuffer: TArray;
+begin
+ Result := nil;
+ totalRecords := InputStream.Size div sizeof(R);
+ if totalRecords = 0 then
+ exit;
+
+ // Fast block read into memory
+ SetLength(rawBuffer, totalRecords);
+ InputStream.Position := 0;
+ InputStream.ReadBuffer(rawBuffer[0], InputStream.Size);
+
+ chunkCount := (totalRecords + ChunkSize - 1) div ChunkSize;
+ SetLength(Result, chunkCount);
+
+ for i := 0 to chunkCount - 1 do
+ begin
+ recsInChunk := Min(ChunkSize, totalRecords - (i * ChunkSize));
+ SetLength(Result[i], recsInChunk);
+ for j := 0 to recsInChunk - 1 do
+ begin
+ Result[i][j] := MapRecord(rawBuffer[i * ChunkSize + j]);
+ end;
+ end;
+end;
+
+function TDataServer.ProcessChunks(
const DataChunks: TArray>>;
Terminated: TState;
Processor: IConsumer>>
@@ -374,36 +444,34 @@ begin
end;
for var i := 0 to High(DataChunks) do
+ begin
if not Terminated.IsSet then
begin
var q := TaskManager.RunTask(Result, callProcess(i));
Result := q;
- end
+ end;
+ end;
end;
-function TDataServer.ProcessFile(
+function TDataServer.ProcessFile(
FileInfo: TDataFile;
const DataFile: TFuture>>>;
const Terminated: TState;
Processor: IConsumer>>
): TState;
begin
- if not FileInfo.IsValid or Terminated.IsSet then
+ if (not FileInfo.IsValid) or (Terminated.IsSet) then
exit(DataFile.Done);
- // Read ahead the next file, while processing the current one
var nextFileInfo := GetNextFile(FileInfo);
var nextFile := LoadDataFile(nextFileInfo);
-
var cTerminated := Terminated;
+
Result :=
DataFile.Chain(
function(const DataChunks: TArray>>): TState
begin
- // Process each chunk, checking for termination between chunks.
- var done := ProcessChunks(DataChunks, Terminated, Processor);
-
- // Move to next file (which is currently preloading) once all Processors are done
+ var done := ProcessChunks(DataChunks, cTerminated, Processor);
Result :=
TaskManager
.RunTask(done, function: TState begin Result := ProcessFile(nextFileInfo, nextFile, cTerminated, Processor); end);
@@ -411,370 +479,35 @@ begin
);
end;
-{ TAskBidFileServer }
-
-function TAskBidFileServer.DoLoad(const FileName: string; const Gate: TLatch): TFuture>>>;
+function TDataServer.ProcessData(
+ const Symbol: String;
+ const Terminated: TState;
+ const Processor: IConsumer>>
+): TState;
begin
- Result := TFuture>>>.Null;
-
- if not TFile.Exists(FileName) then
- exit;
-
- var capFileName := FileName;
- if FileName.EndsWith('_zip', True) then
- begin
- Result :=
- TFuture
- .Construct(Gate.Enqueue, function: TBytes begin Result := TFile.ReadAllBytes(capFileName); end)
- .Chain>>>(
- function(bytes: TBytes): TArray>>
- begin
- var compMemoryStream := TBytesStream.Create(bytes);
- try
- compMemoryStream.Position := 0;
- Result := ReadCompressedData(compMemoryStream);
- finally
- compMemoryStream.Free;
- end;
- end);
- end
- else
- begin
- Result :=
- TFuture>>>.Construct(
- Gate.Enqueue,
- function: TArray>>
- begin
- if TFile.Exists(capFileName) then
- begin
- var stream := TFileStream.Create(capFileName, fmOpenRead or fmShareDenyWrite);
- try
- Result := ReadUncompressedData(stream);
- finally
- stream.Free;
- end;
- end;
- end
- );
- end;
+ var cProc := Processor;
+ var cTerm := Terminated;
+ Result :=
+ FindFirstFile(Symbol)
+ .Chain(function(const Info: TDataFile): TState begin Result := ProcessFile(Info, LoadDataFile(Info), cTerm, cProc); end);
end;
-function TAskBidFileServer.ParseFileName(const FileName: string): TDataFile;
-var
- fileNameNoPath, nameForParsing, baseName, ext, path, symbol: string;
- year, month: Integer;
- parts: TArray;
+{ TTickFileServer }
+
+function TTickFileServer.MapRecord(const RecordBuffer: TTickRecord): TDataPoint;
begin
- Result := Default(TDataFile);
-
- path := TPath.GetDirectoryName(FileName);
- fileNameNoPath := TPath.GetFileName(FileName);
- nameForParsing := fileNameNoPath;
-
- ext := '';
- if nameForParsing.EndsWith('_zip', True) then
- begin
- ext := '_zip';
- nameForParsing := nameForParsing.Substring(0, nameForParsing.Length - 4);
- end;
-
- var fileExt := TPath.GetExtension(nameForParsing) + ext;
- baseName := TPath.GetFileNameWithoutExtension(nameForParsing);
-
- parts := baseName.Split(['_']);
-
- if Length(parts) < 3 then
- exit;
-
- if not TryStrToInt(parts[High(parts)], month) then
- exit;
-
- if (month < 1) or (month > 12) then
- exit;
-
- if not TryStrToInt(parts[High(parts) - 1], year) then
- exit;
-
- if year <= 0 then
- exit;
-
- symbol := string.Join('_', Copy(parts, 0, Length(parts) - 2));
-
- if symbol = '' then
- exit;
-
- Result := TDataFile.Create(path, symbol, fileExt, year, month, baseName);
-end;
-
-class function TAskBidFileServer.ReadCompressedData(const InputStream: TStream): TArray>>;
-var
- decompressionStream: TStream;
- localHeader: TZipHeader;
- entryIndex, i: Integer;
- zipFileInstance: TZipFile;
-begin
- Result := nil;
- decompressionStream := nil;
- zipFileInstance := nil;
- try
- InputStream.Position := 0;
- zipFileInstance := TZipFile.Create;
- zipFileInstance.Open(InputStream, TZipMode.zmRead);
-
- if zipFileInstance.FileCount = 0 then
- exit;
-
- entryIndex := -1;
- for i := 0 to zipFileInstance.FileCount - 1 do
- if zipFileInstance.FileNames[i].EndsWith('.tab', True) then
- begin
- entryIndex := i;
- break;
- end;
-
- if entryIndex = -1 then
- entryIndex := 0;
-
- zipFileInstance.Read(entryIndex, decompressionStream, localHeader);
- if not Assigned(decompressionStream) then
- exit;
- Result := ReadUncompressedData(decompressionStream);
- finally
- decompressionStream.Free;
- zipFileInstance.Free;
- end;
-end;
-
-class function TAskBidFileServer.ReadUncompressedData(const InputStream: TStream): TArray>>;
-type
- TFileRecord = packed record
- TimeStamp: TDateTime;
- Data: TAskBidFileItem;
- end;
-var
- fileSize: Int64;
- totalRecordCount, bytesRead, chunkIndex, indexInChunk, recordIndex: Integer;
- rec: TFileRecord;
-begin
- Result := nil;
- InputStream.Position := 0;
- fileSize := InputStream.Size;
- if (fileSize = 0) or ((fileSize mod SizeOf(TFileRecord)) <> 0) then
- exit;
-
- totalRecordCount := fileSize div SizeOf(TFileRecord);
- if totalRecordCount > 0 then
- begin
- var numChunks := (totalRecordCount + ChunkSize - 1) div ChunkSize;
- SetLength(Result, numChunks);
- chunkIndex := 0;
- indexInChunk := 0;
- SetLength(Result[chunkIndex], Min(ChunkSize, totalRecordCount));
-
- for recordIndex := 0 to totalRecordCount - 1 do
- begin
- if indexInChunk >= ChunkSize then
- begin
- Inc(chunkIndex);
- indexInChunk := 0;
- var remainingRecords := totalRecordCount - (chunkIndex * ChunkSize);
- SetLength(Result[chunkIndex], Min(ChunkSize, remainingRecords));
- end;
-
- bytesRead := InputStream.Read(rec, SizeOf(TFileRecord));
- if bytesRead <> SizeOf(TFileRecord) then
- raise EReadError.CreateFmt('Read error. Expected %d bytes, read %d.', [SizeOf(TFileRecord), bytesRead]);
-
- // Corrected syntax: Assign the newly created record instance.
- Result[chunkIndex][indexInChunk] := TDataPoint.Create(rec.TimeStamp, rec.Data);
- Inc(indexInChunk);
- end;
- end;
+ Result := TDataPoint.Create(RecordBuffer.Time, RecordBuffer);
end;
{ TM1FileServer }
-function TM1FileServer.DoLoad(const FileName: string; const Gate: TLatch): TFuture>>>;
+function TM1FileServer.MapRecord(const RecordBuffer: TM1Record): TDataPoint;
begin
- Result := TFuture>>>.Null;
-
- if not TFile.Exists(FileName) then
- exit;
-
- var capFileName := FileName;
- // M1 files are always compressed with the .m1 extension
- if FileName.EndsWith('.m1', True) then
- begin
- Result :=
- TFuture
- .Construct(Gate.Enqueue, function: TBytes begin Result := TFile.ReadAllBytes(capFileName); end)
- .Chain>>>(
- function(bytes: TBytes): TArray>>
- begin
- var compMemoryStream := TBytesStream.Create(bytes);
- try
- compMemoryStream.Position := 0;
- Result := ReadCompressedData(compMemoryStream);
- finally
- compMemoryStream.Free;
- end;
- end);
- end;
-end;
-
-function TM1FileServer.ParseFileName(const FileName: string): TDataFile;
-var
- path, fileNameNoPath, baseName, ext, symbol: string;
- year, month: Integer;
- parts, dateParts: TArray;
-begin
- Result := Default(TDataFile);
- path := TPath.GetDirectoryName(FileName);
- fileNameNoPath := TPath.GetFileName(FileName);
-
- // M1 files are compressed and have a .m1 extension
- if not fileNameNoPath.EndsWith('.m1', True) then
- exit;
-
- ext := TPath.GetExtension(fileNameNoPath);
- baseName := TPath.GetFileNameWithoutExtension(fileNameNoPath);
-
- // Expected format: SYMBOL_YYYY-MM_YYYY-MM
- parts := baseName.Split(['_']);
- if Length(parts) < 3 then
- exit; // Not enough parts for SYMBOL_START_END
-
- // The symbol can contain underscores, so we take everything before the last two parts.
- var startDatePart := parts[High(parts) - 1];
-
- dateParts := startDatePart.Split(['-']);
- if Length(dateParts) <> 2 then
- exit; // Start date is not YYYY-MM
-
- if not TryStrToInt(dateParts[0], year) then
- exit;
-
- if not TryStrToInt(dateParts[1], month) then
- exit;
-
- if (month < 1) or (month > 12) or (year <= 0) then
- exit;
-
- symbol := string.Join('_', Copy(parts, 0, Length(parts) - 2));
- if symbol = '' then
- exit;
-
- // The TDataFile only represents the start date of the file batch.
- Result := TDataFile.Create(path, symbol, ext, year, month, baseName);
-end;
-
-class function TM1FileServer.ReadCompressedData(const InputStream: TStream): TArray>>;
-var
- decompressionStream: TStream;
- localHeader: TZipHeader;
- entryIndex, i: Integer;
- zipFileInstance: TZipFile;
-begin
- Result := nil;
- decompressionStream := nil;
- zipFileInstance := nil;
-
- // M1 files are now zip archives containing the actual data file.
- if not Assigned(InputStream) or (InputStream.Size = 0) then
- exit;
-
- try
- InputStream.Position := 0;
- zipFileInstance := TZipFile.Create;
- zipFileInstance.Open(InputStream, TZipMode.zmRead);
-
- if zipFileInstance.FileCount = 0 then
- exit;
-
- // Find the data file entry within the archive.
- // The C# code creates an entry with the same name as the base filename, ending in .m1.
- entryIndex := -1;
- for i := 0 to zipFileInstance.FileCount - 1 do
- begin
- if zipFileInstance.FileNames[i].EndsWith('.m1', True) then
- begin
- entryIndex := i;
- break;
- end;
- end;
-
- // Fallback to the first entry if no specific .m1 file is found inside.
- if entryIndex = -1 then
- entryIndex := 0;
-
- zipFileInstance.Read(entryIndex, decompressionStream, localHeader);
- if not Assigned(decompressionStream) then
- exit;
-
- // The decompressed stream now contains the raw binary data.
- Result := ReadUncompressedData(decompressionStream);
- finally
- decompressionStream.Free;
- zipFileInstance.Free;
- end;
-end;
-
-class function TM1FileServer.ReadUncompressedData(const InputStream: TStream): TArray>>;
-type
- TFileRecord = TM1FileItem;
-var
- fileSize: Int64;
- totalRecordCount, bytesRead, chunkIndex, indexInChunk, recordIndex: Integer;
- rec: TFileRecord;
- ohlc: TOhlcItem;
- factor: Double;
-begin
- Result := nil;
- InputStream.Position := 0;
- fileSize := InputStream.Size;
- if (fileSize = 0) or ((fileSize mod SizeOf(TFileRecord)) <> 0) then
- exit;
-
- totalRecordCount := fileSize div SizeOf(TFileRecord);
- if totalRecordCount > 0 then
- begin
- var numChunks := (totalRecordCount + ChunkSize - 1) div ChunkSize;
- SetLength(Result, numChunks);
- chunkIndex := 0;
- indexInChunk := 0;
- SetLength(Result[chunkIndex], Min(ChunkSize, totalRecordCount));
-
- for recordIndex := 0 to totalRecordCount - 1 do
- begin
- if indexInChunk >= ChunkSize then
- begin
- Inc(chunkIndex);
- indexInChunk := 0;
- var remainingRecords := totalRecordCount - (chunkIndex * ChunkSize);
- SetLength(Result[chunkIndex], Min(ChunkSize, remainingRecords));
- end;
-
- bytesRead := InputStream.Read(rec, SizeOf(TFileRecord));
- if bytesRead <> SizeOf(TFileRecord) then
- raise EReadError.CreateFmt('Read error. Expected %d bytes, read %d.', [SizeOf(TFileRecord), bytesRead]);
-
- // Convert from M1 file record to a standard OHLC item
- if rec.Digits > 0 then
- factor := Power(10, rec.Digits)
- else
- factor := 1.0;
-
- ohlc.Open := rec.Open / factor;
- ohlc.High := rec.High / factor;
- ohlc.Low := rec.Low / factor;
- ohlc.Close := rec.Close / factor;
- ohlc.Volume := rec.TickVolume;
-
- // Corrected syntax: Assign the newly created record instance.
- Result[chunkIndex][indexInChunk] := TDataPoint.Create(rec.OADateTime, ohlc);
- Inc(indexInChunk);
- end;
- end;
+ Result :=
+ TDataPoint.Create(
+ RecordBuffer.Time,
+ TOhlcItem.Create(RecordBuffer.Open, RecordBuffer.High, RecordBuffer.Low, RecordBuffer.Close, RecordBuffer.Volume)
+ );
end;
end.