Project setup
Every extension (indicator, strategy, heatmap indicator, column, module or connector) is a .NET class library that references the platform API and is loaded by the installed platform at run time. This article shows how to create such a project, what it has to target and where its output goes.
You need the .NET 10 SDK and an IDE: Visual Studio 2022, JetBrains Rider or VS Code with the C# extension. To run the result, install the classic ATAS or ATAS X.
Target framework and platform
| Your project targets | Platform | Notes |
|---|---|---|
net10.0-windows |
Classic ATAS; ATAS X loads the same DLL after an automatic conversion | WPF types (System.Windows.Media.Color, keys, GDI+ brushes) come with UseWPF |
net10.0 |
ATAS X only (Windows and macOS) | Cross-platform types instead of WPF; needed only for Avalonia custom editors |
The current versions of both the classic ATAS and ATAS X run on .NET 10, so a single net10.0-windows build is
enough for both: at load time ATAS X converts System.Windows.Media.Color and Colors, System.Windows.Input.Key
and KeyEventArgs, System.Windows.Point and the GDI+ SolidBrush, Pen and Font to their cross-platform
counterparts. Any other WPF type in the assembly (brushes, Rect, Dispatcher, MessageBox, controls, XAML) makes
ATAS X skip the whole file and write the reason to the log (Rejected assembly: ...). Custom WPF property editors are
the usual reason for a separate net10.0 build with Avalonia editors.
The target framework must match the runtime of the platform you load the DLL into. The platform version number in the
lower-right corner of the main window does not tell the runtime; the tfm value in OFT.Platform.runtimeconfig.json
(classic ATAS) or OFT.PlatformX.runtimeconfig.json (ATAS X) next to the platform executable does. To support an
older platform build that still runs on .NET 8, build for both runtimes at once
(<TargetFrameworks>net8.0-windows;net10.0-windows</TargetFrameworks>) and install the DLL from the matching output
folder.
Choosing the framework is a matter of compatibility, not performance: the .NET version has virtually no effect on the execution speed of an indicator.
References to the platform assemblies
Reference the assemblies of the installed platform directly. Private=false keeps them out
of your build output: only your own DLL is copied to the platform. UseWPF brings in the WPF types that the API uses
(for example System.Windows.Media.Color).
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<!-- The folder where the ATAS platform is installed -->
<ATAS_BASE>C:\Program Files (x86)\ATAS Platform</ATAS_BASE>
</PropertyGroup>
<ItemGroup>
<Reference Include="ATAS.Indicators">
<HintPath>$(ATAS_BASE)\ATAS.Indicators.dll</HintPath>
<Private>false</Private>
</Reference>
<!-- Chart strategies -->
<Reference Include="ATAS.Strategies">
<HintPath>$(ATAS_BASE)\ATAS.Strategies.dll</HintPath>
<Private>false</Private>
</Reference>
<!-- Built-in indicators (SMA, EMA and others) to compose from -->
<Reference Include="ATAS.Indicators.Technical">
<HintPath>$(ATAS_BASE)\ATAS.Indicators.Technical.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="ATAS.DataFeedsCore">
<HintPath>$(ATAS_BASE)\ATAS.DataFeedsCore.dll</HintPath>
<Private>false</Private>
</Reference>
<!-- Attributes such as [FeatureId] and the property editors -->
<Reference Include="OFT.Attributes">
<HintPath>$(ATAS_BASE)\OFT.Attributes.dll</HintPath>
<Private>false</Private>
</Reference>
<!-- Drawing in OnRender -->
<Reference Include="OFT.Rendering">
<HintPath>$(ATAS_BASE)\OFT.Rendering.dll</HintPath>
<Private>false</Private>
</Reference>
<!-- Logging -->
<Reference Include="Utils.Common">
<HintPath>$(ATAS_BASE)\Utils.Common.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
</Project>
ATAS.Indicators is the only required reference; drop the others your extension does not use. The default
installation folders are C:\Program Files (x86)\ATAS Platform for the classic ATAS and C:\Program Files\ATAS X
for ATAS X on Windows. On macOS the assemblies are inside the application bundle, /Applications/ATAS X.app/Contents/MonoBundle/ for a default install (in Finder, right-click the app and choose Show Package Contents).
When building for several frameworks, the referenced assemblies must be compatible with every target: if they belong to a newer runtime than a target framework, the build for the lower target fails, and you need the assemblies of the corresponding platform version.
Where the platform looks for your DLL
| Extension kind | Folder (classic ATAS / ATAS X on Windows) | Reload |
|---|---|---|
| Chart indicators, heatmap indicators, SmartDOM and Watchlist columns, custom modules | Extensions or Indicators in %APPDATA%\ATAS / in %APPDATA%\ATAS X |
Without a restart, see below |
| Chart strategies | %APPDATA%\ATAS\Strategies / %APPDATA%\ATAS X\Strategies |
The classic ATAS shows a blinking button in the strategies window |
| Connectors | %APPDATA%\ATAS\CustomConnectors / %APPDATA%\ATAS X\CustomConnectors |
At start-up only: replacing the DLL needs a restart |
On macOS the folders are ~/Library/Application Support/ATAS/Extensions, .../Indicators, .../Strategies and
.../CustomConnectors.
Extensions and Indicators are equal: the platform reads both with one loader; Indicators is the historical name.
Keep one copy of an assembly: when the same assembly is in both folders, the platform loads the copy with the higher
assembly version and reports the other one as skipped. A single assembly may contain any number of indicators,
heatmap indicators, columns and modules; connectors are the exception and ship as a separate DLL.
Besides copying the file, the Add custom indicator button of the indicators window installs a DLL into the
Indicators folder and loads it at once, on both platforms.
The platform watches the folders, so a new or replaced DLL is loaded while the platform runs:
- ATAS X reloads the libraries by itself about a second after the files stop changing and shows a notification with the result;
- the classic ATAS shows a reload button in the status bar of the main window when the files changed; the libraries are reloaded when you press it.
Open charts take their indicators again from the new build. The result is reported per file, in the notification and in the platform log: a file that cannot be loaded is named with the reason, and the other files are loaded all the same. A file that a build is still writing is tried again (ATAS X does it by itself for several seconds; in the classic ATAS press the reload button again).