PHP code example of oyi77 / metaapi-cloud-php-sdk

1. Go to this page and download the library: Download oyi77/metaapi-cloud-php-sdk library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

oyi77 / metaapi-cloud-php-sdk example snippets


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();

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();

use Oyi77\MetaapiCloudPhpSdk\AccountApi;

$account = new AccountApi('AUTH_TOKEN');


 when statusCode >= 200 && statusCode < 300;


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;
}


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


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



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;
}



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;
}



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;
}



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;
}



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;
}



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;
}



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;
}


use Oyi77\MetaapiCloudPhpSdk\CopyFactory;

$copyfactory = new CopyFactory('AUTH_TOKEN');



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



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



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



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;
}



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



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



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



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;
}



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



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



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



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;
}



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;
}



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



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;
}


use Oyi77\MetaapiCloudPhpSdk\MetaStats;

$stats = new MetaStats('AUTH_TOKEN');



try {
   return  $stats->metrics("accountId");
    //  You can pass a boolean as second parameter if you want to essage());
    return $response->message;
}



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



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;
}


use Oyi77\MetaapiCloudPhpSdk\ProvisioningProfileApi;

$provisioning = new ProvisioningProfileApi('AUTH_TOKEN');


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;
}



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;
}



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;
}


use Oyi77\MetaapiCloudPhpSdk\TokenManagementApi;

$tokenManagement = new TokenManagementApi('AUTH_TOKEN');


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;
}



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



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



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;
}



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


use Oyi77\MetaapiCloudPhpSdk\RiskManagementApi;

$riskManagement = new RiskManagementApi('AUTH_TOKEN');


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;
}



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;
}


use Oyi77\MetaapiCloudPhpSdk\AccountApi;

$account = new AccountApi('AUTH_TOKEN');


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;
}



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;
}



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;
}


use Oyi77\MetaapiCloudPhpSdk\AccountApi;

$account = new AccountApi('AUTH_TOKEN');


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;
}



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;
}


use Oyi77\MetaapiCloudPhpSdk\DemoAccountGeneratorApi;

$generator = new DemoAccountGeneratorApi('AUTH_TOKEN');


try {
    $demoAccount = $generator->createMt4DemoAccount([
        'balance' => 100000,
        'accountType' => 'type',
        'email' => '[email protected]',
        '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' => '[email protected]',
        'leverage' => 100,
        'serverName' => 'Exness-Trial4',
        'name' => 'Test User',
        'phone' => '+12345678901'
    ], "profileId");
} catch (\Throwable $th) {
    $response = json_decode($th->getMessage());
    return $response->message;
}



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


use Oyi77\MetaapiCloudPhpSdk\ManagerApi;

$manager = new ManagerApi('AUTH_TOKEN');


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;
}


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();

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();

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);


composer test