docker files fixes from liaqat
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
using Managing.Common;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Domain.Candles;
|
||||
using Managing.Domain.Trades;
|
||||
using Managing.Infrastructure.Exchanges.Abstractions;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Infrastructure.Exchanges.Exchanges
|
||||
{
|
||||
public abstract class BaseProcessor : IExchangeProcessor
|
||||
{
|
||||
public abstract void LoadClient(Account account);
|
||||
public abstract Task<bool> CancelOrder(Account account, Ticker ticker);
|
||||
public abstract Enums.TradingExchanges Exchange();
|
||||
public abstract Task<decimal> GetBalance(Account account, bool isForPaperTrading = false);
|
||||
public abstract Candle GetCandle(Account account, Ticker ticker, DateTime date);
|
||||
public abstract Task<List<Candle>> GetCandles(Account account, Ticker ticker, DateTime startDate, Timeframe interval);
|
||||
public abstract decimal GetFee(Account account, bool isForPaperTrading = false);
|
||||
public abstract decimal GetPrice(Account account, Ticker ticker, DateTime date);
|
||||
public abstract Task<decimal> GetQuantityInPosition(Account account, Ticker ticker);
|
||||
public abstract Task<Trade> GetTrade(Account account, string order, Ticker ticker);
|
||||
public abstract Task<List<Trade>> GetTrades(Account account, Ticker ticker);
|
||||
public abstract decimal GetVolume(Account account, Ticker ticker);
|
||||
public abstract Task<Trade> OpenTrade(Account account, Ticker ticker, TradeDirection direction, decimal price, decimal quantity, decimal? leverage = null, Enums.TradeType tradeType = Enums.TradeType.Limit, bool reduceOnly = false, bool isForPaperTrading = false, DateTime? currentDate = null, bool ioc = true);
|
||||
public abstract Orderbook GetOrderbook(Account account, Ticker ticker);
|
||||
public abstract Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false);
|
||||
public abstract Task<List<Trade>> GetOrders(Account account, Ticker ticker);
|
||||
public abstract Task<Trade> GetTrade(string reference, string orderId, Ticker ticker);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
using Binance.Net.Clients;
|
||||
using Binance.Net.Enums;
|
||||
using Binance.Net.Interfaces.Clients;
|
||||
using CryptoExchange.Net.Authentication;
|
||||
using Managing.Common;
|
||||
using Managing.Core;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Domain.Candles;
|
||||
using Managing.Domain.Trades;
|
||||
using Managing.Infrastructure.Exchanges.Helpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Infrastructure.Exchanges.Exchanges;
|
||||
|
||||
public class BinanceProcessor : BaseProcessor
|
||||
{
|
||||
private ILogger<BinanceProcessor> _logger;
|
||||
private IBinanceRestClient _binanceClient;
|
||||
|
||||
public BinanceProcessor(ILogger<BinanceProcessor> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override async Task<bool> CancelOrder(Account account, Ticker ticker)
|
||||
{
|
||||
var binanceResult = await _binanceClient.UsdFuturesApi.Trading.CancelAllOrdersAsync(BinanceHelpers.ToBinanceTicker(ticker));
|
||||
return binanceResult.Success;
|
||||
}
|
||||
|
||||
public override Enums.TradingExchanges Exchange() => Enums.TradingExchanges.Binance;
|
||||
|
||||
public override async Task<decimal> GetBalance(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
var balance = 0m;
|
||||
var binanceBalance = await _binanceClient.UsdFuturesApi.Account.GetBalancesAsync();
|
||||
foreach (var item in binanceBalance.Data)
|
||||
{
|
||||
balance += item.AvailableBalance;
|
||||
}
|
||||
return balance;
|
||||
}
|
||||
|
||||
public override Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Candle GetCandle(Account account, Ticker ticker, DateTime date)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override async Task<List<Candle>> GetCandles(Account account, Ticker ticker, DateTime startDate, Timeframe timeframe)
|
||||
{
|
||||
var binanceCandles = await _binanceClient.UsdFuturesApi.ExchangeData.GetKlinesAsync(BinanceHelpers.ToBinanceTicker(ticker),
|
||||
BinanceHelpers.Map(timeframe), startDate);
|
||||
|
||||
return (List<Candle>)binanceCandles.Data.Select(binanceKline => BinanceHelpers.Map(binanceKline, ticker, account.Exchange));
|
||||
}
|
||||
|
||||
public override decimal GetFee(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Orderbook GetOrderbook(Account account, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Task<List<Trade>> GetOrders(Account account, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override decimal GetPrice(Account account, Ticker ticker, DateTime date)
|
||||
{
|
||||
var binancePrice = _binanceClient.UsdFuturesApi.ExchangeData.GetPriceAsync(BinanceHelpers.ToBinanceTicker(ticker)).Result.Data;
|
||||
return binancePrice.Price;
|
||||
}
|
||||
|
||||
public override async Task<decimal> GetQuantityInPosition(Account account, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override async Task<Trade> GetTrade(Account account, string order, Ticker ticker)
|
||||
{
|
||||
var binanceOrder = await _binanceClient.UsdFuturesApi.Trading.GetOrderAsync(BinanceHelpers.ToBinanceTicker(ticker), origClientOrderId: order);
|
||||
return BinanceHelpers.Map(binanceOrder.Data);
|
||||
}
|
||||
|
||||
public override Task<Trade> GetTrade(string reference, string orderId, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override async Task<List<Trade>> GetTrades(Account account, Ticker ticker)
|
||||
{
|
||||
var binanceOrder =
|
||||
await _binanceClient.UsdFuturesApi.Trading.GetOrdersAsync(BinanceHelpers.ToBinanceTicker(ticker));
|
||||
return (List<Trade>)binanceOrder.Data.Select(o => BinanceHelpers.Map(o));
|
||||
}
|
||||
|
||||
public override decimal GetVolume(Account account, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void LoadClient(Account account)
|
||||
{
|
||||
var credentials = new ApiCredentials(account.Key, account.Secret);
|
||||
_binanceClient = new BinanceRestClient((options) => { options.ApiCredentials = credentials; });
|
||||
}
|
||||
|
||||
public override async Task<Trade> OpenTrade(Account account, Ticker ticker, TradeDirection direction, decimal price, decimal quantity, decimal? leverage = null, TradeType tradeType = TradeType.Limit, bool reduceOnly = false, bool isForPaperTrading = false, DateTime? currentDate = null, bool ioc = true)
|
||||
{
|
||||
var trade = new Trade(DateTime.Now, direction, TradeStatus.PendingOpen, tradeType, ticker, quantity, price, leverage, "", "");
|
||||
trade.SetQuantity(quantity, GetQuantityPrecision(account, ticker));
|
||||
trade.SetPrice(price, GetPricePrecision(account, ticker));
|
||||
|
||||
if (trade.Quantity <= 0)
|
||||
throw new InvalidOperationException(
|
||||
$"Minimum quantity not match, cannot execute trade {direction} for {ticker}.");
|
||||
|
||||
var binanceOrderType = BinanceHelpers.BinanceOrderTypeMap(tradeType);
|
||||
var binanceResult = await _binanceClient.UsdFuturesApi.Trading.PlaceOrderAsync(
|
||||
BinanceHelpers.ToBinanceTicker(ticker),
|
||||
direction != TradeDirection.Long ? OrderSide.Sell : OrderSide.Buy,
|
||||
binanceOrderType,
|
||||
price: binanceOrderType == FuturesOrderType.Limit ? trade.Price : null,
|
||||
quantity: trade.Quantity,
|
||||
reduceOnly: reduceOnly,
|
||||
priceProtect: true,
|
||||
timeInForce: binanceOrderType == FuturesOrderType.Limit ? TimeInForce.GoodTillCanceled : null,
|
||||
activationPrice: binanceOrderType == FuturesOrderType.Limit ? trade.Price : null,
|
||||
stopPrice: binanceOrderType == FuturesOrderType.StopMarket ? trade.Price : null);
|
||||
|
||||
_logger.LogInformation("Exchange result : {0}", JsonConvert.SerializeObject(binanceResult));
|
||||
|
||||
var binanceOrderExecuted = BinanceHelpers.Map(binanceResult, leverage);
|
||||
|
||||
if (binanceResult.Success)
|
||||
{
|
||||
var binanceOrder = await GetTrade(account, binanceOrderExecuted.ExchangeOrderId, ticker);
|
||||
|
||||
trade.Price = binanceOrder.Price;
|
||||
trade.SetStatus(binanceOrder.Status);
|
||||
trade.SetExchangeOrderId(binanceOrderExecuted.ExchangeOrderId);
|
||||
trade.SetMessage(binanceOrderExecuted.Message);
|
||||
}
|
||||
return trade;
|
||||
}
|
||||
|
||||
private int GetPricePrecision(Account account, Ticker ticker)
|
||||
{
|
||||
var binanceFutureInfo = _binanceClient.UsdFuturesApi.ExchangeData.GetExchangeInfoAsync().Result.Data;
|
||||
var precision = binanceFutureInfo.Symbols.Single(p => p.Name == BinanceHelpers.ToBinanceTicker(ticker))
|
||||
.PriceFilter.TickSize;
|
||||
return MathHelpers.GetDecimalPlaces(precision);
|
||||
}
|
||||
|
||||
private int GetQuantityPrecision(Account account, Ticker ticker)
|
||||
{
|
||||
var binanceFutureInfo = _binanceClient.UsdFuturesApi.ExchangeData.GetExchangeInfoAsync().Result.Data;
|
||||
var precision = binanceFutureInfo.Symbols.Single(p => p.Name == BinanceHelpers.ToBinanceTicker(ticker)).QuantityPrecision;
|
||||
return Convert.ToInt32(precision);
|
||||
}
|
||||
}
|
||||
172
src/Managing.Infrastructure.Exchanges/Exchanges/EvmProcessor.cs
Normal file
172
src/Managing.Infrastructure.Exchanges/Exchanges/EvmProcessor.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using Managing.Application.Abstractions.Repositories;
|
||||
using Managing.Common;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Domain.Candles;
|
||||
using Managing.Domain.Evm;
|
||||
using Managing.Domain.Trades;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Infrastructure.Exchanges.Exchanges;
|
||||
|
||||
public class EvmProcessor : BaseProcessor
|
||||
{
|
||||
public override Enums.TradingExchanges Exchange() => Enums.TradingExchanges.Evm;
|
||||
|
||||
private ILogger<EvmProcessor> _logger;
|
||||
private IEvmManager _evmManager;
|
||||
|
||||
public EvmProcessor(ILogger<EvmProcessor> logger, IEvmManager evmManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_evmManager = evmManager;
|
||||
}
|
||||
|
||||
public override async Task<bool> CancelOrder(Account account, Ticker ticker)
|
||||
{
|
||||
return await _evmManager.CancelOrders(account, ticker);
|
||||
}
|
||||
|
||||
|
||||
public override async Task<decimal> GetBalance(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
//var balances = await _evmManager.GetAllBalancesOnAllChain(account.Key);
|
||||
//var balanceAmount = 0m;
|
||||
|
||||
//foreach (var balance in balances)
|
||||
//{
|
||||
// balanceAmount += balance.Value;
|
||||
//}
|
||||
|
||||
var evmBalance = await _evmManager.GetTokenBalance(Constants.Chains.Arbitrum, Ticker.USDC, account.Key);
|
||||
return evmBalance.Balance;
|
||||
}
|
||||
|
||||
public override async Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
var balances = await _evmManager.GetAllBalancesOnAllChain(account.Key);
|
||||
return Map(balances);
|
||||
}
|
||||
|
||||
private List<Balance> Map(List<EvmBalance> balances)
|
||||
{
|
||||
return balances.ConvertAll(balance => new Balance
|
||||
{
|
||||
TokenName = balance.TokenName,
|
||||
Price = balance.Price,
|
||||
Value = balance.Value,
|
||||
Amount = balance.Balance,
|
||||
TokenAdress = balance.TokenAddress,
|
||||
Chain = balance.Chain
|
||||
});
|
||||
}
|
||||
|
||||
public override Candle GetCandle(Account account, Ticker ticker, DateTime date)
|
||||
{
|
||||
return _evmManager.GetCandle(SubgraphProvider.Gbc, ticker).Result;
|
||||
}
|
||||
|
||||
public override async Task<List<Candle>> GetCandles(Account account, Ticker ticker, DateTime startDate, Timeframe interval)
|
||||
{
|
||||
return await _evmManager.GetCandles(SubgraphProvider.Gbc, ticker, startDate, interval);
|
||||
}
|
||||
|
||||
public override decimal GetFee(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
return _evmManager.GetFee(Constants.Chains.Arbitrum).Result;
|
||||
}
|
||||
|
||||
public override decimal GetPrice(Account account, Ticker ticker, DateTime date)
|
||||
{
|
||||
return GetCandle(account, ticker, date).Close;
|
||||
}
|
||||
|
||||
public override async Task<decimal> GetQuantityInPosition(Account account, Ticker ticker)
|
||||
{
|
||||
return await _evmManager.QuantityInPosition(Constants.Chains.Arbitrum, account.Key, ticker);
|
||||
}
|
||||
|
||||
public override async Task<Trade> GetTrade(Account account, string order, Ticker ticker)
|
||||
{
|
||||
return await _evmManager.GetTrade(account, Constants.Chains.Arbitrum, ticker);
|
||||
}
|
||||
|
||||
public override async Task<Trade> GetTrade(string reference, string orderId, Ticker ticker)
|
||||
{
|
||||
return await _evmManager.GetTrade(reference, Constants.Chains.Arbitrum, ticker);
|
||||
}
|
||||
|
||||
public override decimal GetVolume(Account account, Ticker ticker)
|
||||
{
|
||||
var volume = _evmManager.GetVolume(SubgraphProvider.ChainlinkPrice, ticker);
|
||||
return volume;
|
||||
}
|
||||
|
||||
public override async Task<Trade> OpenTrade(
|
||||
Account account,
|
||||
Ticker ticker,
|
||||
TradeDirection direction,
|
||||
decimal price,
|
||||
decimal quantity,
|
||||
decimal? leverage = null,
|
||||
TradeType tradeType = TradeType.Limit,
|
||||
bool reduceOnly = false,
|
||||
bool isForPaperTrading = false,
|
||||
DateTime? currentDate = null,
|
||||
bool ioc = true)
|
||||
{
|
||||
Trade trade;
|
||||
if (reduceOnly)
|
||||
{
|
||||
if (tradeType is TradeType.TakeProfit
|
||||
or TradeType.StopLoss)
|
||||
{
|
||||
// If trade type is TP or SL we create DecreaseOrder
|
||||
trade = await _evmManager.DecreaseOrder(account, tradeType, ticker, direction, price, quantity, leverage);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Trade requested is not an SL nor TP
|
||||
// Price is the current price
|
||||
// We create Decrease position
|
||||
trade = await _evmManager.DecreasePosition(account, ticker, direction, price, quantity, leverage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trade = await _evmManager.IncreasePosition(account, ticker, direction, price, quantity, leverage);
|
||||
}
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
||||
public override async Task<List<Trade>> GetOrders(Account account, Ticker ticker)
|
||||
{
|
||||
return await _evmManager.GetOrders(account, ticker);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region Not implemented
|
||||
|
||||
public override void LoadClient(Account account)
|
||||
{
|
||||
// No client needed
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override async Task<List<Trade>> GetTrades(Account account, Ticker ticker)
|
||||
{
|
||||
// Use by commandHandler to get trades list
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Orderbook GetOrderbook(Account account, Ticker ticker)
|
||||
{
|
||||
// Not use because EVM do not based on an orderbook
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
199
src/Managing.Infrastructure.Exchanges/Exchanges/FtxProcessor.cs
Normal file
199
src/Managing.Infrastructure.Exchanges/Exchanges/FtxProcessor.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
using CryptoExchange.Net.Authentication;
|
||||
using FTX.Net.Clients;
|
||||
using FTX.Net.Interfaces.Clients;
|
||||
using FTX.Net.Objects;
|
||||
using Managing.Common;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Domain.Candles;
|
||||
using Managing.Domain.Trades;
|
||||
using Managing.Infrastructure.Exchanges.Helpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Infrastructure.Exchanges.Exchanges;
|
||||
|
||||
public class FtxProcessor : BaseProcessor
|
||||
{
|
||||
private IFTXClient _ftxClient;
|
||||
private ILogger<FtxProcessor> _logger;
|
||||
|
||||
public FtxProcessor(ILogger<FtxProcessor> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override Enums.TradingExchanges Exchange() => Enums.TradingExchanges.Ftx;
|
||||
|
||||
public override void LoadClient(Account account)
|
||||
{
|
||||
var credentials = new ApiCredentials(account.Key, account.Secret);
|
||||
|
||||
var ftxConfig = new FTXClientOptions()
|
||||
{
|
||||
SubaccountName = account.Name
|
||||
};
|
||||
_ftxClient = new FTXClient(ftxConfig);
|
||||
}
|
||||
|
||||
|
||||
public override async Task<bool> CancelOrder(Account account, Ticker ticker)
|
||||
{
|
||||
LoadClient(account);
|
||||
var ftxResult = await _ftxClient.TradeApi.Trading.CancelAllOrdersAsync(FtxHelpers.ToFtxTicker(ticker));
|
||||
return ftxResult.Success;
|
||||
}
|
||||
|
||||
public override async Task<decimal> GetBalance(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
LoadClient(account);
|
||||
|
||||
var balance = 0m;
|
||||
var ftxBalance = await _ftxClient.TradeApi.Account.GetBalancesAsync();
|
||||
foreach (var item in ftxBalance.Data)
|
||||
{
|
||||
balance += item.UsdValue;
|
||||
}
|
||||
return balance;
|
||||
}
|
||||
|
||||
public override Candle GetCandle(Account account, Ticker ticker, DateTime date)
|
||||
{
|
||||
LoadClient(account);
|
||||
|
||||
var ftxKlines = _ftxClient.TradeApi.ExchangeData.GetKlinesAsync(FtxHelpers.ToFtxTicker(ticker),
|
||||
FTX.Net.Enums.KlineInterval.OneMinute, date.AddHours(-2.5)).Result.Data;
|
||||
if (ftxKlines != null && ftxKlines.Any())
|
||||
{
|
||||
var lastCandle = ftxKlines.ToList().LastOrDefault();
|
||||
return CandleHelpers.Map(lastCandle);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override async Task<List<Candle>> GetCandles(Account account, Ticker ticker, DateTime startDate, Timeframe timeframe)
|
||||
{
|
||||
LoadClient(account);
|
||||
|
||||
var candles = new List<Candle>();
|
||||
var ftxCandles = await _ftxClient.TradeApi.ExchangeData.GetKlinesAsync(FtxHelpers.ToFtxTicker(ticker),
|
||||
FtxHelpers.Map(timeframe), startDate);
|
||||
|
||||
if (ftxCandles.Success)
|
||||
candles.AddRange(ftxCandles.Data.SkipLast(1).Select(ftxKline => FtxHelpers.Map(ftxKline, ticker, account.Exchange, timeframe)));
|
||||
|
||||
return candles;
|
||||
}
|
||||
|
||||
public override decimal GetFee(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
LoadClient(account);
|
||||
var ftxResult = _ftxClient.TradeApi.Account.GetAccountInfoAsync().Result.Data;
|
||||
return ftxResult.TakerFee;
|
||||
}
|
||||
|
||||
public override decimal GetPrice(Account account, Ticker ticker, DateTime date)
|
||||
{
|
||||
LoadClient(account);
|
||||
var ftxKlines = _ftxClient.TradeApi.ExchangeData.GetKlinesAsync(FtxHelpers.ToFtxTicker(ticker),
|
||||
FTX.Net.Enums.KlineInterval.OneMinute, date.AddHours(-2.5)).Result.Data;
|
||||
if (ftxKlines != null && ftxKlines.Any())
|
||||
{
|
||||
return ftxKlines.ToList().LastOrDefault().ClosePrice;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override async Task<decimal> GetQuantityInPosition(Account account, Ticker ticker)
|
||||
{
|
||||
var ftxTickerBalance = _ftxClient.TradeApi.Account.GetPositionsAsync().Result.Data;
|
||||
return ftxTickerBalance.FirstOrDefault(f => f.Future == FtxHelpers.ToFtxTicker(ticker)).Quantity;
|
||||
}
|
||||
|
||||
public override async Task<Trade> GetTrade(Account account, string order, Ticker ticker)
|
||||
{
|
||||
LoadClient(account);
|
||||
var ftxOrder = await _ftxClient.TradeApi.Trading.GetOrderByClientOrderIdAsync(order);
|
||||
return FtxHelpers.Map(ftxOrder.Data);
|
||||
}
|
||||
|
||||
public override async Task<List<Trade>> GetTrades(Account account, Ticker ticker)
|
||||
{
|
||||
LoadClient(account);
|
||||
var ftxOrder = await _ftxClient.TradeApi.Trading.GetOrdersAsync(ticker.ToString());
|
||||
return (List<Trade>)ftxOrder.Data.Select(o => FtxHelpers.Map(o));
|
||||
}
|
||||
|
||||
public override decimal GetVolume(Account account, Ticker ticker)
|
||||
{
|
||||
var futureStats = _ftxClient.TradeApi.ExchangeData.GetFutureStatsAsync(FtxHelpers.ToFtxTicker(ticker)).Result.Data;
|
||||
return futureStats.Volume;
|
||||
}
|
||||
|
||||
public override async Task<Trade> OpenTrade(Account account, Ticker ticker, TradeDirection direction, decimal price, decimal quantity, decimal? leverage = null, TradeType tradeType = TradeType.Limit, bool reduceOnly = false, bool isForPaperTrading = false, DateTime? currentDate = null, bool ioc = true)
|
||||
{
|
||||
LoadClient(account);
|
||||
|
||||
var trade = new Trade(DateTime.Now, direction, TradeStatus.PendingOpen, tradeType, ticker, quantity, price, leverage, "", "");
|
||||
|
||||
trade.SetQuantity(quantity, 6);
|
||||
|
||||
Trade ftxOrder;
|
||||
if (tradeType == TradeType.StopLoss || tradeType == TradeType.TakeProfitLimit || tradeType == TradeType.StopMarket)
|
||||
{
|
||||
var ftxTriggerOrderType = FtxHelpers.FtxTriggerOrderTypeMap(tradeType);
|
||||
var ftxResult = await _ftxClient.TradeApi.Trading.PlaceTriggerOrderAsync(FtxHelpers.ToFtxTicker(ticker),
|
||||
direction != TradeDirection.Long ? FTX.Net.Enums.OrderSide.Sell : FTX.Net.Enums.OrderSide.Buy,
|
||||
ftxTriggerOrderType,
|
||||
triggerPrice: price,
|
||||
reduceOnly: true,
|
||||
retryUntilFilled: false,
|
||||
quantity: quantity);
|
||||
_logger.LogInformation("Exchange result : {0}", JsonConvert.SerializeObject(ftxResult));
|
||||
ftxOrder = FtxHelpers.Map(ftxResult, leverage);
|
||||
}
|
||||
else
|
||||
{
|
||||
var ftxOrderType = FtxHelpers.FtxOrderTypeMap(tradeType);
|
||||
var ftxResult = await _ftxClient.TradeApi.Trading.PlaceOrderAsync(FtxHelpers.ToFtxTicker(ticker),
|
||||
direction != TradeDirection.Long ? FTX.Net.Enums.OrderSide.Sell : FTX.Net.Enums.OrderSide.Buy,
|
||||
ftxOrderType,
|
||||
price: ftxOrderType == FTX.Net.Enums.OrderType.Limit ? price : null,
|
||||
quantity: quantity,
|
||||
clientOrderId: Guid.NewGuid().ToString(),
|
||||
immediateOrCancel: ioc);
|
||||
_logger.LogInformation("Exchange result : {0}", JsonConvert.SerializeObject(ftxResult));
|
||||
ftxOrder = FtxHelpers.Map(ftxResult, leverage);
|
||||
}
|
||||
|
||||
trade.SetStatus(ftxOrder.Status);
|
||||
trade.SetExchangeOrderId(ftxOrder.ExchangeOrderId);
|
||||
trade.SetMessage(ftxOrder.Message);
|
||||
trade.Price = ftxOrder.Price;
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
||||
public override Orderbook GetOrderbook(Account account, Ticker ticker)
|
||||
{
|
||||
LoadClient(account);
|
||||
var ftxOrderBook = _ftxClient.TradeApi.ExchangeData.GetOrderBookAsync(FtxHelpers.ToFtxTicker(ticker), 100).Result;
|
||||
return FtxHelpers.Map(ftxOrderBook);
|
||||
}
|
||||
|
||||
public override Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Task<List<Trade>> GetOrders(Account acount, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Task<Trade> GetTrade(string reference, string orderId, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using CryptoExchange.Net.Authentication;
|
||||
using Kraken.Net.Clients;
|
||||
using Kraken.Net.Interfaces.Clients;
|
||||
using Kraken.Net.Objects.Options;
|
||||
using Managing.Common;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Domain.Candles;
|
||||
using Managing.Domain.Trades;
|
||||
using Managing.Infrastructure.Exchanges.Helpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Infrastructure.Exchanges.Exchanges;
|
||||
|
||||
public class KrakenProcessor : BaseProcessor
|
||||
{
|
||||
private ILogger<KrakenProcessor> _logger;
|
||||
private IKrakenRestClient _krakenClient;
|
||||
|
||||
public KrakenProcessor(ILogger<KrakenProcessor> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
public override Task<bool> CancelOrder(Account account, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Enums.TradingExchanges Exchange() => Enums.TradingExchanges.Kraken;
|
||||
|
||||
public override async Task<decimal> GetBalance(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
LoadClient(account);
|
||||
var balance = await _krakenClient.SpotApi.Account.GetBalancesAsync();
|
||||
balance.Data.TryGetValue("USDT", out decimal krakenBalance);
|
||||
return krakenBalance;
|
||||
}
|
||||
|
||||
public override Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Candle GetCandle(Account account, Ticker ticker, DateTime date)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Task<List<Candle>> GetCandles(Account account, Ticker ticker, DateTime startDate, Timeframe interval)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override decimal GetFee(Account account, bool isForPaperTrading = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Orderbook GetOrderbook(Account account, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Task<List<Trade>> GetOrders(Account account, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override decimal GetPrice(Account account, Ticker ticker, DateTime date)
|
||||
{
|
||||
LoadClient(account);
|
||||
var krakenKline = _krakenClient.SpotApi.ExchangeData.GetKlinesAsync(ticker.ToString(),
|
||||
Kraken.Net.Enums.KlineInterval.OneMinute, date).Result.Data.Data.ToList()[0];
|
||||
return (krakenKline.HighPrice + krakenKline.ClosePrice) / 2;
|
||||
}
|
||||
|
||||
public override Task<decimal> GetQuantityInPosition(Account account, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override async Task<Trade> GetTrade(Account account, string order, Ticker ticker)
|
||||
{
|
||||
LoadClient(account);
|
||||
var krakenOrder = await _krakenClient.SpotApi.Trading.GetOrderAsync(order);
|
||||
return KrakenHelpers.Map(krakenOrder.Data.Values.First());
|
||||
}
|
||||
|
||||
public override Task<Trade> GetTrade(string reference, string orderId, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override async Task<List<Trade>> GetTrades(Account account, Ticker ticker)
|
||||
{
|
||||
LoadClient(account);
|
||||
var krakenOrder = await _krakenClient.SpotApi.Trading.GetOrdersAsync();
|
||||
return (List<Trade>)krakenOrder.Data.Select(o => KrakenHelpers.Map(o));
|
||||
}
|
||||
|
||||
public override decimal GetVolume(Account account, Ticker ticker)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void LoadClient(Account account)
|
||||
{
|
||||
var credentials = new ApiCredentials(account.Key, account.Secret);
|
||||
var krakenConfig = new KrakenRestOptions()
|
||||
{
|
||||
ApiCredentials = credentials
|
||||
};
|
||||
_krakenClient = new KrakenRestClient((options) => { options.ApiCredentials = krakenConfig.ApiCredentials; });
|
||||
}
|
||||
|
||||
public override async Task<Trade> OpenTrade(Account account, Ticker ticker, TradeDirection direction, decimal price, decimal quantity, decimal? leverage = null, TradeType tradeType = TradeType.Limit, bool reduceOnly = false, bool isForPaperTrading = false, DateTime? currentDate = null, bool ioc = true)
|
||||
{
|
||||
LoadClient(account);
|
||||
var trade = new Trade(DateTime.Now, direction, TradeStatus.PendingOpen, tradeType, ticker, quantity, price, leverage, "", "");
|
||||
trade.SetQuantity(quantity, 6);
|
||||
trade.SetPrice(price, 1);
|
||||
|
||||
var order = await _krakenClient.SpotApi.Trading.PlaceOrderAsync(ticker.ToString(),
|
||||
direction != TradeDirection.Long ? Kraken.Net.Enums.OrderSide.Sell : Kraken.Net.Enums.OrderSide.Buy,
|
||||
KrakenHelpers.KrakenOrderTypeMap(tradeType),
|
||||
price: price,
|
||||
quantity: quantity,
|
||||
leverage: leverage);
|
||||
|
||||
_logger.LogInformation("Exchange result : {0}", JsonConvert.SerializeObject(order));
|
||||
var krakenOrderExecuted = GetTrade(account, ((string[])order.Data.OrderIds)[0], ticker).Result;
|
||||
trade.SetStatus(krakenOrderExecuted.Status);
|
||||
trade.SetExchangeOrderId(krakenOrderExecuted.ExchangeOrderId);
|
||||
trade.SetMessage(krakenOrderExecuted.Message);
|
||||
return trade;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user