简体   繁体   English

Deribit FIX API 登录

[英]Deribit FIX API Logon

Following code doesn't seem to work to Logon using FIX API.以下代码似乎不适用于使用 FIX API 登录。 Getting "invalid credentials" from the exchange though same username and access key seem to work with REST API over websockets.尽管相同的用户名和访问密钥似乎可以通过 websockets 与 REST API 一起使用,但从交换中获取“无效凭据”。 Seems like issue with the definition of nonce.似乎是 nonce 定义的问题。 Here I am trying a basic example to try to Logon.在这里,我正在尝试一个基本示例来尝试登录。

        string user = settings->get().getString("Username");
        message.setField(Username(user));
        string pass = settings->get().getString("Password");
        milliseconds ms = duration_cast< milliseconds >(
                system_clock::now().time_since_epoch()
        );
        long long millis = ms.count();
        string nonce = "abcdefghijkabcdefghijkabcdefghijkabcdefghijk";
        nonce = base64_encode(nonce);
        string raw = to_string(millis) + "." + nonce;

        message.setField(RawData(raw));
        string password = base64_encode(sha256(raw+pass));

        message.setField(Password(password));

the functions used for base64 and sha256 encoding are:用于 base64 和 sha256 编码的函数是:

string base64_encode(const std::string &in) {

    std::string out;

    int val = 0, valb = -6;
    for (unsigned char c : in) {
        val = (val << 8) + c;
        valb += 8;
        while (valb >= 0) {
            out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(val>>valb)&0x3F]);
            valb -= 6;
        }
    }
    if (valb>-6) out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((val<<8)>>(valb+8))&0x3F]);
    while (out.size()%4) out.push_back('=');
    return out;
}

string sha256(const string str)
{
    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    SHA256_Update(&sha256, str.c_str(), str.size());
    SHA256_Final(hash, &sha256);
    stringstream ss;
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        ss << hex << setw(2) << setfill('0') << (int)hash[i];
    }
    return ss.str();
}

I am following this documentation from Deribit https://docs.deribit.com/?shell#logon-a and quickfix as the fix engine.我正在关注 Deribit https://docs.deribit.com/?shell#logon-aquickfix作为修复引擎的这个文档。

在此处输入图片说明

Code follows from this description mentioned in the docs.代码遵循文档中提到的这个描述。

Did you solve the issue?你解决问题了吗? I am currently stuck at the same problem... :-(我目前遇到了同样的问题...... :-(

Some hints, that I already checked:一些提示,我已经检查过:

  • Do you have your credentials from the test.deribit.com website?您有来自 test.deribit.com 网站的凭据吗? They differ from the www.deribit.com website!它们与www.deribit.com网站不同! Had to ask support to realize this...不得不寻求支持才能意识到这一点......

  • I don't use quickfix, so I am not sure, what the RawData method does?我不使用 quickfix,所以我不确定 RawData 方法有什么作用? It does now modify the data in any way?它现在是否以任何方式修改数据?

  • At least in the deribit FIX v1 documentation, there is an error, that the password field would be tag 553, while it is actually 554.至少在 deribit FIX v1 文档中,有一个错误,即密码字段将是标签 553,而实际上是 554。

I was able to solve this problem and I am providing it's solution so others can also benefit.我能够解决这个问题,我正在提供它的解决方案,以便其他人也可以受益。

Method used for base64 encoding:用于base64编码的方法:

static const std::string base64_chars =
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
  std::string ret;
  int i = 0;
  int j = 0;
  unsigned char char_array_3[3];
  unsigned char char_array_4[4];

  while (in_len--) {
    char_array_3[i++] = *(bytes_to_encode++);
    if (i == 3) {
      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] = char_array_3[2] & 0x3f;

      for(i = 0; (i <4) ; i++)
        ret += base64_chars[char_array_4[i]];
      i = 0;
    }
  }

  if (i)
  {
    for(j = i; j < 3; j++)
      char_array_3[j] = '\0';

    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] = char_array_3[2] & 0x3f;

    for (j = 0; (j < i + 1); j++)
      ret += base64_chars[char_array_4[j]];

    while((i++ < 3))
      ret += '=';

  }

  return ret;

} 

And how I calculated other fields :以及我如何计算其他字段:

        string user = settings->get().getString("Username");

        milliseconds ms = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
        string timestamp_in_ms = std::to_string(ms.count());
        unsigned char nonce [32] = {};
        RAND_bytes(nonce, sizeof(nonce));
        string nonce64 = base64_encode(nonce, sizeof(nonce));
        string secret = settings->get().getString("Password");
        string raw_data = timestamp_in_ms + "." + nonce64;
        string base_signature_string = raw_data + secret;
        
        unsigned char hash[SHA256_DIGEST_LENGTH];
        SHA256_CTX sha256;
        SHA256_Init(&sha256);
        SHA256_Update(&sha256, base_signature_string.c_str(), base_signature_string.size());
        SHA256_Final(hash, &sha256);

        static string password_sha_base64 = base64_encode(hash, sizeof(hash));

PS: RAND_bytes and SHA functions are pre defined function in openssl. PS:RAND_bytes 和 SHA 函数是 openssl 中预定义的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM