Robots API

Getting Started

When you create a robot you will see the predefined robot class template:

using System;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo.Robots
{
    [Robot("New Robot")]
    public class NewRobot : Robot
    {
        protected override void OnStart()
        {
            // Put your initialization logic here
        }

        protected override void OnTick()
        {
            // Put your core logic here
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

NewRobot class here is already inherited from its base class – Robot. In order to use this class as a robot we must mark it by the [Robot] attribute. It is already applied to the class in the template.

Now you can rename the class. Let’s call it MyFirstRobot and change its friendly name:

[Robot("First Robot!")]
public class MyFirstRobot : Robot 

Robot Lifecycle

The Base Robot class has a set of virtual methods that can be overridden by you robot. In the default robot template you can see three of them:

  • OnStart() is an event handler to be called during the Robot initialization (when Robot is activated on the chart). Here you can put some initialization logic, for example create indicators or execute orders that must be executed on start.
  • OnTick() is called on each tick. It is a good place to check signals from indicators, execute, modify or close orders, etc.
  • OnStop() is called when the robot is stopped. You can put some deinitialization logic in this method.

You can also manually override several trade-related methods to handle trade events.

See Trading below for more details.

BACK TO TOP []
 

Trading

Performing trade operations is a vital function of any robot. Robots can create positions and pending orders, set Stop Loss / Take Profit rates, and modify and close orders.

How to open a position

For opening a position Trade object must be used. It contains several trade-related methods for sending your trade requests to the server.

For example, to create and execute a market order to buy 100k of current symbol, on robot start we do the following:

protected override void OnStart()
{
    Trade.CreateBuyMarketOrder(Symbol, 100000);
} 

In this example we use Trade object and its CreateBuyMarketOrder method to create and send market order to the server. This method accepts two parameters: symbol and volume. For the first one we use Symbol object - symbol this robot is attached to. Volume is a constant. As a result new market order will be creared and sent.

You can also use the following method to create an order:

  • CreateBuyMarketOrder(symbol, volume)
  • CreateSellMarketOrder(symbol, volume)
  • CreateMarketOrder(tradeType, symbolCode, volume)
  • CreateBuyLimitOrder(symbol, volume, targetPrice)
  • CreateSellLimitOrder(symbol, volume, targetPrice)
  • CreateBuyStopOrder(symbol, volume, targetPrice)
  • CreateSellStopOrder(symbol, volume, targetPrice)

As you can see there are different methods for different types of orders. These methods can have different parameters, for example if you create a limit order, the target price must be specified.

Once you open a position you can store it in a variable so that you can close it or perform other operations in future:

private Position myPosition;

protected override void OnStart()
{
    Trade.CreateBuyMarketOrder(Symbol, 100000);
}

protected override void OnPositionOpened(Position openedPosition)
{
    myPosition = openedPosition;
    Print("Position {0} is opened, entry price is {1}", myPosition.Id, myPosition.EntryPrice);
}

Here we override OnPositionOpened method to receive newly created position, then we store it and print message to the robot log.

How to close a position

In the example below I close position stored in myPosition variable when the price goes above a specified rate:

private Position myPosition;

protected override void OnTick()
{
    if (myPosition != null && Symbol.Bid > 1.3808)
    {
        Trade.Close(myPosition)
    }
}

Method OnTick() is called every time new tick comes, each time we check the symbol bid and if it is greater than specified price we close the position. We also check that position is already stored with condition position != null, if we have no position we can not close it. To do this we call Close(position) method of Trade object that sends close request to the server. Althought request is sent when

How to set Stop Loss / Take Profit

Since stop loss and take profit can be specified for existing position only we must modify it when it's opened. To do this we override OnPositionOpened method. In the following example I set the Stop Loss and Take Profit 30 pips from the entry price of newly opened position:

protected override void OnPositionOpened(Position openedPosition)
{
    double newStopLoss = position.EntryPrice - 30 * Symbol.PipSize;
    double newTakeProfit = position.EntryPrice + 30 * Symbol.PipSize;
    Trade.ModifyPosition(position, newStopLossPrice, newTakeProfit);
} 

In case we do not want to have Stop Loss or Take Profit for our position we must pass null for appropriate argument. In this example I set only Take Profit level without Take Profit:

Trade.ModifyPosition(position, null, newTakeProfit);

If we want to set new Stop Loss level, but leave take profit as it was before we can take old Take Profit value from the position:

Trade.ModifyPosition(position, newStopLoss, position.TakeProfit);

BACK TO TOP []
 

Declaring Parameters

Usually robots use some external parameters in their algorithms. In the following example a robot accepts Volume, StopLoss and MaxSpread as parameters. The algorithm will create a market order with the Volume and Stop Loss values as long as the current spread is less the than the given Maximum Spread value.

[Robot("First Robot")]
public class FirstRobot : Robot
{
    [Parameter("Volume", DefaultValue = 100000, MinValue = 10000, MaxValue = 10000000)]
    public int Volume { get; set; }

    [Parameter("Stop Loss (pips)", DefaultValue = 10, MinValue = 1)]
    public int StopLoss { get; set; }
    
    [Parameter("Maximum Spread", DefaultValue = 1.5, MinValue = 0.1)]
    public double MaxSpread { get; set; }

    protected override void OnStart()
    {
        if (Symbol.Spread < MaxSpread) 
    	{
    	    Trade.CreateBuyMarketOrder(Symbol.Code, Volume);   
            Trade.Execute(order);  
        }
    }

    protected override void OnPositionOpened(Position openedPosition)
    {
        double? stopLossPrice = position.EntryPrice - StopLoss * Symbol.PipSize;
        Trade.ModifyPosition(position, stopLossPrice, null);
    }
}

There are several supported data types for parameters:

  • int – Integer value, e.g. distance in pips, order volume.
  • double – Floating point number, e.g. price, indicator value
  • DataSeries – Market price series. User can choose whether to use Open, High, Low or Close series.
  • MovingAverageType – Type of moving average that can be used in indicators (see Indicators chapter).

When you create an instance of this robot you will be able to set values for the specified parameters.

Symbol and Timeframe are common parameters which define all charts for a robot. These parameters are present in the left menu for every instance of every robot.

BACK TO TOP []
 

Using Indicators

Most trading strategies are based on technical indicators. You can access built-in indicators from your robot or custom indicators. With each tick, these indicators are recalculated by the platform prior to the robot receiving the signal.

If your robot uses indicator it must be created in the OnStart() method and stored in a field. To do this, use the Indicators object, which contains all methods for built-in indicators:

Indicators.BollingerBands(source, periods, deviations, maType)

In the following example the robot creates two Simple Moving Average indicators. In the OnTick() method the robot compares the last values of both indicators (the values are sorted chronologically so the last indicator value corresponds to the last trend bar in the current timeframe). An order will be created if the value of a fast moving average is greater than thelast value of the slow moving average.

private MovingAverage slowMa;
private MovingAverage fastMa;

protected override void OnStart()
{
    fastMa = Indicators.SimpleMovingAverage(MarketSeries.Close, 15);
    slowMa = Indicators.SimpleMovingAverage(MarketSeries.Close, 40);
}

protected override void OnTick()
{
    if (fastMa.Result.LastValue > slowMa.Result.LastValue)
    {
        Trade.CreateBuyMarketOrder(Symbol, 10000);
    }
}

BACK TO TOP []
 

Accessing Symbol Properties

Each robot is attached to a specified chart, so it has a specified symbol and timeframe. To access symbol values, the Symbol property can be used. The Symbol object has a set of symbol-related properties:

  • Ask – Current ask price
  • Bid - Current bid price
  • Spread – Current spread, difference between Ask and Bid
  • Code – Symbol code, e.g. “USDJPY”
  • PipSize – size of one pip, e.g. 0.0001 if pip is 4th digit
  • PointSize – size of one pip, e.g. 0.00001 for 5-digits symbol
  • Digits – Number of digits after the point, e.g. 4 or 5

The following code creates a Sell Limit order for the current symbol with a target price 100 pips above the current bid price.

double targetPrice = Symbol.Bid + Symbol.PipSize * 100;   		
Trade.CreateSellLimitOrder(Symbol, 200000, targetPrice);

BACK TO TOP []
 

Accessing Account Information

If the robot needs to access current account properties, the Account object can be used. It contains general account information and current account state:

  • Balance – current balance
  • Currency – Account currency, e.g. “EUR”
  • Equity – Current equity (balance plus unrealized profit and loss)
  • Margin – Current margin
  • FreeMargin – Current free margin
  • MarginLevel – Margin level

In the example below a trade will be placed only if margin is less than half of equity:

if (Account.Margin > Account.Equity / 2)
{
    // Continue trading
}

Printing to robot's log

For printing messages to robot's log use Print() method. For example if I want to log that my robot is started and when position is opened i want to print messages like this:

  • My order to Buy 20000 of EURUSD is opened at price 1.38792
  • Balance is 1069.29

I write following code:

protected override void OnStart()
{
    Print("My robot is started!");
}

protected override void OnPositionOpened(Position position)
{
    Print("My order to {0} {1} of {2} is opened at price {3}",
        position.TradeType, position.Volume, position.SymbolCode, position.EntryPrice);
       
    Print("Balance is {0}", Account.Balance);
}

You can specify message format in standard .NET format with parameter placeholders and list of parameter values. As a result the log of the robot will look like this:

Robot's log

You can also see some system log messages that are printed automatically to the log.

BACK TO TOP []