Clickalgo Knowledge Center
Return to Website

cTrader Market Orders - Create, Modify & Close

You can create Market orders using the cTrader API & Microsoft C# to automatically submit an order with an automated trading system (cBot) based on your trade rules. All orders can be executed by using either synchronous or asynchronous methods. An example of using an asynchronous call would be to close all open positions as fast as possible, so to reduce losses many requests are sent to the broker all at the same time concurrently. An async request would send one request at a time to close and will wait for the response from the broker before dealing with the next position to close.

 

When you execute something synchronously, you wait for it to finish before moving on to another task. When you execute something asynchronously, you can move on to another task before it finishes.

 

Synchronous Market Orders

A market order is a request to buy or sell a security at the best available price in the current market and it is the fastest and most reliable way to enter or exit a trade, the cTrader API allows you to code this feature to run in a cBot automatically on given trade signals. This type of synchronous market order will send a signal to execute the order and wait for another signal to tell the program the result of the order, the code below shows result.IsSuccessful when the order was successfully submitted to the broker.

 

[Robot()]

public class NewRobot : Robot

{ protected override void OnStart()

{

var result = ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000);

if (result.IsSuccessful)

{

var position = result.Position;

Print("Position entry price is {0}", position.EntryPrice);

} } }

 

Asynchronous Market Orders

An asynchronous market order will execute the request for a new order and then continue processing the code before the call has completed and the result of the request is returned. This uses a different return result called TradeOperation.

 

[Robot()]

public class Sample_cBot : Robot

{

protected override void OnStart()

{

TradeOperation operation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000);

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

} } }

 

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 callback 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.

 

[Robot()]

public class Sample_cBot : Robot

{

protected override void OnStart()

{

TradeOperation operation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000, OrderSubmitted)

if (operation.IsExecuting) Print(operation.ToString());

else Print(operation.TradeResult.ToString());

}

private void OrderSubmitted(TradeResult tradeResult)

{

var position = tradeResult.Position;

Print(tradeResult.ToString());

if (tradeResult.IsSuccessful)

Print("Position {0} opened at {1}", position.Id, position.EntryPrice);

} }

 

The method ExecuteMarketOrderAsync, as shown above, has a parameter called OrderSubmitted, this is the callback method that is called when the order has been processed and a result returned to the trading platform from the broker. You can see the method called OrderSubmitted which receives the TradeResult as a parameter and uses the value it contains to decide what happens in the code logic. In the case of the example above it simply prints to the log file the position information if successful.

 

Execute Market Order With Optional Parameters

The ExecuteMarketOrder method allows you to enter the stop loss and the take profit value for the order you wish to submit to the broker. The example below shows the symbol name as a string, it is possible to specify a symbol that is different from the one that the chart that the cBot is running on.

 

var result = ExecuteMarketOrder(TradeType.Buy, "EURUSD", 10000, "InstanceName", 10, 10);

 

The example above shows a MarketOrder request for a Buy position, using the current symbol with a volume of 10K, a label name of "InstanceName" and the last two values are the stop loss and take profit of 10-pips each.

 

ctrader cbot executemarketorder

 

There are 9 optional parameters to choose from with the ExecuteMarketOrder method, the method is overloaded which allows you to configure the type of order you wish to submit. Overloaded methods are differentiated based on the number and type of the parameters passed as arguments to the methods.

  1. TradeType - you can choose a buy or sell trade.
  2. SymbolName - this is the name of the symbol you wish to submit. You can enter a string, so enter the symbol name as a string like "EURUSD".
  3. Volume - this is the volume, enter the full value, so 1K would be 1000.
  4. Label - this can be used as a unique identifier for the position to be managed later.
  5. StopLossPips - this is the stop loss value and can be NULL for no stop loss.
  6. TakeProfitPips - this is the take profit value and can be NULL for no-take profit.
  7. Comment - this is just text and a description of the position for reviewing later in history.
  8. HasTrailingStop - an optional parameter, if set to true, you can use a server-side trailing stop that runs on the server, so it will still work with your PC turned off.
  9. StopLossTriggerMethod - this is an enum value for the type of stop-loss, further details below.

 

var result = ExecuteMarketOrder(TradeType.Buy, "EURUSD", 1000, "Smart-Grid", 10, 10, "comments", true, StopTriggerMethod.DoubleOpposite);

 

StopLossTriggerMethod Explained

There are 4 options for this enum which are explained below.

cbot stop trigger

 

DoubleOpposite

Uses opposite prices for order triggering, and waits for additional confirmation. Two consecutive prices should meet the criteria to trigger order. Buy order and Stop Loss for Sell position will be triggered when two consecutive Bid prices >= order price. Sell order and Stop Loss for Buy position will be triggered when two consecutive Ask prices <= order price.

 

DoubleTrade

Uses default prices for order triggering, but waits for additional confirmation two consecutive prices should meet criteria to trigger order. Buy order and Stop Loss for Sell position will be triggered when two consecutive Ask prices >= order price. Sell order and Stop Loss for Buy position will be triggered when two consecutive Bid prices <= order price.

 

Opposite

The opposite method uses the opposite price for order triggering. Buy order and Stop Loss for Sell position will be triggered when Bid >= order price. Sell order and Stop Loss for Buy position will be triggered when Ask <= order price.

 

Trade

Trade method uses default trigger behaviour for Stop orders. Buy order and Stop Loss for Sell position will be triggered when Ask >= order price. Sell order and Stop Loss for Buy position will be triggered when Bid <= order price.

 

ExecuteMarketRangeOrder

A market range order is the same as a market order, the only difference is that you can specify the base price for the order to be executed and the slippage in pips that is allowed.

 

var result = ExecuteMarketRangeOrder(TradeType.Sell, "EURUSD", 1000, 2, Ask);

 

Why Use a Range Order?

A market range order is useful in a fast-moving market like a major news event to avoid too much slippage, the term slippage is used when an order is filled very late by the broker due to an excess of other orders to be filled, if the order is at the back of the queue then by the time it is filled by the broker it could be far away from the required price and could hot a stop loss and start with a big loss.

 

ctrader market range order

  • MarketRangePips - this is the max allowed pips slippage and if the slippage is higher the order is not submitted.
  • BasePrice - this is the price where the order should be filled.

 

ExecuteMarketRangeOrderAsync

This is the same as an Asynchronous Market order and behaves the same way, the only difference is the parameters where it has a MarketRangePips and BasePrice value.

 

Fractional Volumes

With the introduction of cryptocurrencies, now there are instruments that can be traded using fractional units volume. To adapt to these changes, we added possibilities to work with fractional volumes using API.

For trading operations, you can pass a double value as the volume parameter. Both integer and double values are working:

 

ExecuteMarketOrder(TradeType.Buy, "EURUSD", 1); ExecuteMarketOrder(TradeType.Buy, "EURUSD", 0.5);

 

Modifying Orders

You can modify a market order that is already open and change the volume, stop loss and take profit values. In the next example, we will add only to take profit when the order is executed and then we will 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);

} } }

 

Closing a Market Order

If you wish to cancel an existing order then all you need to do is use the ClosePosition method, the example below will close a position when it is 10 pips in profit, the onTick method is used as this gets called each time there is a price change.

 

[Robot()]

public class Sample_cBot : Robot

{

protected override void OnStart() { }

protected override void OnTick() {
// find a position that has a label name of myLabel.

var position = Positions.Find("myLabel");

if (position != null && position.GrossProfit > 10)

{ ClosePosition(position); Stop();

} } }

 

Trading API Shortcuts

All positions have added the shortcuts for modification or close/cancel actions can be done by calling the methods directly on the Position instance.

  • Position.ModifyVolume
  • Position.ModifyStopLossPips
  • Position.ModifyStopLossPrice
  • Position.ModifyTakeProfitPips
  • Position.ModifyTakeProfitPrice
  • Position.ModifyTrailingStop
  • Position.Reverse
  • Position.Close