211 lines
8.7 KiB
C#
211 lines
8.7 KiB
C#
using System.Numerics;
|
|
using Managing.Common;
|
|
using Managing.Infrastructure.Evm.Models.Gmx.v2;
|
|
using Nethereum.Web3;
|
|
|
|
namespace Managing.Infrastructure.Evm.Services.Gmx;
|
|
|
|
public static class GmxV2Helpers
|
|
{
|
|
public static BigInteger GetFundingFactorPerPeriod(GmxMarketInfo marketInfo, bool isLong, int periodInSeconds)
|
|
{
|
|
var fundingFactorPerSecond = marketInfo.Market.FundingFactorPerSecond;
|
|
var longsPayShorts = marketInfo.Market.LongsPayShorts;
|
|
var longInterestUsd = marketInfo.Infos.LongInterestUsd;
|
|
var shortInterestUsd = marketInfo.Infos.ShortInterestUsd;
|
|
|
|
var isLargerSide = isLong ? longsPayShorts : !longsPayShorts;
|
|
|
|
BigInteger factorPerSecond;
|
|
|
|
if (isLargerSide)
|
|
{
|
|
factorPerSecond = fundingFactorPerSecond * -1;
|
|
}
|
|
else
|
|
{
|
|
var largerInterestUsd = longsPayShorts ? longInterestUsd : shortInterestUsd;
|
|
var smallerInterestUsd = longsPayShorts ? shortInterestUsd : longInterestUsd;
|
|
|
|
var ratio = smallerInterestUsd > 0
|
|
? BigInteger.Multiply(largerInterestUsd, Precision) / smallerInterestUsd
|
|
: 0;
|
|
|
|
factorPerSecond = ApplyFactor(ratio, fundingFactorPerSecond);
|
|
}
|
|
|
|
return factorPerSecond * periodInSeconds;
|
|
}
|
|
|
|
private static BigInteger ApplyFactor(BigInteger ratio, BigInteger fundingFactorPerSecond)
|
|
{
|
|
// Implement the logic for applying the factor based on the ratio
|
|
// This is a placeholder implementation
|
|
return BigInteger.Multiply(ratio, fundingFactorPerSecond) / Precision;
|
|
}
|
|
|
|
private static readonly BigInteger Precision = BigInteger.Pow(10, 18);
|
|
|
|
public static Dictionary<Enums.Timeframe, int> Periods = new Dictionary<Enums.Timeframe, int>()
|
|
{
|
|
{ Enums.Timeframe.FiveMinutes, 300 },
|
|
{ Enums.Timeframe.FifteenMinutes, 900 },
|
|
{ Enums.Timeframe.OneHour, 3600 },
|
|
{ Enums.Timeframe.FourHour, 14400 },
|
|
{ Enums.Timeframe.OneDay, 86400 }
|
|
};
|
|
|
|
public static string GetMarketAddress(Enums.Ticker ticker)
|
|
{
|
|
// Switch statement to return the market address based on the ticker
|
|
switch (ticker)
|
|
{
|
|
case Enums.Ticker.BTC: return Constants.GMX.Markets.BTCUSDC;
|
|
case Enums.Ticker.ETH: return Constants.GMX.Markets.ETHUSDC;
|
|
case Enums.Ticker.LINK: return Constants.GMX.Markets.LINKUSD;
|
|
case Enums.Ticker.PEPE: return Constants.GMX.Markets.PEPEUSD;
|
|
case Enums.Ticker.SOL: return Constants.GMX.Markets.SOLUSD;
|
|
case Enums.Ticker.UNI: return Constants.GMX.Markets.UNIUSD;
|
|
case Enums.Ticker.SHIB: return Constants.GMX.Markets.SHIBUSD;
|
|
case Enums.Ticker.AAVE: return Constants.GMX.Markets.AAVEUSD;
|
|
case Enums.Ticker.OP: return Constants.GMX.Markets.OPUSD;
|
|
case Enums.Ticker.APE: return Constants.GMX.Markets.APEUSD;
|
|
case Enums.Ticker.GMX: return Constants.GMX.Markets.GMXUSD;
|
|
case Enums.Ticker.ARB: return Constants.GMX.Markets.ARBUSD;
|
|
case Enums.Ticker.NEAR: return Constants.GMX.Markets.NEARUSD;
|
|
case Enums.Ticker.STX: return Constants.GMX.Markets.STXUSD;
|
|
case Enums.Ticker.LTC: return Constants.GMX.Markets.LTCUSD;
|
|
case Enums.Ticker.XRP: return Constants.GMX.Markets.XRPUSD;
|
|
case Enums.Ticker.WIF: return Constants.GMX.Markets.WIFUSD;
|
|
case Enums.Ticker.BNB: return Constants.GMX.Markets.BNBUSD;
|
|
case Enums.Ticker.ORDI: return Constants.GMX.Markets.ORDIUSD;
|
|
case Enums.Ticker.DOGE: return Constants.GMX.Markets.DOGEUSD;
|
|
default: throw new ArgumentOutOfRangeException(nameof(ticker), "Invalid ticker value.");
|
|
}
|
|
}
|
|
|
|
public static Enums.Ticker GetTicker(string marketAddress)
|
|
{
|
|
switch (marketAddress)
|
|
{
|
|
case Constants.GMX.Markets.BTCUSDC: return Enums.Ticker.BTC;
|
|
case Constants.GMX.Markets.ETHUSDC: return Enums.Ticker.ETH;
|
|
case Constants.GMX.Markets.LINKUSD: return Enums.Ticker.LINK;
|
|
case Constants.GMX.Markets.PEPEUSD: return Enums.Ticker.PEPE;
|
|
case Constants.GMX.Markets.SOLUSD: return Enums.Ticker.SOL;
|
|
case Constants.GMX.Markets.UNIUSD: return Enums.Ticker.UNI;
|
|
case Constants.GMX.Markets.SHIBUSD: return Enums.Ticker.SHIB;
|
|
case Constants.GMX.Markets.AAVEUSD: return Enums.Ticker.AAVE;
|
|
case Constants.GMX.Markets.OPUSD: return Enums.Ticker.OP;
|
|
case Constants.GMX.Markets.APEUSD: return Enums.Ticker.APE;
|
|
case Constants.GMX.Markets.GMXUSD: return Enums.Ticker.GMX;
|
|
case Constants.GMX.Markets.ARBUSD: return Enums.Ticker.ARB;
|
|
case Constants.GMX.Markets.NEARUSD: return Enums.Ticker.NEAR;
|
|
case Constants.GMX.Markets.STXUSD: return Enums.Ticker.STX;
|
|
case Constants.GMX.Markets.LTCUSD: return Enums.Ticker.LTC;
|
|
case Constants.GMX.Markets.XRPUSD: return Enums.Ticker.XRP;
|
|
case Constants.GMX.Markets.WIFUSD: return Enums.Ticker.WIF;
|
|
case Constants.GMX.Markets.ORDIUSD: return Enums.Ticker.ORDI;
|
|
default: throw new ArgumentOutOfRangeException(nameof(marketAddress), "Invalid market address.");
|
|
}
|
|
}
|
|
|
|
public static Enums.TradeType GetTradeType(GmxV2OrderType orderType)
|
|
{
|
|
return orderType switch
|
|
{
|
|
GmxV2OrderType.LimitIncrease => Enums.TradeType.Limit,
|
|
GmxV2OrderType.LimitDecrease => Enums.TradeType.Limit,
|
|
GmxV2OrderType.MarketIncrease => Enums.TradeType.Market,
|
|
GmxV2OrderType.MarketDecrease => Enums.TradeType.Market,
|
|
GmxV2OrderType.Liquidation => Enums.TradeType.Market,
|
|
_ => throw new ArgumentOutOfRangeException(nameof(orderType), "Invalid order type.")
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parses the contract price to a decimal value.
|
|
/// </summary>
|
|
/// <param name="price"></param>
|
|
/// <param name="tokenDecimals"></param>
|
|
/// <param name="useTransform">Used to tranform the decimal since GMX is not using everytime the decimal from the MarketProps. Use true for prices and false for amounts</param>
|
|
/// <returns></returns>
|
|
public static decimal ParseContractPrice(BigInteger price, int tokenDecimals, bool useTransform = false)
|
|
{
|
|
if (useTransform)
|
|
tokenDecimals = TransformValue(tokenDecimals);
|
|
|
|
return (decimal)price / (decimal)ExpandDecimals(1, tokenDecimals);
|
|
}
|
|
|
|
public static BigInteger ConvertToContractPrice(decimal value, int tokenDecimals, bool useTransform = false)
|
|
{
|
|
if (useTransform)
|
|
tokenDecimals = TransformValue(tokenDecimals);
|
|
|
|
return new BigInteger(value * (decimal)ExpandDecimals(1, tokenDecimals));
|
|
}
|
|
|
|
public static BigInteger ExpandDecimals(int value, int decimals)
|
|
{
|
|
return BigInteger.Multiply(value, BigInteger.Pow(10, decimals));
|
|
}
|
|
|
|
public static int TransformValue(int input)
|
|
{
|
|
// Apply the derived linear equation y = -x + 30
|
|
return -input + 30;
|
|
}
|
|
|
|
public static BigInteger EstimateOrderOraclePriceCount(int swapsCount)
|
|
{
|
|
return 3 + new BigInteger(swapsCount);
|
|
}
|
|
|
|
public static bool SameAddress(string address, string address2)
|
|
{
|
|
return string.Equals(address, address2, StringComparison.CurrentCultureIgnoreCase);
|
|
}
|
|
|
|
public static BigInteger GetAcceptablePrice(decimal price, bool isLong)
|
|
{
|
|
var slippage = 0.003m; // 0.3% slippage
|
|
var priceSlippage = price * slippage;
|
|
var acceptablePrice = isLong ? price + priceSlippage : price - priceSlippage;
|
|
|
|
return Web3.Convert.ToWei(acceptablePrice, 22);
|
|
}
|
|
|
|
public static BigInteger GetCollateralAmount(decimal amount, decimal leverage = 1)
|
|
{
|
|
return Web3.Convert.ToWei(amount * leverage, 30);
|
|
}
|
|
|
|
public static decimal ConvertToUsd(BigInteger amount, int decimals, BigInteger price)
|
|
{
|
|
var result = (amount * price) / ExpandDecimals(1, decimals);
|
|
return (decimal)result;
|
|
}
|
|
|
|
public static BigInteger ParseValue(decimal value, int decimals)
|
|
{
|
|
return Web3.Convert.ToWei(value, decimals);
|
|
}
|
|
|
|
public static string GetPositionKey(string addressesAccount, string addressesMarket,
|
|
string addressesCollateralToken, bool flagsIsLong)
|
|
{
|
|
return $"{addressesAccount}:{addressesMarket}:{addressesCollateralToken}:{flagsIsLong}";
|
|
}
|
|
|
|
public static BigInteger GetEntryPrice(BigInteger positionSizeInUsd, BigInteger positionSizeInTokens,
|
|
int decimals)
|
|
{
|
|
if (positionSizeInTokens <= 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return BigInteger.Multiply(positionSizeInUsd, ExpandDecimals(1, decimals)) / positionSizeInTokens;
|
|
}
|
|
} |