GMX v2 - Trading (#7)

* Move PrivateKeys.cs

* Update gitignore

* Update gitignore

* updt

* Extract GmxServiceTests.cs

* Refact

* update todo

* Update code

* Fix hashdata

* Replace static token hashed datas

* Set allowance

* Add get orders

* Add get orders tests

* Add ignore

* add close orders

* revert

* Add get gas limit

* Start increasePosition. Todo: Finish GetExecutionFee and estimateGas

* little refact

* Update gitignore

* Fix namespaces and clean repo

* Add tests samples

* Add execution fee

* Add increase position

* Handle backtest on the frontend

* Add tests

* Update increase

* Test increase

* fix increase

* Fix size

* Start get position

* Update get positions

* Fix get position

* Update rpc and trade mappers

* Finish close position

* Fix leverage
This commit is contained in:
Oda
2025-01-30 23:06:22 +07:00
committed by GitHub
parent ecaa89c67b
commit 65bdb8e34f
156 changed files with 11253 additions and 4073 deletions

View File

@@ -1,7 +1,9 @@
using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Services;
using Managing.Application.Hubs;
using Managing.Core;
using Managing.Domain.Backtests;
using Managing.Domain.Candles;
using Managing.Domain.MoneyManagements;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@@ -122,7 +124,9 @@ public class BacktestController : ControllerBase
if (string.IsNullOrEmpty(moneyManagementName) && moneyManagement == null)
{
throw new ArgumentException($"'{nameof(moneyManagementName)}' and '{nameof(moneyManagement)}' cannot be null or empty.", nameof(moneyManagementName));
throw new ArgumentException(
$"'{nameof(moneyManagementName)}' and '{nameof(moneyManagement)}' cannot be null or empty.",
nameof(moneyManagementName));
}
if (days > 0)
@@ -146,19 +150,23 @@ public class BacktestController : ControllerBase
if (scenario == null)
return BadRequest("No scenario found");
var localCandles = FileHelpers
.ReadJson<List<Candle>>($"{ticker.ToString()}-{timeframe.ToString()}-candles.json")
.TakeLast(500).ToList();
switch (botType)
{
case BotType.SimpleBot:
break;
case BotType.ScalpingBot:
backtestResult = _backtester.RunScalpingBotBacktest(account, moneyManagement, ticker, scenario,
timeframe, Convert.ToDouble(days), balance, watchOnly, save);
timeframe, Convert.ToDouble(days), balance, watchOnly, save, initialCandles: localCandles);
break;
case BotType.FlippingBot:
backtestResult = _backtester.RunFlippingBotBacktest(account, moneyManagement, ticker, scenario,
timeframe, Convert.ToDouble(days), balance, watchOnly, save);
timeframe, Convert.ToDouble(days), balance, watchOnly, save, initialCandles: localCandles);
break;
}
}
await NotifyBacktesingSubscriberAsync(backtestResult);
@@ -171,7 +179,8 @@ public class BacktestController : ControllerBase
/// <param name="backtesting">The backtest result to notify subscribers about.</param>
private async Task NotifyBacktesingSubscriberAsync(Backtest backtesting)
{
if(backtesting != null){
if (backtesting != null)
{
await _hubContext.Clients.All.SendAsync("BacktestsSubscription", backtesting);
}
}

View File

@@ -1,6 +1,6 @@
using Managing.Api.Models.Requests;
using Managing.Api.Models.Responses;
using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Services;
using Managing.Application.Hubs;
using Managing.Application.ManageBot.Commands;
using MediatR;
@@ -33,7 +33,8 @@ public class BotController : ControllerBase
/// <param name="mediator">Mediator for handling commands and requests.</param>
/// <param name="hubContext">SignalR hub context for real-time communication.</param>
/// <param name="backtester">Backtester for running backtests on bots.</param>
public BotController(ILogger<BotController> logger, IMediator mediator, IHubContext<BotHub> hubContext, IBacktester backtester)
public BotController(ILogger<BotController> logger, IMediator mediator, IHubContext<BotHub> hubContext,
IBacktester backtester)
{
_logger = logger;
_mediator = mediator;
@@ -50,8 +51,9 @@ public class BotController : ControllerBase
[Route("Start")]
public async Task<ActionResult<string>> Start(StartBotRequest request)
{
var result = await _mediator.Send(new StartBotCommand(request.BotType, request.BotName, request.Ticker,
request.Scenario, request.Timeframe, request.AccountName, request.MoneyManagementName, request.IsForWatchOnly));
var result = await _mediator.Send(new StartBotCommand(request.BotType, request.BotName, request.Ticker,
request.Scenario, request.Timeframe, request.AccountName, request.MoneyManagementName,
request.IsForWatchOnly));
await NotifyBotSubscriberAsync();
return Ok(result);

View File

@@ -3,6 +3,7 @@ using Managing.Application.Abstractions.Services;
using Managing.Application.Hubs;
using Managing.Application.Workers.Abstractions;
using Managing.Domain.Candles;
using Managing.Domain.Statistics;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
@@ -58,10 +59,8 @@ public class DataController : ControllerBase
{
var account = await _accountService.GetAccount(accountName, true, false);
var cacheKey = string.Concat(accountName, timeframe.ToString());
var tickers = _cacheService.GetOrSave(cacheKey, () =>
{
return _exchangeService.GetTickers(account, timeframe).Result;
}, TimeSpan.FromHours(2));
var tickers = _cacheService.GetOrSave(cacheKey,
() => { return _exchangeService.GetTickers(account, timeframe).Result; }, TimeSpan.FromHours(2));
return Ok(tickers);
}
@@ -73,10 +72,8 @@ public class DataController : ControllerBase
[HttpGet("Spotlight")]
public ActionResult<SpotlightOverview> GetSpotlight()
{
var overview = _cacheService.GetOrSave(nameof(SpotlightOverview), () =>
{
return _statisticService.GetLastSpotlight(DateTime.Now.AddHours(-3));
}, TimeSpan.FromMinutes(2));
var overview = _cacheService.GetOrSave(nameof(SpotlightOverview),
() => { return _statisticService.GetLastSpotlight(DateTime.Now.AddHours(-3)); }, TimeSpan.FromMinutes(2));
if (overview?.Spotlights.Count < overview?.ScenarioCount)
{
@@ -95,7 +92,8 @@ public class DataController : ControllerBase
/// <param name="timeframe">The timeframe for the candle data.</param>
/// <returns>A list of <see cref="Candle"/> objects.</returns>
[HttpGet("GetCandles")]
public async Task<ActionResult<List<Candle>>> GetCandles(TradingExchanges exchange, Ticker ticker, DateTime startDate, Timeframe timeframe)
public async Task<ActionResult<List<Candle>>> GetCandles(TradingExchanges exchange, Ticker ticker,
DateTime startDate, Timeframe timeframe)
{
return Ok(await _exchangeService.GetCandlesInflux(exchange, ticker, startDate, timeframe));
}

View File

@@ -8,21 +8,25 @@ using Managing.Application.Hubs;
using Managing.Bootstrap;
using Managing.Common;
using Managing.Infrastructure.Databases.InfluxDb.Models;
using Managing.Infrastructure.Databases.MongoDb;
using Managing.Infrastructure.Databases.MongoDb.Configurations;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using NSwag;
using NSwag.Generation.Processors.Security;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.Elasticsearch;
using OpenApiSecurityRequirement = Microsoft.OpenApi.Models.OpenApiSecurityRequirement;
using OpenApiSecurityScheme = NSwag.OpenApiSecurityScheme;
// Builder
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.SetBasePath(System.AppContext.BaseDirectory);
builder.Configuration.SetBasePath(AppContext.BaseDirectory);
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json")
.AddJsonFile($"config.{builder.Environment.EnvironmentName}.json",
optional: true, reloadOnChange: true);
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json")
.AddJsonFile($"config.{builder.Environment.EnvironmentName}.json",
optional: true, reloadOnChange: true);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddUserSecrets<Program>();
@@ -41,7 +45,7 @@ builder.Host.UseSerilog((hostBuilder, loggerConfiguration) =>
AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
TypeName = null,
BatchAction = ElasticOpType.Create,
MinimumLogEventLevel = Serilog.Events.LogEventLevel.Information,
MinimumLogEventLevel = LogEventLevel.Information,
DetectElasticsearchVersion = true,
RegisterTemplateFailure = RegisterTemplateRecovery.IndexAnyway,
};
@@ -65,7 +69,7 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJw
ValidIssuer = builder.Configuration["Authentication:Schemes:Bearer:ValidIssuer"],
ValidAudience = builder.Configuration["Authentication:Schemes:Bearer:ValidAudiences"],
IssuerSigningKey = new SymmetricSecurityKey
(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Secret"])),
(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Secret"])),
ValidateIssuer = false,
ValidateAudience = false,
ValidateIssuerSigningKey = true
@@ -75,12 +79,12 @@ builder.Services.AddAuthorization();
builder.Services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
builder
.SetIsOriginAllowed((host) => true)
.AllowAnyOrigin()
.WithOrigins("http://localhost:3000/")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
.SetIsOriginAllowed((host) => true)
.AllowAnyOrigin()
.WithOrigins("http://localhost:3000/")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
}));
builder.Services.AddSignalR().AddJsonProtocol();
@@ -108,20 +112,23 @@ builder.Services.AddSwaggerGen(options =>
{
Description = "Please insert your JWT Token into field : Bearer {your_token}",
Name = "Authorization",
Type = Microsoft.OpenApi.Models.SecuritySchemeType.Http,
In = Microsoft.OpenApi.Models.ParameterLocation.Header,
Type = SecuritySchemeType.Http,
In = ParameterLocation.Header,
Scheme = "Bearer",
BearerFormat = "JWT"
});
options.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement{
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new Microsoft.OpenApi.Models.OpenApiSecurityScheme{
Reference = new Microsoft.OpenApi.Models.OpenApiReference{
Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
new Microsoft.OpenApi.Models.OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[]{}
new string[] { }
}
});
});
@@ -167,4 +174,4 @@ app.UseEndpoints(endpoints =>
endpoints.MapHub<CandleHub>("/candlehub");
});
app.Run();
app.Run();