diff --git a/README.md b/README.md index 94d9263..1036d7a 100644 --- a/README.md +++ b/README.md @@ -277,6 +277,8 @@ go(function () { | KuMEX\SDK\PublicApi\Symbol::getLevel3Message() | NO | https://docs.kucoin.com/futures/##level-3-pulling-messages | | KuMEX\SDK\PublicApi\Symbol::getTradeHistory() | NO | https://docs.kucoin.com/futures/#get-trade-histories | | KuMEX\SDK\PublicApi\Symbol::getKLines() | NO | https://docs.kucoin.com/futures/?lang=en_US#get-k-line-data-of-contract | +| KuMEX\SDK\PublicApi\Symbol::getLevel2Depth20 | NO | https://docs.kucoin.center/futures/cn/#level-2-2 | +| KuMEX\SDK\PublicApi\Symbol::getLevel2Depth100 | NO | https://docs.kucoin.center/futures/cn/#level-2-2 | diff --git a/src/Api.php b/src/Api.php index a740d86..b33c38c 100644 --- a/src/Api.php +++ b/src/Api.php @@ -21,7 +21,7 @@ abstract class Api /** * @var string SDK update date */ - const UPDATE_DATE = '2020.06.18'; + const UPDATE_DATE = '2021.08.02'; /** * @var string diff --git a/src/PublicApi/Symbol.php b/src/PublicApi/Symbol.php index 0d55e8f..647471b 100644 --- a/src/PublicApi/Symbol.php +++ b/src/PublicApi/Symbol.php @@ -15,7 +15,7 @@ class Symbol extends KuMEXApi /** * Get the ticker details of a symbol. * - * @param string $symbol + * @param string $symbol * @return array * @throws \KuMEX\SDK\Exceptions\BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException @@ -30,7 +30,7 @@ public function getTicker($symbol) /** * Get the snapshot details of a symbol. * - * @param string $symbol + * @param string $symbol * @return array * @throws \KuMEX\SDK\Exceptions\BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException @@ -45,7 +45,7 @@ public function getLevel2Snapshot($symbol) /** * Get the snapshot details of a symbol. * - * @param string $symbol + * @param string $symbol * @return array * @throws \KuMEX\SDK\Exceptions\BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException @@ -60,7 +60,7 @@ public function getLevel3Snapshot($symbol) /** * Get the snapshot details of a symbol. * - * @param string $symbol + * @param string $symbol * @return array * @throws \KuMEX\SDK\Exceptions\BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException @@ -75,9 +75,9 @@ public function getV2Level3Snapshot($symbol) /** * Get the level2 message of a symbol. * - * @param string $symbol - * @param number $start - * @param number $end + * @param string $symbol + * @param number $start + * @param number $end * @return array * @throws \KuMEX\SDK\Exceptions\BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException @@ -92,17 +92,17 @@ public function getLevel2Message($symbol, $start, $end) } /** - * @deprecated - * - * Get the level3 message of a symbol. - * - * @param string $symbol - * @param number $start - * @param number $end + * @param string $symbol + * @param number $start + * @param number $end * @return array * @throws \KuMEX\SDK\Exceptions\BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException * @throws \KuMEX\SDK\Exceptions\InvalidApiUriException + * @deprecated + * + * Get the level3 message of a symbol. + * */ public function getLevel3Message($symbol, $start, $end) { @@ -115,7 +115,7 @@ public function getLevel3Message($symbol, $start, $end) /** * Get the trade history details of a symbol. * - * @param string $symbol + * @param string $symbol * @return array * @throws \KuMEX\SDK\Exceptions\BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException @@ -151,4 +151,32 @@ public function getKLines($symbol, $from, $to, $granularity) ); return $response->getApiData(); } + + /** + * Get the depth20 of level2. + * @param string $symbol + * @return mixed + * @throws \KuMEX\SDK\Exceptions\BusinessException + * @throws \KuMEX\SDK\Exceptions\HttpException + * @throws \KuMEX\SDK\Exceptions\InvalidApiUriException + */ + public function getLevel2Depth20($symbol) + { + $response = $this->call(Request::METHOD_GET, '/api/v1/level2/depth20', ['symbol' => $symbol]); + return $response->getApiData(); + } + + /** + * Get the depth100 of level2. + * @param string $symbol + * @return mixed + * @throws \KuMEX\SDK\Exceptions\BusinessException + * @throws \KuMEX\SDK\Exceptions\HttpException + * @throws \KuMEX\SDK\Exceptions\InvalidApiUriException + */ + public function getLevel2Depth100($symbol) + { + $response = $this->call(Request::METHOD_GET, '/api/v1/level2/depth100', ['symbol' => $symbol]); + return $response->getApiData(); + } } diff --git a/tests/AccountTest.php b/tests/AccountTest.php index 46cd22f..13174c7 100644 --- a/tests/AccountTest.php +++ b/tests/AccountTest.php @@ -2,13 +2,12 @@ namespace KuMEX\SDK\Tests; -use KuMEX\SDK\ApiCode; use KuMEX\SDK\Exceptions\BusinessException; use KuMEX\SDK\PrivateApi\Account; class AccountTest extends TestCase { - protected $apiClass = Account::class; + protected $apiClass = Account::class; protected $apiWithAuth = true; /** @@ -53,12 +52,12 @@ public function testGetTransactionHistory(Account $api) } /** - * @deprecated - * @dataProvider apiProvider * @param Account $api * @throws BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException * @throws \KuMEX\SDK\Exceptions\InvalidApiUriException + * @deprecated + * @dataProvider apiProvider */ // public function testTransferIn(Account $api) // { @@ -79,8 +78,8 @@ public function testGetTransactionHistory(Account $api) */ public function testTransferOut(Account $api) { - $bizNo = rand(1, 9999); - $amount = 0.1; + $bizNo = rand(1, 9999); + $amount = 0.1; $accounts = $api->transferOut($bizNo, $amount); $this->assertInternalType('array', $accounts); if (isset($accounts['applyId'])) { @@ -133,7 +132,7 @@ public function testGetTransferList(Account $api) private function getTransferId($api) { $bizNo = '10000000001'; - $amount = 0.1; + $amount = 0.1; $accounts = $api->transferOut($bizNo, $amount); $this->assertInternalType('array', $accounts); return $accounts['applyId']; @@ -149,14 +148,26 @@ private function getTransferId($api) */ public function testTransferOutV2(Account $api) { - $bizNo = rand(1, 9999); - $amount = 0.1; - $currency = 'XBT'; - $accounts = $api->transferOutV2($bizNo, $amount, $currency); - $this->assertInternalType('array', $accounts); - if (isset($accounts['applyId'])) { - $this->assertArrayHasKey('applyId', $accounts); - } - } + $bizNo = uniqid('t_', false); + $amount = 0.01; + $currency = 'USDT'; + $data = $api->transferOutV2($bizNo, $amount, $currency); + $this->assertInternalType('array', $data); + + $this->assertArrayHasKey('applyId', $data); + $this->assertArrayHasKey('bizNo', $data); + $this->assertArrayHasKey('payAccountType', $data); + $this->assertArrayHasKey('payTag', $data); + $this->assertArrayHasKey('remark', $data); + $this->assertArrayHasKey('recAccountType', $data); + $this->assertArrayHasKey('recTag', $data); + $this->assertArrayHasKey('recRemark', $data); + $this->assertArrayHasKey('recSystem', $data); + $this->assertArrayHasKey('status', $data); + $this->assertArrayHasKey('currency', $data); + $this->assertArrayHasKey('amount', $data); + $this->assertArrayHasKey('fee', $data); + $this->assertArrayHasKey('sn', $data); + } } diff --git a/tests/ContractTest.php b/tests/ContractTest.php index 2c87ec1..bd09e90 100644 --- a/tests/ContractTest.php +++ b/tests/ContractTest.php @@ -6,7 +6,7 @@ namespace KuMEX\SDK\Tests; -use \KuMEX\SDK\PublicApi\Contract; +use KuMEX\SDK\PublicApi\Contract; class ContractTest extends TestCase @@ -16,8 +16,7 @@ class ContractTest extends TestCase protected $apiWithAuth = false; /** - * - * @depends testGetList + * @dataProvider apiProvider * @param Contract $api * @throws \KuMEX\SDK\Exceptions\BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException @@ -27,19 +26,65 @@ public function testGetList(Contract $api) { $data = $api->getList(); $this->assertInternalType('array', $data); - $this->assertArrayHasKey('currency', $data); - $this->assertArrayHasKey('status', $data); - $this->assertArrayHasKey('address', $data); - $this->assertArrayHasKey('isInner', $data); - $this->assertArrayHasKey('amount', $data); - $this->assertArrayHasKey('fee', $data); - $this->assertArrayHasKey('walletTxId', $data); - $this->assertArrayHasKey('createdAt', $data); + + foreach ($data as $item) { + $this->assertInternalType('array', $item); + + $this->assertArrayHasKey('symbol', $item); + $this->assertArrayHasKey('rootSymbol', $item); + $this->assertArrayHasKey('type', $item); + $this->assertArrayHasKey('firstOpenDate', $item); + $this->assertArrayHasKey('expireDate', $item); + $this->assertArrayHasKey('settleDate', $item); + $this->assertArrayHasKey('baseCurrency', $item); + $this->assertArrayHasKey('quoteCurrency', $item); + $this->assertArrayHasKey('settleCurrency', $item); + $this->assertArrayHasKey('maxOrderQty', $item); + $this->assertArrayHasKey('maxPrice', $item); + $this->assertArrayHasKey('lotSize', $item); + $this->assertArrayHasKey('tickSize', $item); + $this->assertArrayHasKey('indexPriceTickSize', $item); + $this->assertArrayHasKey('multiplier', $item); + $this->assertArrayHasKey('initialMargin', $item); + $this->assertArrayHasKey('maintainMargin', $item); + $this->assertArrayHasKey('maxRiskLimit', $item); + $this->assertArrayHasKey('minRiskLimit', $item); + $this->assertArrayHasKey('riskStep', $item); + $this->assertArrayHasKey('makerFeeRate', $item); + $this->assertArrayHasKey('takerFeeRate', $item); + $this->assertArrayHasKey('takerFixFee', $item); + $this->assertArrayHasKey('makerFixFee', $item); + $this->assertArrayHasKey('settlementFee', $item); + $this->assertArrayHasKey('isDeleverage', $item); + $this->assertArrayHasKey('isQuanto', $item); + $this->assertArrayHasKey('isInverse', $item); + $this->assertArrayHasKey('markMethod', $item); + $this->assertArrayHasKey('fairMethod', $item); + $this->assertArrayHasKey('fundingBaseSymbol', $item); + $this->assertArrayHasKey('fundingQuoteSymbol', $item); + $this->assertArrayHasKey('fundingRateSymbol', $item); + $this->assertArrayHasKey('indexSymbol', $item); + $this->assertArrayHasKey('settlementSymbol', $item); + $this->assertArrayHasKey('status', $item); + $this->assertArrayHasKey('fundingFeeRate', $item); + $this->assertArrayHasKey('predictedFundingFeeRate', $item); + $this->assertArrayHasKey('openInterest', $item); + $this->assertArrayHasKey('turnoverOf24h', $item); + $this->assertArrayHasKey('volumeOf24h', $item); + $this->assertArrayHasKey('markPrice', $item); + $this->assertArrayHasKey('indexPrice', $item); + $this->assertArrayHasKey('lastTradePrice', $item); + $this->assertArrayHasKey('nextFundingRateTime', $item); + $this->assertArrayHasKey('maxLeverage', $item); + $this->assertArrayHasKey('lowPrice', $item); + $this->assertArrayHasKey('highPrice', $item); + $this->assertArrayHasKey('priceChgPct', $item); + $this->assertArrayHasKey('priceChg', $item); + } } /** - * - * @depends testGetDetail + * @dataProvider apiProvider * @param Contract $api * @throws \KuMEX\SDK\Exceptions\BusinessException * @throws \KuMEX\SDK\Exceptions\HttpException @@ -49,14 +94,56 @@ public function testGetDetail(Contract $api) { $data = $api->getDetail('XBTUSDM'); $this->assertInternalType('array', $data); - $this->assertArrayHasKey('currency', $data); + + $this->assertArrayHasKey('symbol', $data); + $this->assertArrayHasKey('rootSymbol', $data); + $this->assertArrayHasKey('type', $data); + $this->assertArrayHasKey('firstOpenDate', $data); + $this->assertArrayHasKey('expireDate', $data); + $this->assertArrayHasKey('settleDate', $data); + $this->assertArrayHasKey('baseCurrency', $data); + $this->assertArrayHasKey('quoteCurrency', $data); + $this->assertArrayHasKey('settleCurrency', $data); + $this->assertArrayHasKey('maxOrderQty', $data); + $this->assertArrayHasKey('maxPrice', $data); + $this->assertArrayHasKey('lotSize', $data); + $this->assertArrayHasKey('tickSize', $data); + $this->assertArrayHasKey('indexPriceTickSize', $data); + $this->assertArrayHasKey('multiplier', $data); + $this->assertArrayHasKey('initialMargin', $data); + $this->assertArrayHasKey('maintainMargin', $data); + $this->assertArrayHasKey('maxRiskLimit', $data); + $this->assertArrayHasKey('minRiskLimit', $data); + $this->assertArrayHasKey('riskStep', $data); + $this->assertArrayHasKey('makerFeeRate', $data); + $this->assertArrayHasKey('takerFeeRate', $data); + $this->assertArrayHasKey('takerFixFee', $data); + $this->assertArrayHasKey('makerFixFee', $data); + $this->assertArrayHasKey('settlementFee', $data); + $this->assertArrayHasKey('isDeleverage', $data); + $this->assertArrayHasKey('isQuanto', $data); + $this->assertArrayHasKey('isInverse', $data); + $this->assertArrayHasKey('markMethod', $data); + $this->assertArrayHasKey('fairMethod', $data); + $this->assertArrayHasKey('fundingBaseSymbol', $data); + $this->assertArrayHasKey('fundingQuoteSymbol', $data); + $this->assertArrayHasKey('fundingRateSymbol', $data); + $this->assertArrayHasKey('indexSymbol', $data); + $this->assertArrayHasKey('settlementSymbol', $data); $this->assertArrayHasKey('status', $data); - $this->assertArrayHasKey('address', $data); - $this->assertArrayHasKey('isInner', $data); - $this->assertArrayHasKey('amount', $data); - $this->assertArrayHasKey('fee', $data); - $this->assertArrayHasKey('walletTxId', $data); - $this->assertArrayHasKey('createdAt', $data); + $this->assertArrayHasKey('fundingFeeRate', $data); + $this->assertArrayHasKey('predictedFundingFeeRate', $data); + $this->assertArrayHasKey('openInterest', $data); + $this->assertArrayHasKey('turnoverOf24h', $data); + $this->assertArrayHasKey('volumeOf24h', $data); + $this->assertArrayHasKey('markPrice', $data); + $this->assertArrayHasKey('indexPrice', $data); + $this->assertArrayHasKey('lastTradePrice', $data); + $this->assertArrayHasKey('nextFundingRateTime', $data); + $this->assertArrayHasKey('maxLeverage', $data); + $this->assertArrayHasKey('lowPrice', $data); + $this->assertArrayHasKey('highPrice', $data); + $this->assertArrayHasKey('priceChgPct', $data); + $this->assertArrayHasKey('priceChg', $data); } - } \ No newline at end of file diff --git a/tests/SymbolTest.php b/tests/SymbolTest.php index 1e5d9d1..62c08fd 100644 --- a/tests/SymbolTest.php +++ b/tests/SymbolTest.php @@ -139,4 +139,41 @@ public function testGetTradeHistory(Symbol $api) } } + /** + * @dataProvider apiProvider + * @param Symbol $api + * @throws \KuMEX\SDK\Exceptions\BusinessException + * @throws \KuMEX\SDK\Exceptions\HttpException + * @throws \KuMEX\SDK\Exceptions\InvalidApiUriException + */ + public function testGetLevel2Depth20(Symbol $api) + { + $data = $api->getLevel2Depth20('XBTUSDM'); + + $this->assertInternalType('array', $data); + $this->assertArrayHasKey('symbol', $data); + $this->assertArrayHasKey('sequence', $data); + $this->assertArrayHasKey('asks', $data); + $this->assertInternalType('array', $data['asks']); + $this->assertInternalType('array', $data['bids']); + } + + /** + * @dataProvider apiProvider + * @param Symbol $api + * @throws \KuMEX\SDK\Exceptions\BusinessException + * @throws \KuMEX\SDK\Exceptions\HttpException + * @throws \KuMEX\SDK\Exceptions\InvalidApiUriException + */ + public function testGetLevel2Depth100(Symbol $api) + { + $data = $api->getLevel2Depth100('XBTUSDM'); + + $this->assertInternalType('array', $data); + $this->assertArrayHasKey('symbol', $data); + $this->assertArrayHasKey('sequence', $data); + $this->assertArrayHasKey('asks', $data); + $this->assertInternalType('array', $data['asks']); + $this->assertInternalType('array', $data['bids']); + } } \ No newline at end of file diff --git a/tests/WebSocketFeedTest.php b/tests/WebSocketFeedTest.php index ee8fc1a..1ca3270 100644 --- a/tests/WebSocketFeedTest.php +++ b/tests/WebSocketFeedTest.php @@ -221,4 +221,138 @@ public function testSubscribePrivateChannels(WebSocketFeed $api) echo "OnClose: {$code} {$reason}\n"; }, $options); } + + /** + * @dataProvider apiProvider + * @param WebSocketFeed $api + * @throws \Throwable + */ + public function testSubscribeLevel3v2(WebSocketFeed $api) + { + $query = ['connectId' => uniqid('t_', false),]; + $channel = ['topic' => '/contractMarket/level3v2:XBTUSDM']; + + $options = []; + $api->subscribePublicChannel($query, $channel, function (array $message, WebSocket $ws, LoopInterface $loop) use ($api) { + // Dynamic output + fwrite(STDIN, print_r($message, true)); + + $this->assertInternalType('array', $message); + $this->assertArrayHasKey('type', $message); + $this->assertArrayHasKey('topic', $message); + $this->assertArrayHasKey('subject', $message); + $this->assertArrayHasKey('data', $message); + $this->assertInternalType('array', $message['data']); + $this->assertArrayHasKey('symbol', $message['data']); + $this->assertArrayHasKey('sequence', $message['data']); + $this->assertArrayHasKey('orderId', $message['data']); + + // Stop for phpunit + $loop->stop(); + }, function ($code, $reason) { + echo "OnClose: {$code} {$reason}\n"; + }, $options); + } + + /** + * @dataProvider apiProvider + * @param WebSocketFeed $api + * @throws \Throwable + */ + public function testSubscribeTickerV2(WebSocketFeed $api) + { + $query = ['connectId' => uniqid('t_', false),]; + $channel = ['topic' => '/contractMarket/tickerV2:XBTUSDM']; + + $options = []; + $api->subscribePublicChannel($query, $channel, function (array $message, WebSocket $ws, LoopInterface $loop) use ($api) { + // Dynamic output + fwrite(STDIN, print_r($message, true)); + + $this->assertInternalType('array', $message); + $this->assertArrayHasKey('type', $message); + $this->assertArrayHasKey('topic', $message); + $this->assertArrayHasKey('subject', $message); + $this->assertArrayHasKey('data', $message); + $this->assertArrayHasKey('symbol', $message['data']); + $this->assertArrayHasKey('sequence', $message['data']); + $this->assertArrayHasKey('bestBidSize', $message['data']); + $this->assertArrayHasKey('bestBidPrice', $message['data']); + $this->assertArrayHasKey('bestAskPrice', $message['data']); + $this->assertArrayHasKey('bestAskSize', $message['data']); + $this->assertArrayHasKey('ts', $message['data']); + // Stop for phpunit + $loop->stop(); + }, function ($code, $reason) { + echo "OnClose: {$code} {$reason}\n"; + }, $options); + } + + /** + * @dataProvider apiProvider + * @param WebSocketFeed $api + * @throws \Throwable + */ + public function testSubscribeTradeOrders(WebSocketFeed $api) + { + $query = ['connectId' => uniqid('t_', false),]; + $channel = ['topic' => '/contractMarket/tradeOrders:XBTUSDM']; + + $options = []; + $api->subscribePrivateChannel($query, $channel, function (array $message, WebSocket $ws, LoopInterface $loop) use ($api) { + // Dynamic output + fwrite(STDIN, print_r($message, true)); + + $this->assertInternalType('array', $message); + $this->assertArrayHasKey('type', $message); + $this->assertArrayHasKey('topic', $message); + $this->assertArrayHasKey('subject', $message); + $this->assertArrayHasKey('data', $message); + // Stop for phpunit + $loop->stop(); + }, function ($code, $reason) { + echo "OnClose: {$code} {$reason}\n"; + }, $options); + } + + /** + * @dataProvider apiProvider + * @param WebSocketFeed $api + * @throws \Throwable + */ + public function testSubscribeWalletAvailableBalanceChange(WebSocketFeed $api) + { + $query = ['connectId' => uniqid('t_', false),]; + $channel = ['topic' => '/contractAccount/wallet']; + + $options = []; + $api->subscribePrivateChannel($query, $channel, function (array $message, WebSocket $ws, LoopInterface $loop) use ($api) { + // Dynamic output + fwrite(STDIN, print_r($message, true)); + + $this->assertInternalType('array', $message); + $this->assertArrayHasKey('type', $message); + $this->assertArrayHasKey('topic', $message); + $this->assertArrayHasKey('subject', $message); + $this->assertArrayHasKey('data', $message); + + if ($message['subject'] === 'availableBalance.change') { + $this->assertArrayHasKey('currency', $message['data']); + $this->assertArrayHasKey('holdBalance', $message['data']); + $this->assertArrayHasKey('availableBalance', $message['data']); + $this->assertArrayHasKey('timestamp', $message['data']); + } + + if ($message['subject'] === 'withdrawHold.change') { + $this->assertArrayHasKey('currency', $message['data']); + $this->assertArrayHasKey('withdrawHold', $message['data']); + $this->assertArrayHasKey('timestamp', $message['data']); + } + + // Stop for phpunit + $loop->stop(); + }, function ($code, $reason) { + echo "OnClose: {$code} {$reason}\n"; + }, $options); + } }