Skip to content

Commit

Permalink
- Include current price of contract1:contract2
Browse files Browse the repository at this point in the history
- Add smart retry
- Read configuration from config
  • Loading branch information
ernitingarg committed Oct 10, 2022
1 parent aa49608 commit 9f2dc5d
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 61 deletions.
115 changes: 83 additions & 32 deletions Uniswap.Client/Program.cs
Original file line number Diff line number Diff line change
@@ -1,53 +1,71 @@
using System;
using System.Configuration;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Reflection;
using System.Timers;
using GraphQL.Client.Http;
using GraphQL.Client.Serializer.SystemTextJson;
using log4net;

namespace Uniswap.Client
{
class Program
public class Program
{
static readonly Stopwatch StopWatch = new Stopwatch();
const string UniswapUrl = "https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3";

static async Task Main(string[] args)
static readonly ILog SLogger = LogManager.GetLogger(
MethodBase.GetCurrentMethod()?.DeclaringType);

static void Main(string[] args)
{
Console.WriteLine("1. Please input pool id.");
bool validInput = true;
if (!int.TryParse(ConfigurationManager.AppSettings["PoolId"], out var poolId))
{
Console.WriteLine(
"Configuration for key 'PoolId' is not in correct integer format.");
validInput = false;
}

int poolId;
while (!int.TryParse(Console.ReadLine(), out poolId))
if (!int.TryParse(
ConfigurationManager.AppSettings["PrecisionForPosition0"],
out var precisionForPosition0))
{
Console.WriteLine(
"Entered pool id is not in correct integer format, please input again.");
"Configuration for key 'PrecisionForPosition0' is not in correct integer format.");
validInput = false;
}

Console.WriteLine(
"2. Please input decimal precision for amount0 or input 0 for default.");
int precision0;
while (!int.TryParse(Console.ReadLine(), out precision0))
if (!int.TryParse(
ConfigurationManager.AppSettings["PrecisionForPosition1"],
out var precisionForPosition1))
{
Console.WriteLine(
"Entered precision is not in correct integer format, please input again.");
"Configuration for key 'PrecisionForPosition1' is not in correct integer format.");
validInput = false;
}

Console.WriteLine(
"3. Please input decimal precision for amount1 or input 0 for default.");
int precision1;
while (!int.TryParse(Console.ReadLine(), out precision1))
if (!int.TryParse(
ConfigurationManager.AppSettings["PrecisionForCurrentPrice"],
out var precisionForCurrentPrice))
{
Console.WriteLine(
"Entered precision is not in correct integer format, please input again.");
"Configuration for key 'PrecisionForCurrentPrice' is not in correct integer format.");
validInput = false;
}

Console.WriteLine(
"4. Please input time interval in seconds to fetch the data.");
int interval;
while (!int.TryParse(Console.ReadLine(), out interval))
if (!int.TryParse(
ConfigurationManager.AppSettings["IntervalInSeconds"],
out var interval))
{
Console.WriteLine(
"Entered time interval is not in correct integer format, please input again.");
"Configuration for key 'IntervalInSeconds' is not in correct integer format.");
validInput = false;
}

if (!validInput)
{
return;
}

var graphQlOptions = new GraphQLHttpClientOptions
Expand All @@ -61,11 +79,21 @@ static async Task Main(string[] args)

var unisawp = new GraphQL.Uniswap(graphQlClient);

int retry = 0;
int sum = 0;
do
{
retry++;
sum += 5 * retry;
} while (sum < interval);

var t = new Timer();
t.Elapsed += (sender, e) => Callback(unisawp,
poolId,
precision0 == 0 ? null : (int?)precision0,
precision1 == 0 ? null : (int?)precision1);
retry - 1,
precisionForPosition0 == 0 ? null : (int?)precisionForPosition0,
precisionForPosition1 == 0 ? null : (int?)precisionForPosition1,
precisionForCurrentPrice == 0 ? null : (int?)precisionForCurrentPrice);

t.Interval = TimeSpan.FromSeconds(interval).TotalMilliseconds;
t.Enabled = true;
Expand All @@ -82,17 +110,40 @@ static async Task Main(string[] args)
static async void Callback(
GraphQL.Uniswap uniswapGraphQl,
int poolId,
int? precision0,
int? precision1)
int maxRetryCount,
int? precisionForPosition0,
int? precisionForPosition1,
int? precisionForCurrentPrice)
{
StopWatch.Restart();
var result = await uniswapGraphQl.GetLiquidityPosition(poolId, precision0, precision1);
string msg = string.Empty;

try
{
var result = await uniswapGraphQl.GetLiquidityPosition(
poolId,
maxRetryCount,
precisionForPosition0,
precisionForPosition1,
precisionForCurrentPrice);

msg = $"[{DateTime.Now}] " +
$"{result.Position.Token0.Symbol} position {result.Position.Position0Amount}, " +
$"{result.Position.Token1.Symbol} position {result.Position.Position1Amount}, " +
$"Current Price {result.Position.Price0Amount} ({result.Position.Token0.Symbol} per {result.Position.Token1.Symbol}) " +
$"[Time taken: {StopWatch.ElapsedMilliseconds} ms]";
}
catch(Exception ex)
{
SLogger.Error(ex);
msg = $"[{DateTime.Now}] Unable to retrieve the data from server after {maxRetryCount} retries.";
}
finally
{
SLogger.Info(msg);
Console.WriteLine(msg);
}

Console.WriteLine(
$"[{DateTime.Now}] " +
$"{result.Position.Token0.Symbol} position {result.Position.Amount0}, " +
$"{result.Position.Token1.Symbol} position {result.Position.Amount1} " +
$"[Time taken: {StopWatch.ElapsedMilliseconds} ms]");
StopWatch.Stop();
}
}
Expand Down
2 changes: 2 additions & 0 deletions Uniswap.Client/Uniswap.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
Expand Down Expand Up @@ -89,6 +90,7 @@
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
Expand Down
11 changes: 10 additions & 1 deletion Uniswap.Client/app.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup>

<appSettings>
<add key="PoolId" value="245953" />
<add key="PrecisionForPosition0" value="5" />
<add key="PrecisionForPosition1" value="3" />
<add key="PrecisionForCurrentPrice" value="9" />
<add key="IntervalInSeconds" value="60" />
</appSettings>

<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
Expand Down
3 changes: 3 additions & 0 deletions Uniswap.GraphQL/Entities/Pool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ public class Pool
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string SqrtPrice { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string Token0Price { get; set; }
}
}
5 changes: 3 additions & 2 deletions Uniswap.GraphQL/Entities/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public class Position
public string Liquidity { get; set; }
public Tick TickLower { get; set; }
public Tick TickUpper { get; set; }
public double Amount0 { get; set; }
public double Amount1 { get; set; }
public double Position0Amount { get; set; }
public double Position1Amount { get; set; }
public double Price0Amount { get; set; }
}
}
12 changes: 8 additions & 4 deletions Uniswap.GraphQL/IUniswap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ public interface IUniswap
/// Get liquidity position for a given pool id
/// </summary>
/// <param name="poolId">pool id</param>
/// <param name="precision0">decimal precision for amount0</param>
/// <param name="precision1">decimal precision for amount1</param>
/// <param name="maxRetryCount">Maximum number of retries in case of failure from server</param>
/// <param name="precisionForPosition0">decimal precision for contract0 position</param>
/// <param name="precisionForPosition1">decimal precision for contract1 position</param>
/// /// <param name="precisionForCurrentPrice">decimal precision for current price of contract0:contract1</param>
/// <returns></returns>
Task<LiquidityPosition> GetLiquidityPosition(
int poolId,
int? precision0 = null,
int? precision1 = null);
int maxRetryCount,
int? precisionForPosition0 = null,
int? precisionForPosition1 = null,
int? precisionForCurrentPrice = null);
}
}
5 changes: 5 additions & 0 deletions Uniswap.GraphQL/PositionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ internal static Price GetPriceSqrt(this Position position)

return new Price(priceCurrentSqrt, priceLowerSqrt, priceUpperSqrt);
}

internal static double GetTokenPrice(this Position position)
{
return double.Parse(position.Pool.Token0Price);
}
}

internal class Price
Expand Down
54 changes: 41 additions & 13 deletions Uniswap.GraphQL/PriceHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,46 @@ namespace Uniswap.GraphQL
{
internal class PriceHelper
{
internal static (double Amount0, double Amount1) GetPositionAmounts(
internal static (double Position0, double Position1) GetPositionAmounts(
LiquidityPosition liquidityPosition,
int? precision0 = null,
int? precision1 = null)
int? precisionForPosition0 = null,
int? precisionForPosition1 = null)
{
var position = liquidityPosition.Position;
double positionLiquidity = double.Parse(position.Liquidity);
var price = position.GetPrice();
var priceSqrt = position.GetPriceSqrt();

var amounts = CalculateAmounts(positionLiquidity, price, priceSqrt);
var positionAmounts = CalculatePositionAmounts(positionLiquidity, price, priceSqrt);

var amount0Adjusted = DecimalAdjustment(
amounts.amount0,
var position0AdjustedAmount = DecimalTruncateAdjustment(
positionAmounts.amount0,
position.Token0.Decimals,
precision0);
precisionForPosition0);

var amount1Adjusted = DecimalAdjustment(
amounts.amount1,
var position1AdjustedAmount = DecimalTruncateAdjustment(
positionAmounts.amount1,
position.Token1.Decimals,
precision1);
precisionForPosition1);

return (amount0Adjusted, amount1Adjusted);
return (position0AdjustedAmount, position1AdjustedAmount);
}

static (double amount0, double amount1) CalculateAmounts(
internal static (double Price0, double Price1) GetPriceAmounts(
LiquidityPosition liquidityPosition,
int? precisionForPrice0 = null)
{
var position = liquidityPosition.Position;
var price0 = position.GetTokenPrice();

var price0AdjustedAmount = RoundAdjustment(
price0,
precisionForPrice0);

return (price0AdjustedAmount, double.NaN);
}

static (double amount0, double amount1) CalculatePositionAmounts(
double positionLiquidity,
Price price,
Price priceSqrt)
Expand All @@ -57,7 +71,7 @@ internal static (double Amount0, double Amount1) GetPositionAmounts(
return (amount0, amount1);
}

static double DecimalAdjustment(
static double DecimalTruncateAdjustment(
double amount,
string decimals,
int? precisions)
Expand All @@ -73,5 +87,19 @@ static double DecimalAdjustment(

return adjustedAmount;
}

static double RoundAdjustment(
double amount,
int? precisions)
{
if (precisions.HasValue)
{
return Math.Round(
amount * Math.Pow(10, precisions.Value))
/ Math.Pow(10, precisions.Value);
}

return amount;
}
}
}
2 changes: 2 additions & 0 deletions Uniswap.GraphQL/Uniswap.GraphQL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
Expand Down Expand Up @@ -106,6 +107,7 @@
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
Expand Down
Loading

0 comments on commit 9f2dc5d

Please sign in to comment.