(* --- ## Aura Module API Documentation This unit defines the core interfaces and records for the Aura system, designed for robust algorithmic trading strategy development, backtesting, and optimization. It encapsulates key concepts for defining strategies, executing backtests, performing walk-forward optimizations, and conducting statistical robustness analysis via Monte Carlo simulations. --- ### Core Interfaces and Records #### `IAuraObject` Base interface for all Aura objects, providing a common `Name` property for identification. * `Name`: A writeable string representing the object's name. #### `TAuraArray` A record providing a mutable, observable array-like collection for `IAuraObject` instances. It wraps a `TWriteable>` and offers basic array manipulation methods. * `Items`: A writeable array of `IAuraObject` instances. * `Insert(Idx: Integer; const Item: T)`: Inserts an item at a specified index. * `Delete(Idx: Integer)`: Deletes an item at a specified index. * `IndexOf(const Item: T)`: Returns the index of a given item. #### `IAuraLiveObject` Extends `IAuraObject` for entities that are dynamically produced and actively executing operations, providing logging capabilities and a running status. * `Log`: A `TStrings` object for logging events and status messages. * `IsRunning`: Indicates whether the object is currently active. #### `IAuraNode` Extends `IAuraObject` for objects that can be part of a hierarchical structure and can be serialized. * `Caption`: A human-readable representation of the object's name. * `Serialize(const Write: TJsonWriter)`: Serializes the object's state to a JSON writer. #### `IAuraChilds` A generic interface for `IAuraNode`s that can have child nodes, enabling hierarchical organization within the Aura system. * `Items`: A `TAuraArray` containing the child nodes. #### `TAuraParameterDef` Defines the metadata for a single strategy parameter, including its name, type, and default value. * `Name`: The name of the parameter. * `ParamType`: The data type of the parameter (e.g., integer, float, string, UTC time). * `DefaultValue`: The default value for the parameter, stored as a `TAuraParameterValue`. #### `TAuraParameterRecordDef` Represents a collection of `TAuraParameterDef` records, defining all parameters for a specific strategy. This is an alias for `TArray`. #### `IAuraBot` An interface representing an instance that executes a trading strategy with given parameters over a specified time period. * `PnL`: A mutable data series representing the Profit and Loss (PnL) curve of the bot's execution. #### `IAuraStrategy` Defines a trading strategy, providing methods to create `IAuraBot` instances and specifying its parameter structure. * `CreateBot(const Parameters: TArray; StartTime, EndTime: TDateTime)`: Creates and returns an `IAuraBot` instance configured with the given parameters and time range. * `ParameterRecordDef`: Defines the set of parameters expected by this strategy. #### `TAuraTradePerformance` A record encapsulating key performance metrics from a backtest or optimization run. * `PnL`: Total Profit and Loss. * `SharpeRatio`: Risk-adjusted return. * `MaxDrawdown`: Maximum peak-to-trough decline. * `ProfitFactor`: Ratio of gross profits to gross losses. * `CalmarRatio`: Annualized return divided by the maximum drawdown. * `WinRate`: Percentage of winning trades. #### `TAuraMonteCarloResult` Stores the results of a Monte Carlo simulation, providing a probabilistic distribution of `TAuraTradePerformance` outcomes. * `Percentile`: An array of `TAuraTradePerformance` records, sorted by PnL and distributed into 10% percentiles, allowing for statistical risk assessment. #### `IAuraTradeResult` Represents the comprehensive outcome of a trade simulation (e.g., from a backtest or optimization), including performance metrics, trade details, and the ability to perform Monte Carlo analysis. * `Performance`: The `TAuraTradePerformance` metrics for this result. * `Trades`: A `TDataSeries` representing the PnLs of individual trades, serving as the basis for Monte Carlo simulation. * `CalcMonteCarloSimulation(Steps: Integer)`: Asynchronously performs a Monte Carlo simulation on the `Trades` data, returning a `TFuture` that resolves to a `TAuraMonteCarloResult`. #### `TAuraTimeRange` A record defining a specific time window with a start and end date/time. * `StartTime`: The start of the time range. * `EndTime`: The end of the time range. #### `IAuraBacktest` An interface for executing a single backtest of a trading strategy. * `BacktestResult`: A `TFuture` that resolves to the `IAuraTradeResult` of this backtest. * `Bot`: The `IAuraBot` instance executing the backtest. * `Parameters`: The specific parameters used for this backtest. * `Strategy`: The `IAuraStrategy` being backtested. * `TimeRange`: The historical time window over which the backtest is conducted. #### `IAuraParameterOptimization` Represents a single optimization slot (window) within a Walk-Forward Optimization process. It manages the execution of multiple in-sample backtests to find optimal parameters, followed by an out-of-sample test. * `InSampleTests`: A mutable array of `IAuraBacktest` instances representing the backtests run during the in-sample optimization phase. New tests are added, and less optimal ones may be removed. * `OutOfSampleTest`: A mutable `IAuraBacktest` representing the test run with the best-fit parameters from the in-sample optimization on the subsequent out-of-sample data. #### `IAuraWalkForwardOptimizer` Orchestrates the entire Walk-Forward Optimization (WFO) process, coordinating multiple `IAuraParameterOptimization` slots sequentially to test strategy adaptability across various market phases. * `OptimizationResult`: A `TFuture` that resolves to the aggregated `IAuraTradeResult` representing the combined performance of all out-of-sample tests. * `Slot`: An array of `IAuraParameterOptimization` instances, each representing a distinct optimization window. #### `IAuraParameterNode` Represents a single configurable parameter for optimization algorithms, allowing its value to be set and observed. * `Value`: A mutable `TAuraParameterValue` representing the parameter's current setting. #### `IAuraParameterList` An alias for `IAuraChilds`, providing a structured way to manage collections of `IAuraParameterNode`s. #### `IAuraStudy` Base interface for all types of strategy analysis studies (e.g., single backtests, parameter optimizations, WFOs). * `EventLog`: A `TStrings` object for logging events specific to the study. * `Strategy`: The `IAuraStrategy` that is the subject of the study. #### `TAuraParameterRange` Defines the allowed range for a strategy parameter during optimization. * `MinValue`: The minimum allowed value for the parameter, as a `TAuraParameterValue`. * `MaxValue`: The maximum allowed value for the parameter, as a `TAuraParameterValue`. #### `IAuraBacktestStudy` A specialized `IAuraStudy` for setting up and initiating a single backtest. * `TimeRange`: The `TAuraTimeRange` for the backtest. * `Start`: Initiates and returns an `IAuraBacktest` instance. #### `IAuraParameterOptimizationStudy` A specialized `IAuraStudy` for configuring and initiating a parameter optimization process (e.g., using genetic algorithms) over a specific time range. * `Parameters`: An `IAuraChilds` collection of `IAuraParameterNode`s defining the configuration parameters for the optimization algorithm itself (e.g., max generations, population size). * `TimeRange`: The `TAuraTimeRange` for the optimization. * `Start`: Initiates and returns an `IAuraParameterOptimization` instance. #### `IAuraWFOStudy` A specialized `IAuraStudy` for configuring and initiating a Walk-Forward Optimization process. * `ParameterRange[Idx: Integer]`: A writeable `TAuraParameterRange` defining the search space for each strategy parameter during the optimization phases. * `NumSlots`: A writeable integer indicating the number of time windows (slots) for the WFO. * `Start`: Initiates and returns an `IAuraWalkForwardOptimizer` instance. #### `IAuraTradingMode` An enumeration defining different operational modes for a trading environment. * `tmTesting`: Mode for historical backtesting. * `tmSim`: Mode for simulated live trading (paper trading). * `tmLive`: Mode for actual live trading. #### `IAuraWorkspace` Represents the scope of a complete testing and trading environment, containing various studies and managing the overall trading mode. * `WalkForwardAnalysis`: An `IAuraChilds` collection of `IAuraWFOStudy` instances. * `Backtests`: An `IAuraChilds` collection of `IAuraBacktestStudy` instances. * `ParameterOptimizations`: An `IAuraChilds` collection of `IAuraParameterOptimizationStudy` instances. * `TradingMode`: A writeable `IAuraTradingMode` indicating the current operational mode. #### `IAuraModule` An interface for creating instances of `IAuraStrategy`. Used for managing available strategy types. * `CreateStrategy`: Creates and returns a new `IAuraStrategy` instance. #### `IAuraApplication` The application-level singleton, serving as the root for serialization and providing access to all defined strategies and workspaces. * `Strategies`: An `IAuraChilds` collection of `IAuraModule` instances. * `Workspaces`: An `IAuraChilds` collection of `IAuraWorkspace` instances. --- *) unit Myc.Aura.Module; interface uses System.JSON.Writers, System.Classes, System.Generics.Collections, Myc.Signals, Myc.Futures, Myc.Lazy, Myc.Trade.DataPoint, Myc.Aura.Parameter; type // Base class of all Aura objects IAuraObject = interface function GetName: TWriteable; property Name: TWriteable read GetName; end; TAuraArray = record private FArray: TWriteable>; function GetItems: TWriteable>; public class operator Initialize(out Dest: TAuraArray); procedure Insert(Idx: Integer; const Item: T); procedure Delete(Idx: Integer); function IndexOf(const Item: T): Integer; property Items: TWriteable> read GetItems; end; // Base class for objects that are dynamically produced and are executing IAuraLiveObject = interface(IAuraObject) function GetLog: TStrings; function IsRunning: Boolean; property Log: TStrings read GetLog; end; IAuraNode = interface(IAuraObject) function GetCaption: string; // Serialize the whole project procedure Serialize(const Write: TJsonWriter); // Pretty print of Name property Caption: string read GetCaption; end; IAuraChilds = interface(IAuraNode) function GetItems: TWriteable>; procedure Insert(Idx: Integer; const Item: T); procedure Delete(Idx: Integer); function IndexOf(const Item: T): Integer; // Nodes to add as childs in hierarchical representation property Items: TWriteable> read GetItems; end; TAuraChilds = record private FChilds: IAuraChilds; function GetCaption: string; public constructor Create(const AChilds: IAuraChilds); class operator Implicit(const A: IAuraChilds): TAuraChilds; overload; class operator Implicit(const A: TAuraChilds): IAuraChilds; overload; procedure Serialize(const Write: TJsonWriter); procedure Insert(Idx: Integer; const Item: T); procedure Delete(Idx: Integer); function IndexOf(const Item: T): Integer; property Caption: string read GetCaption; end; TAuraParameterDef = record Name: String; ParamType: TAuraParameterType; DefaultValue: TAuraParameterValue; end; TAuraParameterRecordDef = TArray; // A bot executes a strategy IAuraBot = interface(IAuraLiveObject) function GetPnL: TMutable>; // Zero-based PnL series property PnL: TMutable> read GetPnL; end; // A strategy creates a bot that executes that strategy with given parameters and within a given time slot. IAuraStrategy = interface(IAuraObject) function CreateBot(const Parameters: TArray; StartTime, EndTime: TDateTime): IAuraBot; function GetParameterRecordDef: TAuraParameterRecordDef; // Defines the parameters of this strategy property ParameterRecordDef: TAuraParameterRecordDef read GetParameterRecordDef; end; // The performance of a backtest or walk forward optimization TAuraTradePerformance = record PnL: Double; SharpeRatio, MaxDrawdown, ProfitFactor, CalmarRatio, WinRate: Double; end; TAuraMonteCarloResult = record // Performance sorted by PnL and distributed to percentiles of 10% each Percentile: array[0..10] of TAuraTradePerformance; end; IAuraTradeResult = interface function GetPerformance: TAuraTradePerformance; function GetTrades: TDataSeries; // Perform Monte Carlo Simulation and generate performance distribution function CalcMonteCarloSimulation(Steps: Integer): TFuture; // PnLs of each trade = Equity curve property Trades: TDataSeries read GetTrades; // The performance of this equity curve property Performance: TAuraTradePerformance read GetPerformance; end; TAuraTimeRange = record StartTime: TDateTime; EndTime: TDateTime; end; // Backtesting IAuraBacktest = interface(IAuraLiveObject) function GetParameters: TArray; function GetStrategy: IAuraStrategy; function GetBot: IAuraBot; function GetBacktestResult: TFuture; function GetTimeRange: TAuraTimeRange; // The bot executing the backtest (generated by Strategy.CreateBot with the given parameters). property Bot: IAuraBot read GetBot; // The backtest result property BacktestResult: TFuture read GetBacktestResult; // The strategy parameters for this backtest property Parameters: TArray read GetParameters; // The strategy to backtest property Strategy: IAuraStrategy read GetStrategy; // The tested time window property TimeRange: TAuraTimeRange read GetTimeRange; end; // Generates parameter sets using genetic algorithms (or other techniques). // Executes backtests and finds the best run by evaluating the backtest results. IAuraParameterOptimization = interface(IAuraLiveObject) function GetInSampleTests: TMutable>; function GetOutOfSampleTest: TMutable; // The running in-sample-tests. New tests will be added until the optimization stops. property InSampleTests: TMutable> read GetInSampleTests; // After in sample testing is finished, the out-of-sample-test with the best parameter set is executed. property OutOfSampleTest: TMutable read GetOutOfSampleTest; end; // Walk-Forward-Optimizer IAuraWalkForwardOptimizer = interface(IAuraLiveObject) function GetOptimizationResult: TFuture; function GetSlot: TArray; // When optimization is ready, this will contain the result for the combined WFO slots property OptimizationResult: TFuture read GetOptimizationResult; // The concurrently running optimization slots property Slot: TArray read GetSlot; end; // A Parameter Value IAuraParameterNode = interface(IAuraNode) function GetValue: TMutable; property Value: TMutable read GetValue; end; IAuraParameterList = IAuraChilds; // A study on a strategy IAuraStudy = interface(IAuraNode) function GetEventLog: TStrings; function GetStrategy: IAuraStrategy; property EventLog: TStrings read GetEventLog; // The Strategy to optimize property Strategy: IAuraStrategy read GetStrategy; end; TAuraParameterRange = record MinValue, MaxValue: TAuraParameterValue; end; // Study on a single backtest IAuraBacktestStudy = interface(IAuraStudy) function GetTimeRange: TAuraTimeRange; function Start: IAuraBacktest; property TimeRange: TAuraTimeRange read GetTimeRange; end; // Study parameter optimization IAuraParameterOptimizationStudy = interface(IAuraStudy) function GetParameters: IAuraChilds; function GetTimeRange: TAuraTimeRange; function Start: IAuraParameterOptimization; // Depending on the implementation this may be MaxGenerations, PopulationSize, Mutations, etc property Parameters: IAuraChilds read GetParameters; property TimeRange: TAuraTimeRange read GetTimeRange; end; // Walk forward optimization IAuraWFOStudy = interface(IAuraStudy) function GetParameterRange(Idx: Integer): TWriteable; function GetNumSlots: TWriteable; // Starts WalkForwardOptimizer with the given number of NumSlots. function Start: IAuraWalkForwardOptimizer; // A list of parameter values to test, one for each parameter in the Strategy's parameter definition. // This defines the parameter space for optimization algorithms. property ParameterRange[Idx: Integer]: TWriteable read GetParameterRange; // Number of time slots (windows) to test. property NumSlots: TWriteable read GetNumSlots; end; TAuraTradingMode = (tmTesting, tmSim, tmLive); // Repesents the scope of a workspace IAuraWorkspace = interface(IAuraNode) ['{8485F7E7-F097-4CB8-8186-A6C9AE0048AF}'] // function GetWalkForwardAnalysis: IAuraChilds; // function GetBacktests: IAuraChilds; // function GetParameterOptimizations: IAuraChilds; // function GetWalkForwardAnalysis: IAuraChilds; // function GetBacktests: IAuraChilds; // function GetParameterOptimizations: IAuraChilds; // property WalkForwardAnalysis: IAuraChilds read GetWalkForwardAnalysis; // property Backtests: IAuraChilds read GetBacktests; // property ParameterOptimizations: IAuraChilds read GetParameterOptimizations; // property WalkForwardAnalysis: IAuraChilds read GetWalkForwardAnalysis; // property Backtests: IAuraChilds read GetBacktests; // property ParameterOptimizations: IAuraChilds read GetParameterOptimizations; function GetTradingMode: TWriteable; function GetStudies: TAuraArray; property TradingMode: TWriteable read GetTradingMode; property Studies: TAuraArray read GetStudies; end; IAuraModule = interface procedure SetupWorkspace(const Workspace: IAuraWorkspace); end; // Application singleton, the root for serialization IAuraApplication = interface(IAuraNode) function GetModuleNames: TMutable>; function GetModules(const Name: String): IAuraModule; function GetWorkspaces: IAuraChilds; procedure RegisterModule(const Name: String; const Module: IAuraModule); property ModuleNames: TMutable> read GetModuleNames; property Modules[const Name: String]: IAuraModule read GetModules; property Workspaces: IAuraChilds read GetWorkspaces; end; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Generic implementation for a collection of child nodes. TMycAuraObject = class(TInterfacedObject, IAuraObject) private FName: TWriteable; function GetName: TWriteable; procedure Serialize(const Write: TJsonWriter); public constructor Create(const AName: string); end; // Generic implementation for a collection of child nodes. TMycAuraNode = class(TInterfacedObject, IAuraNode) private FName: TWriteable; function GetName: TWriteable; protected function GetCaption: string; virtual; procedure Serialize(const Write: TJsonWriter); public constructor Create(const AName: string); end; // Generic implementation for a collection of child nodes. TMycAuraChilds = class(TInterfacedObject, IAuraChilds) private FName: TWriteable; FItems: TWriteable>; function GetCaption: string; function GetItems: TWriteable>; function GetName: TWriteable; procedure Serialize(const Write: TJsonWriter); public constructor Create(const AName: string); procedure Delete(Idx: Integer); function IndexOf(const Item: T): Integer; procedure Insert(Idx: Integer; const Item: T); end; TMycAuraWorkspace = class(TMycAuraNode, IAuraWorkspace) private FTradingMode: TWriteable; FStudies: TAuraArray; function GetStudies: TAuraArray; function GetTradingMode: TWriteable; protected function GetCaption: string; override; public constructor Create(const AName: string; TradingMode: TAuraTradingMode); end; TMycAuraApplication = class(TInterfacedObject, IAuraApplication) private FName: TWriteable; FModules: TDictionary; FModulesChanged: TEvent; FModuleNames: TMutable>; FWorkspaces: TAuraChilds; function GetCaption: string; function GetName: TWriteable; function GetModuleNames: TMutable>; function GetModules(const Name: String): IAuraModule; function GetWorkspaces: IAuraChilds; procedure Serialize(const Write: TJsonWriter); public constructor Create; procedure RegisterModule(const Name: String; const Module: IAuraModule); end; implementation { TMycAuraObject } constructor TMycAuraObject.Create(const AName: string); begin inherited Create; FName := TWriteable.CreateWriteable; FName.Value := AName; end; function TMycAuraObject.GetName: TWriteable; begin Result := FName; end; procedure TMycAuraObject.Serialize(const Write: TJsonWriter); begin Write.WriteStartObject; Write.WritePropertyName('Name'); Write.WriteValue(FName.Value); Write.WriteEndObject; end; { TMycAuraNode } constructor TMycAuraNode.Create(const AName: string); begin inherited Create; FName := TWriteable.CreateWriteable; FName.Value := AName; end; function TMycAuraNode.GetCaption: string; begin Result := FName.Value; end; function TMycAuraNode.GetName: TWriteable; begin Result := FName; end; procedure TMycAuraNode.Serialize(const Write: TJsonWriter); begin Write.WriteStartObject; inherited; Write.WriteEndObject; end; { TAuraArray } class operator TAuraArray.Initialize(out Dest: TAuraArray); begin Dest.FArray := TWriteable>.CreateWriteable; end; procedure TAuraArray.Delete(Idx: Integer); var oldArray: TArray; newArray: TArray; oldCount: Integer; begin oldArray := FArray.Value; oldCount := Length(oldArray); if (Idx < 0) or (Idx >= oldCount) then exit; SetLength(newArray, oldCount - 1); // Copy elements before the index if Idx > 0 then TArray.Copy(oldArray, newArray, 0, 0, Idx); // Copy elements after the index if Idx < oldCount - 1 then TArray.Copy(oldArray, newArray, Idx + 1, Idx, oldCount - Idx - 1); FArray.Value := newArray; end; procedure TAuraArray.Insert(Idx: Integer; const Item: T); var oldArray: TArray; newArray: TArray; oldCount: Integer; begin oldArray := FArray.Value; if not Assigned(oldArray) then SetLength(oldArray, 0); oldCount := Length(oldArray); if Idx < 0 then Idx := 0; if Idx > oldCount then Idx := oldCount; SetLength(newArray, oldCount + 1); // Copy elements before the index if Idx > 0 then TArray.Copy(oldArray, newArray, 0, 0, Idx); newArray[Idx] := Item; // Copy elements after the index if Idx < oldCount then TArray.Copy(oldArray, newArray, Idx, Idx + 1, oldCount - Idx); FArray.Value := newArray; end; function TAuraArray.GetItems: TWriteable>; begin Result := FArray; end; function TAuraArray.IndexOf(const Item: T): Integer; begin Result := TArray.IndexOf(FArray.Value, Item); end; { TMycAuraChilds } constructor TMycAuraChilds.Create(const AName: string); begin inherited Create; FName := TWriteable.CreateWriteable(AName); FItems := TWriteable>.CreateWriteable; end; procedure TMycAuraChilds.Delete(Idx: Integer); var oldArray: TArray; newArray: TArray; oldCount: Integer; begin oldArray := FItems.Value; oldCount := Length(oldArray); if (Idx < 0) or (Idx >= oldCount) then exit; SetLength(newArray, oldCount - 1); // Copy elements before the index if Idx > 0 then TArray.Copy(oldArray, newArray, 0, 0, Idx); // Copy elements after the index if Idx < oldCount - 1 then TArray.Copy(oldArray, newArray, Idx + 1, Idx, oldCount - Idx - 1); FItems.Value := newArray; end; function TMycAuraChilds.GetCaption: string; begin Result := FName.Value; end; function TMycAuraChilds.GetItems: TWriteable>; begin Result := FItems; end; function TMycAuraChilds.GetName: TWriteable; begin Result := FName; end; function TMycAuraChilds.IndexOf(const Item: T): Integer; begin Result := TArray.IndexOf(FItems.Value, Item); end; procedure TMycAuraChilds.Insert(Idx: Integer; const Item: T); var oldArray: TArray; newArray: TArray; oldCount: Integer; begin oldArray := FItems.Value; if not Assigned(oldArray) then SetLength(oldArray, 0); oldCount := Length(oldArray); if Idx < 0 then Idx := 0; if Idx > oldCount then Idx := oldCount; SetLength(newArray, oldCount + 1); // Copy elements before the index if Idx > 0 then TArray.Copy(oldArray, newArray, 0, 0, Idx); newArray[Idx] := Item; // Copy elements after the index if Idx < oldCount then TArray.Copy(oldArray, newArray, Idx, Idx + 1, oldCount - Idx); FItems.Value := newArray; end; procedure TMycAuraChilds.Serialize(const Write: TJsonWriter); var Item: T; arr: TArray; begin Write.WriteStartObject; inherited; Write.WritePropertyName('Items'); Write.WriteStartArray; arr := FItems.Value; for Item in arr do Item.Serialize(Write); Write.WriteEndArray; Write.WriteEndObject; end; { TMycAuraApplication } constructor TMycAuraApplication.Create; begin inherited Create; FName := TWriteable.CreateWriteable('Application'); FModules := TDictionary.Create; FModulesChanged := TEvent.CreateEvent; FModuleNames := TMutable>.Construct(FModulesChanged.Signal, function: TArray begin Result := FModules.Keys.ToArray; end); FWorkspaces := TMycAuraChilds.Create('Workspaces'); end; function TMycAuraApplication.GetCaption: string; begin Result := FName.Value; end; function TMycAuraApplication.GetName: TWriteable; begin Result := FName; end; function TMycAuraApplication.GetModuleNames: TMutable>; begin Result := FModuleNames; end; function TMycAuraApplication.GetModules(const Name: String): IAuraModule; begin if not FModules.TryGetValue(Name, Result) then Result := nil; end; function TMycAuraApplication.GetWorkspaces: IAuraChilds; begin Result := FWorkspaces; end; procedure TMycAuraApplication.RegisterModule(const Name: String; const Module: IAuraModule); begin FModules.Add(Name, Module); FModulesChanged.Notify; end; procedure TMycAuraApplication.Serialize(const Write: TJsonWriter); begin Write.WriteStartObject; Write.WritePropertyName('Name'); Write.WriteValue(FName.Value); Write.WritePropertyName('Workspaces'); FWorkspaces.Serialize(Write); Write.WriteEndObject; end; function CreateAuraApplication: IAuraApplication; begin Result := TMycAuraApplication.Create; end; constructor TMycAuraWorkspace.Create(const AName: string; TradingMode: TAuraTradingMode); begin inherited Create(AName); FTradingMode := TWriteable.CreateWriteable(TradingMode); end; function TMycAuraWorkspace.GetCaption: string; begin var mode := ''; case FTradingMode.Value of tmTesting: mode := ' (Test)'; tmSim: mode := ' (Sim)'; tmLive: mode := ' (Live)'; end; Result := inherited GetCaption + mode; end; function TMycAuraWorkspace.GetStudies: TAuraArray; begin Result := FStudies; end; function TMycAuraWorkspace.GetTradingMode: TWriteable; begin Result := FTradingMode; end; constructor TAuraChilds.Create(const AChilds: IAuraChilds); begin FChilds := AChilds; end; procedure TAuraChilds.Delete(Idx: Integer); begin FChilds.Delete(Idx); end; function TAuraChilds.GetCaption: string; begin Result := FChilds.Caption; end; function TAuraChilds.IndexOf(const Item: T): Integer; begin Result := FChilds.IndexOf(Item); end; procedure TAuraChilds.Insert(Idx: Integer; const Item: T); begin FChilds.Insert(Idx, Item); end; procedure TAuraChilds.Serialize(const Write: TJsonWriter); begin FChilds.Serialize(Write); end; class operator TAuraChilds.Implicit(const A: IAuraChilds): TAuraChilds; begin Result.Create(A); end; class operator TAuraChilds.Implicit(const A: TAuraChilds): IAuraChilds; begin Result := A.FChilds; end; end.