Skip to content

cBot Trading Operations

In this guide, we explain in detail the key trading operations you can execute using a cBot developed via the Algo API.

The 'Algo' application of cTrader supports the following operations for cBots.

  • Sending market orders
  • Placing pending orders
  • Modifying pending orders and open positions
  • Closing positions and canceling orders
  • Subscribing to trading events (i.e., positions and orders).

Sending Market Orders

A market order is sent to the trading server when the ExecuteMarketOrder() method is called. After creating a new cBot, you can add this method with several defined properties of the market order (e.g., symbol, volume, take profit, stop loss, etc.). The below example places a market order when the cBot starts.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class TradeOperations : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "", 10, 10, "", false);
        }       
    }
}

Tip

In the example, several order parameters were intentionally left undefined "". Check References for the signatures and order of all ExecuteMarketOrder() parameters.

Upon building the cBot and adding an instance, you will see that a market order with the specified parameters was executed at the start. The ‘Positions’ and ‘Log’ tabs in the TradeWatch panel display the corresponding position and log entries.

Positions

Log

Placing Pending Orders

cTrader supports three types of pending orders, namely stop orders, limit orders, and stop limit orders. To place pending orders at the start, you can replace the market order with the following snippets of code in the earlier cBot example.

1
2
3
PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
PlaceLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask - (Symbol.PipSize * 10), "", 10, 10, null, "", false);
PlaceStopLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), 2, "", 10, 10, null, "", false);

Tip

To quickly inspect the parameters of a method, start typing the method name and an opening parenthesis. You will see an IntelliSense pop-up with additional information.

Image title

Tip

If you click on a method/parameter in cTrader Algo and press F1, the help panel to the right of the code window will show the matching search results. If the text cursor remains outside of the code window and you press F1, the ‘Help Centre’ window will appear to assist you.

You will see the following records in the 'TradeWatch' panel after successful building and running the cBot.

Orders

Log

Modifying Pending Orders and Open Positions

When the pending orders are placed, they become available in your cBot PendingOrders collection. Through this collection, you can access and modify them. The existing pending orders can be modified by adjusting their stop loss level as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
protected override void OnStart()
{
    PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
    PlaceLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask - (Symbol.PipSize * 10), "", 10, 10, null, "", false);
    PlaceStopLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), 2, "", 10, 10, null, "", false);

    foreach(var order in PendingOrders.Where(p => p.SymbolName == SymbolName))
    {
        order.ModifyStopLossPips(20);
    }
}     

The ‘Log’ tab of the 'TradeWatch' panel displays that the three pending orders were successfully modified immediately after being placed.

Image title

After the different order types are executed successfully, positions will be opened for your account. All open positions are available in the Positions collection of your cBot. Similarly to modifying the pending orders in the previous example, you can modify the open position. Since market orders are the fastest way to open positions, let’s add the OnBar() method with a position modification action to the first cBot in this guide.

1
2
3
4
5
6
7
protected override void OnBar()
{
    foreach(var position in Positions.Where(p => p.SymbolName == SymbolName))
    {
        position.ModifyTakeProfitPips(20);
    }
}

As reflected in the log, the open position was modified on the first opened bar.

Image title

Closing Positions and Canceling Orders

You can find a cBot example below that closes all open positions and cancels all pending orders on Friday at 11:00 (UTC) calling the OnTick() method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class TradeOperations : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "", 10, 10, "", false);
            PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
        }  

        protected override void OnTick()
        {
            if(Server.Time.DayOfWeek == DayOfWeek.Friday && Server.Time.Hour >= 11)
            {
                foreach(var position in Positions.Where(p => p.SymbolName == SymbolName))
                {
                    position.Close();    
                }

                foreach(var order in PendingOrders.Where(p => p.SymbolName == SymbolName))
                {
                    order.Cancel();
                }
            }
        }
    }
}

Image title

Subscribing to Trading Events

cTrader allows algorithm developers to subscribe to trading events and monitor trading activity, no matter if these have been initiated by a cBot or manually. It is achieved by listening to events available in the two collections demonstrated earlier, Positions and PendingOrders.

There are three events available for positions:

  • Open
  • Modified
  • Closed

They are triggered when you open, modify, and close the positions on your account, respectively.

In the below code snippet, the three events are declared in the OnStart() method and the methods to be called are assigned. These will automatically create the code signatures for us to use. Afterward, Print() statements are added to each of the event methods.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
protected override void OnStart()
{
    Positions.Opened += Positions_Opened;
    Positions.Modified += Positions_Modified;
    Positions.Closed += Positions_Closed;                    
}  

private void Positions_Opened(PositionOpenedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was opened");
}

private void Positions_Modified(PositionModifiedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was modified");
}

private void Positions_Closed(PositionClosedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was closed");
}   

Whether it is you or the cBot who performs the Open, Modified, and Closed events, the algorithm will reach to them each time with printed messages as shown in the Log below.

Image title

Similarly, you can subscribe to events related to pending orders. There are four available events for pending orders:

  • `Created’
  • Modified
  • Filled
  • Canceled.

The four events are declared in the OnStart() method, and the event handlers are added as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
protected override void OnStart()
{
    PendingOrders.Created += PendingOrders_Created;
    PendingOrders.Modified += PendingOrders_Modified;
    PendingOrders.Filled += PendingOrders_Filled;
    PendingOrders.Cancelled += PendingOrders_Cancelled;
}

private void PendingOrders_Created(PendingOrderCreatedEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was created");
}

private void PendingOrders_Modified(PendingOrderModifiedEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was modified");
}

private void PendingOrders_Filled(PendingOrderFilledEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was filled");
}

private void PendingOrders_Cancelled(PendingOrderCancelledEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was cancelled");
}       

If subscribed to the events related to pending orders, the cBot will react to both manual and programmed trading activities.

Image title

Summary

To conclude, cTrader equips algorithm developers with an impressive arsenal of trading operations that can be executed by cBots. By skillfully applying them, you can pursue tailored and sophisticated trading strategies.

Subscribe to our YouTube channel