为了我自己的目的,我用 PHP 创建了一个功能齐全的 Coinbase API 系统。但是,我无法正常运行系统的一部分:市价单。
下面出现的代码是面向对象系统中发生的步骤的再现。我认为线性代码在这个论坛中比挖掘继承层更容易解决。
Coinbase API 返回错误消息,如此处代码底部的注释文本所示。'market' 订单 API 不需要 'price' 参数,如下所述:Coinbase Exchange API Documentation。当我通过添加请求的字段来响应错误消息时,订单最终成功,但订单被处理为“限价”订单,而不是类型所指示的“市场”订单。
你能看出我犯的错误吗?
<?php
$settings = \parse_ini_file("API.ini", true);
$apiSecret = $settings['trader_sandbox']['API Secret'];
$apiKey = $settings['trader_sandbox']['API Key'];
$apiPassPhrase = $settings['trader_sandbox']['Passphrase'];
$urlBase = "https://api-public.sandbox.exchange.coinbase.com";
//get timestamp
$date = new \DateTime("now", new \DateTimeZone("America/Los_Angeles"));
$timestamp = $date->getTimestamp();
//API url
$relUrl = "/orders";
//set the method type GET|POST|DELETE|PUT
$method = "POST";
$params = [
"type" => "market",
"side" => "sell",
"product_id" => "BTC-USD",
"stp" => "dc",
"size" => "0.10000000"
];
//copied from coinbase's documentation added apiSecret
function signature($request_path = '', $body = '', $timestamp = false, $method = 'GET', $apiSecret=null) {
/**
* Modified $body assignment to exclude empty bodies
* @author Jared Clemence <jaredclemence@alum.drexel.edu>
* @ref https://community.coinbase.com/t/get-fills-invalid-signature-error-php-example-included/911
*/
$body = is_array($body) ? ( \count($body) > 0 ? json_encode($body) : null ) : $body;
$timestamp = $timestamp ? time() : $timestamp;
$what = $timestamp . $method . $request_path . $body;
return base64_encode(hash_hmac("sha256", $what, base64_decode($apiSecret), true));
}
$url = $urlBase . $relUrl;
$ch = curl_init($url);
$output = \json_encode($params);
$signature = \signature($relUrl, $output, $timestamp, $method, $apiSecret);
$headers = [
"User-Agent" => "Traderbot/v1.0",
"CB-ACCESS-KEY" => $apiKey,
"CB-ACCESS-SIGN" => $signature,
"CB-ACCESS-TIMESTAMP" => $timestamp,
"CB-ACCESS-PASSPHRASE" => $apiPassPhrase,
"Content-Type" => "application/json"
];
\curl_setopt($ch, CURLOPT_POST, true);
\curl_setopt($ch, CURLOPT_POSTFIELDS, $output);
foreach ($headers as $key => &$header) {
//this I found is necessary. Before I added this, the headers lacked the field data and only had the content values
$header = "{$key}:$header";
}
\curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
\curl_close($ch);
try {
$newResult = \json_decode($result);
$result = $newResult;
} catch (Exception $ex) {
}
var_dump( $result );
/**
*
* Output:
class stdClass#2 (1) {
public $message =>
string(13) "Invalid price"
}
*/