From 325389cdf81e51ef829bb2c5edd45cd4adc00d09 Mon Sep 17 00:00:00 2001 From: Jan Korf Date: Thu, 20 Jan 2022 21:08:51 +0100 Subject: [PATCH] Added FTX to console example --- .../Exchanges/BinanceExchange.cs | 7 ++ .../ConsoleClient/Exchanges/FTXExchange.cs | 74 +++++++++++++++++++ Examples/ConsoleClient/Exchanges/IExchange.cs | 1 + Examples/ConsoleClient/Program.cs | 24 +++++- 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 Examples/ConsoleClient/Exchanges/FTXExchange.cs diff --git a/Examples/ConsoleClient/Exchanges/BinanceExchange.cs b/Examples/ConsoleClient/Exchanges/BinanceExchange.cs index a4e1865..fd7b750 100644 --- a/Examples/ConsoleClient/Exchanges/BinanceExchange.cs +++ b/Examples/ConsoleClient/Exchanges/BinanceExchange.cs @@ -22,6 +22,13 @@ namespace ConsoleClient.Exchanges return result.AsDataless(); } + public async Task> GetBalances() + { + using var client = new BinanceClient(); + var result = await client.SpotApi.Account.GetAccountInfoAsync(); + return result.Data.Balances.ToDictionary(b => b.Asset, b => b.Total); + } + public async Task> GetOpenOrders() { using var client = new BinanceClient(); diff --git a/Examples/ConsoleClient/Exchanges/FTXExchange.cs b/Examples/ConsoleClient/Exchanges/FTXExchange.cs new file mode 100644 index 0000000..28975e7 --- /dev/null +++ b/Examples/ConsoleClient/Exchanges/FTXExchange.cs @@ -0,0 +1,74 @@ +using ConsoleClient.Models; +using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Sockets; +using FTX.Net.Clients; +using FTX.Net.Interfaces.Clients; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConsoleClient.Exchanges +{ + internal class FTXExchange : IExchange + { + private IFTXSocketClient _socketClient = new FTXSocketClient(); + + public async Task CancelOrder(string symbol, string id) + { + using var client = new FTXClient(); + var result = await client.TradeApi.Trading.CancelOrderAsync(long.Parse(id)); + return result.AsDataless(); + } + + public async Task> GetBalances() + { + using var client = new FTXClient(); + var result = await client.TradeApi.Account.GetBalancesAsync(); + return result.Data.ToDictionary(d => d.Asset, d => d.Total); + } + + public async Task> GetOpenOrders() + { + using var client = new FTXClient(); + var order = await client.TradeApi.Trading.GetOpenOrdersAsync(); + return order.Data.Select(o => new OpenOrder + { + Symbol = o.Symbol, + OrderSide = o.Side.ToString(), + OrderStatus = o.Status.ToString(), + OrderTime = o.CreateTime, + OrderType = o.Type.ToString(), + Price = o.Price ?? 0, + Quantity = o.Quantity, + QuantityFilled = o.QuantityFilled ?? 0 + }); + } + + public async Task GetPrice(string symbol) + { + using var client = new FTXClient(); + var result = await client.TradeApi.ExchangeData.GetSymbolAsync(symbol); + return result.Data.LastPrice ?? 0; + } + + public async Task> PlaceOrder(string symbol, string side, string type, decimal quantity, decimal? price) + { + using var client = new FTXClient(); + var result = await client.TradeApi.Trading.PlaceOrderAsync( + symbol, + side.ToLower() == "buy" ? FTX.Net.Enums.OrderSide.Buy : FTX.Net.Enums.OrderSide.Sell, + type == "market" ? FTX.Net.Enums.OrderType.Market : FTX.Net.Enums.OrderType.Limit, + quantity, + price: price); + return result.As(result.Data?.Id.ToString()); + } + + public async Task SubscribePrice(string symbol, Action handler) + { + var sub = await _socketClient.Streams.SubscribeToTickerUpdatesAsync(symbol, data => handler(data.Data.LastPrice ?? 0)); + return sub.Data; + } + } +} diff --git a/Examples/ConsoleClient/Exchanges/IExchange.cs b/Examples/ConsoleClient/Exchanges/IExchange.cs index be0f0a8..dcd1ff1 100644 --- a/Examples/ConsoleClient/Exchanges/IExchange.cs +++ b/Examples/ConsoleClient/Exchanges/IExchange.cs @@ -13,6 +13,7 @@ namespace ConsoleClient.Exchanges { Task GetPrice(string symbol); Task> GetOpenOrders(); + Task> GetBalances(); Task CancelOrder(string symbol, string id); Task> PlaceOrder(string symbol, string side, string type, decimal quantity, decimal? price ); Task SubscribePrice(string symbol, Action handler); diff --git a/Examples/ConsoleClient/Program.cs b/Examples/ConsoleClient/Program.cs index a5cc86d..7b12272 100644 --- a/Examples/ConsoleClient/Program.cs +++ b/Examples/ConsoleClient/Program.cs @@ -8,6 +8,8 @@ using Binance.Net.Objects; using ConsoleClient.Exchanges; using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Sockets; +using FTX.Net.Clients; +using FTX.Net.Objects; using Microsoft.Extensions.Logging; namespace ConsoleClient @@ -16,7 +18,8 @@ namespace ConsoleClient { static Dictionary _exchanges = new Dictionary { - { "Binance", new BinanceExchange() } + { "Binance", new BinanceExchange() }, + { "FTX", new FTXExchange() } }; static async Task Main(string[] args) @@ -26,10 +29,15 @@ namespace ConsoleClient LogLevel = LogLevel.Trace, ApiCredentials = new ApiCredentials("APIKEY", "APISECRET") }); + FTXClient.SetDefaultOptions(new FTXClientOptions + { + LogLevel = LogLevel.Trace, + ApiCredentials = new ApiCredentials("APIKEY", "APISECRET") + }); while (true) { - Console.WriteLine("> Available commands: PlaceOrder, GetOpenOrders, CancelOrder, GetPrice, SubscribePrice"); + Console.WriteLine("> Available commands: PlaceOrder, GetBalances, GetOpenOrders, CancelOrder, GetPrice, SubscribePrice"); var input = Console.ReadLine(); switch (input) @@ -37,6 +45,9 @@ namespace ConsoleClient case "PlaceOrder": await ProcessPlaceOrder(); break; + case "GetBalances": + await ProcessGetBalances(); + break; case "GetOpenOrders": await ProcessGetOpenOrders(); break; @@ -75,6 +86,15 @@ namespace ConsoleClient Console.WriteLine("Failed to place order: " + result.Error); } + static async Task ProcessGetBalances() + { + var exchange = GetInput("Exchange?"); + Console.WriteLine("Requesting balances..."); + var balances = await _exchanges[exchange].GetBalances(); + foreach (var balance in balances.Where(b => b.Value != 0)) + Console.WriteLine($"> {balance.Key}: {balance.Value}"); + } + static async Task ProcessGetOpenOrders() { var exchange = GetInput("Exchange?");