Can't figure out what this API want's me to use as data when using matlab for a POST request
    조회 수: 5 (최근 30일)
  
       이전 댓글 표시
    
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)
채택된 답변
추가 답변 (1개)
  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.
댓글 수: 0
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

