Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add support for ws-orderbook to Kraken and Gemini Exchanges #588

Merged
merged 2 commits into from
May 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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