diff --git a/src/Managing.Api.Workers/Workers/PricesBaseWorker.cs b/src/Managing.Api.Workers/Workers/PricesBaseWorker.cs index c247fca..8bfcf03 100644 --- a/src/Managing.Api.Workers/Workers/PricesBaseWorker.cs +++ b/src/Managing.Api.Workers/Workers/PricesBaseWorker.cs @@ -22,7 +22,7 @@ public abstract class PricesBaseWorker : BaseWorker where T : class logger, delay, workerService - ) + ) { _pricesService = pricesService; _statisticService = statisticService; @@ -31,11 +31,11 @@ public abstract class PricesBaseWorker : BaseWorker where T : class protected override async Task Run(CancellationToken cancellationToken) { - var tickers = _statisticService.GetTickers(); + var tickers = await _statisticService.GetTickers(); foreach (var ticker in tickers) { await _pricesService.UpdatePrice(TradingExchanges.Evm, ticker, _timeframe); } } -} +} \ No newline at end of file diff --git a/src/Managing.Application.Workers/Abstractions/IStatisticService.cs b/src/Managing.Application.Workers/Abstractions/IStatisticService.cs index 56ad93a..205501b 100644 --- a/src/Managing.Application.Workers/Abstractions/IStatisticService.cs +++ b/src/Managing.Application.Workers/Abstractions/IStatisticService.cs @@ -11,7 +11,7 @@ public interface IStatisticService SpotlightOverview GetLastSpotlight(DateTime dateTime); IList GetLastTopVolumeTicker(); Task> GetLeadboardPositons(); - IList GetTickers(); + Task> GetTickers(); Task UpdateLeaderboard(); Task UpdateNoobiesboard(); Task UpdateSpotlight(); diff --git a/src/Managing.Application.Workers/PricesService.cs b/src/Managing.Application.Workers/PricesService.cs index 77a1b7d..e87b853 100644 --- a/src/Managing.Application.Workers/PricesService.cs +++ b/src/Managing.Application.Workers/PricesService.cs @@ -35,9 +35,10 @@ public class PricesService : IPricesService if (account == null) 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 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 candles = !lastCandles.Any() ? newCandles : newCandles.Where(c => c.Date > lastCandle?.Date); @@ -54,7 +55,6 @@ public class PricesService : IPricesService if (candlesInserted > 0) _logger.LogInformation($"[{exchange}][{ticker}][{timeframe}] New candles inserted : {candlesInserted}"); - } catch (Exception ex) { diff --git a/src/Managing.Application.Workers/StatisticService.cs b/src/Managing.Application.Workers/StatisticService.cs index 0ebef26..dde6191 100644 --- a/src/Managing.Application.Workers/StatisticService.cs +++ b/src/Managing.Application.Workers/StatisticService.cs @@ -159,9 +159,9 @@ public class StatisticService : IStatisticService return _statisticRepository.GetTopVolumeTickers(from); } - public IList GetTickers() + public async Task> GetTickers() { - return _evmManager.GetAvailableTicker().Result; + return await _evmManager.GetAvailableTicker(); } public async Task UpdateSpotlight() @@ -199,7 +199,7 @@ public class StatisticService : IStatisticService await _statisticRepository.SaveSpotligthtOverview(overview); } - var tickers = GetTickers(); + var tickers = await GetTickers(); foreach (var scenario in scenarios) { diff --git a/src/Managing.Infrastructure.Web3/EvmManager.cs b/src/Managing.Infrastructure.Web3/EvmManager.cs index b1f4a2b..2c3ec3d 100644 --- a/src/Managing.Infrastructure.Web3/EvmManager.cs +++ b/src/Managing.Infrastructure.Web3/EvmManager.cs @@ -11,6 +11,7 @@ using Managing.Domain.Trades; using Managing.Infrastructure.Evm.Abstractions; using Managing.Infrastructure.Evm.Models; using Managing.Infrastructure.Evm.Models.Gmx.v1; +using Managing.Infrastructure.Evm.Models.Gmx.v2; using Managing.Infrastructure.Evm.Referentials; using Managing.Infrastructure.Evm.Services; using Managing.Infrastructure.Evm.Services.Gmx; @@ -38,6 +39,12 @@ public class EvmManager : IEvmManager private Dictionary> _geckoPrices; private readonly GmxV2Service _gmxV2Service; + private readonly List _eligibleTickers = new List() + { + 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 subgraphs) { var defaultChain = ChainService.GetEthereum(); @@ -366,27 +373,24 @@ public class EvmManager : IEvmManager Timeframe timeframe) { string gmxTimeframe = GmxHelpers.GeTimeframe(timeframe); - var gmxPrices = await _httpClient.GetFromJsonAsync( - $"https://stats.gmx.io/api/candles/{ticker}?preferableChainId=42161&period={gmxTimeframe}&from={startDate.ToUnixTimestamp()}&preferableSource=fast"); - //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; - // } - //} + var gmxPrices = await _httpClient.GetFromJsonAsync( + $"https://arbitrum-api.gmxinfra.io/prices/candles?tokenSymbol={ticker}&period={gmxTimeframe}&limit=10000"); if (gmxPrices == null) return null; - gmxPrices.prices.RemoveAt(gmxPrices.prices.Count - 1); - return gmxPrices.prices.Select(p => GmxMappers.Map(p, ticker, timeframe)).ToList(); + gmxPrices.Candles = gmxPrices.Candles.Where(p => p[0] >= startDate.ToUnixTimestamp()).ToList(); + gmxPrices.Candles.RemoveAt(gmxPrices.Candles.Count - 1); + + var candles = new List(); + 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) @@ -403,9 +407,13 @@ public class EvmManager : IEvmManager public async Task> GetAvailableTicker() { - var subgraph = GetSubgraph(SubgraphProvider.Gbc); - var pairs = await subgraph.GetTickers(); - return pairs.ToList(); + var tokenList = await _httpClient.GetFromJsonAsync( + "https://arbitrum-api.gmxinfra.io/tokens"); + + if (tokenList == null) + return null; + + return GmxV2Mappers.Map(tokenList).Where(t => _eligibleTickers.Contains(t)).ToList(); } public async Task GetCandle(SubgraphProvider subgraphProvider, Ticker ticker) diff --git a/src/Managing.Infrastructure.Web3/Models/Gmx/v2/GmxV2Prices.cs b/src/Managing.Infrastructure.Web3/Models/Gmx/v2/GmxV2Prices.cs new file mode 100644 index 0000000..6abf773 --- /dev/null +++ b/src/Managing.Infrastructure.Web3/Models/Gmx/v2/GmxV2Prices.cs @@ -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> Candles { get; set; } +} \ No newline at end of file diff --git a/src/Managing.Infrastructure.Web3/Models/Gmx/v2/GmxV2TokenList.cs b/src/Managing.Infrastructure.Web3/Models/Gmx/v2/GmxV2TokenList.cs new file mode 100644 index 0000000..a16f5a7 --- /dev/null +++ b/src/Managing.Infrastructure.Web3/Models/Gmx/v2/GmxV2TokenList.cs @@ -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 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; } +} \ No newline at end of file diff --git a/src/Managing.Infrastructure.Web3/Services/Gmx/GmxV2Mappers.cs b/src/Managing.Infrastructure.Web3/Services/Gmx/GmxV2Mappers.cs index d6b9757..59ba263 100644 --- a/src/Managing.Infrastructure.Web3/Services/Gmx/GmxV2Mappers.cs +++ b/src/Managing.Infrastructure.Web3/Services/Gmx/GmxV2Mappers.cs @@ -2,6 +2,7 @@ using System.Numerics; using Managing.ABI.GmxV2.SyntheticsReader.ContractDefinition; using Managing.Common; using Managing.Core; +using Managing.Domain.Candles; using Managing.Domain.Trades; using Managing.Infrastructure.Evm.Models.Gmx.v2; using Nethereum.Web3; @@ -104,4 +105,39 @@ internal static class GmxV2Mappers ShortTokenPrice = mp.ShortTokenPrice }).ToList(); } + + public static Candle Map(List 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 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(e); + } + } + + return tokens; + } } \ No newline at end of file diff --git a/src/Managing.WebApp/src/components/organism/Backtest/backtestModal.tsx b/src/Managing.WebApp/src/components/organism/Backtest/backtestModal.tsx index c7f39c8..8289667 100644 --- a/src/Managing.WebApp/src/components/organism/Backtest/backtestModal.tsx +++ b/src/Managing.WebApp/src/components/organism/Backtest/backtestModal.tsx @@ -157,8 +157,7 @@ const BacktestModal: React.FC = ({ enabled: !!selectedAccount && !!selectedTimeframe, queryFn: () => { if (selectedAccount && selectedTimeframe) { - // return dataClient.data_GetTickers(selectedAccount, selectedTimeframe) - return [Ticker.BTC] + return dataClient.data_GetTickers(selectedAccount, selectedTimeframe) } }, queryKey: ['tickers', selectedAccount, selectedTimeframe], @@ -262,25 +261,27 @@ const BacktestModal: React.FC = ({ - setDays(e.target.value)} step="1" min="-360" max="-1" - > + > - setBalance(e.target.value)} step="1000" min="1000" max="100000" - > + >