Guides

Keep connection live

Follow these steps to maintain a live WebSocket connection with the Deriv API:

Import the Deriv API library

Import the DerivAPIBasic library, which provides an interface to interact with the Deriv WebSocket API:

import DerivAPIBasic from 'https://cdn.skypack.dev/@deriv/deriv-api/dist/DerivAPIBasic';

Establish a WebSocket connection

Create a WebSocket connection using your app_id and the API URL:

(wss://ws.derivws.com/websockets/v3?app_id=${app_id}).

This connection will be used to send and receive messages from the Deriv API.

const connection = new WebSocket(wss://ws.derivws.com/websockets/v3?app_id=${app_id});

Create an API object

Create an instance of DerivAPIBasic, passing the WebSocket connection as a parameter.

This object interacts with the API, such as subscribing to proposals and sending pings.

const api = new DerivAPIBasic({ connection });

Send a proposal subscription

The proposal() function subscribes to a proposal and sends details such as the trade amount, currency, contract type, duration, and asset symbol.

After this subscription, the API will send real-time updates about the proposal (market data).

const proposal = () => {  
  api.subscribe({  
    proposal: 1,  
    subscribe: 1,  
    amount: 10,  
    basis: 'payout',  
    contract_type: 'CALL',  
    currency: 'USD',  
    duration: 1,  
    duration_unit: 'm',  
    symbol: 'R_100',  
    barrier: '+0.1',  
  });  
};

Send ping to keep the connection alive

The ping() function sends a "ping" message every 30 seconds using setInterval.

This ensures that the WebSocket connection remains active, as WebSocket servers may close idle connections.

const ping = () => {
  setInterval(() => {
    api.ping();
  }, 30000);
};

Handle WebSocket responses

The wsResponse() function processes incoming WebSocket messages and handles:

  • Errors: Logs errors and disconnects the WebSocket if an error is received.
  • Proposal Messages: Logs proposal details (e.g., ask price, payout).
  • Ping Messages: Logs ping responses from the server.
const wsResponse = async (res) => {
  const data = JSON.parse(res.data);
  if (data.error !== undefined) {
    console.log('Error: %s ', data.error.message);
    connection.removeEventListener('message', wsResponse, false);
    await api.disconnect();
  } else if (data.msg_type === 'proposal') {
    console.log('Details: %s', data.proposal.longcode);
    console.log('Ask Price: %s', data.proposal.display_value);
    console.log('Payout: %f', data.proposal.payout);
    console.log('Spot: %f', data.proposal.spot);
  } else if (data.msg_type === 'ping') {
    console.log('ping');
  }
};

Start the signal processing

The checkSignal() function starts the signal processing by:

  1. proposal(): Subscribes to market data.
  2. ping(): Starts sending pings.
  3. connection.addEventListener('message', wsResponse): Listens for messages from the WebSocket server and processing them using wsResponse().
const checkSignal = () => {
  proposal();
  ping();
  connection.addEventListener('message', wsResponse);
};

End the WebSocket subscription

The endCall() function stops receiving proposal updates by:

  1. Removing the WebSocket message listener.
  2. Calling unsubscribe() on the proposal()to stop the subscription.
const endCall = () => {
  connection.removeEventListener('message', wsResponse, false);
  proposal().unsubscribe();
};

These steps outline how the code works to establish a WebSocket connection, subscribe to proposals, keep the connection alive with pings, handle responses, and eventually unsubscribe from the proposals.

import DerivAPIBasic from 'https://cdn.skypack.dev/@deriv/deriv-api/dist/DerivAPIBasic';

const app_id = app_id; // Replace with your app_id.
const connection = new WebSocket(`wss://ws.derivws.com/websockets/v3?app_id=${app_id}`);

const api = new DerivAPIBasic({ connection });

const proposal = () => {
  api.subscribe({
    proposal: 1,
    subscribe: 1,
    amount: 10,
    basis: 'payout',
    contract_type: 'CALL',
    currency: 'USD',
    duration: 1,
    duration_unit: 'm',
    symbol: 'R_100',
    barrier: '+0.1',
  });
};

// Send a ping every 30 seconds to keep the connection alive
// Needs to use the same websocket connection as the one you want to maintain.
const ping = () => {
  setInterval(() => {
    api.ping();
  }, 30000);
};

const wsResponse = async (res) => {
  const data = JSON.parse(res.data);
  if (data.error !== undefined) {
    console.log('Error: %s ', data.error.message);
    connection.removeEventListener('message', wsResponse, false);
    await api.disconnect();
  } else if (data.msg_type === 'proposal') {
    console.log('Details: %s', data.proposal.longcode);
    console.log('Ask Price: %s', data.proposal.display_value);
    console.log('Payout: %f', data.proposal.payout);
    console.log('Spot: %f', data.proposal.spot);
  } else if (data.msg_type === 'ping') {
    console.log('ping');
  }
};

const checkSignal = () => {
  proposal();
  ping();
  connection.addEventListener('message', wsResponse);
};

const endCall = () => {
  connection.removeEventListener('message', wsResponse, false);
  proposal().unsubscribe();
};

const keep_alive_button = document.querySelector('#keep_alive');
keep_alive_button.addEventListener('click', checkSignal);

const end_call_button = document.querySelector('#end_call');
end_call_button.addEventListener('click', endCall);

import json
import asyncio
import websockets
from deriv_api import DerivAPIBasic  # Assuming you have DerivAPIBasic installed or available.

# Replace with your app_id.
app_id = 'your_app_id'
connection_url = f'wss://ws.derivws.com/websockets/v3?app_id={app_id}'

# Initialize the WebSocket connection
async def connect_to_deriv():
    async with websockets.connect(connection_url) as websocket:
        api = DerivAPIBasic(websocket)  # Create Deriv API object using the websocket connection

        # Function to send a proposal subscription request to the API
        async def proposal():
            await api.subscribe({
                "proposal": 1,
                "subscribe": 1,
                "amount": 10,
                "basis": "payout",
                "contract_type": "CALL",
                "currency": "USD",
                "duration": 1,
                "duration_unit": "m",
                "symbol": "R_100",
                "barrier": "+0.1"
            })

        # Function to send a ping every 30 seconds to keep the connection alive
        async def ping():
            while True:
                await api.ping()  # Send a ping
                await asyncio.sleep(30)  # Wait for 30 seconds before sending the next ping

        # Function to handle WebSocket responses
        async def ws_response(response):
            data = json.loads(response)

            if "error" in data:
                print(f"Error: {data['error']['message']}")
                await api.disconnect()  # Disconnect if there's an error
            elif data["msg_type"] == "proposal":
                # Print proposal details if received
                print(f"Details: {data['proposal']['longcode']}")
                print(f"Ask Price: {data['proposal']['display_value']}")
                print(f"Payout: {data['proposal']['payout']}")
                print(f"Spot: {data['proposal']['spot']}")
            elif data["msg_type"] == "ping":
                print("ping")

        # Function to manage the signal check and ping
        async def check_signal():
            await proposal()  # Subscribe to proposal
            asyncio.create_task(ping())  # Start the ping loop
            async for message in websocket:
                await ws_response(message)  # Handle each WebSocket message

        # Function to end the call
        async def end_call():
            await api.unsubscribe()  # Unsubscribe from the proposal
            await websocket.close()  # Close the WebSocket connection

        await check_signal()  # Start the signal checking process

# Start the WebSocket connection
asyncio.get_event_loop().run_until_complete(connect_to_deriv())

use strict;
use warnings;
use IO::Socket::SSL;
use Protocol::WebSocket::Client;
use JSON;
use AnyEvent;

# Replace with your app_id
my $app_id = 'your_app_id';
my $connection_url = "wss://ws.derivws.com/websockets/v3?app_id=$app_id";

# Create a WebSocket client
my $client = Protocol::WebSocket::Client->new(url => $connection_url);

# Initialize the AnyEvent loop to handle asynchronous operations
my $cv = AnyEvent->condvar;

# WebSocket connection setup
$client->on(connect => sub {
    print "Connected to Deriv API\n";
    
    # Send the proposal subscription
    proposal();

    # Set up a ping interval every 30 seconds to keep the connection alive
    my $ping_watcher = AnyEvent->timer(
        after    => 0,
        interval => 30,
        cb       => sub {
            ping();
        }
    );
});

# WebSocket message handler
$client->on(read => sub {
    my ($client, $message) = @_;
    ws_response($message);
});

# Error handling
$client->on(error => sub {
    my ($client, $error) = @_;
    print "Error: $error\n";
    $client->disconnect();
});

# Close WebSocket on disconnect
$client->on(finish => sub {
    print "Connection closed\n";
    $cv->send;
});

# Function to send the proposal subscription request
sub proposal {
    my $message = encode_json({
        proposal      => 1,
        subscribe     => 1,
        amount        => 10,
        basis         => 'payout',
        contract_type => 'CALL',
        currency      => 'USD',
        duration      => 1,
        duration_unit => 'm',
        symbol        => 'R_100',
        barrier       => '+0.1'
    });
    
    $client->write($message);
}

# Function to send a ping request to keep the connection alive
sub ping {
    my $message = encode_json({
        ping => 1
    });
    $client->write($message);
    print "Ping sent\n";
}

# Function to handle WebSocket responses
sub ws_response {
    my ($message) = @_;
    my $data = decode_json($message);

    if (exists $data->{error}) {
        print "Error: $data->{error}->{message}\n";
        $client->disconnect();
    } elsif ($data->{msg_type} eq 'proposal') {
        # Print proposal details if received
        print "Details: $data->{proposal}->{longcode}\n";
        print "Ask Price: $data->{proposal}->{display_value}\n";
        print "Payout: $data->{proposal}->{payout}\n";
        print "Spot: $data->{proposal}->{spot}\n";
    } elsif ($data->{msg_type} eq 'ping') {
        print "Ping response received\n";
    }
}

# Function to unsubscribe from the proposal and close connection
sub end_call {
    my $message = encode_json({ unsubscribe => 1 });
    $client->write($message);
    $client->disconnect();
}

# Start WebSocket connection
$client->connect;

# Wait for the connection to finish
$cv->recv;


import Foundation

// Define the app_id for Deriv API
let app_id = "your_app_id"
let connectionUrl = URL(string: "wss://ws.derivws.com/websockets/v3?app_id=\(app_id)")!

// WebSocket delegate class to handle WebSocket events
class WebSocketDelegate: NSObject, URLSessionWebSocketDelegate {
    var webSocketTask: URLSessionWebSocketTask?

    // Function to initiate a WebSocket connection
    func connectToDeriv() {
        let session = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue())
        webSocketTask = session.webSocketTask(with: connectionUrl)
        webSocketTask?.resume()

        // Subscribe to the proposal and start sending pings
        subscribeToProposal()
        sendPingPeriodically()
        
        receiveMessage()  // Start receiving messages
    }

    // Function to subscribe to the proposal
    func subscribeToProposal() {
        let proposalRequest: [String: Any] = [
            "proposal": 1,
            "subscribe": 1,
            "amount": 10,
            "basis": "payout",
            "contract_type": "CALL",
            "currency": "USD",
            "duration": 1,
            "duration_unit": "m",
            "symbol": "R_100",
            "barrier": "+0.1"
        ]

        send(jsonData: proposalRequest)
    }

    // Function to send a ping every 30 seconds to keep the connection alive
    func sendPingPeriodically() {
        Timer.scheduledTimer(withTimeInterval: 30, repeats: true) { _ in
            self.sendPing()
        }
    }

    // Function to send a ping message
    func sendPing() {
        let pingMessage: [String: Any] = ["ping": 1]
        send(jsonData: pingMessage)
        print("Ping sent")
    }

    // Function to send a message (JSON format) through the WebSocket
    func send(jsonData: [String: Any]) {
        do {
            let data = try JSONSerialization.data(withJSONObject: jsonData, options: [])
            let jsonString = String(data: data, encoding: .utf8) ?? ""
            let message = URLSessionWebSocketTask.Message.string(jsonString)
            webSocketTask?.send(message) { error in
                if let error = error {
                    print("WebSocket sending error: \(error)")
                }
            }
        } catch {
            print("JSON serialization error: \(error)")
        }
    }

    // Function to receive messages from the WebSocket
    func receiveMessage() {
        webSocketTask?.receive { [weak self] result in
            switch result {
            case .failure(let error):
                print("WebSocket receiving error: \(error)")
            case .success(let message):
                switch message {
                case .string(let text):
                    self?.handleMessage(text: text)
                default:
                    break
                }
                self?.receiveMessage()  // Continue listening for more messages
            }
        }
    }

    // Function to handle incoming messages from the WebSocket
    func handleMessage(text: String) {
        guard let data = text.data(using: .utf8),
              let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
            print("Invalid message received")
            return
        }

        if let error = json["error"] as? [String: Any] {
            print("Error: \(error["message"] ?? "Unknown error")")
            disconnect()
        } else if let msgType = json["msg_type"] as? String, msgType == "proposal" {
            if let proposal = json["proposal"] as? [String: Any] {
                print("Details: \(proposal["longcode"] ?? "")")
                print("Ask Price: \(proposal["display_value"] ?? "")")
                print("Payout: \(proposal["payout"] ?? "")")
                print("Spot: \(proposal["spot"] ?? "")")
            }
        } else if let msgType = json["msg_type"] as? String, msgType == "ping" {
            print("Ping response received")
        }
    }

    // Function to disconnect the WebSocket
    func disconnect() {
        webSocketTask?.cancel(with: .goingAway, reason: nil)
    }
}

// Create an instance of WebSocketDelegate and connect
let webSocketDelegate = WebSocketDelegate()
webSocketDelegate.connectToDeriv()

// Keep the run loop alive to keep the WebSocket connection active
RunLoop.main.run()

use futures_util::{StreamExt, SinkExt};
use serde_json::json;
use std::time::Duration;
use tokio::time;
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
use url::Url;

// The app_id for the Deriv API
const APP_ID: &str = "your_app_id";
const WS_URL: &str = "wss://ws.derivws.com/websockets/v3";

#[tokio::main]
async fn main() {
    // Establish WebSocket connection
    let url = format!("{}?app_id={}", WS_URL, APP_ID);
    let (mut ws_stream, _) = connect_async(Url::parse(&url).unwrap()).await.expect("Failed to connect");

    println!("Connected to Deriv API");

    // Subscribe to proposal and send pings periodically
    tokio::spawn(send_proposal(&mut ws_stream));
    tokio::spawn(send_ping_periodically(&mut ws_stream));

    // Handle incoming WebSocket messages
    while let Some(message) = ws_stream.next().await {
        match message {
            Ok(Message::Text(text)) => handle_message(text).await,
            Ok(_) => (),
            Err(e) => {
                println!("Error receiving message: {}", e);
                break;
            }
        }
    }

    println!("Connection closed");
}

// Function to send a proposal subscription request
async fn send_proposal(ws_stream: &mut tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>) {
    let proposal_request = json!({
        "proposal": 1,
        "subscribe": 1,
        "amount": 10,
        "basis": "payout",
        "contract_type": "CALL",
        "currency": "USD",
        "duration": 1,
        "duration_unit": "m",
        "symbol": "R_100",
        "barrier": "+0.1"
    });

    let request_text = proposal_request.to_string();
    ws_stream.send(Message::Text(request_text)).await.expect("Failed to send proposal request");
    println!("Proposal request sent");
}

// Function to send a ping every 30 seconds to keep the connection alive
async fn send_ping_periodically(ws_stream: &mut tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>) {
    let ping_message = json!({
        "ping": 1
    });

    loop {
        ws_stream.send(Message::Text(ping_message.to_string())).await.expect("Failed to send ping");
        println!("Ping sent");
        time::sleep(Duration::from_secs(30)).await;  // Wait for 30 seconds before sending the next ping
    }
}

// Function to handle incoming WebSocket messages
async fn handle_message(message: String) {
    let data: serde_json::Value = serde_json::from_str(&message).unwrap();

    if let Some(error) = data.get("error") {
        println!("Error: {}", error["message"]);
    } else if let Some(proposal) = data.get("proposal") {
        println!("Details: {}", proposal["longcode"]);
        println!("Ask Price: {}", proposal["display_value"]);
        println!("Payout: {}", proposal["payout"]);
        println!("Spot: {}", proposal["spot"]);
    } else if data.get("msg_type") == Some(&serde_json::Value::String("ping".to_string())) {
        println!("Ping response received");
    }
}
//[dependencies]
//tokio = { version = "1", features = ["full"] }
//tokio-tungstenite = "0.16"
//tungstenite = "0.16"
//serde_json = "1.0"
//futures-util = "0.3"
//url = "2.2"

<?php
// Set the app_id for Deriv API
$app_id = 'your_app_id';
$connection_url = "wss://ws.derivws.com/websockets/v3?app_id=$app_id";

// Function to establish WebSocket connection
function connect_to_deriv() {
    global $connection_url;

    // Create a WebSocket connection using the Ratchet library
    $client = new WebSocket\Client($connection_url);

    // Send the proposal request
    proposal($client);

    // Set up the ping to keep the connection alive every 30 seconds
    ping($client);

    // Handle incoming messages from the WebSocket
    while ($message = $client->receive()) {
        ws_response($client, $message);
    }

    // Close the connection
    $client->close();
}

// Function to send the proposal subscription request
function proposal($client) {
    $request = [
        "proposal" => 1,
        "subscribe" => 1,
        "amount" => 10,
        "basis" => "payout",
        "contract_type" => "CALL",
        "currency" => "USD",
        "duration" => 1,
        "duration_unit" => "m",
        "symbol" => "R_100",
        "barrier" => "+0.1"
    ];

    // Send the subscription request to the WebSocket
    $client->send(json_encode($request));
}

// Function to send a ping request every 30 seconds to keep the connection alive
function ping($client) {
    $ping_interval = 30;

    // Start an infinite loop

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.net.http.WebSocket.Listener;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.TimeUnit;

import org.json.JSONObject;

public class DerivWebSocketClient {

    // Define your app_id for Deriv API
    private static final String APP_ID = "your_app_id";
    private static final String WS_URL = "wss://ws.derivws.com/websockets/v3?app_id=" + APP_ID;

    private WebSocket webSocket;

    public static void main(String[] args) {
        DerivWebSocketClient client = new DerivWebSocketClient();
        client.connectToDeriv();
    }

    // Function to establish a WebSocket connection
    public void connectToDeriv() {
        HttpClient client = HttpClient.newHttpClient();
        webSocket = client.newWebSocketBuilder()
                .buildAsync(URI.create(WS_URL), new DerivWebSocketListener())
                .join();

        // Subscribe to the proposal
        subscribeToProposal();

        // Schedule a ping every 30 seconds
        schedulePing();
    }

    // Function to send a proposal subscription request
    private void subscribeToProposal() {
        JSONObject proposalRequest = new JSONObject();
        proposalRequest.put("proposal", 1);
        proposalRequest.put("subscribe", 1);
        proposalRequest.put("amount", 10);
        proposalRequest.put("basis", "payout");
        proposalRequest.put("contract_type", "CALL");
        proposalRequest.put("currency", "USD");
        proposalRequest.put("duration", 1);
        proposalRequest.put("duration_unit", "m");
        proposalRequest.put("symbol", "R_100");
        proposalRequest.put("barrier", "+0.1");

        webSocket.sendText(proposalRequest.toString(), true);
        System.out.println("Proposal subscription sent");
    }

    // Function to send a ping message every 30 seconds to keep the connection alive
    private void schedulePing() {
        Runnable pingTask = () -> {
            JSONObject pingMessage = new JSONObject();
            pingMessage.put("ping", 1);
            webSocket.sendText(pingMessage.toString(), true);
            System.out.println("Ping sent");
        };

        // Schedule ping task to run every 30 seconds
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(pingTask, 0, 30, TimeUnit.SECONDS);
    }

    // Listener class to handle WebSocket events
    private static class DerivWebSocketListener implements Listener {

        @Override
        public void onOpen(WebSocket webSocket) {
            System.out.println("WebSocket opened");
            Listener.super.onOpen(webSocket);
        }

        @Override
        public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
            handleMessage(data.toString());
            return Listener.super.onText(webSocket, data, last);
        }

        @Override
        public void onError(WebSocket webSocket, Throwable error) {
            System.out.println("Error occurred: " + error.getMessage());
            Listener.super.onError(webSocket, error);
        }

        @Override
        public CompletionStage<?> onClose(WebSocket webSocket, int statusCode, String reason) {
            System.out.println("WebSocket closed: " + reason);
            return Listener.super.onClose(webSocket, statusCode, reason);
        }

        // Function to handle incoming WebSocket messages
        private void handleMessage(String message) {
            JSONObject json = new JSONObject(message);

            if (json.has("error")) {
                System.out.println("Error: " + json.getJSONObject("error").getString("message"));
            } else if (json.has("proposal")) {
                JSONObject proposal = json.getJSONObject("proposal");
                System.out.println("Details: " + proposal.getString("longcode"));
                System.out.println("Ask Price: " + proposal.getString("display_value"));
                System.out.println("Payout: " + proposal.getDouble("payout"));
                System.out.println("Spot: " + proposal.getDouble("spot"));
            } else if ("ping".equals(json.optString("msg_type"))) {
                System.out.println("Ping response received");
            }
        }
    }
}

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/url"
	"os"
	"os/signal"
	"time"

	"github.com/gorilla/websocket"
)

// Constants for WebSocket connection and app ID
const appID = "your_app_id"
const wsURL = "wss://ws.derivws.com/websockets/v3"

// Struct for WebSocket messages (proposal request and ping)
type ProposalRequest struct {
	Proposal      int     `json:"proposal"`
	Subscribe     int     `json:"subscribe"`
	Amount        int     `json:"amount"`
	Basis         string  `json:"basis"`
	ContractType  string  `json:"contract_type"`
	Currency      string  `json:"currency"`
	Duration      int     `json:"duration"`
	DurationUnit  string  `json:"duration_unit"`
	Symbol        string  `json:"symbol"`
	Barrier       string  `json:"barrier"`
}

type PingMessage struct {
	Ping int `json:"ping"`
}

func main() {
	// Parse the WebSocket URL
	u := url.URL{Scheme: "wss", Host: "ws.derivws.com", Path: "/websockets/v3", RawQuery: "app_id=" + appID}
	log.Printf("Connecting to %s", u.String())

	// Establish WebSocket connection
	conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
	if err != nil {
		log.Fatal("Error while connecting to WebSocket:", err)
	}
	defer conn.Close()

	// Channel to listen for interruptions
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)

	// Send a proposal subscription
	go sendProposal(conn)

	// Send ping every 30 seconds
	go sendPing(conn)

	// Handle incoming WebSocket messages
	go func() {
		for {
			_, message, err := conn.ReadMessage()
			if err != nil {
				log.Println("Error reading WebSocket message:", err)
				return
			}
			handleMessage(message)
		}
	}()

	// Wait for interrupt signal to gracefully shut down
	<-interrupt
	log.Println("Interrupt received, closing connection")
	err = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
	if err != nil {
		log.Println("Error closing WebSocket connection:", err)
	}
}

// Function to send a proposal subscription request
func sendProposal(conn *websocket.Conn) {
	proposalRequest := ProposalRequest{
		Proposal:     1,
		Subscribe:    1,
		Amount:       10,
		Basis:        "payout",
		ContractType: "CALL",
		Currency:     "USD",
		Duration:     1,
		DurationUnit: "m",
		Symbol:       "R_100",
		Barrier:      "+0.1",
	}

	message, err := json.Marshal(proposalRequest)
	if err != nil {
		log.Println("Error marshaling proposal request:", err)
		return
	}

	err = conn.WriteMessage(websocket.TextMessage, message)
	if err != nil {
		log.Println("Error sending proposal request:", err)
	} else {
		log.Println("Proposal subscription sent")
	}
}

// Function to send a ping every 30 seconds to keep the connection alive
func sendPing(conn *websocket.Conn) {
	pingMessage := PingMessage{Ping: 1}

	for {
		message, err := json.Marshal(pingMessage)
		if err != nil {
			log.Println("Error marshaling ping message:", err)
			return
		}

		err = conn.WriteMessage(websocket.TextMessage, message)
		if err != nil {
			log.Println("Error sending ping message:", err)
		} else {
			log.Println("Ping sent")
		}

		// Wait for 30 seconds before sending the next ping
		time.Sleep(30 * time.Second)
	}
}

// Function to handle incoming WebSocket messages
func handleMessage(message []byte) {
	var data map[string]interface{}
	err := json.Unmarshal(message, &data)
	if err != nil {
		log.Println("Error unmarshaling WebSocket message:", err)
		return
	}

	// Check for errors in the message
	if errorData, exists := data["error"]; exists {
		errorMap := errorData.(map[string]interface{})
		log.Printf("Error: %s", errorMap["message"])
	} else if proposal, exists := data["proposal"]; exists {
		// If it's a proposal, print details
		proposalMap := proposal.(map[string]interface{})
		log.Printf("Details: %s", proposalMap["longcode"])
		log.Printf("Ask Price: %s", proposalMap["display_value"])
		log.Printf("Payout: %v", proposalMap["payout"])
		log.Printf("Spot: %v", proposalMap["spot"])
	} else if data["msg_type"] == "ping" {
		// If it's a ping response, log it
		log.Println("Ping response received")
	}
}

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DerivWebSocketClient
{
    class Program
    {
        private static readonly string appId = "your_app_id"; // Replace with your app_id
        private static readonly Uri wsUri = new Uri($"wss://ws.derivws.com/websockets/v3?app_id={appId}");
        private static ClientWebSocket webSocket;

        static async Task Main(string[] args)
        {
            webSocket = new ClientWebSocket();

            try
            {
                // Connect to the WebSocket server
                await webSocket.ConnectAsync(wsUri, CancellationToken.None);
                Console.WriteLine("Connected to WebSocket server.");

                // Send proposal subscription
                await SendProposal();

                // Start the ping task to send pings every 30 seconds
                _ = Task.Run(SendPingPeriodically);

                // Handle incoming WebSocket messages
                await ReceiveMessages();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
            finally
            {
                // Close the WebSocket connection when done
                await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
                webSocket.Dispose();
                Console.WriteLine("WebSocket closed.");
            }
        }

        // Function to send a proposal subscription request
        private static async Task SendProposal()
        {
            var proposalRequest = new
            {
                proposal = 1,
                subscribe = 1,
                amount = 10,
                basis = "payout",
                contract_type = "CALL",
                currency = "USD",
                duration = 1,
                duration_unit = "m",
                symbol = "R_100",
                barrier = "+0.1"
            };

            string jsonRequest = JsonConvert.SerializeObject(proposalRequest);
            await SendMessage(jsonRequest);
            Console.WriteLine("Proposal subscription sent.");
        }

        // Function to send a ping message every 30 seconds to keep the connection alive
        private static async Task SendPingPeriodically()
        {
            var pingMessage = new { ping = 1 };

            while (webSocket.State == WebSocketState.Open)
            {
                string jsonPing = JsonConvert.SerializeObject(pingMessage);
                await SendMessage(jsonPing);
                Console.WriteLine("Ping sent.");
                await Task.Delay(30000); // Wait for 30 seconds before sending the next ping
            }
        }

        // Function to handle receiving messages from the WebSocket
        private static async Task ReceiveMessages()
        {
            var buffer = new byte[1024 * 4];

            while (webSocket.State == WebSocketState.Open)
            {
                var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                if (result.MessageType == WebSocketMessageType.Close)
                {
                    break;
                }

                var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                HandleMessage(message);
            }
        }

        // Function to handle incoming WebSocket messages
        private static void HandleMessage(string message)
        {
            JObject data = JObject.Parse(message);

            if (data.ContainsKey("error"))
            {
                Console.WriteLine("Error: " + data["error"]["message"]);
            }
            else if (data.ContainsKey("proposal"))
            {
                Console.WriteLine("Details: " + data["proposal"]["longcode"]);
                Console.WriteLine("Ask Price: " + data["proposal"]["display_value"]);
                Console.WriteLine("Payout: " + data["proposal"]["payout"]);
                Console.WriteLine("Spot: " + data["proposal"]["spot"]);
            }
            else if (data.ContainsKey("msg_type") && data["msg_type"].ToString() == "ping")
            {
                Console.WriteLine("Ping response received.");
            }
        }

        // Function to send a message through the WebSocket
        private static async Task SendMessage(string message)
        {
            var messageBytes = Encoding.UTF8.GetBytes(message);
            var buffer = new ArraySegment<byte>(messageBytes);
            await webSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
        }
    }
}

#include <libwebsockets.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include "cJSON.h"

static int interrupted;
static struct lws_context *context;
static struct lws *wsi;

#define PING_INTERVAL 30

// WebSocket message type
enum protocol_demo {
    PROTOCOL_DEMO,
    PROTOCOL_COUNT
};

// JSON proposal request function
void send_proposal(struct lws *wsi) {
    // Build JSON message
    cJSON *proposal = cJSON_CreateObject();
    cJSON_AddNumberToObject(proposal, "proposal", 1);
    cJSON_AddNumberToObject(proposal, "subscribe", 1);
    cJSON_AddNumberToObject(proposal, "amount", 10);
    cJSON_AddStringToObject(proposal, "basis", "payout");
    cJSON_AddStringToObject(proposal, "contract_type", "CALL");
    cJSON_AddStringToObject(proposal, "currency", "USD");
    cJSON_AddNumberToObject(proposal, "duration", 1);
    cJSON_AddStringToObject(proposal, "duration_unit", "m");
    cJSON_AddStringToObject(proposal, "symbol", "R_100");
    cJSON_AddStringToObject(proposal, "barrier", "+0.1");

    char *proposal_string = cJSON_PrintUnformatted(proposal);
    lws_write(wsi, (unsigned char *)proposal_string, strlen(proposal_string), LWS_WRITE_TEXT);
    free(proposal_string);
    cJSON_Delete(proposal);

    printf("Proposal subscription sent.\n");
}

// Ping function to keep the WebSocket connection alive
void send_ping(struct lws *wsi) {
    cJSON *ping = cJSON_CreateObject();
    cJSON_AddNumberToObject(ping, "ping", 1);

    char *ping_string = cJSON_PrintUnformatted(ping);
    lws_write(wsi, (unsigned char *)ping_string, strlen(ping_string), LWS_WRITE_TEXT);
    free(ping_string);
    cJSON_Delete(ping);

    printf("Ping sent.\n");
}

// Callback function for handling events
static int callback_demo(struct lws *wsi, enum lws_callback_reasons reason,
                         void *user, void *in, size_t len) {
    switch (reason) {
        case LWS_CALLBACK_CLIENT_ESTABLISHED:
            printf("WebSocket connection established\n");
            send_proposal(wsi); // Send proposal on connection
            break;

        case LWS_CALLBACK_CLIENT_RECEIVE: {
            char *message = (char *)in;
            cJSON *data = cJSON_Parse(message);
            if (!data) {
                printf("Error parsing JSON message\n");
                break;
            }

            cJSON *error = cJSON_GetObjectItem(data, "error");
            if (error) {
                printf("Error: %s\n", cJSON_GetObjectItem(error, "message")->valuestring);
            } else if (cJSON_GetObjectItem(data, "proposal")) {
                cJSON *proposal = cJSON_GetObjectItem(data, "proposal");
                printf("Details: %s\n", cJSON_GetObjectItem(proposal, "longcode")->valuestring);
                printf("Ask Price: %s\n", cJSON_GetObjectItem(proposal, "display_value")->valuestring);
                printf("Payout: %f\n", cJSON_GetObjectItem(proposal, "payout")->valuedouble);
                printf("Spot: %f\n", cJSON_GetObjectItem(proposal, "spot")->valuedouble);
            } else if (strcmp(cJSON_GetObjectItem(data, "msg_type")->valuestring, "ping") == 0) {
                printf("Ping response received\n");
            }

            cJSON_Delete(data);
            break;
        }

        case LWS_CALLBACK_CLIENT_CLOSED:
            printf("WebSocket connection closed\n");
            interrupted = 1;
            break;

        default:
            break;
    }

    return 0;
}

// Structure for WebSocket protocols
static const struct lws_protocols protocols[] = {
    {
        "example-protocol",
        callback_demo,
        0,
        4096,
    },
    {NULL, NULL, 0, 0}
};

// Timer function for sending pings periodically
static void *ping_timer(void *arg) {
    while (!interrupted) {
        sleep(PING_INTERVAL);
        if (wsi) {
            send_ping(wsi);
        }
    }
    return NULL;
}

// Main function
int main(void) {
    struct lws_client_connect_info ccinfo = {0};
    struct lws_context_creation_info ctx_creation_info = {0};

    ctx_creation_info.port = CONTEXT_PORT_NO_LISTEN;
    ctx_creation_info.protocols = protocols;

    context = lws_create_context(&ctx_creation_info);
    if (!context) {
        printf("Failed to create context\n");
        return 1;
    }

    ccinfo.context = context;
    ccinfo.address = "ws.derivws.com";
    ccinfo.port = 443;
    ccinfo.path = "/websockets/v3?app_id=your_app_id"; // Replace with your app_id
    ccinfo.host = lws_canonical_hostname(context);
    ccinfo.origin = ccinfo.host;
    ccinfo.ssl_connection = LCCSCF_USE_SSL;
    ccinfo.protocol = protocols[0].name;
    ccinfo.pwsi = &wsi;

    // Establish WebSocket connection
    wsi = lws_client_connect_via_info(&ccinfo);
    if (!wsi) {
        printf("WebSocket connection failed\n");
        lws_context_destroy(context);
        return 1;
    }

    // Create a thread to send ping messages periodically
    pthread_t ping_thread;
    pthread_create(&ping_thread, NULL, ping_timer, NULL);

    // Main loop to handle WebSocket events
    while (!interrupted) {
        lws_service(context, 1000);
    }

    // Clean up
    pthread_join(ping_thread, NULL);
    lws_context_destroy(context);

    return 0;
}