Skip to content

Commit

Permalink
Feature: Add support for ws-orderbook to Kraken and Gemini Exchanges (
Browse files Browse the repository at this point in the history
#588)

* Linting. Consistent tabs for code formatting.

* Add support for ws-orderbooks to Kraken and Gemini.
  • Loading branch information
EcBen authored May 7, 2021
1 parent a6d417e commit 21135b0
Show file tree
Hide file tree
Showing 9 changed files with 2,139 additions and 1,886 deletions.
629 changes: 317 additions & 312 deletions src/ExchangeSharp/API/Exchanges/Gemini/ExchangeGeminiAPI.cs

Large diffs are not rendered by default.

1,496 changes: 823 additions & 673 deletions src/ExchangeSharp/API/Exchanges/Kraken/ExchangeKrakenAPI.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using ExchangeSharp.API.Exchanges.Kraken.Models.Types;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Text;

namespace ExchangeSharp.API.Exchanges.Kraken.Models.Request
{
internal class ChannelAction
{
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("event")]
public ActionType Event { get; set; }

[JsonProperty("pair")]
public List<string> Pairs { get; set; }

[JsonProperty("subscription")]
public Subscription SubscriptionSettings { get; set; }
}
}
16 changes: 16 additions & 0 deletions src/ExchangeSharp/API/Exchanges/Kraken/Models/Types/ActionType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;

namespace ExchangeSharp.API.Exchanges.Kraken.Models.Types
{
internal enum ActionType
{
[EnumMember(Value = "subscribe")]
Subscribe,

[EnumMember(Value = "unsubscribe")]
Unsubscribe
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

namespace ExchangeSharp.API.Exchanges.Kraken.Models.Types
{
internal class Subscription
{
[JsonProperty("name")]
public string Name { get; set; }

[JsonProperty("depth")]
public int Depth { get; set; }
}
}
1,374 changes: 707 additions & 667 deletions src/ExchangeSharp/API/Exchanges/_Base/ExchangeAPI.cs

Large diffs are not rendered by default.

432 changes: 219 additions & 213 deletions src/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs

Large diffs are not rendered by default.

22 changes: 10 additions & 12 deletions src/ExchangeSharpConsole/Options/BaseOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public async Task CheckDebugger()
return;
}

using (var proc = Process.GetCurrentProcess())
using(var proc = Process.GetCurrentProcess())
{
Console.Error.WriteLine($"Connect debugger to PID: {proc.Id}.");
Console.Error.WriteLine("Waiting...");
Expand Down Expand Up @@ -166,17 +166,15 @@ protected async Task RunWebSocket(string exchangeName, Func<IExchangeAPI, Task<I
}
}


/// <summary>
/// Makes the app keep running after main thread has exited
/// </summary>
/// <param name="callback">A callback for when the user press CTRL-C or Q</param>
protected static IDisposable KeepSessionAlive(Action callback = null)
=> new ConsoleSessionKeeper(callback);
protected static IDisposable KeepSessionAlive(Action callback = null) => new ConsoleSessionKeeper(callback);

protected static async Task<string[]> ValidateMarketSymbolsAsync(IExchangeAPI api, string[] marketSymbols)
protected static async Task<string[]> ValidateMarketSymbolsAsync(IExchangeAPI api, string[] marketSymbols, bool isWebSocket = false)
{
var apiSymbols = (await api.GetMarketSymbolsAsync()).ToArray();
var apiSymbols = (await api.GetMarketSymbolsAsync(isWebSocket)).ToArray();

if (marketSymbols is null || marketSymbols.Length == 0)
{
Expand Down Expand Up @@ -209,8 +207,8 @@ string[] apiSymbols
var validSymbols = string.Join(",", apiSymbols.OrderBy(s => s));

throw new ArgumentException(
$"Symbol {marketSymbol} does not exist in API {api.Name}.\n" +
$"Valid symbols: {validSymbols}"
$"Symbol {marketSymbol} does not exist in API {api.Name}.\n"
+ $"Valid symbols: {validSymbols}"
);
}
}
Expand All @@ -230,10 +228,10 @@ protected void PrintOrderBook(ExchangeOrderBook orderBook)

for (var i = 0; i < length; i++)
{
var (_, ask) = orderBook.Asks.ElementAtOrDefault(i);
var (_, bid) = orderBook.Bids.ElementAtOrDefault(i);
Console.WriteLine($"{bid.Price,10} ({bid.Amount,9:N2}) | " +
$"{ask.Price,10} ({ask.Amount,9:N})");
var(_, ask) = orderBook.Asks.ElementAtOrDefault(i);
var(_, bid) = orderBook.Bids.ElementAtOrDefault(i);
Console.WriteLine($"{bid.Price,10} ({bid.Amount,9:N2}) | "
+ $"{ask.Price,10} ({ask.Amount,9:N})");
}
}
}
Expand Down
18 changes: 9 additions & 9 deletions src/ExchangeSharpConsole/Options/WebSocketsOrderbookOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
namespace ExchangeSharpConsole.Options
{
[Verb("ws-orderbook", HelpText =
"Connects to the given exchange websocket and keeps printing the first bid and ask prices and amounts for the given market symbols." +
"If market symbol is not set then uses all.")]
"Connects to the given exchange websocket and keeps printing the first bid and ask prices and amounts for the given market symbols."
+ "If market symbol is not set then uses all.")]
public class WebSocketsOrderbookOption : BaseOption, IOptionPerExchange, IOptionWithMultipleMarketSymbol
{
public override async Task RunCommand()
{
async Task<IWebSocket> GetWebSocket(IExchangeAPI api)
{
var symbols = await ValidateMarketSymbolsAsync(api, MarketSymbols.ToArray());
var symbols = await ValidateMarketSymbolsAsync(api, MarketSymbols.ToArray(), true);

return await api.GetFullOrderBookWebSocketAsync(
OrderBookCallback,
symbols: symbols
symbols : symbols
);
}

Expand All @@ -30,13 +30,13 @@ async Task<IWebSocket> GetWebSocket(IExchangeAPI api)

private static void OrderBookCallback(ExchangeOrderBook msg)
{
var (_, bid) = msg.Bids.FirstOrDefault();
var (_, ask) = msg.Asks.FirstOrDefault();
var(_, bid) = msg.Bids.FirstOrDefault();
var(_, ask) = msg.Asks.FirstOrDefault();

Console.WriteLine(
$"[{msg.MarketSymbol,-8}:{msg.SequenceId,10}] " +
$"{bid.Price,10} ({bid.Amount,9:N2}) | " +
$"{ask.Price,10} ({ask.Amount,9:N})"
$"[{msg.MarketSymbol,-8}:{msg.SequenceId,10}] "
+ $"{bid.Price,10} ({bid.Amount,9:N2}) | "
+ $"{ask.Price,10} ({ask.Amount,9:N})"
);
}

Expand Down

0 comments on commit 21135b0

Please sign in to comment.