using System.Numerics; using Managing.ABI.GmxV2.SyntheticsReader.ContractDefinition; using Managing.Common; using Managing.Core; using Managing.Domain.Candles; using Managing.Domain.MoneyManagements; using Managing.Domain.Trades; using Managing.Domain.Users; using Managing.Infrastructure.Evm.Models.Gmx.v2; using Managing.Infrastructure.Evm.Models.Proxy; using Nethereum.Web3; using static Managing.Common.Enums; namespace Managing.Infrastructure.Evm.Services.Gmx; internal static class GmxV2Mappers { public static Trade Map(GmxV2Position position, Ticker ticker) { var entryPrice = GmxV2Helpers.GetEntryPrice(position.SizeInUsd, position.SizeInTokens, position.TokenData.Decimals); var parsedEntryPrice = GmxHelpers.FormatAmount(entryPrice, Constants.GMX.Config.Decimals.USD - 2, 4); var collateralLeverage = CalculateCollateralAndLeverage(position.SizeInUsd, position.CollateralAmount); var trade = new Trade( DateHelpers.GetFromUnixTimestamp((int)position.IncreasedAtTime), position.IsLong ? TradeDirection.Long : TradeDirection.Short, TradeStatus.Filled, TradeType.Limit, ticker, collateralLeverage.collateral / parsedEntryPrice, parsedEntryPrice, collateralLeverage.leverage, position.Key, "" ); return trade; } public static List Map(List orders) { var trades = new List(); foreach (var order in orders) { var shortToken = TokenV2Service.GetTokenByAddress(order.InitialCollateralTokenAddress); var ticker = GmxV2Helpers.GetTicker(order.MarketAddress); var indexToken = TokenV2Service.GetByTicker(ticker); var sizeDelta = GmxHelpers.FormatAmount(order.SizeDeltaUsd, Constants.GMX.Config.Decimals.USD, 4); var triggerPrice = GmxV2Helpers.ParseContractPrice(order.ContractTriggerPrice, indexToken.Decimals, true); var quantity = sizeDelta / triggerPrice; var initialCollateral = GmxV2Helpers.ParseContractPrice(order.InitialCollateralDeltaAmount, shortToken.Decimals); var leverage = sizeDelta == 0 || initialCollateral == 0 ? 0 : sizeDelta / initialCollateral; var trade = new Trade( order.Date, order.IsLong ? TradeDirection.Long : TradeDirection.Short, TradeStatus.PendingOpen, GmxV2Helpers.GetTradeType(order.OrderType), ticker, Convert.ToDecimal(quantity), Convert.ToDecimal(triggerPrice), leverage, "", "" ); trades.Add(trade); } return trades; } // // public static GmxV2Position MapPosition(GmxV2Service.PositionInfoDTO positionInfo) // { // return new GmxV2Position // { // PositionKey = GetPositionKeyV2( // positionInfo.Position.Account, // positionInfo.Position.Market, // positionInfo.Position.CollateralToken, // positionInfo.Position.IsLong // ), // SizeInUsd = positionInfo.Position.SizeInUsd, // CollateralAmount = positionInfo.Position.CollateralAmount, // IncreasedAtTime = positionInfo.Position.IncreasedAtTime, // IsLong = positionInfo.Position.IsLong, // Leverage = CalculateLeverage(positionInfo.Position.SizeInUsd, positionInfo.Position.CollateralAmount) // }; // } private static (decimal collateral, decimal leverage) CalculateCollateralAndLeverage(BigInteger sizeInUsd, BigInteger collateralAmount) { if (collateralAmount == 0) return (0m, 0m); const int collateralDecimals = 6; var size = Web3.Convert.FromWei(sizeInUsd, 30); var collateral = Web3.Convert.FromWei(collateralAmount, collateralDecimals); return (collateral, collateral == 0 ? 0 : Math.Round(size / collateral)); } public static List Map(List marketPrices) { return marketPrices.Select(mp => new MarketPrices { IndexTokenPrice = mp.IndexTokenPrice, LongTokenPrice = mp.LongTokenPrice, ShortTokenPrice = mp.ShortTokenPrice }).ToList(); } public static Candle Map(List marketPrices, Ticker ticker, Timeframe timeframe, int timeBetween) { return new Candle() { Date = DateHelpers.GetFromUnixTimestamp((int)marketPrices[0] + timeBetween).AddSeconds(-1), OpenTime = DateHelpers.GetFromUnixTimestamp((int)marketPrices[0]), Open = Convert.ToDecimal(marketPrices[1]), High = Convert.ToDecimal(marketPrices[2]), Low = Convert.ToDecimal(marketPrices[3]), Close = Convert.ToDecimal(marketPrices[4]), Exchange = TradingExchanges.Evm, Ticker = ticker.ToString(), Timeframe = timeframe }; } public static List Map(GmxV2TokenList tokenList) { var tokens = new List(); foreach (var t in tokenList.Tokens) { try { var ticker = MiscExtensions.ParseEnum(t.Symbol); tokens.Add(ticker); } catch (Exception e) { Console.WriteLine($"Could not parse ticker for symbol {t.Symbol}: {e.Message}"); } } return tokens; } /// /// Maps raw GMX positions fetched from the proxy/contract to domain Position objects. /// /// List of GmxPosition objects from the proxy. /// List of domain Position objects. /// /// Assumes GmxPosition contains necessary details like Account, Market, CollateralToken, IsLong, etc. /// Requires resolution of MoneyManagement dependency. /// public static List Map(List resultPositions) { var positions = new List(); foreach (var gmxPosition in resultPositions) { try { var direction = MiscExtensions.ParseEnum(gmxPosition.Direction); var ticker = MiscExtensions.ParseEnum(gmxPosition.Ticker); var position = new Position("", "", direction, ticker, new MoneyManagement(), PositionInitiator.User, gmxPosition.Date, new User()); position.Open = new Trade(position.Date, direction, TradeStatus.Filled, TradeType.Market, ticker, (decimal)gmxPosition.Quantity, (decimal)gmxPosition.Price, (decimal)gmxPosition.Leverage, gmxPosition.Open.ExchangeOrderId, ""); if (gmxPosition.TakeProfit1 != null) { position.TakeProfit1 = Map(gmxPosition.TakeProfit1); } if (gmxPosition.StopLoss != null) { position.StopLoss = Map(gmxPosition.StopLoss); } position.ProfitAndLoss = new ProfitAndLoss() { Realized = (decimal)gmxPosition.Pnl }; position.Status = MiscExtensions.ParseEnum(gmxPosition.Status); positions.Add(position); } catch (Exception ex) { Console.WriteLine( $"Error mapping GMX position {gmxPosition?.ExchangeOrderId}: {ex.Message} \n StackTrace: {ex.StackTrace}"); } } return positions; } private static Trade Map(GmxTrade gmxPosition) { return new Trade(gmxPosition.Date, MiscExtensions.ParseEnum(gmxPosition.Direction), MiscExtensions.ParseEnum(gmxPosition.Status), MiscExtensions.ParseEnum(gmxPosition.TradeType), MiscExtensions.ParseEnum(gmxPosition.Ticker), (decimal)gmxPosition.Quantity, (decimal)gmxPosition.Price, gmxPosition.Leverage, gmxPosition.ExchangeOrderId, ""); } public static List Map(List resultPositions) { var trades = new List(); foreach (var gmxPosition in resultPositions) { trades.Add(Map(gmxPosition)); } return trades; } }