Skip to content

Commit

Permalink
error handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
ridicoulous committed Mar 25, 2020
1 parent a6a8745 commit 8abf648
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 44 deletions.
45 changes: 35 additions & 10 deletions Bitmex.Net.ClientExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ static async Task Main(string[] args)
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
var builder = new ConfigurationBuilder()
.AddJsonFile("appconfig.json", optional: true, reloadOnChange: true);
ob = new BitmexSymbolOrderBook("XBTUSD", new BitmexSocketOrderBookOptions("XBT"));
ob = new BitmexSymbolOrderBook("XBTUSD", new BitmexSocketOrderBookOptions("XBT") { LogVerbosity = CryptoExchange.Net.Logging.LogVerbosity.Info });
ob.OnBestOffersChanged += Ob_OnBestOffersChanged;


Expand All @@ -36,20 +36,29 @@ static async Task Main(string[] args)
var configuration = builder.Build();


var socket = new BitmexSocketClient(new BitmexSocketClientOptions(false) { LogVerbosity = CryptoExchange.Net.Logging.LogVerbosity.Debug });

var socket = new BitmexSocketClient(new BitmexSocketClientOptions(configuration["key"], configuration["secret"], bool.Parse(configuration["testnet"])));
//var socket = new BitmexSocketClient(new BitmexSocketClientOptions(configuration["key"], configuration["secret"], bool.Parse(configuration["testnet"])) { LogVerbosity = CryptoExchange.Net.Logging.LogVerbosity.Debug });

socket.OnUserOrdersUpdate += OnBitmexOrderUpdate;
socket.OnUserExecutionsUpdate += OnExecution;
socket.OnUserPositionsUpdate += BitmexSocketClient_OnUserPositionsUpdate;
socket.OnOrderBookL2_25Update += Socket_OnOrderBookL2_25Update;
socket.OnTradeUpdate += Socket_OnTradeUpdate;
socket.OnSocketClose += Socket_OnSocketClose;
socket.OnSocketException += Socket_OnSocketException;
socket.OnChatMessageUpdate += Socket_OnChatMessageUpdate;
socket.Subscribe(new BitmexSubscribeRequest()
.AddSubscription(BitmexSubscribtions.Order, "XBTUSD")
.AddSubscription(BitmexSubscribtions.Execution, "XBTUSD")
.AddSubscription(BitmexSubscribtions.Position, "XBTUSD")
//.AddSubscription(BitmexSubscribtions.Order, "XBTUSD")
//.AddSubscription(BitmexSubscribtions.Execution, "XBTUSD")
//.AddSubscription(BitmexSubscribtions.Position, "XBTUSD")
.AddSubscription(BitmexSubscribtions.Trade, "XBTUSD")
.AddSubscription(BitmexSubscribtions.Chat)
.AddSubscription(BitmexSubscribtions.OrderBookL2_25, "XBTUSD"));
//socket.Subscribe(new BitmexSubscribeRequest()
// .AddSubscription(BitmexSubscribtions.Trade, "XBTUSD"));
//socket.Subscribe(new BitmexSubscribeRequest()
// .AddSubscription(BitmexSubscribtions.OrderBookL2_25, "XBTUSD"));
// var client = new BitmexClient(new BitmexClientOptions(configuration["key"], configuration["secret"], bool.Parse(configuration["testnet"])));
// var posit = client.GetExecutions(new BitmexRequestWithFilter().WithSymbolFilter("XBTUSD").WithOldestFirst().WithResultsCount(19));
//string id = posit.Data.FirstOrDefault().OrderID;
Expand All @@ -62,31 +71,47 @@ static async Task Main(string[] args)
Console.ReadLine();
}

private static void Socket_OnChatMessageUpdate(BitmexSocketEvent<Chat> obj)
{
Console.WriteLine($"{obj.Data[0].Date}{obj.Data[0].Message}");
}

private static void Socket_OnSocketException(Exception obj)
{
Console.WriteLine($"{DateTime.UtcNow}:EXCEPTION: {obj}");
}

private static void Socket_OnSocketClose()
{
Console.WriteLine($"{DateTime.UtcNow}:CLOSED");

}

private static void Socket_OnTradeUpdate(BitmexSocketEvent<Trade> obj)
{
Console.WriteLine("trade");
Console.WriteLine($"{DateTime.UtcNow}:trade");
}

private static void Socket_OnOrderBookL2_25Update(BitmexSocketEvent<BitmexOrderBookEntry> obj)
{
Console.WriteLine("ob");
Console.WriteLine($"{DateTime.UtcNow}:ob");
}

private static void BitmexSocketClient_OnUserPositionsUpdate(BitmexSocketEvent<Position> obj)
{
Console.WriteLine($"Catched POSITION {JsonConvert.SerializeObject(obj.AsDictionary())}");
Console.WriteLine($"{DateTime.UtcNow}:Catched POSITION {JsonConvert.SerializeObject(obj.AsDictionary())}");
Console.WriteLine();
}

private static void OnExecution(BitmexSocketEvent<Execution> obj)
{
Console.WriteLine($"Catched EXEC {JsonConvert.SerializeObject(obj.AsDictionary())}");
Console.WriteLine($"{DateTime.UtcNow}:Catched EXEC {JsonConvert.SerializeObject(obj.AsDictionary())}");
Console.WriteLine();
}

private static void OnBitmexOrderUpdate(BitmexSocketEvent<Order> obj)
{
Console.WriteLine($"Catched ORDER {JsonConvert.SerializeObject(obj.AsDictionary())}");
Console.WriteLine($"{DateTime.UtcNow}:Catched ORDER {JsonConvert.SerializeObject(obj.AsDictionary())}");
Console.WriteLine();
}

Expand Down
2 changes: 1 addition & 1 deletion Bitmex.Net.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bitmex.Net.Client", "Bitmex
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bitmex.Net.Tests", "Bitmex.Net.Tests\Bitmex.Net.Tests.csproj", "{E79E7122-28A2-427E-AD85-14988D241692}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bitmex.Net.ClientExample", "Bitmex.Net.ClientExample\Bitmex.Net.ClientExample.csproj", "{BC5277BC-080C-46E7-B7C3-D3C959E108C4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bitmex.Net.ClientExample", "Bitmex.Net.ClientExample\Bitmex.Net.ClientExample.csproj", "{BC5277BC-080C-46E7-B7C3-D3C959E108C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
2 changes: 1 addition & 1 deletion Bitmex.Net/Bitmex.Net.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<LangVersion>latest</LangVersion>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>0.2.9</Version>
<Version>0.3.5</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>Bitmex.Net.Client</PackageId>
<Authors>ridicoulous</Authors>
Expand Down
103 changes: 84 additions & 19 deletions Bitmex.Net/BitmexSocketClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using CryptoExchange.Net.Logging;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Sockets;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
Expand All @@ -32,9 +33,8 @@ public BitmexSocketClient() : this(DefaultOptions)
}
public BitmexSocketClient(BitmexSocketClientOptions bitmexSocketClientOptions) : base(bitmexSocketClientOptions, bitmexSocketClientOptions.ApiCredentials == null ? null : new BitmexAuthenticationProvider(bitmexSocketClientOptions.ApiCredentials))
{
//var rest = Query<GreetingsMessage>("ping", false).Result;

//SendPeriodic(TimeSpan.FromSeconds(10), conn => "ping");
AddGenericHandler("ping", OnPong);
SendPeriodic(TimeSpan.FromSeconds(10), connection => "ping");
if (bitmexSocketClientOptions.LoadInstruments)
{
using (var bitmexClient = new BitmexClient(new BitmexClientOptions(bitmexSocketClientOptions.IsTestnet)))
Expand All @@ -55,6 +55,15 @@ public BitmexSocketClient() : this(DefaultOptions)
}

}

private void OnPong(SocketConnection arg1, JToken arg2)
{
if (arg2.Type == JTokenType.String && (string)arg2 == "pong")
{
OnPongReceived?.Invoke();
}
}

public event Action OnPongReceived;
public event Action<BitmexSocketEvent<Announcement>> OnAnnouncementUpdate;
public event Action<BitmexSocketEvent<Chat>> OnChatMessageUpdate;
Expand Down Expand Up @@ -85,14 +94,72 @@ public BitmexSocketClient() : this(DefaultOptions)
public event Action<BitmexSocketEvent<Position>> OnUserPositionsUpdate;
public event Action<BitmexSocketEvent<Transaction>> OnUserTransactionsUpdate;
public event Action<BitmexSocketEvent<Wallet>> OnUserWalletUpdate;
public event Action<Exception> OnSocketException;
public event Action OnSocketClose;
public event Action OnSocketOpened;
private bool isBrocked = false;


protected override IWebsocket CreateSocket(string address)
{
Dictionary<string, string> empty = new Dictionary<string, string>();
var s = SocketFactory.CreateWebsocket(this.log, address, empty, this.authProvider == null ? empty : this.authProvider.AddAuthenticationToHeaders("bitmex.com/realtime", HttpMethod.Get, null, true));
s.OnClose += S_OnClose;
s.OnError += S_OnError;
s.OnOpen += S_OnOpen;

//s.SSLProtocols = System.Security.Authentication.SslProtocols.Tls
// | System.Security.Authentication.SslProtocols.Tls11
// | System.Security.Authentication.SslProtocols.Tls12
// | System.Security.Authentication.SslProtocols.Ssl2
// | System.Security.Authentication.SslProtocols.Ssl3;
//s.vers
return s;
}

private void S_OnOpen()
{
if (isBrocked)
{
foreach (var s in this.sockets)
{
s.Value.Send("ping");
}
}
OnSocketOpened?.Invoke();
}

private void S_OnError(Exception obj)
{
OnSocketException?.Invoke(obj);
}

private void S_OnClose()
{
isBrocked = true;
OnSocketClose?.Invoke();
//try
//{
// foreach (var s in this.sockets.Values)
// {
// if (!s.Connected || !s.Socket.IsOpen || s.Socket.IsClosed)
// {
// log.Write(LogVerbosity.Error, $"socket {s.Socket.Id} was closed, try to reconnect it and send ping"); // s.Socket.Reset();

// s.Socket.Connect();
// s.Socket.Send("ping");

// }
// }
//}
//catch (Exception ex)
//{
// log.Write(LogVerbosity.Error, $"On closing socket error catched: {ex.ToString()}");
// OnSocketException?.Invoke(ex);
//}

}

protected override async Task<CallResult<bool>> AuthenticateSocket(SocketConnection s)
{
if (authProvider == null)
Expand All @@ -103,12 +170,12 @@ protected override async Task<CallResult<bool>> AuthenticateSocket(SocketConnect
}

protected override async Task<bool> Unsubscribe(SocketConnection connection, SocketSubscription s)
{
if(s.Request is BitmexSubscribeRequest)
{
if (s.Request is BitmexSubscribeRequest)
{
var unsub = s.Request as BitmexSubscribeRequest;
unsub.Op = BitmexWebSocketOperation.Unsubscribe;
var handler = new Action<string>(data=>
var handler = new Action<string>(data =>
{
log.Write(LogVerbosity.Debug, data);
});
Expand All @@ -129,22 +196,12 @@ protected override bool HandleSubscriptionResponse(SocketConnection s, SocketSub

if (message.Type == JTokenType.String && (string)message == "pong")
{
//callResult = new CallResult<object>(, null);
return true;
}

// var greetings = message.ToObject<GreetingsMessage>();
var response = Deserialize<BitmexSubscriptionResponse>(message, false);

var bRequest = (BitmexSubscribeRequest)request;
if (response.Success && response.Data.Success)
{
//if (response.Data.Request.Args.Contains(response.Data.Subscribe) || response.Data.Request.Args.Contains(response.Data.Unsubscribe))
//{
// callResult = new CallResult<object>(response, response.Success ? null : new ServerError("Subscribtion was not success", response));

// return true;
//}
if (bRequest.Args.Contains(response.Data.Subscribe))
{
callResult = new CallResult<object>(response, response.Success ? null : new ServerError("Subscribtion was not success", response));
Expand Down Expand Up @@ -199,8 +256,16 @@ public async Task<CallResult<UpdateSubscription>> SubscribeAsync(BitmexSubscribe
var table = (string)token["table"];
if (String.IsNullOrEmpty(table) || !Map.Mappings.ContainsKey(table))
{
log.Write(LogVerbosity.Warning, $"Unknown table [{table}] update catched at data {data}");
return;
if (data.Contains("info") || data.StartsWith("{\r\n \"success\": true"))
{
return;
}
else
{
log.Write(LogVerbosity.Warning, $"Unknown table [{table}] update catched at data {data}");
return;
}

}
BitmexSubscribtions updatedTable = Map.Mappings[table];

Expand Down Expand Up @@ -501,7 +566,7 @@ private async Task<CallResult<UpdateSubscription>> Subscribe<T>(BitmexSubscribeR
{
request.Args.ValidateNotNull(nameof(request));
var url = BaseAddress + $"?{request.Op.ToString().ToLower()}={String.Join(",", request.Args)}";
return await Subscribe(url, request, url + NextId(), authProvider != null, onData).ConfigureAwait(false);
return await Subscribe(url, null, url + NextId(), authProvider != null, onData).ConfigureAwait(false);
}
public void Ping()
{
Expand Down
53 changes: 40 additions & 13 deletions Bitmex.Net/BitmexSymbolOrderBook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ public class BitmexSymbolOrderBook : SymbolOrderBook
private readonly int InstrumentIndex;
private readonly decimal InstrumentTickSize;
private bool IsInititalBookSetted;
public BitmexSymbolOrderBook(string symbol, BitmexSocketOrderBookOptions options) : base(symbol, options)
private bool isTestnet;
public BitmexSymbolOrderBook(string symbol, BitmexSocketOrderBookOptions options, BitmexSocketClient? bitmexSocketClient = null) : base(symbol, options)
{
_bitmexSocketClient = new BitmexSocketClient(new BitmexSocketClientOptions(options.IsTestnet));
InstrumentIndex = _bitmexSocketClient.InstrumentsIndexesAndTicks[symbol].Index;
isTestnet = options.IsTestnet;
_bitmexSocketClient = bitmexSocketClient ?? new BitmexSocketClient(new BitmexSocketClientOptions(options.IsTestnet));
InstrumentIndex = _bitmexSocketClient.InstrumentsIndexesAndTicks[symbol].Index;
InstrumentTickSize = options.TickSize.HasValue ? options.TickSize.Value : _bitmexSocketClient.InstrumentsIndexesAndTicks[symbol].TickSize;
}
public void Ping()
Expand All @@ -34,7 +36,7 @@ public override void Dispose()
{
processBuffer.Clear();
asks.Clear();
bids.Clear();
bids.Clear();
_bitmexSocketClient.Dispose();
}

Expand All @@ -53,16 +55,19 @@ protected override async Task<CallResult<UpdateSubscription>> DoStart()
var setResult = await WaitForSetOrderBook(10000).ConfigureAwait(false);
return setResult ? subscriptionResult : new CallResult<UpdateSubscription>(null, setResult.Error);
}

public DateTime LastOrderBookMessage;
public DateTime LastAction;
private void OnUpdate(BitmexSocketEvent<BitmexOrderBookEntry> update)
{
LastOrderBookMessage = DateTime.UtcNow;
if (update.Action == Objects.Socket.BitmexAction.Partial)
{
Create(update.Data);
return;
}
Update(update.Data);
}

/// <summary>
/// You may receive other messages before the partial comes through. In that case, drop any messages received until you have received the partial.
/// </summary>
Expand All @@ -71,22 +76,44 @@ private void Create(List<BitmexOrderBookEntry> entries)
{
SetInitialOrderBook(DateTime.UtcNow.Ticks, entries.Where(e => e.Side == OrderBookEntryType.Bid), entries.Where(e => e.Side == OrderBookEntryType.Ask));
IsInititalBookSetted = true;

}
private void Update(List<BitmexOrderBookEntry> entries)
{
if (IsInititalBookSetted)
try
{
if(entries==null||!entries.Any())
if (IsInititalBookSetted)
{
return;
if (entries == null || !entries.Any())
{
return;
}
foreach (var e in entries)
{
e.SetPrice(InstrumentIndex, InstrumentTickSize);
}
UpdateOrderBook(DateTime.UtcNow.Ticks, entries.Where(e => e.Side == OrderBookEntryType.Bid), entries.Where(e => e.Side == OrderBookEntryType.Ask));
LastAction = DateTime.UtcNow;
}
foreach (var e in entries)
else
{
e.SetPrice(InstrumentIndex, InstrumentTickSize);
// log.Write(CryptoExchange.Net.Logging.LogVerbosity.Warning, $"Price for orderboook level {e.Id} was not setted");
}
log.Write(CryptoExchange.Net.Logging.LogVerbosity.Error, $"Orderbook was not updated cause not initiated");
using (var client = new BitmexClient(new BitmexClientOptions(isTestnet)))
{
log.Write(CryptoExchange.Net.Logging.LogVerbosity.Debug, $"Setting orderdbook through api");

UpdateOrderBook(DateTime.UtcNow.Ticks, entries.Where(e => e.Side == OrderBookEntryType.Bid), entries.Where(e => e.Side == OrderBookEntryType.Ask));
var ob = client.GetOrderBook(Symbol);
if (ob)
{
SetInitialOrderBook(DateTime.UtcNow.Ticks, ob.Data.Where(x => x.Side == OrderBookEntryType.Bid), ob.Data.Where(x => x.Side == OrderBookEntryType.Ask));
IsInititalBookSetted = true;
}
}
}
}
catch (Exception ex)
{
log.Write(CryptoExchange.Net.Logging.LogVerbosity.Error, $"Orderbook was not updated {ex.ToString()}");
}
}
}
Expand Down

0 comments on commit 8abf648

Please sign in to comment.