Table of Contents

Chart strategies: overview and lifecycle

A chart strategy is a chart indicator that also trades. ChartStrategy inherits from Indicator, so a strategy receives the same bars, trades and order book as an indicator, draws its data series the same way, and in addition holds a position, sends orders and receives the trading events of the chart.

What you build

Create a class library (see Project setup), inherit from ChartStrategy and put the trading logic into OnCalculate. The minimal strategy below sends one market buy order when a bar closes above the high of the previous bar.

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;

using ATAS.DataFeedsCore;
using ATAS.Strategies.Chart;
using Utils.Common.Logging;

namespace ATAS.Docs.Samples.ChartStrategies;

/// <summary>
/// A breakout strategy: one market buy order when a bar closes above the high of the previous bar.
/// It trades for real once started on a live account.
/// </summary>
[DisplayName("Breakout sample")]
public class BreakoutSampleStrategy : ChartStrategy
{
    private Order? _order;

    [Display(Name = "Order volume", GroupName = "Settings", Order = 10)]
    [Range(1, 1000)]
    public decimal OrderVolume { get; set; } = 1;

    protected override void OnCalculate(int bar, decimal value)
    {
        // CanProcess is true only for the last bar of a started strategy:
        // nothing is sent while the history is being calculated.
        if (!CanProcess(bar) || bar < 1 || _order != null)
            return;

        var candle = GetCandle(bar);
        var previous = GetCandle(bar - 1);

        if (candle.Close <= previous.High)
            return;

        _order = new Order
        {
            Portfolio = Portfolio,
            Security = Security,
            Direction = OrderDirections.Buy,
            Type = OrderTypes.Market,
            QuantityToFill = OrderVolume,
        };

        _ = PlaceAsync(_order);
    }

    protected override void OnOrderChanged(Order order)
    {
        // The handler receives every order of the chart instrument and portfolio, including manual ones.
        if (order != _order)
            return;

        if (order.State == OrderStates.Failed || order.Status() == OrderStatus.Canceled)
            _order = null; // allow a new attempt
    }

    private async Task PlaceAsync(Order order)
    {
        try
        {
            await OpenOrderAsync(order);
        }
        catch (Exception e)
        {
            this.LogError("Order placement failed.", e);
            _order = null;
        }
    }
}

Two things in it are specific to strategies:

  • CanProcess is true only for the last bar of a started strategy, so nothing is sent while the history is being calculated.
  • Orders are sent with OpenOrderAsync; the result arrives through the order handlers (OnOrderChanged and the others, see below), which receive every order of the chart instrument and portfolio, including the orders placed by hand.

The built strategy is installed into the strategies folder of the platform:

  • %APPDATA%\ATAS\Strategies for the classic ATAS;
  • %APPDATA%\ATAS X\Strategies for ATAS X on Windows;
  • ~/Library/Application Support/ATAS/Strategies for ATAS X on macOS.

Copy the DLL there after the build (or add a post-build step that does it). In the classic ATAS, click the blinking button in the strategies window for the changed list of strategies to take effect.

Updating the strategy list

To add the strategy to a chart, open the chart context menu, click the strategy list icon, select the strategy and click Add. The control button of the strategy starts and stops it.

Loading a chart strategy

Properties and methods

In addition to the indicator API, a strategy has:

Properties

Order methods

Virtual methods to override when needed:

  • OnStarted: the strategy was started;
  • OnStopping: the strategy is about to stop. It is still started at this moment, so orders placed here (for example, to close the position) are sent;
  • OnStopped: the strategy was stopped;
  • OnSuspended: the strategy was suspended by SuspendAsync, after OnStopping and before OnStopped. The platform itself never suspends a chart strategy: when a chart with a strategy is closed, the strategy is stopped;
  • OnCurrentPositionChanged: the strategy's position changed;
  • CanProcess: whether trading is possible right now. By default it checks that the strategy is started and the bar being processed is the last one.

If you override the indicator handlers in a strategy, call their base implementation: the strategy calculates its position and PnL in OnNewMyTrade and OnBestBidAskChanged, and without the base call these values are not updated.

Lifecycle

A strategy is calculated and drawn like an indicator, on the same threads: see Lifecycle and threads. The calls of all the extension kinds side by side are in Call model.

  • A strategy does not start if no instrument or portfolio is selected on the chart; an error notification is shown instead.
  • Orders are sent only while the strategy is started: in any other state the order methods return without sending anything.
  • The platform stops the strategy itself when the instrument, the time frame or the portfolio of the chart is changed, when the chart history is reloaded and when the chart is closed. When the connection is lost, the strategy is stopped too, and it is started again automatically when the same instrument and portfolio become available.
  • When a strategy is stopped, its position and its lists of orders and trades are reset.

Positions

Every strategy holds its own position, which can differ from the position of the account: the account position is TradingManager.Position, the strategy position is CurrentPosition with AveragePrice.

Important

When a strategy is stopped, its internal position is reset to zero, but the position on the account stays. Override OnStopping and close the position and cancel the working orders there.

Next

  • Orders: placing, changing and cancelling orders, following their results, the order options.
  • Trading data and events: the portfolio, the position, the orders and trades of the chart, and the trading statistics.
  • Full example: SMA cross: a complete strategy with settings, signals and position handling.