MATLAB Answers

Can't figure out what this API want's me to use as data when using matlab for a POST request

14 ビュー (過去 30 日間)
Erik Nyström
Erik Nyström 2018 年 5 月 31 日
回答済み: Lautaro Parada 2020 年 5 月 19 日
If you look at this 2 links:
I have been trying for 2 days now to structure my code so I can authenticate there, but it's just wrong.
What exactly should I put in the data param for the HMAC encryption? How does the body Matlab sends in a webread POST request look? As I said, Im getting nowhere with this.
import matlab.net.*
import matlab.net.http.*
URI = matlab.net.URI('https://testnet.bitmex.com/api/v1/order');
U = '?symbol=XBTUSD&side=Sell&orderQty=30&clOrdLinkID=SoL&ordType=Market&contingencyType=OneCancelsTheOther';
Meth = matlab.net.http.RequestMethod.POST;
Req = matlab.net.http.RequestMessage;
Req.Method = Meth;
Body = matlab.net.http.MessageBody(U);
Req.Body = Body;
ApiExpires = datetime('now','format','yyyy-MM-dd''T''HH:mm:ss''Z') + days(5);
ApiExpires = posixtime(ApiExpires);
ApiExpires = round(ApiExpires);
ApiExpires = num2str(ApiExpires);
ApiSecret = 'Tu9CNn_04cQxvjdgGm3MBV7KsqxzkNMAw_3LtUuLUhqC--iX';
Com = complete(Req,URI);
Path = '/api/v1/order';
Verb = 'POST';
EncData = strcat(Verb,Path,ApiExpires,'?symbol=XBTUSD&side=Sell&orderQty=30&clOrdLinkID=SoL&ordType=Market&contingencyType=OneCancelsTheOther');
signature = HMAC(ApiSecret,EncData,'SHA-256');
signature = lower(signature);
ApiSignature = matlab.net.http.HeaderField('api-signature',signature);
ApiKey2 = matlab.net.http.HeaderField('api-key','C8VW3PArKaNoh04CE103hucF');
ApiExpires2 = matlab.net.http.HeaderField('api-expires',ApiExpires);
Header = [ApiExpires2,ApiKey2,ApiSignature];
Req.Header = Header;
Why is this unauthorized when doing send(Req,URI)? (Testnet so do what you want with the keys)

採用された回答

Erik Nyström
Erik Nyström 2018 年 5 月 31 日
編集済み: Erik Nyström 2018 年 5 月 31 日
Solved it by adding:
ContentType = matlab.net.http.HeaderField('Content-Type','application/x-www-form-urlencoded');
Header = [ContentType,ApiExpires2,ApiKey2,ApiSignature];

その他の回答 (1 件)

Lautaro Parada
Lautaro Parada 2020 年 5 月 19 日
I highly recommend you to separate your script in functions or classes, this helps with the error handling and leads anyone to follow along with the logic of your code. Therefore, I think a more robust approach should be separate your script in 3 functions, and with that, generate your signature for your trading bot.
An example of my suggestion could be the following:
clear; clc;
% Reference information based on the script that you uploaded to mathworks
% please change or delete the key and the secret tokens in your production enviroment!!
key = 'C8VW3PArKaNoh04CE103hucF';
secret = 'Tu9CNn_04cQxvjdgGm3MBV7KsqxzkNMAw_3LtUuLUhqC--iX';
endpoint = '/order';
method = 'post';
server = 'https://testnet.bitmex.com/api/v1';
% Example of which data are you sending to the Exchange
nonce = get_nonce()
signature = get_sign(secret, method, endpoint, nonce)
% making the actual request to the
request(key, secret, server, method, endpoint)
function req = request(key, secret, server, method, endpoint)
% custom request handler for the Api of Bitmex
%
% Arguments
% -------
% key(char): key token of the user from the API
% secret(char): secret token of the user from the API
% endpoint(char): functionality to use from the API
% nonce(double): timestamp in milliseconds
%
% Output
% -------
% data from the API with the custom inputs
% error handling
method = upper(method);
% create the headers for the private calls
nonce = get_nonce();
signature = get_sign(secret, method, endpoint, nonce);
% packaging all the headers into a cell array
headers = {
'api-key' key; ...
'api-expires' nonce; ...
'api-signature' signature; ...
'Content-Type' 'application/x-www-form-urlencoded'};
disp(headers) % this should be removed in a production enviroment!
% weboptions of the request
private_options = weboptions('HeaderFields', headers);
url = [server endpoint];
% sending the request to the Bitmex server
req = webread(url, private_options);
end
function nonce = get_nonce(~)
% The nonce must be an integer that must always
% meet the condition of being greater than the
% last nonce used. This ensures that your requests
% cannot be repeated by a "Man in the middle".
% A (good) way to accomplish this is to use a timestamp.
%
% Arguments
% -------
% None
%
% Output
% -------
% timestamp in microseconds, as a character array.
% Generate a nonce (timestamp in microseconds)
nonce_ = datetime('now','format','yyyy-MM-dd''T''HH:mm:ss''Z') + days(5);
nonce = num2str(round(posixtime(nonce_)));
end
function signature = get_sign(secret, method, endpoint, nonce)
% Java framework used to generate the signature, based
% on the nonce. Please see the Matlab documentation for details.
%
% Arguments
% -------
% secret(char): secret api token
% method(char): http method to use with the API (e.g. GET, POST, etc)
% endpoint(char): functionality to use from the api
% nonce(double): timestamp to be used for the dynamic signature
%
% Output
% -------
% char array with the desired signature using HMACSHA256 encoding format
% prepare the string for the signature
msg = strjoin([method endpoint string(nonce)]);
msg_bytes = unicode2native(msg, 'UTF-8');
secret_key_bytes = unicode2native(string(secret), 'UTF-8');
secret_key_spec = javax.crypto.spec.SecretKeySpec(secret_key_bytes,'HmacSHA256');
hmac_provider = javax.crypto.Mac.getInstance('HmacSHA384');
hmac_provider.init(secret_key_spec);
% creating the signature
signature = org.apache.commons.codec.binary.Hex.encodeHex(hmac_provider.doFinal(msg_bytes)).';
end
Naturally, the server will return the status 401 for this request (since I don't know if the credentials are correct nor the most updated version of these ones). Thereby, please refresh your credentials.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by