定制 oyi77/metaapi-cloud-php-sdk 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

oyi77/metaapi-cloud-php-sdk

最新稳定版本:2.1.0

Composer 安装命令:

composer require oyi77/metaapi-cloud-php-sdk

包简介

PHP SDK for MetaApi, a professional cloud forex API

README 文档

README

A PHP Package that let you seamlessly perform API calls to MetaApi https://metaapi.cloud/

This SDK provides access to:

  • Account Management API
  • CopyFactory (Copy Trading) API
  • MetaStats (Trading Statistics) API
  • Provisioning Profile API
  • Token Management API
  • Risk Management API

Installation

To install the SDK in your project you need to install the package via composer:

composer require oyi77/metaapi-cloud-php-sdk

Usage

MetaApi Websocket (RPC & Real-time streaming)

This SDK now includes a minimal Socket.IO-based websocket client for MetaApi RPC API and MetaApi real-time streaming API (see the guideline docs in guideline/ and the official websocket docs on metaapi.cloud).

RPC Connection (Request/Response)

use Oyi77\MetaapiCloudPhpSdk\MetaApi\MetaApi;

$token = 'AUTH_TOKEN';
$accountId = 'ACCOUNT_ID';

$metaApi = new MetaApi($token, ['region' => 'new-york']);

// RPC connection for query-and-response workflows
$rpc = $metaApi->rpcConnection($accountId);
$rpc->connect();
$rpc->waitSynchronized();

// Query terminal state
$accountInfo = $rpc->getAccountInformation();
$positions = $rpc->getPositions();
$symbols = $rpc->getSymbols();
$serverTime = $rpc->getServerTime();

// Calculate margin
$marginInfo = $rpc->calculateMargin([
    'symbol' => 'GBPUSD',
    'type' => 'ORDER_TYPE_BUY',
    'volume' => 0.1,
    'openPrice' => 1.25,
]);

// Execute trades with convenience methods
$result = $rpc->createMarketBuyOrder('EURUSD', 0.01, 1.0900, 1.1100, [
    'comment' => 'Trade from PHP',
    'clientId' => 'php_' . time(),
    'trailingStopLoss' => [
        'distance' => ['distance' => 50, 'units' => 'RELATIVE_POINTS'],
    ],
]);

$rpc->close();

Streaming Connection (Continuous Synchronization)

use Oyi77\MetaapiCloudPhpSdk\MetaApi\MetaApi;
use Oyi77\MetaapiCloudPhpSdk\MetaApi\Streaming\SynchronizationListener;

// Streaming connection for real-time updates
$stream = $metaApi->streamingConnection($accountId);

// Add typed listener for market data events
class MyListener implements SynchronizationListener {
    public function onSymbolPriceUpdated(int $instanceIndex, array $price): void {
        echo "Price update: {$price['symbol']} bid={$price['bid']} ask={$price['ask']}\n";
    }
    
    public function onCandlesUpdated(int $instanceIndex, array $candles, ?float $equity = null, ?float $margin = null, ?float $freeMargin = null, ?float $marginLevel = null): void {
        // Handle candle updates
    }
    
    // Implement other methods as needed (ticks, books, positions, orders, etc.)
    public function onTicksUpdated(...$args): void {}
    public function onBooksUpdated(...$args): void {}
    public function onSubscriptionDowngraded(...$args): void {}
    public function onPositionsUpdated(...$args): void {}
    public function onOrdersUpdated(...$args): void {}
    public function onHistoryOrdersUpdated(...$args): void {}
    public function onDealsUpdated(...$args): void {}
}

$stream->addTypedSynchronizationListener(new MyListener());
$stream->connect();
$stream->waitSynchronized();

// Subscribe to market data
$stream->subscribeToMarketData('EURUSD', [
    ['type' => 'quotes', 'intervalInMilliseconds' => 5000],
    ['type' => 'candles', 'timeframe' => '1m'],
    ['type' => 'ticks'],
]);

// Access cached terminal state
$price = $stream->terminalState->price('EURUSD');
$spec = $stream->terminalState->specification('EURUSD');
$accountInfo = $stream->terminalState->accountInformation;
$positions = $stream->terminalState->positions;

// Access history storage
$historyOrders = $stream->historyStorage->getHistoryOrders();
$deals = $stream->historyStorage->getDeals();

// Poll for events
while (true) {
    $stream->poll(0.25);
}

$stream->close();

Examples

For complete working examples, see the examples/ directory:

MetaApi Examples:

CopyFactory Examples:

Risk Management Examples:

Account Management

You can create an instance of the SDK like so for Account Management:

use Oyi77\MetaapiCloudPhpSdk\AccountApi;

$account = new AccountApi('AUTH_TOKEN');

All methods throws exceptions when the request is not successful, so be sure to put your code in a try and catch block.

 when statusCode >= 200 && statusCode < 300;

You can add a trading account and starts a cloud API server for the trading account like so:

try {
    return $account->create([
        "login" => "123456", 
        "password" => "password", 
        "name" => "testAccount", 
        "server" => "ICMarketsSC-Demo", 
        "platform" => "mt5", 
        "magic" => 123456 
    ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

if the request was successful , you will get the the account id and state, else an Exception will be thrown

    [
        "id" => "1eda642a-a9a3-457c-99af-3bc5e8d5c4c9", 
        "state" => "DEPLOYED" 
    ]

You can read an account by the id

try {
     return $account->readById("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

You can read all trading accounts in your metaapi account

try {
    // Using the legacy method (deprecated)
    return $account->readAll();
    
    // Using infinite scroll pagination (recommended)
    return $account->readAllWithInfiniteScroll([
        'limit' => 10,
        'offset' => 0,
        'query' => 'ICMarketsSC-MT5',
        'state' => ['DEPLOYED']
    ]);
    
    // Using classic pagination (returns count for page calculation)
    $result = $account->readAllWithClassicPagination([
        'limit' => 10,
        'offset' => 0
    ]);
    // $result['items'] contains accounts
    // $result['count'] contains total count
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

You can update an account

try {
    return  $account->update("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9",[
        "password" => "password", 
        "name" => "testAccount", 
        "server" => "ICMarketsSC-Demo", 
    ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Undeploy an account

try {
    return $account->unDeploy("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9");
    // you can pass other parameters 
    return $account->unDeploy("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9", false);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Deploy an account

try {
    return $account->deploy("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9");
     // you can pass other parameters 
    return $account->deploy("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9", false);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Redeploy an account

try {
    return $account->reDeploy("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9");
     // you can pass other parameters 
    return $account->reDeploy("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9", false);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Delete an account

try {
    return $account->delete("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9");
     // you can pass other parameters 
    return $account->delete("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9", true);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Create configuration link for end-user account setup

try {
    // Create a link that allows end users to configure their account
    $link = $account->createConfigurationLink("1eda642a-a9a3-457c-99af-3bc5e8d5c4c9", 7); // 7 days validity
    // Use $link['url'] to redirect users to account configuration page
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

CopyFactory

You can create an instance of the SDK like so for Copyfactory:

use Oyi77\MetaapiCloudPhpSdk\CopyFactory;

$copyfactory = new CopyFactory('AUTH_TOKEN');

To generate a strategy id

try {
   return $copyfactory->generateStrategyId();
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To get all your strategies

try {
   // Using legacy method (deprecated)
   return $copyfactory->strategies();
   
   // Using infinite scroll pagination (recommended)
   return $copyfactory->strategiesWithInfiniteScroll([
       'includeRemoved' => false,
       'limit' => 1000,
       'offset' => 0
   ]);
   
   // Using classic pagination
   return $copyfactory->strategiesWithClassicPagination([
       'includeRemoved' => false,
       'limit' => 1000,
       'offset' => 0
   ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To get a single strategy

try {
   return $copyfactory->strategy("strategid");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To update a strategy

try {
   return $copyfactory->updateStrategy("strategid", [
        "name" => "Test strategy", 
        "description" => "Some useful description about your strategy", 
        "accountId" => "105646d8-8c97-4d4d-9b74-413bd66cd4ed" 
   ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To remove a strategy

try {
   return $copyfactory->removeStrategy("strategid");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To get all your subscribers

try {
   // Using legacy method (deprecated)
   return $copyfactory->subscribers();
   
   // Using infinite scroll pagination (recommended)
   return $copyfactory->subscribersWithInfiniteScroll([
       'includeRemoved' => false,
       'limit' => 1000,
       'offset' => 0
   ]);
   
   // Using classic pagination
   return $copyfactory->subscribersWithClassicPagination([
       'includeRemoved' => false,
       'limit' => 1000,
       'offset' => 0
   ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To get a subscriber

try {
   return $copyfactory->subscriber("subscriberiId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To update a subscriber data

try {
   return $copyfactory->updateSubscriber("subsciberId", [
        'name' => "Copy Trade Subscriber",
        'subscriptions' => [
            [
                'strategyId' => 'dJZq',
                'multiplier' => 1,
            ]
        ]
    ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To remove a subscriber

try {
   return $copyfactory->removeSubscriber("subsciberId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To delete a subscription

try {
   return $copyfactory->deleteSubscription("subsciberId", "strategyId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Webhooks

CopyFactory supports webhooks for receiving trading signals.

Create a webhook

try {
    $webhook = $copyfactory->createWebhook("strategyId", [
        'symbolMapping' => [
            ['from' => 'EURUSD.m', 'to' => 'EURUSD']
        ],
        'magic' => 100
    ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Update a webhook

try {
    $copyfactory->updateWebhook("strategyId", "webhookId", [
        'symbolMapping' => [
            ['from' => 'EURUSD.m', 'to' => 'EURUSD'],
            ['from' => 'BTCUSD.m', 'to' => 'BTCUSD']
        ],
        'magic' => 100
    ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Get webhooks

try {
    // Infinite scroll pagination
    $webhooks = $copyfactory->webhooksWithInfiniteScroll("strategyId");
    
    // Classic pagination
    $webhooks = $copyfactory->webhooksWithClassicPagination("strategyId", [
        'limit' => 10,
        'offset' => 0
    ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Delete a webhook

try {
    $copyfactory->deleteWebhook("strategyId", "webhookId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Copy Trade

To Copy a trade from provider to subscriber. I recommend you create a strategy before hand and save to your database before you perform a copy trade, but its not compulsory as the package will create one for you. You can always read all your strategies in your account with the " $copyfactory->strategies()".

To Copy trade do:

try {
    $strategyId = "yd24";
    $providerAccountId = "Enter your provider account ID";
    $subAccountId = "Enter Subscriber Account ID";

    return $copyfactory->copy($providerAccountId, $subAccountId, $strategyId);

    /*
    * You can ommit the strategy Id and just copy the trade 
    * The package will create a strategy as part of the copy process.
    */

    return $copyfactory->copy($providerAccountId, $subAccountId);

} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Note: copying a trade will take some seconds to finish, you you can have a loading indicator as feedback.

MetaStats

You can get metrics for you account

You can create an instance of the SDK like so for MetaStats:

use Oyi77\MetaapiCloudPhpSdk\MetaStats;

$stats = new MetaStats('AUTH_TOKEN');

To get metrics:

try {
   return  $stats->metrics("accountId");
    //  You can pass a boolean as second parameter if you want to include open positions in your metrics
     return  $stats->metrics("accountId", true);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To get open trades for MetaApi account:

try {
   return  $stats->openTrades("accountId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

To get account trades for a time range:

try {
   return $stats->accountTrades("accountId", "2020-01-01 00:00:00.000", "2021-01-01 00:00:00.000");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Provisioning Profile API

Provisioning profiles can be used as an alternative way to create MetaTrader accounts if automatic broker settings detection has failed.

use Oyi77\MetaapiCloudPhpSdk\ProvisioningProfileApi;

$provisioning = new ProvisioningProfileApi('AUTH_TOKEN');

Create a provisioning profile

try {
    $profile = $provisioning->createProfile([
        'name' => 'My profile',
        'version' => 5, // 4 for MT4, 5 for MT5
        'brokerTimezone' => 'EET',
        'brokerDSTSwitchTimezone' => 'EET'
    ]);
    
    // Upload servers.dat file for MT5 (or .srv file for MT4)
    $provisioning->uploadFile($profile['id'], 'servers.dat', '/path/to/servers.dat');
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Get provisioning profiles

try {
    // Infinite scroll pagination
    $profiles = $provisioning->getProfilesWithInfiniteScroll([
        'limit' => 10,
        'offset' => 0,
        'query' => 'ICMarketsSC-MT5',
        'version' => 5
    ]);
    
    // Classic pagination
    $result = $provisioning->getProfilesWithClassicPagination([
        'limit' => 10,
        'offset' => 0
    ]);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Get, update, and delete provisioning profile

try {
    // Get profile by ID
    $profile = $provisioning->getProfile("profileId");
    
    // Update profile
    $provisioning->updateProfile("profileId", [
        'name' => 'New name'
    ]);
    
    // Delete profile
    $provisioning->deleteProfile("profileId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Token Management API

Generate narrowed-down tokens for use in Web or Mobile applications.

use Oyi77\MetaapiCloudPhpSdk\TokenManagementApi;

$tokenManagement = new TokenManagementApi('AUTH_TOKEN');

Narrow down token to specific applications

try {
    $narrowedToken = $tokenManagement->narrowDownTokenApplications(
        ['trading-account-management-api', 'metastats-api'],
        24 // validity in hours
    );
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Narrow down token to specific roles

try {
    $narrowedToken = $tokenManagement->narrowDownTokenRoles(
        ['reader'], // read-only access
        24
    );
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Narrow down token to specific resources

try {
    $narrowedToken = $tokenManagement->narrowDownTokenResources(
        [['entity' => 'account', 'id' => 'account-id']],
        24
    );
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Narrow down token with combined restrictions

try {
    $narrowedToken = $tokenManagement->narrowDownToken([
        'applications' => ['metaapi-api'],
        'roles' => ['reader'],
        'resources' => [['entity' => 'account', 'id' => 'account-id']]
    ], 24);
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Get access rules manifest

try {
    $manifest = $tokenManagement->getAccessRules();
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Risk Management API

Risk Management API for executing trading challenges and competitions.

use Oyi77\MetaapiCloudPhpSdk\RiskManagementApi;

$riskManagement = new RiskManagementApi('AUTH_TOKEN');

Create and manage trackers

try {
    // Create a tracker
    $tracker = $riskManagement->createTracker("accountId", [
        'name' => 'Test tracker',
        'period' => 'day',
        'absoluteDrawdownThreshold' => 100
    ]);
    
    // Get all trackers
    $trackers = $riskManagement->getTrackers("accountId");
    
    // Get tracker by ID
    $tracker = $riskManagement->getTracker("accountId", "trackerId");
    
    // Update tracker
    $riskManagement->updateTracker("accountId", "trackerId", [
        'name' => 'Updated name'
    ]);
    
    // Delete tracker
    $riskManagement->deleteTracker("accountId", "trackerId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Get tracker events and statistics

try {
    // Get tracker events
    $events = $riskManagement->getTrackerEvents(
        "2022-04-13 09:30:00.000",
        "2022-05-14 09:30:00.000",
        ['accountId' => 'account-id', 'trackerId' => 'tracker-id']
    );
    
    // Get tracking statistics
    $statistics = $riskManagement->getTrackingStatistics("accountId", "trackerId");
    
    // Get equity chart
    $equityChart = $riskManagement->getEquityChart("accountId", [
        'startTime' => '2022-04-13 09:30:00.000',
        'endTime' => '2022-05-14 09:30:00.000'
    ]);
    
    // Get period statistics
    $periodStats = $riskManagement->getPeriodStatistics("accountId", "trackerId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Expert Advisor Management

Manage custom expert advisors (EAs) for MT4 accounts on G1 infrastructure. Note: EAs using DLLs are not supported.

use Oyi77\MetaapiCloudPhpSdk\AccountApi;

$account = new AccountApi('AUTH_TOKEN');

Create an expert advisor

try {
    // Note: preset field should be base64-encoded preset file
    $expert = $account->createExpertAdvisor("accountId", "expertId", [
        'period' => '1h',
        'symbol' => 'EURUSD',
        'preset' => 'a2V5MT12YWx1ZTEKa2V5Mj12YWx1ZTIKa2V5Mz12YWx1ZTMKc3VwZXI9dHJ1ZQ'
    ]);
    
    // Upload EA file
    $account->uploadExpertAdvisorFile("accountId", "expertId", "/path/to/custom-ea");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Get expert advisors

try {
    // Get all expert advisors
    $experts = $account->getExpertAdvisors("accountId");
    
    // Get expert advisor by ID
    $expert = $account->getExpertAdvisor("accountId", "expertId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Update and delete expert advisor

try {
    // Update expert advisor
    $account->updateExpertAdvisor("accountId", "expertId", [
        'period' => '4h',
        'symbol' => 'EURUSD',
        'preset' => 'a2V5MT12YWx1ZTEKa2V5Mj12YWx1ZTIKa2V5Mz12YWx1ZTMKc3VwZXI9dHJ1ZQ'
    ]);
    $account->uploadExpertAdvisorFile("accountId", "expertId", "/path/to/custom-ea");
    
    // Delete expert advisor
    $account->deleteExpertAdvisor("accountId", "expertId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Historical Data API

Retrieve historical market data (candles and ticks). Available on G1 and MT4 G2 instances only.

use Oyi77\MetaapiCloudPhpSdk\AccountApi;

$account = new AccountApi('AUTH_TOKEN');

Get historical candles

try {
    // Get latest 1000 candles
    $candles = $account->getHistoricalCandles("accountId", "EURUSD", "1m", null, 1000);
    
    // Get candles from specific time
    $candles = $account->getHistoricalCandles(
        "accountId",
        "EURUSD",
        "1m",
        "2021-05-01 00:00:00.000",
        1000
    );
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Get historical ticks

try {
    // Get latest 1000 ticks
    $ticks = $account->getHistoricalTicks("accountId", "EURUSD", null, 0, 1000);
    
    // Get ticks from specific time with offset
    $ticks = $account->getHistoricalTicks(
        "accountId",
        "EURUSD",
        "2021-05-01 00:00:00.000",
        5,
        1000
    );
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Demo Account Generator API

Create MT4 and MT5 demo accounts. Note: Not all MT4/MT5 servers allow creating demo accounts using this method.

use Oyi77\MetaapiCloudPhpSdk\DemoAccountGeneratorApi;

$generator = new DemoAccountGeneratorApi('AUTH_TOKEN');

Create MT4 demo account

try {
    $demoAccount = $generator->createMt4DemoAccount([
        'balance' => 100000,
        'accountType' => 'type',
        'email' => 'example@example.com',
        'leverage' => 100,
        'serverName' => 'Exness-Trial4',
        'name' => 'Test User',
        'phone' => '+12345678901',
        'keywords' => ["Exness Technologies Ltd"]
    ]);
    
    // Optionally specify provisioning profile ID
    $demoAccount = $generator->createMt4DemoAccount([
        'balance' => 100000,
        'accountType' => 'type',
        'email' => 'example@example.com',
        'leverage' => 100,
        'serverName' => 'Exness-Trial4',
        'name' => 'Test User',
        'phone' => '+12345678901'
    ], "profileId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Create MT5 demo account

try {
    $demoAccount = $generator->createMt5DemoAccount([
        'accountType' => 'type',
        'balance' => 100000,
        'email' => 'example@example.com',
        'leverage' => 100,
        'serverName' => 'ICMarketsSC-Demo',
        'keywords' => ["Raw Trading Ltd"]
    ]);
    
    // Optionally specify provisioning profile ID
    $demoAccount = $generator->createMt5DemoAccount([
        'accountType' => 'type',
        'balance' => 100000,
        'email' => 'example@example.com',
        'leverage' => 100,
        'serverName' => 'Exness-Trial4',
        'name' => 'Test User',
        'phone' => '+12345678901'
    ], "profileId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Manager API

Access and manage MT4 and MT5 servers. For detailed endpoint documentation, see: https://metaapi.cloud/docs/manager/

use Oyi77\MetaapiCloudPhpSdk\ManagerApi;

$manager = new ManagerApi('AUTH_TOKEN');

The Manager API provides generic methods for accessing MT Manager endpoints:

try {
    // GET request
    $result = $manager->get('servers', ['limit' => 10]);
    
    // POST request
    $result = $manager->post('servers', ['name' => 'My Server']);
    
    // PUT request
    $result = $manager->put('servers/serverId', ['name' => 'Updated Name']);
    
    // DELETE request
    $result = $manager->delete('servers/serverId');
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}

Latency Monitor

Track API latencies for monitoring and optimization.

use Oyi77\MetaapiCloudPhpSdk\Support\LatencyMonitor;

$monitor = new LatencyMonitor();

// Record latencies
$monitor->recordTradeLatency(150.5);
$monitor->recordRequestLatency(45.2);
$monitor->recordUpdateLatency(120.0);
$monitor->recordQuoteLatency(80.3);

// Get latency arrays
$tradeLatencies = $monitor->getTradeLatencies();
$requestLatencies = $monitor->getRequestLatencies();

// Get statistics
$tradeStats = $monitor->getTradeLatencyStats();
// Returns: ['count' => 1, 'min' => 150.5, 'max' => 150.5, 'avg' => 150.5, 'median' => 150.5]

$requestStats = $monitor->getRequestLatencyStats();
// Returns: ['count' => 1, 'min' => 45.2, 'max' => 45.2, 'avg' => 45.2, 'median' => 45.2]

// Clear all records
$monitor->clear();

Logging Support

Enable logging for debugging and monitoring. Supports PSR-3 compatible loggers and file logging.

use Oyi77\MetaapiCloudPhpSdk\Support\Logger;

// Enable logging with PSR-3 logger
use Psr\Log\LoggerInterface;
$psrLogger = new YourPSR3Logger();
Logger::enable($psrLogger);

// Or enable file logging
Logger::enableFileLogging('./logs/metaapi.log');

// Use logging
Logger::info('API request completed', ['endpoint' => '/accounts']);
Logger::debug('Debug information', ['data' => $data]);
Logger::warning('Warning message');
Logger::error('Error occurred', ['error' => $error]);

// Disable logging
Logger::disable();

Pagination Helper

The SDK includes a pagination helper utility for working with paginated responses:

use Oyi77\MetaapiCloudPhpSdk\Support\Pagination;

// Get items from paginated response
$accounts = $account->readAllWithClassicPagination(['limit' => 10, 'offset' => 0]);
$items = Pagination::getItems($accounts);

// Get total count (for classic pagination)
$totalCount = Pagination::getCount($accounts);

// Check if there are more pages
$hasMore = Pagination::hasMore($accounts, 10);

// Calculate total pages
$totalPages = Pagination::getTotalPages($accounts, 10);

Testing

composer test

API Reference

All API references can be found on Metaapi documentation website. https://metaapi.cloud/

Security

If you discover any security related issues, please open an issue.

Contributing

Pull requests are welcome.

How can I thank you?

Why not star the github repo? I'd love the attention! you can share the link for this repository on Twitter or HackerNews?

Don't forget to follow me on twitter!

Thanks! Efekpogua Victory.

About This Repository

So here's the story - I was working on a project that needed to integrate with MetaApi, and I found this PHP SDK that looked promising. Turned out it was created by Efekpogua Victory a couple years back, and it worked fine for basic stuff. But when I dug deeper, I realized it was missing a bunch of features that the Python SDK already had.

The original SDK hadn't been touched in like 2 years, and I really needed those missing APIs. Instead of starting from scratch (which would've been a pain), I decided to fork it and bring it up to speed. I spent some time going through the Python SDK docs and examples, figuring out what was missing, then added all the REST API stuff that should've been there.

Now I'm maintaining this actively, so if you find bugs or need something added, just open an issue. I'll get to it faster than the previous maintainer did (no offense to the original author - we all get busy).

Credits

Big shoutout to Efekpogua Victory for building the initial version of this SDK. He did the hard work of setting up the foundation, and without that, I'd still be writing HTTP wrappers from scratch. So thanks for that!

I (Oyi77) forked it and updated everything to match what the Python SDK can do. The goal is to keep this thing maintained and useful for anyone who needs a PHP SDK for MetaApi.

License

The MIT License (MIT). Please see License File or more information.

统计信息

  • 总下载量: 10
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-12-13