Gmx V2 Prices (#8)
* Update prices api * Update worker services in Program.cs
This commit is contained in:
@@ -22,7 +22,7 @@ public abstract class PricesBaseWorker<T> : BaseWorker<T> where T : class
|
|||||||
logger,
|
logger,
|
||||||
delay,
|
delay,
|
||||||
workerService
|
workerService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_pricesService = pricesService;
|
_pricesService = pricesService;
|
||||||
_statisticService = statisticService;
|
_statisticService = statisticService;
|
||||||
@@ -31,11 +31,11 @@ public abstract class PricesBaseWorker<T> : BaseWorker<T> where T : class
|
|||||||
|
|
||||||
protected override async Task Run(CancellationToken cancellationToken)
|
protected override async Task Run(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tickers = _statisticService.GetTickers();
|
var tickers = await _statisticService.GetTickers();
|
||||||
|
|
||||||
foreach (var ticker in tickers)
|
foreach (var ticker in tickers)
|
||||||
{
|
{
|
||||||
await _pricesService.UpdatePrice(TradingExchanges.Evm, ticker, _timeframe);
|
await _pricesService.UpdatePrice(TradingExchanges.Evm, ticker, _timeframe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ public interface IStatisticService
|
|||||||
SpotlightOverview GetLastSpotlight(DateTime dateTime);
|
SpotlightOverview GetLastSpotlight(DateTime dateTime);
|
||||||
IList<TopVolumeTicker> GetLastTopVolumeTicker();
|
IList<TopVolumeTicker> GetLastTopVolumeTicker();
|
||||||
Task<List<Trade>> GetLeadboardPositons();
|
Task<List<Trade>> GetLeadboardPositons();
|
||||||
IList<Enums.Ticker> GetTickers();
|
Task<IList<Enums.Ticker>> GetTickers();
|
||||||
Task UpdateLeaderboard();
|
Task UpdateLeaderboard();
|
||||||
Task UpdateNoobiesboard();
|
Task UpdateNoobiesboard();
|
||||||
Task UpdateSpotlight();
|
Task UpdateSpotlight();
|
||||||
|
|||||||
@@ -35,9 +35,10 @@ public class PricesService : IPricesService
|
|||||||
if (account == null)
|
if (account == null)
|
||||||
throw new Exception($"Enable to found account for exchange {exchange}");
|
throw new Exception($"Enable to found account for exchange {exchange}");
|
||||||
|
|
||||||
var lastCandles = await _candleRepository.GetCandles(exchange, ticker, timeframe, DateTime.UtcNow.AddDays(-2));
|
var lastCandles =
|
||||||
|
await _candleRepository.GetCandles(exchange, ticker, timeframe, DateTime.UtcNow.AddDays(-2));
|
||||||
var lastCandle = lastCandles.LastOrDefault();
|
var lastCandle = lastCandles.LastOrDefault();
|
||||||
var startDate = lastCandle != null ? lastCandle.Date : CandleExtensions.GetPreloadSinceFromTimeframe(timeframe);
|
var startDate = lastCandle != null ? lastCandle.Date : new DateTime(2017, 1, 1);
|
||||||
var newCandles = await _exchangeService.GetCandles(account, ticker, startDate, timeframe);
|
var newCandles = await _exchangeService.GetCandles(account, ticker, startDate, timeframe);
|
||||||
|
|
||||||
var candles = !lastCandles.Any() ? newCandles : newCandles.Where(c => c.Date > lastCandle?.Date);
|
var candles = !lastCandles.Any() ? newCandles : newCandles.Where(c => c.Date > lastCandle?.Date);
|
||||||
@@ -54,7 +55,6 @@ public class PricesService : IPricesService
|
|||||||
|
|
||||||
if (candlesInserted > 0)
|
if (candlesInserted > 0)
|
||||||
_logger.LogInformation($"[{exchange}][{ticker}][{timeframe}] New candles inserted : {candlesInserted}");
|
_logger.LogInformation($"[{exchange}][{ticker}][{timeframe}] New candles inserted : {candlesInserted}");
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -159,9 +159,9 @@ public class StatisticService : IStatisticService
|
|||||||
return _statisticRepository.GetTopVolumeTickers(from);
|
return _statisticRepository.GetTopVolumeTickers(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<Ticker> GetTickers()
|
public async Task<IList<Ticker>> GetTickers()
|
||||||
{
|
{
|
||||||
return _evmManager.GetAvailableTicker().Result;
|
return await _evmManager.GetAvailableTicker();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateSpotlight()
|
public async Task UpdateSpotlight()
|
||||||
@@ -199,7 +199,7 @@ public class StatisticService : IStatisticService
|
|||||||
await _statisticRepository.SaveSpotligthtOverview(overview);
|
await _statisticRepository.SaveSpotligthtOverview(overview);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tickers = GetTickers();
|
var tickers = await GetTickers();
|
||||||
|
|
||||||
foreach (var scenario in scenarios)
|
foreach (var scenario in scenarios)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using Managing.Domain.Trades;
|
|||||||
using Managing.Infrastructure.Evm.Abstractions;
|
using Managing.Infrastructure.Evm.Abstractions;
|
||||||
using Managing.Infrastructure.Evm.Models;
|
using Managing.Infrastructure.Evm.Models;
|
||||||
using Managing.Infrastructure.Evm.Models.Gmx.v1;
|
using Managing.Infrastructure.Evm.Models.Gmx.v1;
|
||||||
|
using Managing.Infrastructure.Evm.Models.Gmx.v2;
|
||||||
using Managing.Infrastructure.Evm.Referentials;
|
using Managing.Infrastructure.Evm.Referentials;
|
||||||
using Managing.Infrastructure.Evm.Services;
|
using Managing.Infrastructure.Evm.Services;
|
||||||
using Managing.Infrastructure.Evm.Services.Gmx;
|
using Managing.Infrastructure.Evm.Services.Gmx;
|
||||||
@@ -38,6 +39,12 @@ public class EvmManager : IEvmManager
|
|||||||
private Dictionary<string, Dictionary<string, decimal>> _geckoPrices;
|
private Dictionary<string, Dictionary<string, decimal>> _geckoPrices;
|
||||||
private readonly GmxV2Service _gmxV2Service;
|
private readonly GmxV2Service _gmxV2Service;
|
||||||
|
|
||||||
|
private readonly List<Ticker> _eligibleTickers = new List<Ticker>()
|
||||||
|
{
|
||||||
|
Ticker.BTC, Ticker.ETH, Ticker.LINK, Ticker.GMX, Ticker.SOL, Ticker.XRP, Ticker.ARB, Ticker.BNB, Ticker.AAVE,
|
||||||
|
Ticker.PEPE, Ticker.DOGE, Ticker.UNI
|
||||||
|
};
|
||||||
|
|
||||||
public EvmManager(IEnumerable<ISubgraphPrices> subgraphs)
|
public EvmManager(IEnumerable<ISubgraphPrices> subgraphs)
|
||||||
{
|
{
|
||||||
var defaultChain = ChainService.GetEthereum();
|
var defaultChain = ChainService.GetEthereum();
|
||||||
@@ -366,27 +373,24 @@ public class EvmManager : IEvmManager
|
|||||||
Timeframe timeframe)
|
Timeframe timeframe)
|
||||||
{
|
{
|
||||||
string gmxTimeframe = GmxHelpers.GeTimeframe(timeframe);
|
string gmxTimeframe = GmxHelpers.GeTimeframe(timeframe);
|
||||||
var gmxPrices = await _httpClient.GetFromJsonAsync<GmxPrices>(
|
var gmxPrices = await _httpClient.GetFromJsonAsync<GmxV2Prices>(
|
||||||
$"https://stats.gmx.io/api/candles/{ticker}?preferableChainId=42161&period={gmxTimeframe}&from={startDate.ToUnixTimestamp()}&preferableSource=fast");
|
$"https://arbitrum-api.gmxinfra.io/prices/candles?tokenSymbol={ticker}&period={gmxTimeframe}&limit=10000");
|
||||||
//var subgraph = _subgraphs.First(s => s.GetProvider() == subgraphProvider);
|
|
||||||
//var prices = await subgraph.GetPrices(ticker, startDate, timeframe);
|
|
||||||
|
|
||||||
//if (prices == null)
|
|
||||||
//{
|
|
||||||
// foreach (var subgraphFallback in _subgraphs.Where(s => s.GetProvider() != subgraphProvider))
|
|
||||||
// {
|
|
||||||
// prices = await subgraphFallback.GetPrices(ticker, startDate, timeframe);
|
|
||||||
|
|
||||||
// if (prices != null)
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (gmxPrices == null)
|
if (gmxPrices == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
gmxPrices.prices.RemoveAt(gmxPrices.prices.Count - 1);
|
gmxPrices.Candles = gmxPrices.Candles.Where(p => p[0] >= startDate.ToUnixTimestamp()).ToList();
|
||||||
return gmxPrices.prices.Select(p => GmxMappers.Map(p, ticker, timeframe)).ToList();
|
gmxPrices.Candles.RemoveAt(gmxPrices.Candles.Count - 1);
|
||||||
|
|
||||||
|
var candles = new List<Candle>();
|
||||||
|
var timeBetweenCandles = gmxPrices.Candles[0][0] - gmxPrices.Candles[1][0];
|
||||||
|
for (int i = 0; i < gmxPrices.Candles.Count; i++)
|
||||||
|
{
|
||||||
|
var c = GmxV2Mappers.Map(gmxPrices.Candles[i], ticker, timeframe, (int)timeBetweenCandles);
|
||||||
|
candles.Add(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return candles.OrderBy(c => c.Date).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public decimal GetVolume(SubgraphProvider subgraphProvider, Ticker ticker)
|
public decimal GetVolume(SubgraphProvider subgraphProvider, Ticker ticker)
|
||||||
@@ -403,9 +407,13 @@ public class EvmManager : IEvmManager
|
|||||||
|
|
||||||
public async Task<List<Ticker>> GetAvailableTicker()
|
public async Task<List<Ticker>> GetAvailableTicker()
|
||||||
{
|
{
|
||||||
var subgraph = GetSubgraph(SubgraphProvider.Gbc);
|
var tokenList = await _httpClient.GetFromJsonAsync<GmxV2TokenList>(
|
||||||
var pairs = await subgraph.GetTickers();
|
"https://arbitrum-api.gmxinfra.io/tokens");
|
||||||
return pairs.ToList();
|
|
||||||
|
if (tokenList == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return GmxV2Mappers.Map(tokenList).Where(t => _eligibleTickers.Contains(t)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Candle> GetCandle(SubgraphProvider subgraphProvider, Ticker ticker)
|
public async Task<Candle> GetCandle(SubgraphProvider subgraphProvider, Ticker ticker)
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Managing.Infrastructure.Evm.Models.Gmx.v2;
|
||||||
|
|
||||||
|
public class GmxV2Prices
|
||||||
|
{
|
||||||
|
[JsonProperty("period")]
|
||||||
|
[JsonPropertyName("period")]
|
||||||
|
public string Period { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("candles")]
|
||||||
|
[JsonPropertyName("candles")]
|
||||||
|
public List<List<double>> Candles { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Managing.Infrastructure.Evm.Models.Gmx.v2;
|
||||||
|
|
||||||
|
public class GmxV2TokenList
|
||||||
|
{
|
||||||
|
[JsonProperty("tokens")]
|
||||||
|
[JsonPropertyName("tokens")]
|
||||||
|
public List<Token> Tokens { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Token
|
||||||
|
{
|
||||||
|
[JsonProperty("symbol")]
|
||||||
|
[JsonPropertyName("symbol")]
|
||||||
|
public string Symbol { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("address")]
|
||||||
|
[JsonPropertyName("address")]
|
||||||
|
public string Address { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("decimals")]
|
||||||
|
[JsonPropertyName("decimals")]
|
||||||
|
public int Decimals { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("synthetic")]
|
||||||
|
[JsonPropertyName("synthetic")]
|
||||||
|
public bool? Synthetic { get; set; }
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ using System.Numerics;
|
|||||||
using Managing.ABI.GmxV2.SyntheticsReader.ContractDefinition;
|
using Managing.ABI.GmxV2.SyntheticsReader.ContractDefinition;
|
||||||
using Managing.Common;
|
using Managing.Common;
|
||||||
using Managing.Core;
|
using Managing.Core;
|
||||||
|
using Managing.Domain.Candles;
|
||||||
using Managing.Domain.Trades;
|
using Managing.Domain.Trades;
|
||||||
using Managing.Infrastructure.Evm.Models.Gmx.v2;
|
using Managing.Infrastructure.Evm.Models.Gmx.v2;
|
||||||
using Nethereum.Web3;
|
using Nethereum.Web3;
|
||||||
@@ -104,4 +105,39 @@ internal static class GmxV2Mappers
|
|||||||
ShortTokenPrice = mp.ShortTokenPrice
|
ShortTokenPrice = mp.ShortTokenPrice
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Candle Map(List<double> marketPrices, Enums.Ticker ticker, Enums.Timeframe timeframe, int timeBetween)
|
||||||
|
{
|
||||||
|
return new Candle()
|
||||||
|
{
|
||||||
|
Date = DateHelpers.GetFromUnixTimestamp((int)marketPrices[0]).AddSeconds(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 = Enums.TradingExchanges.Evm,
|
||||||
|
Ticker = ticker.ToString(),
|
||||||
|
Timeframe = timeframe
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Enums.Ticker> Map(GmxV2TokenList tokenList)
|
||||||
|
{
|
||||||
|
var tokens = new List<Enums.Ticker>();
|
||||||
|
foreach (var t in tokenList.Tokens)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ticker = MiscExtensions.ParseEnum<Enums.Ticker>(t.Symbol);
|
||||||
|
tokens.Add(ticker);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -157,8 +157,7 @@ const BacktestModal: React.FC<BacktestModalProps> = ({
|
|||||||
enabled: !!selectedAccount && !!selectedTimeframe,
|
enabled: !!selectedAccount && !!selectedTimeframe,
|
||||||
queryFn: () => {
|
queryFn: () => {
|
||||||
if (selectedAccount && selectedTimeframe) {
|
if (selectedAccount && selectedTimeframe) {
|
||||||
// return dataClient.data_GetTickers(selectedAccount, selectedTimeframe)
|
return dataClient.data_GetTickers(selectedAccount, selectedTimeframe)
|
||||||
return [Ticker.BTC]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
queryKey: ['tickers', selectedAccount, selectedTimeframe],
|
queryKey: ['tickers', selectedAccount, selectedTimeframe],
|
||||||
@@ -262,25 +261,27 @@ const BacktestModal: React.FC<BacktestModalProps> = ({
|
|||||||
</FormInput>
|
</FormInput>
|
||||||
|
|
||||||
<FormInput label="Days" htmlFor="days">
|
<FormInput label="Days" htmlFor="days">
|
||||||
<Slider
|
<input
|
||||||
id="days"
|
id="days"
|
||||||
|
type="number"
|
||||||
value={days}
|
value={days}
|
||||||
onChange={(e: any) => setDays(e.target.value)}
|
onChange={(e: any) => setDays(e.target.value)}
|
||||||
step="1"
|
step="1"
|
||||||
min="-360"
|
min="-360"
|
||||||
max="-1"
|
max="-1"
|
||||||
></Slider>
|
></input>
|
||||||
</FormInput>
|
</FormInput>
|
||||||
|
|
||||||
<FormInput label="Balance" htmlFor="balance">
|
<FormInput label="Balance" htmlFor="balance">
|
||||||
<Slider
|
<input
|
||||||
id="balance"
|
id="balance"
|
||||||
|
type='number'
|
||||||
value={balance}
|
value={balance}
|
||||||
onChange={(e: any) => setBalance(e.target.value)}
|
onChange={(e: any) => setBalance(e.target.value)}
|
||||||
step="1000"
|
step="1000"
|
||||||
min="1000"
|
min="1000"
|
||||||
max="100000"
|
max="100000"
|
||||||
></Slider>
|
></input>
|
||||||
</FormInput>
|
</FormInput>
|
||||||
|
|
||||||
<FormInput label="Scenario" htmlFor="scenarioName">
|
<FormInput label="Scenario" htmlFor="scenarioName">
|
||||||
|
|||||||
Reference in New Issue
Block a user