ExecuteMarketOrder not setting SL

Created at 05 Jul 2024, 12:01
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
PA

paul_leppard

Joined 05.07.2024

ExecuteMarketOrder not setting SL
05 Jul 2024, 12:01


I am listening for POST requests on port 8080 to fire off market orders. When I send a JPY based pair everything works fine SL and TP is set correctly but for a non JPY pair the SL is not set at all and the TP is set very close to the entry not with the value I provided. I'm not sure why. I'm thinking of switching to doing this with MT5 as I can't see why this is doing this. Any help here greatly received I've spent too long trying to figure this out. The TP and SL values are prices and not pips. I've seen elsewhere on older posts that I should use pips but then I get invalid SLTP errors.

 

using System;
using cAlgo.API;
using System.Net;
using System.Threading.Tasks;
using System.Text;
using Newtonsoft.Json.Linq;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class TradeBot : Robot
    {
        [Parameter("Port", DefaultValue = 8080)]
        public int Port { get; set; }

        [Parameter("Volume in Units", DefaultValue = 1000)]
        public int VolumeInUnits { get; set; }

        [Parameter("Default Symbol", DefaultValue = "EURUSD")]
        public string DefaultSymbol { get; set; }

        [Parameter("Symbol Suffix", DefaultValue = "_SB")]
        public string SymbolSuffix { get; set; }

        private HttpListener _listener;
        private string UrlPrefix => $"http://localhost:{Port}/";

        protected override void OnStart()
        {
            _listener = new HttpListener();
            _listener.Prefixes.Add(UrlPrefix);
            _listener.Start();

            Print($"TradeBot started and listening for HTTP requests on port {Port}");

            Task.Run(() => HandleIncomingConnections());
        }

        private async Task HandleIncomingConnections()
        {
            while (_listener.IsListening)
            {
                var context = await _listener.GetContextAsync();
                var request = context.Request;

                if (request.HttpMethod == "POST" && request.HasEntityBody)
                {
                    using (var reader = new System.IO.StreamReader(request.InputStream, request.ContentEncoding))
                    {
                        var json = await reader.ReadToEndAsync();
                        var order = JObject.Parse(json);

                        var symbolCode = (order["symbol"]?.ToString() ?? DefaultSymbol) + SymbolSuffix;
                        var direction = order["direction"].ToString().ToUpper();
                        var entryPrice = (double)order["entryPrice"];
                        var takeProfit = (double)order["takeProfit"];
                        var stopLoss = (double)order["stopLoss"];

                        Print($"Received order: {symbolCode} {direction} @ {entryPrice}, TP: {takeProfit}, SL: {stopLoss}");

                        BeginInvokeOnMainThread(() => ExecuteMarketTrade(symbolCode, direction, takeProfit, stopLoss));

                        var response = context.Response;
                        var buffer = Encoding.UTF8.GetBytes("Order received and executed.");
                        response.ContentLength64 = buffer.Length;
                        await response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
                        response.OutputStream.Close();
                    }
                }
                else
                {
                    var response = context.Response;
                    response.StatusCode = (int)HttpStatusCode.BadRequest;
                    response.Close();
                }
            }
        }

        private void ExecuteMarketTrade(string symbolCode, string direction, double takeProfit, double stopLoss)
        {
            var symbol = Symbols.GetSymbol(symbolCode);

            if (symbol == null)
            {
                Print($"Symbol not found: {symbolCode}");
                return;
            }

            TradeType tradeType = direction == "BUY" ? TradeType.Buy : TradeType.Sell;

            Print($"Executing market trade: Symbol: {symbolCode}, Direction: {direction}, Take Profit: {takeProfit}, Stop Loss: {stopLoss}");

            var result = ExecuteMarketOrder(tradeType, symbol.Name, VolumeInUnits, "PostmanOrder", stopLoss, takeProfit);

            if (result.IsSuccessful)
            {
                Print($"Market order placed successfully: ID {result.Position.Id}, Take Profit: {takeProfit}, Stop Loss: {stopLoss}");
            }
            else
            {
                Print($"Market order placement failed: {result.Error}");
            }
        }

        protected override void OnStop()
        {
            if (_listener != null)
            {
                _listener.Stop();
                _listener.Close();
                _listener = null;
            }
        }
    }
}

@paul_leppard
Replies

PanagiotisCharalampous
05 Jul 2024, 12:17

Hi  there,

Can you share an example of such a post request?

Best regards,

Panagiotis


@PanagiotisCharalampous

paul_leppard
05 Jul 2024, 14:40 ( Updated at: 06 Jul 2024, 05:42 )

RE: ExecuteMarketOrder not setting SL

PanagiotisCharalampous said: 

Hi  there,

Can you share an example of such a post request?

Best regards,

Panagiotis

Terrible sorry for wasting time. I was sending pips through in the POST request and then converting again to pips in the CBot so I had values of 0.00000042 etc. Silly mistake. I tried to delete this post but could not. For the record here is my finished working code. I'm sending POST request from Postman like this now. Its working as expected.

{
  "symbol": "EURJPY",
  "direction": "BUY",
  "entryPrice": 169.985,
  "takeProfit": 170.792,
  "stopLoss": 169.235
}

 

using System;
using cAlgo.API;
using System.Net;
using System.Threading.Tasks;
using System.Text;
using Newtonsoft.Json.Linq;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class TradeBot : Robot
    {
        [Parameter("Port", DefaultValue = 8080)]
        public int Port { get; set; }

        [Parameter("Volume in Units", DefaultValue = 1000)]
        public int VolumeInUnits { get; set; }

        [Parameter("Volume in Units for JPY", DefaultValue = 10)]
        public int VolumeInUnitsJPY { get; set; }

        [Parameter("Default Symbol", DefaultValue = "EURUSD")]
        public string DefaultSymbol { get; set; }

        [Parameter("Symbol Suffix", DefaultValue = "_SB")]
        public string SymbolSuffix { get; set; }

        private HttpListener _listener;
        private string UrlPrefix => $"http://localhost:{Port}/";

        protected override void OnStart()
        {
            _listener = new HttpListener();
            _listener.Prefixes.Add(UrlPrefix);
            _listener.Start();

            Print($"TradeBot started and listening for HTTP requests on port {Port}");

            Task.Run(() => HandleIncomingConnections());
        }

        private async Task HandleIncomingConnections()
        {
            while (_listener.IsListening)
            {
                var context = await _listener.GetContextAsync();
                var request = context.Request;

                if (request.HttpMethod == "POST" && request.HasEntityBody)
                {
                    using (var reader = new System.IO.StreamReader(request.InputStream, request.ContentEncoding))
                    {
                        var json = await reader.ReadToEndAsync();
                        var order = JObject.Parse(json);

                        var symbolCode = (order["symbol"]?.ToString() ?? DefaultSymbol) + SymbolSuffix;
                        var direction = order["direction"].ToString().ToUpper();
                        var entryPrice = (double)order["entryPrice"];
                        var takeProfit = (double)order["takeProfit"];
                        var stopLoss = (double)order["stopLoss"];

                        Print($"Received order: {symbolCode} {direction} @ {entryPrice}, TP: {takeProfit}, SL: {stopLoss}");

                        BeginInvokeOnMainThread(() => ExecuteMarketTrade(symbolCode, direction, entryPrice, takeProfit, stopLoss));

                        var response = context.Response;
                        var buffer = Encoding.UTF8.GetBytes("Order received and executed.");
                        response.ContentLength64 = buffer.Length;
                        await response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
                        response.OutputStream.Close();
                    }
                }
                else
                {
                    var response = context.Response;
                    response.StatusCode = (int)HttpStatusCode.BadRequest;
                    response.Close();
                }
            }
        }

        private void ExecuteMarketTrade(string symbolCode, string direction, double entryPrice, double takeProfit, double stopLoss)
        {
            var symbol = Symbols.GetSymbol(symbolCode);

            if (symbol == null)
            {
                Print($"Symbol not found: {symbolCode}");
                return;
            }

            TradeType tradeType = direction == "BUY" ? TradeType.Buy : TradeType.Sell;

            double tpPips = 0;
            double slPips = 0;

            if (tradeType == TradeType.Buy)
            {
                tpPips = (takeProfit - entryPrice) / symbol.PipSize;
                slPips = (entryPrice - stopLoss) / symbol.PipSize;
            }
            else
            {
                tpPips = (entryPrice - takeProfit) / symbol.PipSize;
                slPips = (stopLoss - entryPrice) / symbol.PipSize;
            }

            int volume = symbolCode.Contains("JPY") ? VolumeInUnitsJPY : VolumeInUnits;

            Print($"Executing market trade: Symbol: {symbolCode}, Direction: {direction}, Stop Loss: {slPips}, Take Profit: {tpPips}, PipSize: {symbol.PipSize}");

            var result = ExecuteMarketOrder(tradeType, symbol.Name, volume, "PostmanOrder", slPips, tpPips);

            if (result.IsSuccessful)
            {
                Print($"Market order placed successfully: ID {result.Position.Id}, Stop Loss: {slPips}, Take Profit: {tpPips}");
            }
            else
            {
                Print($"Market order placement failed: {result.Error}");
            }
        }

        protected override void OnStop()
        {
            if (_listener != null)
            {
                _listener.Stop();
                _listener.Close();
                _listener = null;
            }
        }
    }
}

@paul_leppard