Backtesting Log Output missing?

Created at 17 Apr 2025, 08:55
ZY

zytotoxiziteat

Joined 04.08.2021

Backtesting Log Output missing?
17 Apr 2025, 08:55


Hello

I have a DRL module in Python. I try to establish a communication through a websocket with my cBot.

Unfortunately the log shows insufficient output during/after the backtesting phase despite more detailed log request in the ctrader code:

 

using System;
using System.Linq;
using System.Threading.Tasks;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using System.Collections.Generic;
using System.Threading;
using System.Net.NetworkInformation;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Collections;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class DRLcTraderBot : Robot
    {
        // WebSocket Configuration
        [Parameter("WebSocket URL", DefaultValue = "ws://127.0.0.1:8765")]
        public string WebSocketUrl { get; set; }

        // Trading Parameters
        [Parameter("Trade Volume (Lots)", DefaultValue = 0.02, MinValue = 0.01)]
        public double TradeVolumeLots { get; set; }

        [Parameter("ATR Period for SL", DefaultValue = 14, MinValue = 1)]
        public int AtrPeriod { get; set; }

        [Parameter("ATR Multiplier for SL", DefaultValue = 3.5, MinValue = 0.1)]
        public double AtrMultiplier { get; set; }

        [Parameter("Lookback Window Size", DefaultValue = 60, MinValue = 10)]
        public int LookbackWindowSize { get; set; }

        [Parameter("WebSocket Retry Interval (seconds)", DefaultValue = 10, MinValue = 5)]
        public int RetryIntervalSeconds { get; set; }

        [Parameter("Max Retry Attempts", DefaultValue = 5, MinValue = 1)]
        public int MaxRetryAttempts { get; set; }

        // Feature Calculation Periods
        private const int SmaSlowPeriod = 50;
        private const int RsiPeriod = 14;
        private const int MacdFast = 12;
        private const int MacdSlow = 26;
        private const int MacdSignal = 9;
        private const int AtrFeaturePeriod = 14;

        // Internal Variables
        private ClientWebSocket _clientWebSocket;
        private CancellationTokenSource _cts;
        private Bars _bars1H;
        private AverageTrueRange _atr;
        private SimpleMovingAverage _smaSlow;
        private RelativeStrengthIndex _rsi;
        private MacdCrossOver _macd;
        private Position _currentPosition;
        private bool _isWebSocketConnected;
        private List<double[]> _featureBuffer;
        private const int NumFeatures = 8;
        private bool _isProcessing;
        private DateTime _lastConnectionAttempt;
        private int _retryCount;
        private const string CodeVersion = "3.2"; // Updated version to confirm deployment
        private const string LogFilePath = @"C:\Users\zytot\DRLcTraderBot_Log.txt"; // Adjust path as needed
        private string _lastConnectionError;

        // Static constructor for earliest logging
        static DRLcTraderBot()
        {
            try
            {
                string message = "[Static Constructor] DRLcTraderBot loaded. Code Version: " + CodeVersion + " at " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff");
                Console.WriteLine(message);
                File.AppendAllText(LogFilePath, message + Environment.NewLine);
            }
            catch (Exception ex)
            {
                string errorMessage = "[Static Constructor] Error: " + ex.ToString();
                Console.WriteLine(errorMessage);
                File.AppendAllText(LogFilePath, errorMessage + Environment.NewLine);
            }
        }

        protected override void OnStart()
        {
            // Log immediately to confirm OnStart is called
            LogWithFallback("OnStart called. Code Version: " + CodeVersion);
            LogWithFallback("Start Time: " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff"));

            // Log runtime environment
            LogEnvironmentInfo();

            // Initialize 1-hour bars
            try
            {
                _bars1H = MarketData.GetBars(TimeFrame.Hour);
                LogWithFallback("Initialized 1-hour bars.");
            }
            catch (Exception ex)
            {
                LogWithFallback("Error initializing 1-hour bars: " + ex.ToString());
                return;
            }

            // Initialize indicators
            try
            {
                _atr = Indicators.AverageTrueRange(_bars1H, AtrPeriod, MovingAverageType.Simple);
                _smaSlow = Indicators.SimpleMovingAverage(_bars1H.ClosePrices, SmaSlowPeriod);
                _rsi = Indicators.RelativeStrengthIndex(_bars1H.ClosePrices, RsiPeriod);
                _macd = Indicators.MacdCrossOver(_bars1H.ClosePrices, MacdFast, MacdSlow, MacdSignal);
                LogWithFallback("Indicators initialized.");
            }
            catch (Exception ex)
            {
                LogWithFallback("Error initializing indicators: " + ex.ToString());
                return;
            }

            // Log network information
            LogNetworkInfo();

            // Log resolved IP for WebSocket URL
            try
            {
                Uri uri = new Uri(WebSocketUrl);
                var hostAddresses = Dns.GetHostAddresses(uri.Host);
                LogWithFallback("Resolved IPs for " + uri.Host + ": " + string.Join(", ", hostAddresses.Select(ip => ip.ToString())));
            }
            catch (Exception ex)
            {
                LogWithFallback("Error resolving WebSocket host " + WebSocketUrl + ": " + ex.ToString());
            }

            // Initialize feature buffer
            _featureBuffer = new List<double[]>();
            _isWebSocketConnected = false;
            _isProcessing = false;
            _lastConnectionAttempt = DateTime.MinValue;
            _retryCount = 0;
            _lastConnectionError = "None";
            _cts = new CancellationTokenSource();

            // Initialize WebSocket
            LogWithFallback("Attempting to initialize WebSocket...");
            try
            {
                _ = InitializeWebSocketAsync();
            }
            catch (Exception ex)
            {
                LogWithFallback("Error during WebSocket initialization: " + ex.ToString());
                LogExceptionDetails(ex);
            }

            // Subscribe to bar events
            _bars1H.BarOpened += OnBarOpened1H;
            LogWithFallback("Bot started. Waiting for new 1H bar...");
        }

        private void LogWithFallback(string message)
        {
            try
            {
                string formattedMessage = "[" + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff") + "] " + message;
                Print(formattedMessage);
                File.AppendAllText(LogFilePath, formattedMessage + Environment.NewLine);
            }
            catch (Exception ex)
            {
                Print("Logging error: " + ex.ToString());
            }
        }

        private void LogExceptionDetails(Exception ex)
        {
            LogWithFallback("Exception: " + ex.ToString());
            LogWithFallback("Inner Exception: " + (ex.InnerException != null ? ex.InnerException.ToString() : "null"));
            LogWithFallback("Source: " + ex.Source);
            LogWithFallback("TargetSite: " + (ex.TargetSite != null ? ex.TargetSite.ToString() : "null"));
            LogWithFallback("HResult: " + ex.HResult.ToString());
            LogWithFallback("Data: " + (ex.Data.Count > 0 ? string.Join(", ", ex.Data.Cast<DictionaryEntry>().Select(de => de.Key.ToString() + ": " + de.Value.ToString())) : "null"));
            LogWithFallback("Stack Trace: " + ex.StackTrace);
        }

        private void LogEnvironmentInfo()
        {
            try
            {
                LogWithFallback("Environment Info:");
                LogWithFallback("  .NET Runtime: " + Environment.Version.ToString());
                LogWithFallback("  OS Version: " + Environment.OSVersion.ToString());
                LogWithFallback("  Machine Name: " + Environment.MachineName);
                LogWithFallback("  User Name: " + Environment.UserName);
                LogWithFallback("  cTrader Version: Not directly accessible (check cTrader UI)");
            }
            catch (Exception ex)
            {
                LogWithFallback("Error logging environment info: " + ex.ToString());
            }
        }

        private void LogNetworkInfo()
        {
            try
            {
                bool isNetworkAvailable = NetworkInterface.GetIsNetworkAvailable();
                LogWithFallback("Network Available: " + isNetworkAvailable.ToString());

                var host = Dns.GetHostEntry(Dns.GetHostName());
                var localIps = host.AddressList
                    .Where(ip => ip.AddressFamily == AddressFamily.InterNetwork || ip.AddressFamily == AddressFamily.InterNetworkV6)
                    .Select(ip => ip.ToString());
                LogWithFallback("Local IP Addresses: " + string.Join(", ", localIps));

                using (var ping = new Ping())
                {
                    var reply = ping.Send("127.0.0.1", 1000);
                    LogWithFallback("Ping to 127.0.0.1: Status=" + reply.Status.ToString() + ", RoundtripTime=" + reply.RoundtripTime.ToString() + "ms");
                }
            }
            catch (Exception ex)
            {
                LogWithFallback("Error logging network info: " + ex.ToString());
            }
        }

        private void DiagnoseWebSocketServer()
        {
            try
            {
                Uri uri = new Uri(WebSocketUrl);
                LogWithFallback("Diagnosing WebSocket server at " + uri.Host + ":" + uri.Port.ToString());

                // Check if the port is open
                using (var client = new TcpClient())
                {
                    var connectTask = client.ConnectAsync(uri.Host, uri.Port);
                    if (connectTask.Wait(1000)) // 1-second timeout
                    {
                        LogWithFallback("TCP connection to " + uri.Host + ":" + uri.Port.ToString() + " succeeded.");
                        client.Close();
                    }
                    else
                    {
                        LogWithFallback("TCP connection to " + uri.Host + ":" + uri.Port.ToString() + " failed (timeout).");
                    }
                }

                // Check network availability again
                bool isNetworkAvailable = NetworkInterface.GetIsNetworkAvailable();
                LogWithFallback("Network Available (recheck): " + isNetworkAvailable.ToString());
            }
            catch (Exception ex)
            {
                LogWithFallback("Error diagnosing WebSocket server: " + ex.ToString());
            }
        }

        private async Task InitializeWebSocketAsync()
        {
            LogWithFallback("InitializeWebSocketAsync started at " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff"));

            if (_clientWebSocket != null)
            {
                try
                {
                    await _clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Reinitializing", _cts.Token);
                    LogWithFallback("Closed existing WebSocket. Final state: " + _clientWebSocket.State.ToString());
                }
                catch (Exception ex)
                {
                    LogWithFallback("Error closing existing WebSocket: " + ex.ToString());
                }
                _clientWebSocket.Dispose();
            }

            try
            {
                _clientWebSocket = new ClientWebSocket();
                LogWithFallback("ClientWebSocket created successfully.");
            }
            catch (Exception ex)
            {
                LogWithFallback("Error creating ClientWebSocket: " + ex.ToString());
                LogExceptionDetails(ex);
                _lastConnectionError = ex.ToString();
                return;
            }

            try
            {
                _clientWebSocket.Options.KeepAliveInterval = TimeSpan.FromSeconds(30);
                LogWithFallback("WebSocket initialized with KeepAliveInterval: " + _clientWebSocket.Options.KeepAliveInterval.TotalSeconds.ToString() + "s");
                LogWithFallback("WebSocket initial state: " + _clientWebSocket.State.ToString());
            }
            catch (Exception ex)
            {
                LogWithFallback("Error setting WebSocket options: " + ex.ToString());
                LogExceptionDetails(ex);
                _lastConnectionError = ex.ToString();
                return;
            }

            try
            {
                _ = Task.Run(() => ReceiveMessagesAsync(_cts.Token));
                LogWithFallback("Started WebSocket receive task.");
            }
            catch (Exception ex)
            {
                LogWithFallback("Error starting WebSocket receive task: " + ex.ToString());
                LogExceptionDetails(ex);
                _lastConnectionError = ex.ToString();
            }

            await TryConnectWebSocket();
        }

        private async Task TryConnectWebSocket()
        {
            if (_isWebSocketConnected || (DateTime.UtcNow - _lastConnectionAttempt).TotalSeconds < RetryIntervalSeconds * Math.Pow(2, _retryCount))
            {
                LogWithFallback("Skipping connection attempt. IsConnected: " + _isWebSocketConnected.ToString() + ", Time since last attempt: " + (DateTime.UtcNow - _lastConnectionAttempt).TotalSeconds.ToString() + "s");
                return;
            }

            if (_retryCount >= MaxRetryAttempts)
            {
                LogWithFallback("Max retry attempts (" + MaxRetryAttempts.ToString() + ") reached. Stopping connection attempts.");
                return;
            }

            _lastConnectionAttempt = DateTime.UtcNow;
            _retryCount++;
            LogWithFallback("Attempting to connect to WebSocket at " + WebSocketUrl + " (Attempt " + _retryCount.ToString() + "/" + MaxRetryAttempts.ToString() + ") at " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            LogWithFallback("WebSocket state before connect: " + _clientWebSocket.State.ToString());

            try
            {
                using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
                {
                    var startTime = DateTime.UtcNow;
                    await _clientWebSocket.ConnectAsync(new Uri(WebSocketUrl), cts.Token);
                    var duration = (DateTime.UtcNow - startTime).TotalMilliseconds;
                    LogWithFallback("WebSocket connected to " + WebSocketUrl + " in " + duration.ToString() + "ms");
                    LogWithFallback("WebSocket state after connect: " + _clientWebSocket.State.ToString());
                    _isWebSocketConnected = true;
                    _retryCount = 0;
                    _lastConnectionError = "None";
                }
            }
            catch (Exception ex)
            {
                LogWithFallback("WebSocket connection failed after " + (DateTime.UtcNow - _lastConnectionAttempt).TotalMilliseconds.ToString() + "ms");
                LogWithFallback("WebSocket state after failure: " + _clientWebSocket.State.ToString());
                LogExceptionDetails(ex);
                _lastConnectionError = ex.ToString();
                _isWebSocketConnected = false;
            }
        }

        private async Task ReceiveMessagesAsync(CancellationToken cancellationToken)
        {
            var buffer = new byte[1024 * 4];
            var received = new StringBuilder();

            while (!cancellationToken.IsCancellationRequested)
            {
                if (_clientWebSocket.State != WebSocketState.Open)
                {
                    LogWithFallback("WebSocket not open (state: " + _clientWebSocket.State.ToString() + "). Waiting before retrying...");
                    await Task.Delay(1000, cancellationToken);
                    continue;
                }

                try
                {
                    received.Clear();
                    bool isJsonComplete = false;
                    WebSocketReceiveResult result = null;

                    LogWithFallback("Starting to receive message at " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                    while (_clientWebSocket.State == WebSocketState.Open && !isJsonComplete && !cancellationToken.IsCancellationRequested)
                    {
                        var receiveStartTime = DateTime.UtcNow;
                        result = await _clientWebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);
                        var receiveDuration = (DateTime.UtcNow - receiveStartTime).TotalMilliseconds;
                        string fragment = Encoding.UTF8.GetString(buffer, 0, result.Count);
                        LogWithFallback("Received fragment after " + receiveDuration.ToString() + "ms: " + fragment + " (Length: " + result.Count.ToString() + ", EndOfMessage: " + result.EndOfMessage.ToString() + ")");
                        received.Append(fragment);

                        try
                        {
                            JsonSerializer.Deserialize<object>(received.ToString());
                            isJsonComplete = true;
                        }
                        catch (JsonException)
                        {
                            continue;
                        }
                    }

                    if (isJsonComplete)
                    {
                        var message = received.ToString().Trim();
                        LogWithFallback("Raw Response: " + message);
                        OnWebSocketMessage(message);
                    }

                    if (result != null && result.CloseStatus.HasValue)
                    {
                        LogWithFallback("WebSocket closed by server with status: " + result.CloseStatus.ToString() + ", description: " + (result.CloseStatusDescription != null ? result.CloseStatusDescription : "null"));
                        _isWebSocketConnected = false;
                        await InitializeWebSocketAsync();
                    }
                }
                catch (Exception ex)
                {
                    LogWithFallback("WebSocket receive error: " + ex.ToString());
                    LogExceptionDetails(ex);
                    _lastConnectionError = ex.ToString();
                    _isWebSocketConnected = false;
                    await InitializeWebSocketAsync();
                }
            }
        }

        private void OnWebSocketMessage(string message)
        {
            try
            {
                LogWithFallback("Received WebSocket message: " + message);
                var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
                var response = JsonSerializer.Deserialize<WebSocketResponse>(message, options);
                if (response.Status == "success")
                {
                    LogWithFallback("Received action: " + response.PredictedAction.ToString());
                    ExecuteAction(response.PredictedAction);
                }
                else if (!string.IsNullOrEmpty(response.Error))
                {
                    LogWithFallback("WebSocket error response: " + response.Error);
                }
            }
            catch (Exception ex)
            {
                LogWithFallback("Error processing WebSocket message: " + ex.ToString());
            }
            finally
            {
                _isProcessing = false;
            }
        }

        private void OnBarOpened1H(BarOpenedEventArgs args)
        {
            if (!_isWebSocketConnected)
            {
                LogWithFallback("WebSocket not connected. Attempting to reconnect at " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff") + "...");
                LogWithFallback("Current WebSocket state: " + (_clientWebSocket != null ? _clientWebSocket.State.ToString() : "WebSocket is null"));
                LogWithFallback("Last connection error: " + _lastConnectionError);
                LogWithFallback("Retry count: " + _retryCount.ToString() + "/" + MaxRetryAttempts.ToString());
                DiagnoseWebSocketServer();
                _ = InitializeWebSocketAsync();
                if (_retryCount >= MaxRetryAttempts)
                {
                    LogWithFallback("Max retries reached. Using default action: Hold.");
                    ExecuteAction(0);
                    _isProcessing = false;
                    return;
                }
                return;
            }

            if (_isProcessing)
            {
                LogWithFallback("Still processing previous bar. Skipping...");
                return;
            }

            _isProcessing = true;
            _ = ComputeAndSendFeatures();
        }

        private async Task ComputeAndSendFeatures()
        {
            try
            {
                await InitializeWebSocketAsync();

                if (!_isWebSocketConnected || _clientWebSocket.State != WebSocketState.Open)
                {
                    LogWithFallback("WebSocket not connected after reinitialization (state: " + _clientWebSocket.State.ToString() + "). Skipping...");
                    _isProcessing = false;
                    return;
                }

                int lastIndex = _bars1H.Count - 1;
                if (lastIndex < SmaSlowPeriod + 5)
                {
                    LogWithFallback("Not enough bars for feature calculation. Need at least " + (SmaSlowPeriod + 5).ToString() + ".");
                    _isProcessing = false;
                    return;
                }

                var closePrices = _bars1H.ClosePrices;
                var highPrices = _bars1H.HighPrices;
                var lowPrices = _bars1H.LowPrices;
                var openTimes = _bars1H.OpenTimes;

                double[] feature1 = new double[LookbackWindowSize];
                double[] feature2 = new double[LookbackWindowSize];
                double[] feature3 = new double[LookbackWindowSize];
                double[] feature4 = new double[LookbackWindowSize];
                double[] feature5 = new double[LookbackWindowSize];
                double[] feature6 = new double[LookbackWindowSize];
                double[] feature7 = new double[LookbackWindowSize];
                double[] feature8 = new double[LookbackWindowSize];

                _currentPosition = Positions.FirstOrDefault(p => p.SymbolName == SymbolName);
                double positionState = _currentPosition == null ? 0.0 :
                                      _currentPosition.TradeType == TradeType.Buy ? 1.0 : -1.0;

                for (int i = 0; i < LookbackWindowSize; i++)
                {
                    int idx = lastIndex - LookbackWindowSize + 1 + i;
                    if (idx < 0) continue;

                    double close = closePrices[idx];
                    double high = highPrices[idx];
                    double low = lowPrices[idx];
                    double smaSlow = _smaSlow.Result[idx];
                    double rsi = _rsi.Result[idx];
                    double macdLine = _macd.MACD[idx];
                    double signalLine = _macd.Signal[idx];
                    double macdDiff = macdLine - signalLine;
                    double atr = _atr.Result[idx];

                    double[] closeWindow = new double[MacdSlow + 5];
                    for (int j = 0; j < MacdSlow + 5 && idx - j >= 0; j++)
                        closeWindow[j] = closePrices[idx - j];
                    double closeStd = CalculateStdDev(closeWindow.Take(Math.Min(MacdSlow + 5, idx + 1)).ToArray());
                    closeStd = closeStd == 0 ? 1e-6 : closeStd;

                    feature1[i] = (close - smaSlow) / (atr + 1e-8);
                    feature2[i] = (rsi / 50.0) - 1.0;
                    feature3[i] = Math.Max(-5, Math.Min(5, macdDiff / (closeStd + 1e-8)));
                    feature4[i] = atr / (close + 1e-8);
                    feature5[i] = positionState;
                    DateTime openTime = openTimes[idx];
                    double hour = openTime.Hour;
                    double dayOfWeek = (int)openTime.DayOfWeek;
                    feature6[i] = Math.Sin(2 * Math.PI * hour / 24.0);
                    feature7[i] = Math.Cos(2 * Math.PI * hour / 24.0);
                    feature8[i] = dayOfWeek / 6.0;
                }

                double[][] features = new double[LookbackWindowSize][];
                for (int i = 0; i < LookbackWindowSize; i++)
                {
                    features[i] = new double[] {
                        feature1[i], feature2[i], feature3[i], feature4[i],
                        feature5[i], feature6[i], feature7[i], feature8[i]
                    };
                }

                var message = new { features = features };
                string jsonMessage = JsonSerializer.Serialize(message);
                if (_clientWebSocket.State == WebSocketState.Open)
                {
                    var sendStartTime = DateTime.UtcNow;
                    var bytes = Encoding.UTF8.GetBytes(jsonMessage);
                    await _clientWebSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, _cts.Token);
                    var sendDuration = (DateTime.UtcNow - sendStartTime).TotalMilliseconds;
                    LogWithFallback("Sent features to WebSocket server in " + sendDuration.ToString() + "ms.");
                }
                else
                {
                    LogWithFallback("WebSocket not alive after reinitialization (state: " + _clientWebSocket.State.ToString() + "). Skipping...");
                    _isProcessing = false;
                }
            }
            catch (Exception ex)
            {
                LogWithFallback("Error computing/sending features: " + ex.ToString());
                _isProcessing = false;
            }
        }

        private double CalculateStdDev(double[] values)
        {
            if (values.Length == 0) return 0;
            double mean = values.Average();
            double sumOfSquares = values.Sum(x => (x - mean) * (x - mean));
            return Math.Sqrt(sumOfSquares / values.Length);
        }

        private void ExecuteAction(int action)
        {
            try
            {
                _currentPosition = Positions.FirstOrDefault(p => p.SymbolName == SymbolName);
                double volume = TradeVolumeLots * 100000;
                int lastIndex = _bars1H.Count - 1;
                double atrValue = _atr.Result[lastIndex];
                double stopLossPips = atrValue * AtrMultiplier / Symbol.PipSize;

                switch (action)
                {
                    case 0:
                        LogWithFallback("Action: Hold - No action taken.");
                        break;

                    case 1:
                        if (_currentPosition == null)
                        {
                            ExecuteMarketOrder(TradeType.Buy, SymbolName, volume, "DRL_Buy", stopLossPips, null);
                            LogWithFallback("Executed Buy order with SL: " + stopLossPips.ToString() + " pips");
                        }
                        else if (_currentPosition.TradeType == TradeType.Sell)
                        {
                            ClosePosition(_currentPosition);
                            ExecuteMarketOrder(TradeType.Buy, SymbolName, volume, "DRL_Buy", stopLossPips, null);
                            LogWithFallback("Closed Sell and opened Buy with SL: " + stopLossPips.ToString() + " pips");
                        }
                        break;

                    case 2:
                        if (_currentPosition == null)
                        {
                            ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, "DRL_Sell", stopLossPips, null);
                            LogWithFallback("Executed Sell order with SL: " + stopLossPips.ToString() + " pips");
                        }
                        else if (_currentPosition.TradeType == TradeType.Buy)
                        {
                            ClosePosition(_currentPosition);
                            ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, "DRL_Sell", stopLossPips, null);
                            LogWithFallback("Closed Buy and opened Sell with SL: " + stopLossPips.ToString() + " pips");
                        }
                        break;

                    case 3:
                        if (_currentPosition != null)
                        {
                            ClosePosition(_currentPosition);
                            LogWithFallback("Closed position.");
                        }
                        else
                        {
                            LogWithFallback("Action: Close - No position to close.");
                        }
                        break;

                    default:
                        LogWithFallback("Unknown action received: " + action.ToString());
                        break;
                }
            }
            catch (Exception ex)
            {
                LogWithFallback("Error executing action: " + ex.ToString());
            }
        }

        protected override void OnStop()
        {
            _cts.Cancel();
            if (_clientWebSocket != null && _clientWebSocket.State == WebSocketState.Open)
            {
                try
                {
                    _clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bot stopped", CancellationToken.None).GetAwaiter().GetResult();
                    LogWithFallback("WebSocket closed on bot stop. Final state: " + _clientWebSocket.State.ToString());
                }
                catch (Exception ex)
                {
                    LogWithFallback("Error closing WebSocket: " + ex.ToString());
                }
            }
            _clientWebSocket.Dispose();
            _cts.Dispose();
            LogWithFallback("Bot stopped.");
        }

        public class WebSocketResponse
        {
            public string Status { get; set; }
            public int PredictedAction { get; set; }
            public string Error { get; set; }
        }
    }
}

 

Actual ctrader Bot log output:

28/06/2024 00:00:00.000 | Info | CBot instance [DRL, NZDUSD, h1] started.
28.06.2024 00:00:00.155 | Info | Initialized 1-hour bars.
28.06.2024 00:00:00.155 | Info | Indicators initialized.
28.06.2024 00:00:00.155 | Info | Attempting to connect to WebSocket...
28.06.2024 00:00:00.155 | Info | Bot started. Waiting for new 1H bar...
28.06.2024 00:04:44.396 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 01:00:00.046 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 01:02:05.916 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 02:00:00.244 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 02:01:25.885 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 03:00:00.059 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 03:02:41.745 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 04:00:00.450 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 04:03:37.422 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 05:00:00.181 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 05:02:16.001 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 06:00:00.243 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 06:03:47.759 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 07:00:00.243 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 07:01:58.652 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 08:00:00.081 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 08:03:10.000 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 09:00:00.064 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 09:04:59.083 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 10:00:00.150 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 10:01:30.811 | Info | WebSocket closed: An exception has occurred while connecting.
28.06.2024 11:00:00.246 | Info | WebSocket not connected. Attempting to reconnect...
28.06.2024 12:00:00.073 | Info | WebSocket not connected. Attempting to reconnect...

….

 

The Firewall has been opened and the Websocket is running and has been tested with other standalone apps and it can receive and send information although not from/to the cbot:

 

 

Is there something wrong with my ctrader bot logging code or is there an issue with the ctrader platform.

 

Thank you!

Zyto


@zytotoxiziteat