前前后后在3,5天里,花了大概10個小時的時間,研究BitMEX官方API接口,開源的交易所的API接口集合。最后也沒有一個好的方法能夠讓我的程序掛單到BitMEX交易所。最后沒有辦法了,索性自己寫吧。經(jīng)過一番周折,最終不負所望。成功的用PHP實現(xiàn)了接入BitMEX API,并且掛單成功。
這個功能的實現(xiàn)再一次說明,功夫不負有心人。同時,也讓我對HTTP方式的POST,GET,DELETE;對指定內(nèi)容簽名;HTTP數(shù)據(jù)域的組織;HTTP標準頭的使用等等有了更近一步的了解。
先上源碼:
<?php
date_default_timezone_set("UTC"); // 把系統(tǒng)時間設(shè)置為UTC時候,因為在與BitMEX交互的時候,對方需要的是UTC時間戳
$verb = 'POST';
$path = '/api/v1/order';
$apiNonce = (string)(time()+100); // 時間戳,加了100,因為延時的原因,不加的話,服務(wù)器會返回這個時候比較舊的錯誤。
$data = 'symbol=XBTUSD&price=6300&orderQty=1'; // 這里的數(shù)據(jù)組織形式和API文檔中的例子不一樣。文檔中說了,可以使用不同形式的組織方式來組織data;只要簽名的字符串和傳到服務(wù)器的字符串一致就行;這句話非常關(guān)鍵。
$apiKey = ''; // 填上自己的api KEY
$apiSecret = ''; // 填上自己的api Secret
$stringToHash = (string)($verb.$path.$apiNonce.$data); // 按BitMEX官方API文檔指示,拼接指定字符串,以備簽名之用。
$signature = hash_hmac('sha256', $stringToHash, $apiSecret); // 簽名
$postJsonString = $data; // 發(fā)送給服務(wù)器的字符串,和簽名所用的字符串必須一致。不然會報("Signature Not Valid")簽名無效的錯誤
$contentLength = strlen($postJsonString);
// 合成頭部所需
$headers = array(
"Content-type: application/x-www-form-urlencoded", // 這里的內(nèi)容類型與data字符串的組合形式也是相對應(yīng)的,不然也會報"Signature Not Valid"的錯誤。
"Accept: application/json",
"Content-length: ".$contentLength,
"X-Requested-With: XMLHttpRequest",
"api-expires:".$apiNonce, // 時間戳
"api-signature:".$signature,// 簽名后的字符串
"api-key:".$apiKey
);
$ch = curl_init();
$uri = 'https://www.bitmex.com/api/v1/order';
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); // 這里可以作POST,GET,DELETE等等操作
curl_setopt($ch, CURLOPT_HEADER, TRUE); //FALSE
curl_setopt($ch, CURLOPT_RETURNTRANSFER , TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postJsonString);
curl_setopt($ch, CURLOPT_HTTPHEADER , $headers);
// 執(zhí)行并獲取HTML文檔內(nèi)容
$output = curl_exec($ch);
if($output === FALSE ){
echo "\n";
echo "CURL Error:".curl_error($ch);
}
$info = curl_getinfo($ch);
print_r($info);
// 釋放curl句柄
curl_close($ch);
echo "\n";
echo "output is ".$output;
難點主要在于簽名,http頭部內(nèi)容的組織。我看了官方接口,ccxt在github上關(guān)于PHP的源碼,也沒有找到合適的方法來解決這兩個問題。這個時候就犯難了,怎么辦?
后來,還是在官方API文檔中找到了蛛絲馬跡。
身份驗證可通過發(fā)送以下 HTTP 標頭完成:
- API-expires :這個UNIX時間戳以后請求不再有效。 這是為了防止重放攻擊。
UNIX時間戳以秒為單位。 例如, 2018-02-08T04:30:37Z 為 1518064237。
API-鍵 :您的API公鑰。 當你通過 API 創(chuàng)建一個 API 密鑰時,一個 id 參數(shù)會被返回。
api-signature: 你的當前請求的簽名。 它的計算方法為 hex(HMAC_SHA256(apiSecret, verb + path + nonce + data))。 請參閱下面的計算示例。
‘data’ 參數(shù)
HMAC 中的 data 部分應(yīng)該完全與你發(fā)送到服務(wù)器的原始數(shù)據(jù)一致。 你可以發(fā)送 JSON 或形式編碼,只需確保你在 HMAC 中使用同樣的字符串。通常你可以用自己喜歡的編程語言創(chuàng)建你的請求,然后在 HMAC 中使用與請求中一樣的字符串。
是的,有的時候,閱讀理解能力非常的關(guān)鍵。像這種情況下就體現(xiàn)出來了。我是反復(fù)讀了好多次,才真正明白里面的涵義;再加上反復(fù)調(diào)試;最后終于成功?,F(xiàn)在看來,這段代碼看似簡單,實則不易呀。
從現(xiàn)在起,養(yǎng)成一個好習(xí)慣——把難得的好東西分享出來。
