Click to Show Menu

cBot Code Samples

Synchronous Operation Method

Executing Market Orders
  1. A simple cBot with a successful result.

The following simple cBot creates a Market Order upon startup and saves the result in the result variable. If the order execution is successful the entry price is printed to the log.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, Symbol, 10000);

            if (result.IsSuccessful)
            {
                var position = result.Position;
                Print("Position entry price is {0}", position.EntryPrice);
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD
→ Executing Market Order to Buy 10000 EURUSD SUCCEEDED, Position PID14576001
Position entry price is 1.19067

  1. A simple cBot with an unsuccessful result.

If we modify the volume parameter in the previous example to -1 which is not a valid value for a volume, we will get the error printed in the log. This example shows how you can modify the cBots to stop in case there is an error.

[Robot(TimeZone = TimeZones.UTC)]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, Symbol, -1);

            if (!result.IsSuccessful)
                Stop();
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy -1 EURUSD
→ Executing Market Order to Buy -1 EURUSD FAILED with error "BadVolume"
cBot "New cBot" was stopped for EURUSD, h1.

  1. Execute a Market Order with more parameters.

In the previous example, we have used the minimum parameters in the ExecuteMarketOrder method. They were the Trade type (TradeType.Buy), the Symbol (Symbol) and the Volume (-1).

The additional optional parameters are Label, Stop Loss, Take Profit, Slippage and the Comment. The example below specifies the label ("order 1"), Stop Loss protection (10), and Take Profit protection (10) as well.

[Robot(TimeZone = TimeZones.UTC)]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "order 1", 10, 10);

            if (result.IsSuccessful)
            {
                var position = result.Position;
                Print("Position entry price is {0}", position.EntryPrice);
                Print("Position SL price is {0}", position.StopLoss);
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD (SL: 10, TP: 10)
→ Executing Market Order to Buy 10000 EURUSD (SL: 10, TP: 10) SUCCEEDED, Position PID14576098
Position entry price is 1.1896
Position SL price is 1.1886

Modifying a Position

Modify Take Profit

In the example below we add only Take Profit value (10) when the order is executed, and then we modify the position to add Stop Loss as well. In order to omit the Stop Loss parameter, we have to write null in its place.

[Robot()]
    public class SamplecBbot : Robot
    {
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, Symbol, 10000,
                                    "order 1", null, 10);
            if (result.IsSuccessful)
            {
                var position = result.Position;
                Print("Position SL price is {0}", position.StopLoss);

                var stopLoss = position.EntryPrice - 10*Symbol.PipSize;
                ModifyPosition(position, stopLoss, position.TakeProfit);

                Print("New Position SL price is {0}", position.StopLoss);

            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD (TP: 10)
→ Executing Market Order to Buy 10000 EURUSD (TP: 10) SUCCEEDED, Position PID14576161
Position SL price is null
Modifying position PID14576161 (SL: 1.18744, TP: 1.18944)
→ Modifying position PID14576161 (SL: 1.18744, TP: 1.18944) SUCCEEDED, Position PID14576161
New Position SL price is 1.18744

Closing a Position
  1. Close position.

The code sample below creates a Market Order and if the position Gross Profit is above a certain value (null && position.GrossProfit > 10), it closes the position.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "myLabel");
        }

        protected override void OnTick()
        {
            var position = Positions.Find("myLabel");
            if (position != null && position.GrossProfit > 10)
            {
                ClosePosition(position);
                Stop();
            }
        }
    }

Log output:

|10/05/2018 14:55:17.901 | cBot "New cBot" was started successfully for EURUSD, h1.
|10/05/2018 14:55:17.901 | Executing Market Order to Buy 10000 EURUSD
|10/05/2018 14:55:18.292 | → Executing Market Order to Buy 10000 EURUSD SUCCEEDED, Position PID14576180

  1. Partial Close.

Let’s modify the previous example to create two market orders with the same labels ("myLabel"). On each new incoming bar, the cBot will look for the order with one of two labels and close only half of it, if the volume is equal to or greater than 20,000. Here we illustrate the method FindAll (Positions.FindAll) which returns an array of positions that we can loop through.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, Symbol, 20000, "myLabel");
            ExecuteMarketOrder(TradeType.Buy, Symbol, 30000, "myLabel");
        }

        protected override void OnBar()
        {
            var positions = Positions.FindAll("myLabel", Symbol, TradeType.Buy);

            foreach (var position in positions)
            {
                if (position.VolumeInUnits >= 20000)
                {
                    ClosePosition(position, 15000);
                }
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 20000 EURUSD
→ Executing Market Order to Buy 20000 EURUSD SUCCEEDED, Position PID14579299
Executing Market Order to Buy 30000 EURUSD
→ Executing Market Order to Buy 30000 EURUSD SUCCEEDED, Position PID14579300

Creating Pending Orders
  1. Creating Limit and Stop Orders.

Limit and Stop Orders are pending orders but they are created in a similar way to the Market Orders. The difference is that their target price must be specified and there is no market range. The cBot below creates two Limit Orders and a Stop Order, loops through the orders and prints their label and IDs to the log.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            PlaceLimitOrder(TradeType.Buy, Symbol, 10000, Symbol.Bid, "myLimitOrder");
            PlaceLimitOrder(TradeType.Buy, Symbol, 20000, Symbol.Bid-2*Symbol.PipSize,
                    "myLimitOrder");
            PlaceStopOrder(TradeType.Buy, Symbol, 10000, Symbol.Ask, "myStopOrder");

            foreach (var pendingOrder in PendingOrders)
            {
                 Print("Order placed with label {0}, id {1}",
                                              pendingOrder.Label, pendingOrder.Id);
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Placing Limit Order to Buy 10000 EURUSD (Price: 1.19036)
→ Placing Limit Order to Buy 10000 EURUSD (Price: 1.19036) SUCCEEDED, PendingOrder OID25220794
Placing Limit Order to Buy 20000 EURUSD (Price: 1.19017)
→ Placing Limit Order to Buy 20000 EURUSD (Price: 1.19017) SUCCEEDED, PendingOrder OID25220795
Placing Stop Order to Buy 10000 EURUSD (Price: 1.19040)
→ Placing Stop Order to Buy 10000 EURUSD (Price: 1.19040) SUCCEEDED, PendingOrder OID25220796
Order placed with label myLimitOrder, id 25220794
Order placed with label myLimitOrder, id 25220795
Order placed with label myStopOrder, id 25220796

  1. Creating pending orders with more parameters.

Just as with the Market Orders you may also specify the representing label, protection, expiry date, and time and comment.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            DateTime midnight = Server.Time.AddDays(1).Date;

            PlaceLimitOrder(TradeType.Buy, Symbol, 10000, Symbol.Bid, "mySample_cBot", 10, null, midnight, "First");

            PlaceStopOrder(TradeType.Buy, Symbol, 10000, Symbol.Ask, "mySample_cBot", 10, 10, null, "Second");

            foreach (var order in PendingOrders)
            {
                var sl = order.StopLoss == null ? "" : "SL: " + order.StopLoss;
                var tp = order.TakeProfit == null ? "" : " TP: " + order.TakeProfit;

                var text = string.Format("{0} {1}", sl, tp);

                if (order.OrderType == PendingOrderType.Limit)
                    Print(order.Comment + " Limit Order " + text);
                else
                    Print(order.Comment + " Stop Order " + text);
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Placing Limit Order to Buy 10000 EURUSD (Price: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00)
→ Placing Limit Order to Buy 10000 EURUSD (Price: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00) SUCCEEDED, PendingOrder OID25220807
Placing Stop Order to Buy 10000 EURUSD (Price: 1.19053, SL: 10, TP: 10)
→ Placing Stop Order to Buy 10000 EURUSD (Price: 1.19053, SL: 10, TP: 10) SUCCEEDED, PendingOrder OID25220808
Limit Order
First Limit Order SL: 1.18949
Second Stop Order SL: 1.18953 TP: 1.19153

Modifying Pending Orders

Modify the target price of the Pending Orders.

To modify the target price, the protection levels or the expiration date and time of a pending order, use the syntax below.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            var price = Symbol.Ask + 10 * Symbol.PipSize;
            DateTime? expiry = Server.Time.AddHours(12);
            PlaceStopOrder(TradeType.Buy, Symbol, 10000, price, "myLabel", 10, 10, expiry);
        }

        protected override void OnBar()
        {
            foreach (var order in PendingOrders)
            {
                if (order.Label == "myLabel")
                {
                    double newPrice = Symbol.Ask + 5 * Symbol.PipSize;
                    ModifyPendingOrder(order, newPrice, order.StopLossPips,
                                                                order.TakeProfitPips, order.ExpirationTime);
                }
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Placing Stop Order to Buy 10000 EURUSD (Price: 1.19254, SL: 10, TP: 10, ExpireTime: 11/05/2018 20:07:25)
→ Placing Stop Order to Buy 10000 EURUSD (Price: 1.19254, SL: 10, TP: 10, ExpireTime: 11/05/2018 20:07:25) SUCCEEDED, PendingOrder OID25220877

Canceling Pending Order

The syntax for canceling an order is CancelPendingOrder(order), where order is of type PendingOrder.

The example of canceling all the orders with the label "myLabel".

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnTick()
        {
            foreach (var order in PendingOrders)
            {
                if (order.Label == "myLabel")
                {
                    CancelPendingOrder(order);
                }
            }
        }
    }
Position Events

Subscribe an event to the Position.

To test when a position is opened we can subscribe an event to Positions. This event will also be raised if a position opens manually or by another cBot.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            Positions.Opened += PositionsOnOpened;
            ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "myLabel", 10, 10);
        }

        private void PositionsOnOpened(PositionOpenedEventArgs args)
        {
            var pos = args.Position;
            Print("Position opened at {0}", pos.EntryPrice);
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD (SL: 10, TP: 10)
→ Executing Market Order to Buy 10000 EURUSD (SL: 10, TP: 10) SUCCEEDED, Position PID14579468
Position opened at 1.19224

Similarly, the events that are raised each time a position is closed can be subscribed.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            Positions.Closed += PositionsOnClosed;
            ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "myLabel", 10, 10);
        }

        protected override void OnBar()
        {
            var position = Positions.Find("myLabel");
            if (position != null)
                ClosePosition(position);
        }

        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            var pos = args.Position;
            Print("Position closed with {0} profit", pos.GrossProfit);
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD (SL: 10, TP: 10)
→ Executing Market Order to Buy 10000 EURUSD (SL: 10, TP: 10) SUCCEEDED, Position PID14579479
Closing position PID14579299
→ Closing position PID14579299 SUCCEEDED, Position PID14579299
Position closed with 20.64 profit

Asynchronous execution

The code samples above are designed to implement cBots using synchronous trade operation methods. Synchronous operation is more intuitive and straightforward as far as coding is concerned. Synchronous trade operation methods send requests to the server and wait for the server response, then pass execution to the next statement.

In asynchronous operation, when a request is sent to the server, the program continues to execute the next statements without waiting for the response from the server. The statements that follow the asynchronous trade operation request cannot assume anything about the result of those requests.

For example, if the program sends a request to execute a Market Order and then continues to place a Limit Order, the request to place a Limit Order will most probably be sent to the server before the response on the opened position is received. When the server response is received, the program can pass execution control to a callback function, then the necessary statements will be executed according to whether the operation was successful or not. More information on the callbacks can be found in this section below.

The benefit of using asynchronous execution is that a potentially time-consuming process of waiting for the response from the server is avoided. Instead, execution continues and when the response arrives, control is passed to a callback if one is specified.

Do not confuse asynchronous operation with multi-threading. At any given time only one method can be invoked. cTrader automate never invokes your methods in parallel so you don’t have to worry about multi-threading issues.

Executing Market Orders Asynchronously

The syntax of the asynchronous methods is very similar to that of the synchronous ones. They accept the same type of argument lists. The main difference is that the return type is TradeOperation instead of TradeResult.

  1. Asynchronous operation.

The following simple cBot demonstrates asynchronous operation. A market order is created and then it checks if the operation is executing in the next statement.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            TradeOperation operation = ExecuteMarketOrderAsync(TradeType.Buy, Symbol, 10000);

            if (operation.IsExecuting)
            {
                Print("Operation Is Executing");
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD
Operation Is Executing
→ Executing Market Order to Buy 10000 EURUSD SUCCEEDED, Position PID14579532

  1. Executing an Order.

In the next example, a combination of an asynchronous method and a synchronous method is used to demonstrate the difference between them. The cBot checks if an operation is executing right after the asynchronous one and then again after the synchronous one. As you can see in the log output, the results are different.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            TradeOperation operation = ExecuteMarketOrderAsync(TradeType.Buy, Symbol, 10000);
            Print(operation.IsExecuting ? "Operation Is Executing" : "Operation executed");
            ExecuteMarketOrder(TradeType.Buy, Symbol, 20000);
            Print(operation.IsExecuting ? "Operation Is Executing" : "Operation executed");

        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD
Operation Is Executing
Executing Market Order to Buy 20000 EURUSD
→ Executing Market Order to Buy 10000 EURUSD SUCCEEDED, Position PID14579541
→ Executing Market Order to Buy 20000 EURUSD SUCCEEDED, Position PID14579542
Operation executed

  1. Executing an Order with more parameters.

The following cBot creates an order specifying the label ("myLabel"), protection (10, 10), symbol (Symbol) and volume (10000). Also, the Positions collection and the method FindAll are demonstrated. Find and FindAll can be used to query positions of the same label, symbol and trade type.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrderAsync(TradeType.Buy, Symbol, 10000, "myLabel", 10, 10);
        }
        protected override void OnTick()
        {
            Position[] positions = Positions.FindAll("myLabel", Symbol, TradeType.Buy);
            if (positions.Length == 0)
                return;

            foreach (var position in positions)
                Print("Buy at {0} SL {1}", position.EntryPrice, position.StopLoss);

            Stop();
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD (SL: 10, TP: 10)
→ Executing Market Order to Buy 10000 EURUSD (SL: 10, TP: 10) SUCCEEDED, Position PID14579719
Buy at 1.19087 SL null
Buy at 1.19357 SL 1.19257
cBot "New cBot" was stopped for EURUSD, h1.

Modifying Position Asynchronously

Modify a positions protection.

The sample below executes a Market Order and then modifies the position.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrderAsync(TradeType.Buy, Symbol, 10000, "myLabel", null, 10);
        }

        protected override void OnTick()
        {
            Position myPosition = Positions.Find("myLabel");
            if (myPosition != null && myPosition.StopLoss == null)
            {
                double stopLoss = Symbol.Bid - 10 * Symbol.PipSize;
                ModifyPositionAsync(myPosition, stopLoss, myPosition.TakeProfit);
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD (TP: 10)
→ Executing Market Order to Buy 10000 EURUSD (TP: 10) SUCCEEDED, Position PID14579736
Modifying position PID14579300 (SL: 1.19213, TP: null)
→ Modifying position PID14579300 (SL: 1.19213, TP: null) SUCCEEDED, Position PID14579300

Closing a Position Asynchronously

The next example demonstrates closing a position asynchronously if the position exists. The Find method is used to query the Positions collection for the position with a specific label.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrderAsync(TradeType.Buy, Symbol, 10000, "myLabel", null, 10);
        }

        protected override void OnTick()
        {
            Position myPosition = Positions.Find("myLabel");
            if (myPosition != null && myPosition.GrossProfit > 10)
            {
                ClosePosition(myPosition);
                Stop();
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD (TP: 10)
→ Executing Market Order to Buy 10000 EURUSD (TP: 10) SUCCEEDED, Position PID14579740
Closing position PID14579300
→ Closing position PID14579300 SUCCEEDED, Position PID14579300
cBot "New cBot" was stopped for EURUSD, h1.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            DateTime expiry = Server.Time.AddHours(12);
            PlaceLimitOrderAsync(TradeType.Buy, Symbol, 10000, Symbol.Bid, "myLabel", null, null, expiry);
            PlaceStopOrderAsync(TradeType.Buy, Symbol, 10000, Symbol.Ask + 10 * Symbol.PipSize, "myLabel", null, null, expiry);
        }
    }
}
Placing Limit and Stop Orders Asynchronously

As with synchronous methods, placing pending orders is similar to executing Market Orders. The arguments only differ in that the target price is required, the market range is not in the argument list, and there is another optional parameter - the expiration date of the order.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            DateTime expiry = Server.Time.AddHours(12);
            PlaceLimitOrderAsync(TradeType.Buy, Symbol, 10000, Symbol.Bid, "myLabel", null, null, expiry);
            PlaceStopOrderAsync(TradeType.Buy, Symbol, 10000, Symbol.Ask + 10 * Symbol.PipSize, "myLabel", null, null, expiry);
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Placing Limit Order to Buy 10000 EURUSD (Price: 1.19382, ExpireTime: 12/05/2018 00:18:19)
Placing Stop Order to Buy 10000 EURUSD (Price: 1.19487, ExpireTime: 12/05/2018 00:18:19)
→ Placing Limit Order to Buy 10000 EURUSD (Price: 1.19382, ExpireTime: 12/05/2018 00:18:19) SUCCEEDED, PendingOrder OID25221859
→ Placing Stop Order to Buy 10000 EURUSD (Price: 1.19487, ExpireTime: 12/05/2018 00:18:19) SUCCEEDED, PendingOrder OID25221860

Modify Pending Orders Asynchronously

Modify Limit Order asynchronously

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            DateTime expiry = Server.Time.AddHours(12);
            PlaceLimitOrderAsync(TradeType.Buy, Symbol, 10000, Symbol.Bid, "myLabel", null, 10, expiry);

        }
        protected override void OnTick()
        {
            foreach (var order in PendingOrders)
            {
                if (order.Label == "myLabel" && order.StopLoss == null)
                    ModifyPendingOrderAsync(order, order.TargetPrice, 10, 10, null);
            }
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Placing Limit Order to Buy 10000 EURUSD (Price: 1.19347, TP: 10, ExpireTime: 12/05/2018 00:22:08)
Modifying pending order OID25221860 (Volume: 10000, Price: 1.19487, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:18:19)
→ Placing Limit Order to Buy 10000 EURUSD (Price: 1.19347, TP: 10, ExpireTime: 12/05/2018 00:22:08) SUCCEEDED, PendingOrder OID25221906
→ Modifying pending order OID25221860 (Volume: 10000, Price: 1.19487, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:18:19) SUCCEEDED, PendingOrder OID25221860
Modifying pending order OID25221906 (Volume: 10000, Price: 1.19347, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:22:08)
→ Modifying pending order OID25221906 (Volume: 10000, Price: 1.19347, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:22:08) SUCCEEDED, PendingOrder OID25221906

Canceling Pending Orders Asynchronously
  1. Cancel All the Pending Orders.
[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnBar()
        {
            foreach (var pendingOrder in PendingOrders)
            {
                CancelPendingOrderAsync(pendingOrder);
            }
        }
    }
}

Log output:

cBot "cancel pending order" was started successfully for EURUSD, h1.
Cancelling pending order OID274705
Cancelling pending order OID274706
Cancelling pending order OID274707
Cancelling pending order OID274708
Cancelling pending order OID274709
→ Cancelling pending order OID274705 SUCCEEDED, PendingOrder OID274705
→ Cancelling pending order OID274706 SUCCEEDED, PendingOrder OID274706
→ Cancelling pending order OID274707 SUCCEEDED, PendingOrder OID274707
→ Cancelling pending order OID274708 SUCCEEDED, PendingOrder OID274708
→ Cancelling pending order OID274709 SUCCEEDED, PendingOrder OID274709

  1. Cancel pending orders with the label myLabel.
[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnBar()
        {
            foreach (var pendingOrder in PendingOrders)
            {
                if (pendingOrder.Label == "myLabel")
                    CancelPendingOrderAsync(pendingOrder);
            }
        }
    }
Callbacks for Asynchronous methods

Using asynchronous mode often requires controlling execution, once a result is returned from the server. To handle this, one can add a callback function at the end of the list of parameters of all asynchronous methods. This function is called once the response from the server is received, for instance when a position is opened, modified or closed or a pending order filled.

  1. Asynchronous Market Order with a callback.
[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            TradeOperation operation =
                        ExecuteMarketOrderAsync(TradeType.Buy, Symbol, 10000, PositionOpened);
            if (operation.IsExecuting)
                Print(operation.ToString());
            else
                Print(operation.TradeResult.ToString());

        }

        private void PositionOpened(TradeResult tradeResult)
        {
            var position = tradeResult.Position;
            Print(tradeResult.ToString());
            if (tradeResult.IsSuccessful)
                Print("Position {0} opened at {1}", position.Id, position.EntryPrice);
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Executing Market Order to Buy 10000 EURUSD
TradeOperation (Executing Market Order to Buy 10000 EURUSD EXECUTING)
→ Executing Market Order to Buy 10000 EURUSD SUCCEEDED, Position PID14579835
TradeResult (Success, Position: PID14579835)
Position 14579835 opened at 1.19414

  1. Using Lambda Expressions.

Instead of defining a callback method one can use lambda expressions. In the following example, when the order is placed the result description will be printed to the log.

[Robot()]
    public class Sample_cBot : Robot
    {
        protected override void OnStart()
        {
            PlaceLimitOrderAsync(TradeType.Buy, Symbol, 10000,
                       Symbol.Ask - 20 * Symbol.PipSize, "myLabel", result => Print(result.ToString()));
        }
    }

Log output:

cBot "New cBot" was started successfully for EURUSD, h1.
Placing Limit Order to Buy 10000 EURUSD (Price: 1.19320)
→ Placing Limit Order to Buy 10000 EURUSD (Price: 1.19320) SUCCEEDED, PendingOrder OID25222083
TradeResult (Success, PendingOrder: OID25222083)