websocket connection in Python

Created at 17 Nov 2023, 07:13
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!
KA

kadnan

Joined 17.11.2023

websocket connection in Python
17 Nov 2023, 07:13


Hi, 

 

I am trying to connect Websocket in Python, I could not find any help other than WS API, no idea what kind of message to send for a subscription. Can anyone guide me? Below is my code which is not working, it just prints that “WebSocket connection opened”

 

import websocket
import json
import ssl
import threading
import time

if __name__ == '__main__':
    ws = None
    CLIENT_ID = 'x'
    SECRET = 'xx'
    CTRADER_ID = 'xx'

    # Define the WebSocket endpoint URL
    # websocket_url = "wss://api.ctrader.com/v1/socket"
    websocket_url = "wss://demo.ctraderapi.com:5035"

    # Define your Client ID and Secret
    client_id = CLIENT_ID
    client_secret = SECRET

    # Define the instrument you want to fetch data for
    instrument = "EURUSD"  # Change this to your desired instrument

    # Define the subscription message
    subscribe_message = {
        "op": "subscribe",
        "topic": f"candles.{instrument}.1min",
    }

    # Define the authentication message
    auth_message = {
        "op": "auth",
        "apiKey": client_id,
        "secret": client_secret,
    }


    def on_message(ws, message):
        data = json.loads(message)
        print(data)

        # Check if the message is a candle update
        if data["op"] == "candle":
            candle = data["body"]
            print(f"Received candle: {candle}")


    def on_open(ws):
        print("WebSocket connection opened")
        # Send authentication message when the connection is opened
        ws.send(json.dumps(auth_message))
        # Send the subscribe message to start receiving data
        ws.send(json.dumps(subscribe_message))


    ssl_context = ssl.create_default_context()
    ssl_context.options |= ssl.OP_NO_SSLv2 | ssl.OP_NO_COMPRESSION | ssl.OP_CIPHER_SERVER_PREFERENCE | ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_DH_USE | ssl.OP_SINGLE_ECDH_USE | ssl.OP_NO_TICKET
    ssl_context.set_ciphers(
        "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-CCM8:DHE-RSA-AES128-CCM:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-CCM8:AES256-CCM:AES128-CCM8:AES128-CCM:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA")
    # Create a WebSocket connection with on_open callback
    ws = websocket.WebSocketApp(websocket_url, on_message=on_message, on_open=on_open)

    # Run the WebSocket connection in a separate thread
    def run_ws():
        ws.run_forever()


    # Start the WebSocket connection thread
    thread = threading.Thread(target=run_ws)
    thread.start()

    # Run the WebSocket connection
    # sslopt = {"ssl_context": ssl_context}
    # ws.run_forever(sslopt=sslopt)
    # # ws.run_forever()
    # Keep the main thread alive
    while True:
        try:
            time.sleep(1)
        except KeyboardInterrupt:
            ws.close()
            thread.join()
            break
 


@kadnan
Replies

williamfoley285
19 Jul 2024, 07:13 ( Updated at: 22 Jul 2024, 06:25 )

Hello @ poppy playtime chapter 3, I think you can add print statements or logging messages at various points in your code to help debug and track the flow of execution. You can print the received messages, any errors encountered, or other relevant information to aid in troubleshooting.
Here's an updated version of your code with minor modifications for error handling and logging:

python
import websocket
import json
import ssl
import threading
import time

if __name__ == '__main__':
   ws = None
   CLIENT_ID = 'x'
   SECRET = 'xx'
   CTRADER_ID = 'xx'

   # Define the WebSocket endpoint URL
   # websocket_url = "wss://api.ctrader.com/v1/socket"
   websocket_url = "wss://demo.ctraderapi.com:5035"

   # Define your Client ID and Secret
   client_id = CLIENT_ID
   client_secret = SECRET

   # Define the instrument you want to fetch data for
   instrument = "EURUSD"  # Change this to your desired instrument

   # Define the subscription message
   subscribe_message = {
       "op": "subscribe",
       "topic": f"candles.{instrument}.1min",
   }

   # Define the authentication message
   auth_message = {
       "op": "auth",
       "apiKey": client_id,
       "secret": client_secret,
   }

   def on_message(ws, message):
       data = json.loads(message)
       print(data)

       # Check if the message is a candle update
       if data["op"] == "candle":
           candle = data["body"]
           print(f"Received candle: {candle}")

   def on_open(ws):
       print("WebSocket connection opened")
       # Send authentication message when the connection is opened
       ws.send(json.dumps(auth_message))
       # Send the subscribe message to start receiving data
       ws.send(json.dumps(subscribe_message))

   def on_error(ws, error):
       print(f"WebSocket error: {error}")

   def on_close(ws):
       print("WebSocket connection closed")

   ssl_context = ssl.create_default_context()
   # Add your SSL context options and ciphers if necessary

   # Create a WebSocket connection with on_open, on_message, on_error, and on_close callbacks
   ws = websocket.WebSocketApp(
       websocket_url,
       on_message=on_message,
       on_open=on_open,
       on_error=on_error,
       on_close=on_close
   )

   # Run the WebSocket connection in a separate thread
   def run_ws():
       ws.run_forever()

   # Start the WebSocket connection thread
   thread = threading.Thread(target=run_ws)
   thread.start()

   # Keep the main thread alive
   while True:
       try:
           time.sleep(1)
       except KeyboardInterrupt:
           ws.close()
           thread.join()
           break
By incorporating these suggestions and carefully reviewing the WebSocket URL, authentication credentials, and subscription message, you should be able to establish a successful connection and receive data from the WebSocket. Remember to adjust the SSL context options and ciphers if necessary, depending on the server's requirements.


@williamfoley285