timirey/xapi-php

A PHP wrapper for the X-Trade Brokers (XTB) xStation5 Trading API, supporting real-time streaming and simple commands via socket connection.

6.3.2 2025-01-06 13:54 UTC

README

XTB Online Investing

Tests Latest Stable Version Total Downloads License

This PHP library provides a comprehensive and user-friendly interface for interacting with the X-Trade Brokers (XTB) xStation5 Trading API. It supports a wide range of functionalities, including account management, trade execution, market data retrieval, and real-time streaming commands via socket, making it an ideal tool for developers looking to integrate advanced trading features and live market data into their applications.

Table of contents

Installation

Install the package via Composer.

composer require timirey/xapi-php

Usage

Basic usage example.

use Timirey\XApi\Client;
use Timirey\XApi\Enums\Host;
use Timirey\XApi\Responses\GetSymbolResponse;

$client = new Client(
    userId: 12345678,
    password: 'password',
    host: Host::DEMO,
    appName: 'My Test App'
);

/**
 * @var $response GetSymbolResponse
 */
$response = $client->getSymbol(
    symbol: 'EURUSD'
);

Subscribe to a stream channel.

use Timirey\XApi\Client;
use Timirey\XApi\Enums\Host;
use Timirey\XApi\Responses\Data\TickStreamRecord;
use Timirey\XApi\Responses\FetchTickPricesResponse;

$client = new Client(
    userId: 12345678,
    password: 'password',
    host: Host::DEMO,
    appName: 'My Test App'
);

// Meant to be a daemon, run as separate process.
$client->fetchTickPrices(
    symbol: 'EURUSD',
    callback: static function (FetchTickPricesResponse $response): void {
        /**
         * @var TickStreamRecord $record
         */
        $record = $response->tickStreamRecord;
    },
    minArrivalTime: 100,
    maxLevel: 1
);

// Unreachable code.

Available commands

Request-Reply commands are performed on main connection socket. The reply is sent by main connection socket.

login

Logs in to the xStation5 API.

use Timirey\XApi\Responses\LoginResponse;
use Timirey\XApi\Client;

/** 
 * @var LoginResponse $response 
 * @var Client $client
 */
$response = $client->login(
    userId: 123456789, 
    password: 'password',
    appName: 'My App'
);

logout

Logs out from the xStation5 API.

use Timirey\XApi\Responses\LogoutResponse;
use Timirey\XApi\Client;

/** 
 * @var LogoutResponse $response
 * @var Client $client
 */
$response = $client->logout();

Available streaming commands

fetchBalance (getBalance)

Allows to get actual account indicators values in real-time, as soon as they are available in the system.

use Timirey\XApi\Responses\Data\BalanceStreamRecord;
use Timirey\XApi\Responses\FetchBalanceResponse;
use Timirey\XApi\Client;

/**
 * @var Client $client
 */
$client->fetchBalance(
    callback: static function (FetchBalanceResponse $response): void {
        /**
         * @var BalanceStreamRecord $record
         */
        $record = $response->balanceStreamRecord;
    }
);

fetchCandles (getCandles)

Subscribes for and unsubscribes from API chart candles. The interval of every candle is 1 minute. A new candle arrives every minute.

use Timirey\XApi\Responses\Data\CandleStreamRecord;
use Timirey\XApi\Responses\FetchCandlesResponse;
use Timirey\XApi\Client;

/**
 * @var Client $client
 */
$client->fetchCandles(
    symbol: 'EURUSD',
    callback: static function (FetchCandlesResponse $response): void {
        /**
         * @var CandleStreamRecord $record
         */
        $record = $response->candleStreamRecord;
    }
);

The getCandles API operation often fails to subscribe directly to the desired symbol. To reliably listen for candle data, the price history must be requested first.

Before subscribing to candle updates, initiate a request for the symbol's historical price data using getChartLastRequest.

use DateTime;
use Timirey\XApi\Client;
use Timirey\XApi\Enums\Period;
use Timirey\XApi\Payloads\Data\ChartLastInfoRecord;
use Timirey\XApi\Responses\Data\CandleStreamRecord;
use Timirey\XApi\Responses\FetchCandlesResponse;
use Timirey\XApi\Responses\GetChartLastRequestResponse;

$chartLastInfoRecord = new ChartLastInfoRecord(
    period: Period::PERIOD_M1,
    start: new DateTime(),
    symbol: $symbol
);

/**
 * @var GetChartLastRequestResponse $response
 * @var Client $client
 * 
 * The $response is not used anywhere.
 */
$response = $client->getChartLastRequest($chartLastInfoRecord);

/**
 * @var Client $client
 */
$client->fetchCandles(
    symbol: 'EURUSD',
    callback: static function (FetchCandlesResponse $response): void {
        /**
         * @var CandleStreamRecord $record
         */
        $record = $response->candleStreamRecord;
    }
);

fetchKeepAlive (getKeepAlive)

Subscribes for and unsubscribes from 'keep alive' messages. A new 'keep alive' message is sent by the API every 3 seconds.

use Timirey\XApi\Responses\Data\KeepAliveStreamRecord;
use Timirey\XApi\Responses\FetchKeepAliveResponse;
use Timirey\XApi\Client;

/**
 * @var Client $client
 */
$client->fetchKeepAlive(
    callback: static function (FetchKeepAliveResponse $response): void {
        /**
         * @var KeepAliveStreamRecord $record
         */
        $record = $response->keepAliveStreamRecord;
    }
);

fetchNews (getNews)

Subscribes for and unsubscribes from news.

use Timirey\XApi\Responses\Data\NewsStreamRecord;
use Timirey\XApi\Responses\FetchNewsResponse;
use Timirey\XApi\Client;

/**
 * @var Client $client
 */
$client->fetchNews(
    callback: static function (FetchNewsResponse $response): void {
        /**
         * @var NewsStreamRecord $record
         */
        $record = $response->newsStreamRecord;
    }
);

fetchProfits (getProfits)

Subscribes for and unsubscribes from profits.

use Timirey\XApi\Responses\Data\ProfitStreamRecord;
use Timirey\XApi\Responses\FetchProfitsResponse;
use Timirey\XApi\Client;

/**
 * @var Client $client
 */
$client->fetchProfits(
    callback: static function (FetchProfitsResponse $response): void {
        /**
         * @var ProfitStreamRecord $record
         */
        $record = $response->profitStreamRecord;
    }
);

fetchTickPrices (getTickPrices)

Establishes subscription for quotations and allows to obtain the relevant information in real-time, as soon as it is available in the system.

use Timirey\XApi\Responses\Data\TickStreamRecord;
use Timirey\XApi\Responses\FetchTickPricesResponse;
use Timirey\XApi\Client;

/**
 * @var Client $client
 */
$client->fetchTickPrices(
    symbol: 'EURUSD',
    callback: static function (FetchTickPricesResponse $response): void {
        /**
         * @var TickStreamRecord $record
         */
        $record = $response->tickStreamRecord;
    },
    maxLevel: 1,
    minArrivalTime: 200
);

fetchTrades (getTrades)

Establishes subscription for user trade status data and allows to obtain the relevant information in real-time, as soon as it is available in the system.

use Timirey\XApi\Responses\Data\TradeStreamRecord;
use Timirey\XApi\Responses\FetchTradesResponse;
use Timirey\XApi\Client;

/**
 * @var Client $client
 */
$client->fetchTrades(
    callback: static function (FetchTradesResponse $response): void {
        /**
         * @var TradeStreamRecord $record
         */
        $record = $response->tradeStreamRecord;
    }
);

fetchTradeStatus (getTradeStatus)

Allows to get status for sent trade requests in real-time, as soon as it is available in the system.

use Timirey\XApi\Responses\Data\TradeStatusStreamRecord;
use Timirey\XApi\Responses\FetchTradeStatusResponse;
use Timirey\XApi\Client;

/**
 * @var Client $client
 */
$client->fetchTradeStatus(
    callback: static function (FetchTradeStatusResponse $response): void {
        /**
         * @var TradeStatusStreamRecord $record
         */
        $record = $response->tradeStatusStreamRecord;
    }
);

pingStream (ping)

Regularly calling this function is enough to refresh the internal state of all the components in the system.

use Timirey\XApi\Client;

/**
 * @var Client $client
 */
$client->pingStream();

Retrieving trading data

getAllSymbols

Retrieves information about all symbols.

use Timirey\XApi\Responses\GetAllSymbolsResponse;
use Timirey\XApi\Client;

/** 
 * @var GetAllSymbolsResponse $response 
 * @var Client $client
 */
$response = $client->getAllSymbols();

getCalendar

Returns a calendar with market events.

use Timirey\XApi\Responses\GetCalendarResponse;
use Timirey\XApi\Client;

/** 
 * @var GetCalendarResponse $response 
 * @var Client $client
 */
$response = $client->getCalendar();

getChartLastRequest

Returns chart info from the start date to the current time.

use Timirey\XApi\Responses\GetChartLastRequestResponse;
use Timirey\XApi\Client;
use Timirey\XApi\Payloads\Data\ChartLastInfoRecord;
use Timirey\XApi\Enums\Period;
use DateTime;

$chartLastInfoRecord = new ChartLastInfoRecord(
    period: Period::PERIOD_M1,
    start: new DateTime('-1 week'),
    symbol: 'EURUSD'
);

/** 
 * @var GetChartLastRequestResponse $response 
 * @var Client $client
 */
$response = $client->getChartLastRequest(
    chartLastInfoRecord: $chartLastInfoRecord
);

getChartRangeRequest

Returns chart info from the start date to the current time.

use Timirey\XApi\Responses\GetChartRangeRequestResponse;
use Timirey\XApi\Client;
use Timirey\XApi\Payloads\Data\ChartRangeInfoRecord;
use Timirey\XApi\Enums\Period;
use DateTime;

$chartRangeInfoRecord = new ChartRangeInfoRecord(
    period: Period::PERIOD_H1,
    start: new DateTime('-1 month'),
    end: new DateTime(),
    symbol: 'EURUSD',
    ticks: 1000
);

/** 
 * @var GetChartRangeRequestResponse $response 
 * @var Client $client
 */
$response = $client->getChartRangeRequest(
    chartRangeInfoRecord: $chartRangeInfoRecord
);

getCommissionDef

Returns the calculation of commission and rate of exchange.

use Timirey\XApi\Responses\GetCommissionDefResponse;
use Timirey\XApi\Client;

/** 
 * @var GetCommissionDefResponse $response 
 * @var Client $client
 */
$response = $client->getCommissionDef(
    symbol: 'EURUSD',
    volume: 1.0
);

getCurrentUserData

Returns information about account currency and leverage.

use Timirey\XApi\Responses\GetCurrentUserDataResponse;
use Timirey\XApi\Client;

/** 
 * @var GetCurrentUserDataResponse $response 
 * @var Client $client
 */
$response = $client->getCurrentUserData();

getIbsHistory

Returns IBs data from the given time range.

use Timirey\XApi\Responses\GetIbsHistoryResponse;
use Timirey\XApi\Client;
use DateTime;

/** 
 * @var GetIbsHistoryResponse $response 
 * @var Client $client
 */
$response = $client->getIbsHistory(
    start: new DateTime('-1 month'),
    end: new DateTime()
);

getMarginLevel

Returns various account indicators.

use Timirey\XApi\Responses\GetMarginLevelResponse;
use Timirey\XApi\Client;

/** 
 * @var GetMarginLevelResponse $response 
 * @var Client $client
 */
$response = $client->getMarginLevel();

getMarginTrade

Returns expected margin for a given instrument and volume.

use Timirey\XApi\Responses\GetMarginTradeResponse;
use Timirey\XApi\Client;

/** 
 * @var GetMarginTradeResponse $response 
 * @var Client $client
 */
$response = $client->getMarginTrade(
    symbol: 'EURPLN', 
    volume: 1.0
);

getNews

Returns news from the trading server which were sent within a specified period.

use Timirey\XApi\Responses\GetNewsResponse;
use Timirey\XApi\Client;
use DateTime;

/** 
 * @var GetNewsResponse $response 
 * @var Client $client
 */
$response = $client->getNews(
    start: new DateTime('-1 month'), 
    end: new DateTime()
);

getProfitCalculation

Calculates estimated profit for given deal data.

use Timirey\XApi\Responses\GetProfitCalculationResponse;
use Timirey\XApi\Client;
use Timirey\XApi\Enums\Cmd;

/** 
 * @var GetProfitCalculationResponse $response 
 * @var Client $client
 */
$response = $client->getProfitCalculation(
  closePrice: 1.3000, 
  cmd: Cmd::BUY, 
  openPrice: 1.2233, 
  symbol: 'EURPLN', 
  volume: 1.0
);

getServerTime

Returns the current time on the trading server.

use Timirey\XApi\Responses\GetServerTimeResponse;
use Timirey\XApi\Client;

/** 
 * @var GetServerTimeResponse $response 
 * @var Client $client
 */
$response = $client->getServerTime();

getStepRules

Returns a list of step rules for DMAs.

use Timirey\XApi\Responses\GetStepRulesResponse;
use Timirey\XApi\Client;

/** 
 * @var GetStepRulesResponse $response 
 * @var Client $client
 */
$response = $client->getStepRules();

getSymbol

Retrieves information about a specific symbol.

use Timirey\XApi\Responses\GetSymbolResponse;
use Timirey\XApi\Client;

/** 
 * @var GetSymbolResponse $response 
 * @var Client $client
 */
$response = $client->getSymbol(
    symbol: EURUSD
);

getTickPrices

Returns an array of current quotations for given symbols.

use Timirey\XApi\Responses\GetTickPricesResponse;
use Timirey\XApi\Enums\Level;
use Timirey\XApi\Client;
use DateTime;

/**
 * @var GetTickPricesResponse $response
 * @var Client $client
 */
$response = $client->getTickPrices(
    level: Level::BASE, 
    symbols: ['EURPLN', 'AGO.PL'], 
    timestamp: new DateTime()
);

getTradeRecords

Returns an array of trades listed in orders argument.

use Timirey\XApi\Responses\GetTradeRecordsResponse;
use Timirey\XApi\Client;

/** 
 * @var GetTradeRecordsResponse $response 
 * @var Client $client
 */
$response = $client->getTradeRecords(
    orders: [7489839, 7489841]
);

getTrades

Returns an array of user's trades.

use Timirey\XApi\Responses\GetTradesResponse;
use Timirey\XApi\Client;

/** 
 * @var GetTradesResponse $response 
 * @var Client $client
 */
$response = $client->getTrades(
    openedOnly: true
);

getTradesHistory

Returns an array of user's trades which were closed within a specified period.

use Timirey\XApi\Responses\GetTradesHistoryResponse;
use Timirey\XApi\Client;
use DateTime;

/** 
 * @var GetTradesHistoryResponse $response 
 * @var Client $client
 */
$response = $client->getTradesHistory(
    start: new DateTime('last month'), 
    end: new DateTime()
);

getTradingHours

Returns quotes and trading times.

use Timirey\XApi\Responses\GetTradingHoursResponse;
use Timirey\XApi\Client;

/** 
 * @var GetTradingHoursResponse $response 
 * @var Client $client
 */
$response = $client->getTradingHours(
    symbols: ['EURPLN', 'AGO.PL']
);

getVersion

Returns the current API version.

use Timirey\XApi\Responses\GetVersionResponse;
use Timirey\XApi\Client;

/** 
 * @var GetVersionResponse $response 
 * @var Client $client
 */
$response = $client->getVersion();

ping

Regularly calling this function is enough to refresh the internal state of all the components in the system.

use Timirey\XApi\Responses\PingResponse;
use Timirey\XApi\Client;

/** 
 * @var PingResponse $response 
 * @var Client $client
 */
$response = $client->ping();

tradeTransaction

Starts a trade transaction.

use Timirey\XApi\Responses\TradeTransactionResponse;
use Timirey\XApi\Payloads\Data\TradeTransInfo;
use Timirey\XApi\Client;

$tradeTransInfo = new TradeTransInfo(
    cmd: Cmd::BUY,
    customComment: 'Test trade',
    expiration: new DateTime(),
    offset: 0,
    order: 0,
    price: 1.12345,
    sl: 1.12000,
    symbol: 'EURUSD',
    tp: 1.12500,
    type: Type::OPEN,
    volume: 1.0
);

/** 
 * @var TradeTransactionResponse $response 
 * @var Client $client
 */
$response = $client->tradeTransaction(
    tradeTransInfo: $tradeTransInfo
);

tradeTransactionStatus

Returns the current transaction status.

use Timirey\XApi\Responses\TradeTransactionStatusResponse;
use Timirey\XApi\Client;

/** 
 * @var TradeTransactionStatusResponse $response 
 * @var Client $client
 */
$response = $client->tradeTransactionStatus(
    order: 123456
);

Error handling

Custom exceptions for handling request errors.

ErrorResponseException

Thrown when the API returns an error (e.g., invalid password). Provides error code and description.

use Timirey\XApi\Exceptions\ResponseException;
use Timirey\XApi\Enums\Host;
use Timirey\XApi\Client;

/** 
 * @var Client $client 
 */
$client = new Client(
    userId: 123456789, 
    password: 'invalidPassword', 
    host: Host::DEMO
);

try {
    $client->getVersion();
} catch (ErrorResponseException $e) {
    echo ($e->getErrorCode()); // 'BE005'
    echo ($e->getErrorDescr()); // 'userPasswordCheck: Invalid login or password.'
}

All error codes and descriptions can be found in the official documentation.

InvalidResponseException

Thrown when a request fails and the API does not return a proper error response (e.g., invalid or incomplete response).

InvalidPayloadException

Thrown when for some reason the payload is invalid (usually invalid response from the xApi).

SocketException

Thrown when socket fails to connect/read/write for some reason.

Testing

This package uses the PestPHP framework for testing.

./vendor/bin/pest

License

This library is open-sourced software licensed under the MIT license.

Reference

For more detailed documentation, please refer to the XTB xStation5 Trading API Documentation.