xtb-api-unofficial - v0.1.0
    Preparing search index...

    Class XTBWebSocketClient

    Low-level WebSocket client for xStation5.

    Implements the CoreAPI protocol with full CAS authentication support. Provides real-time data subscriptions and trading capabilities via WebSocket.

    Features:

    • Full CAS authentication flow (credentials → TGT → Service Ticket → WebSocket auth)
    • Real-time subscriptions (ticks, positions, request status)
    • Symbol cache for fast instrument search (11,888+ instruments)
    • Auto-reconnection with exponential backoff
    • Typed event emitters for real-time data
    • Direct trading via tradeTransaction commands

    Event Types:

    • connected - WebSocket connection established
    • authenticated - CAS authentication successful
    • tick - Real-time price updates
    • position - Position/trade updates
    • push - Generic push messages from server
    const ws = new XTBWebSocketClient({
    url: 'wss://api5demoa.x-station.eu/v1/xstation',
    accountNumber: 12345678,
    auth: {
    credentials: { email: 'user@example.com', password: 'password' }
    }
    });

    ws.on('tick', (tick) => console.log('Price update:', tick));
    ws.on('authenticated', (result) => console.log('Logged in:', result));

    await ws.connect();
    const balance = await ws.getBalance();

    Hierarchy

    • EventEmitter
      • XTBWebSocketClient
    Index

    Constructors

    Accessors

    • get accountId(): string

      Get the account ID in the format required by the WebSocket API.

      Returns string

      Account ID string (e.g., 'meta1_12345678')

    • get isAuthenticated(): boolean

      Check if authenticated with XTB servers.

      Returns boolean

      True if authenticated, false otherwise

    • get isConnected(): boolean

      Check if WebSocket is connected.

      Returns boolean

      True if connected, false otherwise

    Methods

    • The Symbol.for('nodejs.rejection') method is called in case a promise rejection happens when emitting an event and captureRejections is enabled on the emitter. It is possible to use events.captureRejectionSymbol in place of Symbol.for('nodejs.rejection').

      import { EventEmitter, captureRejectionSymbol } from 'node:events';

      class MyClass extends EventEmitter {
      constructor() {
      super({ captureRejections: true });
      }

      [captureRejectionSymbol](err, event, ...args) {
      console.log('rejection happened for', event, 'with', err, ...args);
      this.destroy(err);
      }

      destroy(err) {
      // Tear the resource down here.
      }
      }

      Parameters

      • error: Error
      • event: string | symbol
      • ...args: any[]

      Returns void

      v13.4.0, v12.16.0

    • Alias for emitter.on(eventName, listener).

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol
      • listener: (...args: any[]) => void

      Returns this

      v0.1.26

    • Execute a BUY order via WebSocket tradeTransaction.

      ⚠️ WARNING: This executes real trades. Always test on demo accounts first.

      Sends a market buy order using the CoreAPI tradeTransaction command. Automatically looks up instrument ID via symbol search.

      Parameters

      • symbol: string

        Symbol name (e.g., 'CIG.PL', 'AAPL.US')

      • volume: number

        Volume to buy (number of units)

      • Optionaloptions: TradeOptions

        Optional trade parameters (stop loss, take profit, trailing stop)

      Returns Promise<TradeResult>

      Promise that resolves to trade execution result

      Error if not authenticated, symbol not found, or trade fails

    • Connect to the WebSocket server and perform authentication if configured.

      Establishes WebSocket connection and performs full CAS authentication flow if auth options are provided. Emits 'connected' when WebSocket is ready and 'authenticated' when CAS login completes.

      Returns Promise<void>

      Error if connection fails, authentication fails, or services are unavailable

    • Disconnect from the WebSocket server.

      Cleanly closes the WebSocket connection, disables auto-reconnect, and cleans up all resources including pending requests and timers.

      Returns void

    • Synchronously calls each of the listeners registered for the event named eventName, in the order they were registered, passing the supplied arguments to each.

      Returns true if the event had listeners, false otherwise.

      import { EventEmitter } from 'node:events';
      const myEmitter = new EventEmitter();

      // First listener
      myEmitter.on('event', function firstListener() {
      console.log('Helloooo! first listener');
      });
      // Second listener
      myEmitter.on('event', function secondListener(arg1, arg2) {
      console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
      });
      // Third listener
      myEmitter.on('event', function thirdListener(...args) {
      const parameters = args.join(', ');
      console.log(`event with parameters ${parameters} in third listener`);
      });

      console.log(myEmitter.listeners('event'));

      myEmitter.emit('event', 1, 2, 3, 4, 5);

      // Prints:
      // [
      // [Function: firstListener],
      // [Function: secondListener],
      // [Function: thirdListener]
      // ]
      // Helloooo! first listener
      // event with parameters 1, 2 in second listener
      // event with parameters 1, 2, 3, 4, 5 in third listener

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol
      • ...args: any[]

      Returns boolean

      v0.1.26

    • Returns an array listing the events for which the emitter has registered listeners.

      import { EventEmitter } from 'node:events';

      const myEE = new EventEmitter();
      myEE.on('foo', () => {});
      myEE.on('bar', () => {});

      const sym = Symbol('symbol');
      myEE.on(sym, () => {});

      console.log(myEE.eventNames());
      // Prints: [ 'foo', 'bar', Symbol(symbol) ]

      Returns (string | symbol)[]

      v6.0.0

    • Get the account number for this WebSocket session.

      Returns the account number from the login result if available, otherwise falls back to the configured account number.

      Returns number

      Account number for this session

    • Get account balance and equity information.

      Uses EID 1043 (xtotalbalance) for real-time balance data. Falls back to account info from login result if balance data unavailable.

      Returns Promise<AccountBalance>

      Promise that resolves to account balance with equity, free margin, and currency

      Error if not authenticated or balance service fails

    • Returns the current max listener value for the EventEmitter which is either set by emitter.setMaxListeners(n) or defaults to events.defaultMaxListeners.

      Returns number

      v1.0.0

    • Get all open trading positions.

      Uses EID 1 (xcfdtrade) to retrieve current positions with details like volume, open price, profit/loss, stop loss, take profit, etc. Also subscribes to real-time position updates via 'position' events.

      Returns Promise<Position[]>

      Promise that resolves to array of open positions

      Error if not authenticated or position service fails

    • Get current quote (bid/ask prices) for a symbol.

      Uses EID 2 (xcfdtick) to retrieve real-time price data. Automatically tries common symbol key patterns if exact key not provided. Also subscribes to tick updates, so 'tick' events will be emitted for this symbol.

      Symbol Key Format: Accepts both symbol names ('CIG.PL') and full keys ('9_CIG.PL_6')

      Parameters

      • symbol: string

        Symbol name or full symbol key

      Returns Promise<Quote | null>

      Promise that resolves to quote data or null if symbol not found

      Error if not authenticated or quote service fails

      const quote = await ws.getQuote('CIG.PL');
      if (quote) {
      console.log(`Bid: ${quote.bid}, Ask: ${quote.ask}`);
      }
    • Returns the number of listeners listening for the event named eventName. If listener is provided, it will return how many times the listener is found in the list of the listeners of the event.

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol

        The name of the event being listened for

      • Optionallistener: (...args: any[]) => void

        The event handler function

      Returns number

      v3.2.0

    • Returns a copy of the array of listeners for the event named eventName.

      server.on('connection', (stream) => {
      console.log('someone connected!');
      });
      console.log(util.inspect(server.listeners('connection')));
      // Prints: [ [Function] ]

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol

      Returns ((...args: any[]) => void)[]

      v0.1.26

    • Login with service ticket - second step in authentication flow.

      Uses service ticket (ST) obtained from CAS to authenticate with WebSocket. Must be called after registerClientInfo() for the auth flow to succeed. Emits 'authenticated' event when successful.

      Parameters

      • serviceTicket: string

        Service ticket from CAS (format: ST-...)

      Returns Promise<XLoginResult>

      Promise that resolves to login result with account list and user data

      Error if login fails or service ticket is invalid

    • Alias for emitter.removeListener().

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol
      • listener: (...args: any[]) => void

      Returns this

      v10.0.0

    • Emitted when WebSocket connection is established (before authentication).

      Parameters

      • event: "connected"
      • listener: () => void

      Returns this

    • Emitted when authentication completes successfully.

      Parameters

      • event: "authenticated"
      • listener: (loginResult: XLoginResult) => void

      Returns this

    • Emitted when WebSocket connection is closed.

      Parameters

      • event: "disconnected"
      • listener: (code: number, reason: string) => void

      Returns this

    • Emitted when a WebSocket or protocol error occurs.

      Parameters

      • event: "error"
      • listener: (error: Error) => void

      Returns this

    • Emitted when connection status changes.

      Parameters

      • event: "statusUpdate"
      • listener: (status: SocketStatus) => void

      Returns this

    • Emitted for incoming push messages from the server.

      Parameters

      Returns this

    • Emitted for generic WebSocket messages.

      Parameters

      Returns this

    • Emitted for real-time tick/quote data updates.

      Parameters

      • event: "tick"
      • listener: (tick: any) => void

      Returns this

    • Emitted for position updates.

      Parameters

      • event: "position"
      • listener: (position: any) => void

      Returns this

    • Emitted for symbol/instrument data updates.

      Parameters

      • event: "symbol"
      • listener: (symbol: any) => void

      Returns this

    • Emitted when two-factor authentication is required.

      Parameters

      • event: "requires_2fa"
      • listener: (
            sessionData: { expiresAt: number; methods: string[]; sessionId: string },
        ) => void

      Returns this

    • Adds a one-time listener function for the event named eventName. The next time eventName is triggered, this listener is removed and then invoked.

      server.once('connection', (stream) => {
      console.log('Ah, we have our first user!');
      });

      Returns a reference to the EventEmitter, so that calls can be chained.

      By default, event listeners are invoked in the order they are added. The emitter.prependOnceListener() method can be used as an alternative to add the event listener to the beginning of the listeners array.

      import { EventEmitter } from 'node:events';
      const myEE = new EventEmitter();
      myEE.once('foo', () => console.log('a'));
      myEE.prependOnceListener('foo', () => console.log('b'));
      myEE.emit('foo');
      // Prints:
      // b
      // a

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol

        The name of the event.

      • listener: (...args: any[]) => void

        The callback function

      Returns this

      v0.3.0

    • Ping the server to measure latency.

      Sends a ping command and measures round-trip time. Useful for connection quality monitoring.

      Returns Promise<number>

      Promise that resolves to latency in milliseconds

    • Adds the listener function to the beginning of the listeners array for the event named eventName. No checks are made to see if the listener has already been added. Multiple calls passing the same combination of eventName and listener will result in the listener being added, and called, multiple times.

      server.prependListener('connection', (stream) => {
      console.log('someone connected!');
      });

      Returns a reference to the EventEmitter, so that calls can be chained.

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol

        The name of the event.

      • listener: (...args: any[]) => void

        The callback function

      Returns this

      v6.0.0

    • Adds a one-time listener function for the event named eventName to the beginning of the listeners array. The next time eventName is triggered, this listener is removed, and then invoked.

      server.prependOnceListener('connection', (stream) => {
      console.log('Ah, we have our first user!');
      });

      Returns a reference to the EventEmitter, so that calls can be chained.

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol

        The name of the event.

      • listener: (...args: any[]) => void

        The callback function

      Returns this

      v6.0.0

    • Returns a copy of the array of listeners for the event named eventName, including any wrappers (such as those created by .once()).

      import { EventEmitter } from 'node:events';
      const emitter = new EventEmitter();
      emitter.once('log', () => console.log('log once'));

      // Returns a new Array with a function `onceWrapper` which has a property
      // `listener` which contains the original listener bound above
      const listeners = emitter.rawListeners('log');
      const logFnWrapper = listeners[0];

      // Logs "log once" to the console and does not unbind the `once` event
      logFnWrapper.listener();

      // Logs "log once" to the console and removes the listener
      logFnWrapper();

      emitter.on('log', () => console.log('log persistently'));
      // Will return a new Array with a single function bound by `.on()` above
      const newListeners = emitter.rawListeners('log');

      // Logs "log persistently" twice
      newListeners[0]();
      emitter.emit('log');

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol

      Returns ((...args: any[]) => void)[]

      v9.4.0

    • Register client info - first step in authentication flow.

      Must match xStation5 client info exactly for authentication to work. This identifies the client to the server and establishes compatibility.

      Returns Promise<WSResponse>

      Promise that resolves when client info is registered

      Error if registration fails

    • Removes all listeners, or those of the specified eventName.

      It is bad practice to remove listeners added elsewhere in the code, particularly when the EventEmitter instance was created by some other component or module (e.g. sockets or file streams).

      Returns a reference to the EventEmitter, so that calls can be chained.

      Type Parameters

      • E extends string | symbol

      Parameters

      • OptionaleventName: string | symbol

      Returns this

      v0.1.26

    • Removes the specified listener from the listener array for the event named eventName.

      const callback = (stream) => {
      console.log('someone connected!');
      };
      server.on('connection', callback);
      // ...
      server.removeListener('connection', callback);

      removeListener() will remove, at most, one instance of a listener from the listener array. If any single listener has been added multiple times to the listener array for the specified eventName, then removeListener() must be called multiple times to remove each instance.

      Once an event is emitted, all listeners attached to it at the time of emitting are called in order. This implies that any removeListener() or removeAllListeners() calls after emitting and before the last listener finishes execution will not remove them from emit() in progress. Subsequent events behave as expected.

      import { EventEmitter } from 'node:events';
      class MyEmitter extends EventEmitter {}
      const myEmitter = new MyEmitter();

      const callbackA = () => {
      console.log('A');
      myEmitter.removeListener('event', callbackB);
      };

      const callbackB = () => {
      console.log('B');
      };

      myEmitter.on('event', callbackA);

      myEmitter.on('event', callbackB);

      // callbackA removes listener callbackB but it will still be called.
      // Internal listener array at time of emit [callbackA, callbackB]
      myEmitter.emit('event');
      // Prints:
      // A
      // B

      // callbackB is now removed.
      // Internal listener array [callbackA]
      myEmitter.emit('event');
      // Prints:
      // A

      Because listeners are managed using an internal array, calling this will change the position indexes of any listener registered after the listener being removed. This will not impact the order in which listeners are called, but it means that any copies of the listener array as returned by the emitter.listeners() method will need to be recreated.

      When a single function has been added as a handler multiple times for a single event (as in the example below), removeListener() will remove the most recently added instance. In the example the once('ping') listener is removed:

      import { EventEmitter } from 'node:events';
      const ee = new EventEmitter();

      function pong() {
      console.log('pong');
      }

      ee.on('ping', pong);
      ee.once('ping', pong);
      ee.removeListener('ping', pong);

      ee.emit('ping');
      ee.emit('ping');

      Returns a reference to the EventEmitter, so that calls can be chained.

      Type Parameters

      • E extends string | symbol

      Parameters

      • eventName: string | symbol
      • listener: (...args: any[]) => void

      Returns this

      v0.1.26

    • Search for financial instruments with intelligent caching.

      Performance Optimization: Downloads all 11,888+ instruments on first call and caches them locally. Subsequent searches are instant, filtering from cache.

      Uses EID 3 (xcfdsymbol) to retrieve complete instrument catalog including symbol names, descriptions, instrument IDs, and symbol keys.

      Symbol Key Format: {assetClassId}_{symbolName}_{groupId} (e.g., '9_CIG.PL_6')

      Parameters

      • query: string

        Search query (case-insensitive, matches symbol name or description)

      Returns Promise<InstrumentSearchResult[]>

      Promise that resolves to array of matching instruments

      Error if not authenticated or symbol service fails

      // First call downloads all symbols (~1-3 seconds)
      const results1 = await ws.searchInstrument('Apple');

      // Subsequent calls are instant (cached)
      const results2 = await ws.searchInstrument('Microsoft');
      const results3 = await ws.searchInstrument('Tesla');
    • Execute a SELL order via WebSocket tradeTransaction.

      ⚠️ WARNING: This executes real trades. Always test on demo accounts first.

      Sends a market sell order using the CoreAPI tradeTransaction command. Automatically looks up instrument ID via symbol search.

      Parameters

      • symbol: string

        Symbol name (e.g., 'CIG.PL', 'AAPL.US')

      • volume: number

        Volume to sell (number of units)

      • Optionaloptions: TradeOptions

        Optional trade parameters (stop loss, take profit, trailing stop)

      Returns Promise<TradeResult>

      Promise that resolves to trade execution result

      Error if not authenticated, symbol not found, or trade fails

    • Send a raw CoreAPI command and wait for response.

      Low-level method for sending commands to the WebSocket API. Most users should use the higher-level methods instead.

      Parameters

      • commandName: string

        Command name for request ID generation

      • payload: Partial<CoreAPICommand["CoreAPI"]>

        CoreAPI command payload

      • timeoutMs: number = 10000

        Request timeout in milliseconds (default: 10000)

      Returns Promise<WSResponse>

      Promise that resolves to the command response

      Error if not connected, command fails, or timeout occurs

    • By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. This is a useful default that helps finding memory leaks. The emitter.setMaxListeners() method allows the limit to be modified for this specific EventEmitter instance. The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.

      Returns a reference to the EventEmitter, so that calls can be chained.

      Parameters

      • n: number

      Returns this

      v0.3.5

    • Submit two-factor authentication code to complete login.

      Call this method when you receive a 'requires_2fa' event. If successful, authentication will continue automatically.

      Parameters

      • sessionId: string

        Session ID from 'requires_2fa' event

      • code: string

        6-digit OTP code from authenticator app, SMS, or email

      Returns Promise<void>

      Promise that resolves when authentication completes

      Error if 2FA code is invalid, expired, or rate limited

    • Subscribe to request status updates for trade confirmations.

      Subscribes to EID 6 for trade execution confirmations and status updates. Essential for monitoring trade execution results.

      Returns Promise<WSResponse>

      Promise that resolves when subscription is confirmed

    • Subscribe to real-time tick/quote data for a symbol.

      Subscribes to EID 2 (xcfdtick) for bid, ask, high, low, volume updates. Tick events will be emitted via the 'tick' event.

      Parameters

      • symbolKey: string

        Symbol key in format {assetClassId}{symbolName}{groupId} (e.g., '9_CIG.PL_6')

      Returns Promise<WSResponse>

      Promise that resolves when subscription is confirmed

    • Unsubscribe from real-time tick data for a symbol.

      Parameters

      • symbolKey: string

        Symbol key to unsubscribe from

      Returns Promise<WSResponse>

      Promise that resolves when unsubscription is confirmed