简体   繁体   English

如何使用C#.NET CORE 2.0将FIX登录消息发送到GDAX

[英]How to send FIX logon message with C# .NET CORE 2.0 to GDAX

I'm I'm trying to establish a FIX 4.2 session to fix.gdax.com (docs: https://docs.gdax.com/#fix-api ) using C# with .Net Core 2.0. 我正在尝试将C#与.Net Core 2.0建立一个FIX 4.2会话来fix.gdax.com(docs: https ://docs.gdax.com/#fix-api)。 when i try to logon i receive 0 bytes as response as server. 当我尝试登录时,我收到0字节作为服务器响应。 I really dont know what i have wrong, this is the code: 我真的不知道我错了,这是代码:

    private async Task ConnectToGdaxFix()
    {
        _socketTcpClient = new TcpClient();
        _socketTcpClient.NoDelay = true;
        _bufferEnd = 0;
        await _socketTcpClient.ConnectAsync(_gdaxFixGateway, _gdaxFixPort);
        _sslStream = new SslStream(_socketTcpClient.GetStream());
        await _sslStream.AuthenticateAsClientAsync(_gdaxFixGateway);
        byte[] buffer = new byte[2048];
        var message = await FixSendLoginMessage();
        var bytes = await _sslStream.ReadAsync(buffer, 0, buffer.Length);
    }

    private async Task<string> FixSendLoginMessage()
    {
        var sendTime = DateTime.UtcNow.ToString("yyyyMMdd-HH:mm:ss.fff");
        string msgType = "A";
        var messageSeqNumber = (++messageSeqNum).ToString();
        var senderCompId = "apiKey";
        var targetCompId = "Coinbase";
        var password = "passphrase";
        var accessSign = CreateAccessSign(
                sendTime,
                msgType,
                messageSeqNumber,
                senderCompId,
                targetCompId,
                password
            );
        var logonMessage = $"98=0{'\x01'}108=30{'\x01'}554={password}{'\x01'}96={accessSign}{'\x01'}8013=Y";
        var headerAfter9Tag = $"35={msgType}{'\x01'}34={messageSeqNumber}{'\x01'}52={sendTime}{'\x01'}49={senderCompId}{'\x01'}56={targetCompId}";
        var length = logonMessage.Length + headerAfter9Tag.Length + 1;
        var messageHeader = $"8=FIX.4.2{'\x01'}9={length}{'\x01'}{headerAfter9Tag}";
        var messageWithHeader = $"{messageHeader}{'\x01'}{logonMessage}{'\x01'}";
        int sum = 0;
        int len = messageWithHeader.Length;
        for (int i = 0; i < len; i++)
        {
            sum += Convert.ToChar(messageWithHeader.Substring(i, 1));
        }
        sum = sum % 256;
        var messageWithChecksum = $"{messageWithHeader}10={sum.ToString("000")}{'\x01'}";
        byte[] buffer = Encoding.ASCII.GetBytes(messageWithChecksum);
        await _sslStream.WriteAsync(buffer, 0, buffer.Length);
        await _sslStream.FlushAsync();
        return messageWithChecksum;
    }

    private string CreateAccessSign(
            string sendingTime,
            string msgType,
            string msgSeqNumber,
            string senderCompId,
            string targetCompId,
            string password
        )
    {
        var stringToHash = string.Join('\x01', sendingTime, msgType, msgSeqNumber, senderCompId, targetCompId, password);
        var privateKeyAsBytes = Encoding.UTF8.GetBytes("privateKey");
        using (var hmac = new HMACSHA256(privateKeyAsBytes))
        {
            var signature = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToHash));
            return Convert.ToBase64String(signature);
        }
    }

Can anyone please help me to see what is wrong with the logon message or ssl encryption? 谁能帮我看看登录消息或SSL加密有什么问题吗?

This is the message sent to Gdax(the characters of the sensitive data have been replaced and the \\x01 is the | to simplify the view): 8=FIX.4.2|9=161|35=A|34=1|52=20180124-00:50:34.083|49=426123d789fa8e5c3782c549kj9de06e|56=Coinbase|98=0|108=30|554=outswrt|96=qkE5KPMLjn+Ef9Zgk1/kvL0Etem6bK2llINwMjOkDy9=|8013=Y|10=028 这是发送到Gdax的消息(敏感数据的字符已被替换,\\ x01是|以简化视图):8 = FIX.4.2 | 9 = 161 | 35 = A | 34 = 1 | 52 = 20180124-00:50:34.083 | 49 = 426123d789fa8e5c3782c549kj9de06e | 56 = Coinbase | 98 = 0 | 108 = 30 | 554 = outswrt | 96 = qkE5KPMLjn + Ef9Zgk1 / kvL0Etem6bK2llINwMjOkDy9 = | 8013 = Y | 10 = 028

CreateAccessSign is wrong, privateKeyAsBytes need to use Convert.FromBase64String: CreateAccessSign错误,privateKeyAsBytes需要使用Convert.FromBase64String:

    var privateKeyAsBytes = Convert.FromBase64String("privateKey");

FixSendLoginMessage is wrong, this is the correct implementation: FixSendLoginMessage错误,这是正确的实现:

    private async Task<string> FixSendLoginMessage()
{
    var sendTime = DateTime.UtcNow.ToString("yyyyMMdd-HH:mm:ss.fff");
    string msgType = "A";
    var messageSeqNumber = (++messageSeqNum).ToString();
    var senderCompId = "apiKey";
    var targetCompId = "Coinbase";
    var password = "passphrase";
    var accessSign = CreateAccessSign(
            sendTime,
            msgType,
            messageSeqNumber,
            senderCompId,
            targetCompId,
            password
        );
    var logonMessage = $"98=0{'\x01'}108=30{'\x01'}554={password}{'\x01'}96={accessSign}{'\x01'}8013=Y{'\x01'}";
    var headerAfter9Tag = $"35={msgType}{'\x01'}34={messageSeqNumber}{'\x01'}52={sendTime}{'\x01'}49={senderCompId}{'\x01'}56={targetCompId}{'\x01'}";
    var length = logonMessage.Length + headerAfter9Tag.Length;
    var messageHeader = $"8=FIX.4.2{'\x01'}9={length}{'\x01'}{headerAfter9Tag}";
    var messageWithHeader = $"{messageHeader}{logonMessage}";
    int sum = 0;
    int len = messageWithHeader.Length;
    for (int i = 0; i < len; i++)
    {
        sum += Convert.ToChar(messageWithHeader.Substring(i, 1));
    }
    sum = sum % 256;
    var messageWithChecksum = $"{messageWithHeader}10={sum.ToString("000")}{'\x01'}";
    byte[] buffer = Encoding.ASCII.GetBytes(messageWithChecksum);
    await _sslStream.WriteAsync(buffer, 0, buffer.Length);
    await _sslStream.FlushAsync();
    return messageWithChecksum;
}

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

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