Can't figure out what this API want's me to use as data when using matlab for a POST request
2 views (last 30 days)
Show older comments
Erik Nyström
on 31 May 2018
Answered: Lautaro Parada
on 19 May 2020
If you look at this 2 links:
- https://testnet.bitmex.com/app/apiKeysUsage
- https://testnet.bitmex.com/api/explorer/#!/Order/Order_new
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)
Accepted Answer
More Answers (1)
Lautaro Parada
on 19 May 2020
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.
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!