Replies

paul_leppard
28 Sep 2024, 19:56 ( Updated at: 29 Sep 2024, 11:21 )

Where can I download latest version?

I've just downloaded version 5.0.20 but it seems the backtesting is not starting. The chart does not show and the play button is missing. Is this fixed in a later release? the only link I can find is the one from the Ctrader website at that downloads 5.0.20 Thanks. This is the MacOS version.


@paul_leppard

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