Refactor user settings management to remove IsGmxEnabled and DefaultExchange from updatable fields, introducing GmxSlippage instead. Update UserController, UserService, and related DTOs to reflect these changes, ensuring proper handling of user settings. Adjust database schema and migrations to accommodate the new GmxSlippage property, enhancing user customization options for trading configurations.
This commit is contained in:
@@ -157,6 +157,7 @@ public class UserController : BaseController
|
|||||||
{
|
{
|
||||||
var user = await GetUser();
|
var user = await GetUser();
|
||||||
// Map API request to DTO
|
// Map API request to DTO
|
||||||
|
// Note: IsGmxEnabled and DefaultExchange are not updatable via settings endpoint
|
||||||
var settingsDto = new Managing.Application.Abstractions.Models.UserSettingsDto
|
var settingsDto = new Managing.Application.Abstractions.Models.UserSettingsDto
|
||||||
{
|
{
|
||||||
LowEthAmountAlert = settings.LowEthAmountAlert,
|
LowEthAmountAlert = settings.LowEthAmountAlert,
|
||||||
@@ -164,12 +165,11 @@ public class UserController : BaseController
|
|||||||
AutoswapAmount = settings.AutoswapAmount,
|
AutoswapAmount = settings.AutoswapAmount,
|
||||||
MaxWaitingTimeForPositionToGetFilledSeconds = settings.MaxWaitingTimeForPositionToGetFilledSeconds,
|
MaxWaitingTimeForPositionToGetFilledSeconds = settings.MaxWaitingTimeForPositionToGetFilledSeconds,
|
||||||
MaxTxnGasFeePerPosition = settings.MaxTxnGasFeePerPosition,
|
MaxTxnGasFeePerPosition = settings.MaxTxnGasFeePerPosition,
|
||||||
IsGmxEnabled = settings.IsGmxEnabled,
|
GmxSlippage = settings.GmxSlippage,
|
||||||
MinimumConfidence = settings.MinimumConfidence,
|
MinimumConfidence = settings.MinimumConfidence,
|
||||||
TrendStrongAgreementThreshold = settings.TrendStrongAgreementThreshold,
|
TrendStrongAgreementThreshold = settings.TrendStrongAgreementThreshold,
|
||||||
SignalAgreementThreshold = settings.SignalAgreementThreshold,
|
SignalAgreementThreshold = settings.SignalAgreementThreshold,
|
||||||
AllowSignalTrendOverride = settings.AllowSignalTrendOverride,
|
AllowSignalTrendOverride = settings.AllowSignalTrendOverride
|
||||||
DefaultExchange = settings.DefaultExchange
|
|
||||||
};
|
};
|
||||||
var updatedUser = await _userService.UpdateUserSettings(user, settingsDto);
|
var updatedUser = await _userService.UpdateUserSettings(user, settingsDto);
|
||||||
return Ok(updatedUser);
|
return Ok(updatedUser);
|
||||||
|
|||||||
@@ -11,13 +11,14 @@ public class UpdateUserSettingsRequest
|
|||||||
public decimal? AutoswapAmount { get; set; }
|
public decimal? AutoswapAmount { get; set; }
|
||||||
public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; }
|
public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; }
|
||||||
public decimal? MaxTxnGasFeePerPosition { get; set; }
|
public decimal? MaxTxnGasFeePerPosition { get; set; }
|
||||||
public bool? IsGmxEnabled { get; set; }
|
// Note: IsGmxEnabled is not updatable via settings endpoint
|
||||||
|
public decimal? GmxSlippage { get; set; }
|
||||||
|
|
||||||
// Indicator Combo Configuration
|
// Indicator Combo Configuration
|
||||||
public Confidence? MinimumConfidence { get; set; }
|
public Confidence? MinimumConfidence { get; set; }
|
||||||
public decimal? TrendStrongAgreementThreshold { get; set; }
|
public decimal? TrendStrongAgreementThreshold { get; set; }
|
||||||
public decimal? SignalAgreementThreshold { get; set; }
|
public decimal? SignalAgreementThreshold { get; set; }
|
||||||
public bool? AllowSignalTrendOverride { get; set; }
|
public bool? AllowSignalTrendOverride { get; set; }
|
||||||
public TradingExchanges? DefaultExchange { get; set; }
|
// Note: DefaultExchange is not updatable via settings endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,14 @@ public class UserSettingsDto
|
|||||||
public decimal? AutoswapAmount { get; set; }
|
public decimal? AutoswapAmount { get; set; }
|
||||||
public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; }
|
public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; }
|
||||||
public decimal? MaxTxnGasFeePerPosition { get; set; }
|
public decimal? MaxTxnGasFeePerPosition { get; set; }
|
||||||
public bool? IsGmxEnabled { get; set; }
|
// Note: IsGmxEnabled is not updatable via settings endpoint
|
||||||
|
public decimal? GmxSlippage { get; set; }
|
||||||
|
|
||||||
// Indicator Combo Configuration
|
// Indicator Combo Configuration
|
||||||
public Confidence? MinimumConfidence { get; set; }
|
public Confidence? MinimumConfidence { get; set; }
|
||||||
public decimal? TrendStrongAgreementThreshold { get; set; }
|
public decimal? TrendStrongAgreementThreshold { get; set; }
|
||||||
public decimal? SignalAgreementThreshold { get; set; }
|
public decimal? SignalAgreementThreshold { get; set; }
|
||||||
public bool? AllowSignalTrendOverride { get; set; }
|
public bool? AllowSignalTrendOverride { get; set; }
|
||||||
public TradingExchanges? DefaultExchange { get; set; }
|
// Note: DefaultExchange is not updatable via settings endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ public interface IEvmManager
|
|||||||
Task<Trade> IncreasePosition(Account account, Ticker ticker, TradeDirection direction, decimal price,
|
Task<Trade> IncreasePosition(Account account, Ticker ticker, TradeDirection direction, decimal price,
|
||||||
decimal quantity, decimal? leverage = 1,
|
decimal quantity, decimal? leverage = 1,
|
||||||
decimal? stopLossPrice = null,
|
decimal? stopLossPrice = null,
|
||||||
decimal? takeProfitPrice = null);
|
decimal? takeProfitPrice = null,
|
||||||
|
decimal? allowedSlippage = null);
|
||||||
|
|
||||||
Task<Trade> GetTrade(Account account, string chainName, Ticker ticker);
|
Task<Trade> GetTrade(Account account, string chainName, Ticker ticker);
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ public interface IExchangeService
|
|||||||
DateTime? currentDate = null,
|
DateTime? currentDate = null,
|
||||||
bool ioc = true,
|
bool ioc = true,
|
||||||
decimal? stopLossPrice = null,
|
decimal? stopLossPrice = null,
|
||||||
decimal? takeProfitPrice = null);
|
decimal? takeProfitPrice = null,
|
||||||
|
decimal? allowedSlippage = null);
|
||||||
|
|
||||||
Task<decimal> GetBalance(Account account, bool isForPaperTrading = false);
|
Task<decimal> GetBalance(Account account, bool isForPaperTrading = false);
|
||||||
Task<Balance?> GetBalance(Account account, Ticker ticker);
|
Task<Balance?> GetBalance(Account account, Ticker ticker);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public interface ITradingService
|
|||||||
Task<Scenario?> GetScenarioByNameUserAsync(string scenarioName, User user);
|
Task<Scenario?> GetScenarioByNameUserAsync(string scenarioName, User user);
|
||||||
Task<IEnumerable<Position>> GetPositionByUserIdAsync(int userId);
|
Task<IEnumerable<Position>> GetPositionByUserIdAsync(int userId);
|
||||||
Task<SwapInfos> SwapGmxTokensAsync(User user, string accountName, Ticker fromTicker, Ticker toTicker,
|
Task<SwapInfos> SwapGmxTokensAsync(User user, string accountName, Ticker fromTicker, Ticker toTicker,
|
||||||
double amount, string orderType = "market", double? triggerRatio = null, double allowedSlippage = 0.5);
|
double amount, string orderType = "market", double? triggerRatio = null, double? allowedSlippage = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates indicator values and generates signals for a given ticker, timeframe, and date range with selected indicators.
|
/// Calculates indicator values and generates signals for a given ticker, timeframe, and date range with selected indicators.
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ namespace Managing.Application.Trading.Handlers
|
|||||||
var stopLossPrice = RiskHelpers.GetStopLossPrice(request.Direction, openPrice, request.MoneyManagement);
|
var stopLossPrice = RiskHelpers.GetStopLossPrice(request.Direction, openPrice, request.MoneyManagement);
|
||||||
var takeProfitPrice = RiskHelpers.GetTakeProfitPrice(request.Direction, openPrice, request.MoneyManagement);
|
var takeProfitPrice = RiskHelpers.GetTakeProfitPrice(request.Direction, openPrice, request.MoneyManagement);
|
||||||
|
|
||||||
|
// Get user's slippage setting from IndicatorComboConfig
|
||||||
|
var config = TradingBox.CreateConfigFromUserSettings(request.User);
|
||||||
|
var allowedSlippage = request.User.GmxSlippage ?? config.GmxSlippage;
|
||||||
|
|
||||||
var trade = await exchangeService.OpenTrade(
|
var trade = await exchangeService.OpenTrade(
|
||||||
account,
|
account,
|
||||||
request.Ticker,
|
request.Ticker,
|
||||||
@@ -84,7 +88,8 @@ namespace Managing.Application.Trading.Handlers
|
|||||||
isForPaperTrading: request.IsForPaperTrading,
|
isForPaperTrading: request.IsForPaperTrading,
|
||||||
currentDate: request.Date,
|
currentDate: request.Date,
|
||||||
stopLossPrice: stopLossPrice,
|
stopLossPrice: stopLossPrice,
|
||||||
takeProfitPrice: takeProfitPrice);
|
takeProfitPrice: takeProfitPrice,
|
||||||
|
allowedSlippage: allowedSlippage);
|
||||||
|
|
||||||
position.Open = trade;
|
position.Open = trade;
|
||||||
|
|
||||||
|
|||||||
@@ -455,7 +455,7 @@ public class TradingService : ITradingService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SwapInfos> SwapGmxTokensAsync(User user, string accountName, Ticker fromTicker, Ticker toTicker,
|
public async Task<SwapInfos> SwapGmxTokensAsync(User user, string accountName, Ticker fromTicker, Ticker toTicker,
|
||||||
double amount, string orderType = "market", double? triggerRatio = null, double allowedSlippage = 0.5)
|
double amount, string orderType = "market", double? triggerRatio = null, double? allowedSlippage = null)
|
||||||
{
|
{
|
||||||
// Get the account for the user
|
// Get the account for the user
|
||||||
var account = await _accountService.GetAccountByUser(user, accountName, true, false);
|
var account = await _accountService.GetAccountByUser(user, accountName, true, false);
|
||||||
@@ -473,6 +473,14 @@ public class TradingService : ITradingService
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Get user's config to access default slippage value
|
||||||
|
var config = TradingBox.CreateConfigFromUserSettings(user);
|
||||||
|
|
||||||
|
// Use provided allowedSlippage if specified, otherwise use user's GmxSlippage setting, or default from IndicatorComboConfig
|
||||||
|
var slippageToUse = (double)(allowedSlippage.HasValue
|
||||||
|
? (decimal)allowedSlippage.Value
|
||||||
|
: (user.GmxSlippage ?? config.GmxSlippage));
|
||||||
|
|
||||||
// Call the Web3ProxyService to swap GMX tokens
|
// Call the Web3ProxyService to swap GMX tokens
|
||||||
var swapInfos = await _web3ProxyService.SwapGmxTokensAsync(
|
var swapInfos = await _web3ProxyService.SwapGmxTokensAsync(
|
||||||
account.Key,
|
account.Key,
|
||||||
@@ -481,7 +489,7 @@ public class TradingService : ITradingService
|
|||||||
amount,
|
amount,
|
||||||
orderType,
|
orderType,
|
||||||
triggerRatio,
|
triggerRatio,
|
||||||
allowedSlippage
|
slippageToUse
|
||||||
);
|
);
|
||||||
|
|
||||||
return swapInfos;
|
return swapInfos;
|
||||||
|
|||||||
@@ -359,8 +359,10 @@ public class UserService : IUserService
|
|||||||
if (settings.MaxTxnGasFeePerPosition.HasValue)
|
if (settings.MaxTxnGasFeePerPosition.HasValue)
|
||||||
user.MaxTxnGasFeePerPosition = settings.MaxTxnGasFeePerPosition.Value;
|
user.MaxTxnGasFeePerPosition = settings.MaxTxnGasFeePerPosition.Value;
|
||||||
|
|
||||||
if (settings.IsGmxEnabled.HasValue)
|
// Note: IsGmxEnabled is not updatable via settings endpoint - managed internally
|
||||||
user.IsGmxEnabled = settings.IsGmxEnabled.Value;
|
|
||||||
|
if (settings.GmxSlippage.HasValue)
|
||||||
|
user.GmxSlippage = settings.GmxSlippage.Value;
|
||||||
|
|
||||||
if (settings.MinimumConfidence.HasValue)
|
if (settings.MinimumConfidence.HasValue)
|
||||||
user.MinimumConfidence = settings.MinimumConfidence.Value;
|
user.MinimumConfidence = settings.MinimumConfidence.Value;
|
||||||
@@ -374,8 +376,7 @@ public class UserService : IUserService
|
|||||||
if (settings.AllowSignalTrendOverride.HasValue)
|
if (settings.AllowSignalTrendOverride.HasValue)
|
||||||
user.AllowSignalTrendOverride = settings.AllowSignalTrendOverride.Value;
|
user.AllowSignalTrendOverride = settings.AllowSignalTrendOverride.Value;
|
||||||
|
|
||||||
if (settings.DefaultExchange.HasValue)
|
// Note: DefaultExchange is not updatable via settings endpoint - managed internally
|
||||||
user.DefaultExchange = settings.DefaultExchange.Value;
|
|
||||||
|
|
||||||
await _userRepository.SaveOrUpdateUserAsync(user);
|
await _userRepository.SaveOrUpdateUserAsync(user);
|
||||||
return user;
|
return user;
|
||||||
|
|||||||
@@ -58,6 +58,12 @@ public class IndicatorComboConfig
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Id(5)]
|
[Id(5)]
|
||||||
public TradingExchanges DefaultExchange { get; set; } = TradingExchanges.GmxV2;
|
public TradingExchanges DefaultExchange { get; set; } = TradingExchanges.GmxV2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GMX slippage tolerance percentage for trades (default: 0.5%)
|
||||||
|
/// </summary>
|
||||||
|
[Id(6)]
|
||||||
|
public decimal GmxSlippage { get; set; } = 0.5m;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TradingBox
|
public static class TradingBox
|
||||||
@@ -80,6 +86,8 @@ public static class TradingBox
|
|||||||
config.AllowSignalTrendOverride = user.AllowSignalTrendOverride ?? true;
|
config.AllowSignalTrendOverride = user.AllowSignalTrendOverride ?? true;
|
||||||
// DefaultExchange defaults to GMX if not set
|
// DefaultExchange defaults to GMX if not set
|
||||||
config.DefaultExchange = user.DefaultExchange ?? TradingExchanges.GmxV2;
|
config.DefaultExchange = user.DefaultExchange ?? TradingExchanges.GmxV2;
|
||||||
|
// GmxSlippage defaults to 0.5% if not set
|
||||||
|
config.GmxSlippage = user.GmxSlippage ?? 0.5m;
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public class User
|
|||||||
[Id(12)] public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; }
|
[Id(12)] public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; }
|
||||||
[Id(13)] public decimal? MaxTxnGasFeePerPosition { get; set; }
|
[Id(13)] public decimal? MaxTxnGasFeePerPosition { get; set; }
|
||||||
[Id(14)] public bool IsGmxEnabled { get; set; } = false;
|
[Id(14)] public bool IsGmxEnabled { get; set; } = false;
|
||||||
|
[Id(20)] public decimal? GmxSlippage { get; set; }
|
||||||
|
|
||||||
// User Settings - Indicator Combo Configuration
|
// User Settings - Indicator Combo Configuration
|
||||||
[Id(15)] public Confidence? MinimumConfidence { get; set; }
|
[Id(15)] public Confidence? MinimumConfidence { get; set; }
|
||||||
|
|||||||
1788
src/Managing.Infrastructure.Database/Migrations/20251230000830_AddGmxSlippageSetting.Designer.cs
generated
Normal file
1788
src/Managing.Infrastructure.Database/Migrations/20251230000830_AddGmxSlippageSetting.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Managing.Infrastructure.Databases.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddGmxSlippageSetting : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
// Add column with default value
|
||||||
|
migrationBuilder.AddColumn<decimal>(
|
||||||
|
name: "GmxSlippage",
|
||||||
|
table: "Users",
|
||||||
|
type: "numeric(5,2)",
|
||||||
|
nullable: true,
|
||||||
|
defaultValue: 0.5m);
|
||||||
|
|
||||||
|
// Update existing NULL values to default
|
||||||
|
migrationBuilder.Sql(@"
|
||||||
|
UPDATE ""Users""
|
||||||
|
SET ""GmxSlippage"" = 0.5
|
||||||
|
WHERE ""GmxSlippage"" IS NULL;
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "GmxSlippage",
|
||||||
|
table: "Users");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1441,6 +1441,9 @@ namespace Managing.Infrastructure.Databases.Migrations
|
|||||||
b.Property<bool>("EnableAutoswap")
|
b.Property<bool>("EnableAutoswap")
|
||||||
.HasColumnType("boolean");
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<decimal?>("GmxSlippage")
|
||||||
|
.HasColumnType("decimal(5,2)");
|
||||||
|
|
||||||
b.Property<bool>("IsAdmin")
|
b.Property<bool>("IsAdmin")
|
||||||
.HasColumnType("boolean");
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public class UserEntity
|
|||||||
public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; } = 600; // Default: 10 minutes (600 seconds)
|
public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; } = 600; // Default: 10 minutes (600 seconds)
|
||||||
[Column(TypeName = "decimal(18,8)")] public decimal? MaxTxnGasFeePerPosition { get; set; } = 1.5m; // Default: MaximumGasFeeUsd
|
[Column(TypeName = "decimal(18,8)")] public decimal? MaxTxnGasFeePerPosition { get; set; } = 1.5m; // Default: MaximumGasFeeUsd
|
||||||
public bool IsGmxEnabled { get; set; } = false;
|
public bool IsGmxEnabled { get; set; } = false;
|
||||||
|
[Column(TypeName = "decimal(5,2)")] public decimal? GmxSlippage { get; set; } = 0.5m; // Default: 0.5% slippage for GMX trades
|
||||||
|
|
||||||
// User Settings - Indicator Combo Configuration
|
// User Settings - Indicator Combo Configuration
|
||||||
public Confidence? MinimumConfidence { get; set; } = Confidence.Medium; // Default: Medium confidence for context indicators
|
public Confidence? MinimumConfidence { get; set; } = Confidence.Medium; // Default: Medium confidence for context indicators
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ public static class PostgreSqlMappers
|
|||||||
MaxWaitingTimeForPositionToGetFilledSeconds = entity.MaxWaitingTimeForPositionToGetFilledSeconds,
|
MaxWaitingTimeForPositionToGetFilledSeconds = entity.MaxWaitingTimeForPositionToGetFilledSeconds,
|
||||||
MaxTxnGasFeePerPosition = entity.MaxTxnGasFeePerPosition,
|
MaxTxnGasFeePerPosition = entity.MaxTxnGasFeePerPosition,
|
||||||
IsGmxEnabled = entity.IsGmxEnabled,
|
IsGmxEnabled = entity.IsGmxEnabled,
|
||||||
|
GmxSlippage = entity.GmxSlippage,
|
||||||
MinimumConfidence = entity.MinimumConfidence,
|
MinimumConfidence = entity.MinimumConfidence,
|
||||||
TrendStrongAgreementThreshold = entity.TrendStrongAgreementThreshold,
|
TrendStrongAgreementThreshold = entity.TrendStrongAgreementThreshold,
|
||||||
SignalAgreementThreshold = entity.SignalAgreementThreshold,
|
SignalAgreementThreshold = entity.SignalAgreementThreshold,
|
||||||
@@ -187,6 +188,7 @@ public static class PostgreSqlMappers
|
|||||||
MaxWaitingTimeForPositionToGetFilledSeconds = user.MaxWaitingTimeForPositionToGetFilledSeconds,
|
MaxWaitingTimeForPositionToGetFilledSeconds = user.MaxWaitingTimeForPositionToGetFilledSeconds,
|
||||||
MaxTxnGasFeePerPosition = user.MaxTxnGasFeePerPosition,
|
MaxTxnGasFeePerPosition = user.MaxTxnGasFeePerPosition,
|
||||||
IsGmxEnabled = user.IsGmxEnabled,
|
IsGmxEnabled = user.IsGmxEnabled,
|
||||||
|
GmxSlippage = user.GmxSlippage,
|
||||||
MinimumConfidence = user.MinimumConfidence,
|
MinimumConfidence = user.MinimumConfidence,
|
||||||
TrendStrongAgreementThreshold = user.TrendStrongAgreementThreshold,
|
TrendStrongAgreementThreshold = user.TrendStrongAgreementThreshold,
|
||||||
SignalAgreementThreshold = user.SignalAgreementThreshold,
|
SignalAgreementThreshold = user.SignalAgreementThreshold,
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
|
|||||||
existingUser.MaxWaitingTimeForPositionToGetFilledSeconds = user.MaxWaitingTimeForPositionToGetFilledSeconds;
|
existingUser.MaxWaitingTimeForPositionToGetFilledSeconds = user.MaxWaitingTimeForPositionToGetFilledSeconds;
|
||||||
existingUser.MaxTxnGasFeePerPosition = user.MaxTxnGasFeePerPosition;
|
existingUser.MaxTxnGasFeePerPosition = user.MaxTxnGasFeePerPosition;
|
||||||
existingUser.IsGmxEnabled = user.IsGmxEnabled;
|
existingUser.IsGmxEnabled = user.IsGmxEnabled;
|
||||||
|
existingUser.GmxSlippage = user.GmxSlippage;
|
||||||
existingUser.MinimumConfidence = user.MinimumConfidence;
|
existingUser.MinimumConfidence = user.MinimumConfidence;
|
||||||
existingUser.TrendStrongAgreementThreshold = user.TrendStrongAgreementThreshold;
|
existingUser.TrendStrongAgreementThreshold = user.TrendStrongAgreementThreshold;
|
||||||
existingUser.SignalAgreementThreshold = user.SignalAgreementThreshold;
|
existingUser.SignalAgreementThreshold = user.SignalAgreementThreshold;
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ public interface IExchangeProcessor
|
|||||||
DateTime? currentDate = null,
|
DateTime? currentDate = null,
|
||||||
bool ioc = true,
|
bool ioc = true,
|
||||||
decimal? stopLossPrice = null,
|
decimal? stopLossPrice = null,
|
||||||
decimal? takeProfitPrice = null);
|
decimal? takeProfitPrice = null,
|
||||||
|
decimal? allowedSlippage = null);
|
||||||
Task<decimal> GetBalance(Account account, bool isForPaperTrading = false);
|
Task<decimal> GetBalance(Account account, bool isForPaperTrading = false);
|
||||||
Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false);
|
Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false);
|
||||||
Task<decimal> GetPrice(Account account, Ticker ticker, DateTime date);
|
Task<decimal> GetPrice(Account account, Ticker ticker, DateTime date);
|
||||||
|
|||||||
@@ -46,10 +46,11 @@ namespace Managing.Infrastructure.Exchanges
|
|||||||
DateTime? currentDate = null,
|
DateTime? currentDate = null,
|
||||||
bool ioc = true,
|
bool ioc = true,
|
||||||
decimal? stopLossPrice = null,
|
decimal? stopLossPrice = null,
|
||||||
decimal? takeProfitPrice = null)
|
decimal? takeProfitPrice = null,
|
||||||
|
decimal? allowedSlippage = null)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(
|
_logger.LogDebug(
|
||||||
$"OpenMarketTrade - {ticker} - Type: {tradeType} - {direction} - Price: {price} - Quantity: {quantity} - Leverage: {leverage} - SL: {stopLossPrice} - TP: {takeProfitPrice}");
|
$"OpenMarketTrade - {ticker} - Type: {tradeType} - {direction} - Price: {price} - Quantity: {quantity} - Leverage: {leverage} - SL: {stopLossPrice} - TP: {takeProfitPrice} - Slippage: {allowedSlippage}");
|
||||||
|
|
||||||
if (isForPaperTrading)
|
if (isForPaperTrading)
|
||||||
{
|
{
|
||||||
@@ -60,7 +61,7 @@ namespace Managing.Infrastructure.Exchanges
|
|||||||
|
|
||||||
var processor = GetProcessor(account);
|
var processor = GetProcessor(account);
|
||||||
return await processor.OpenTrade(account, ticker, direction, price, quantity, leverage, tradeType,
|
return await processor.OpenTrade(account, ticker, direction, price, quantity, leverage, tradeType,
|
||||||
reduceOnly, isForPaperTrading, currentDate, ioc, stopLossPrice, takeProfitPrice);
|
reduceOnly, isForPaperTrading, currentDate, ioc, stopLossPrice, takeProfitPrice, allowedSlippage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IExchangeProcessor GetProcessor(Account account)
|
private IExchangeProcessor GetProcessor(Account account)
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ namespace Managing.Infrastructure.Exchanges.Exchanges
|
|||||||
DateTime? currentDate = null,
|
DateTime? currentDate = null,
|
||||||
bool ioc = true,
|
bool ioc = true,
|
||||||
decimal? stopLossPrice = null,
|
decimal? stopLossPrice = null,
|
||||||
decimal? takeProfitPrice = null);
|
decimal? takeProfitPrice = null,
|
||||||
|
decimal? allowedSlippage = null);
|
||||||
public abstract Orderbook GetOrderbook(Account account, Ticker ticker);
|
public abstract Orderbook GetOrderbook(Account account, Ticker ticker);
|
||||||
public abstract Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false);
|
public abstract Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false);
|
||||||
public abstract Task<List<Trade>> GetOrders(Account account, Ticker ticker);
|
public abstract Task<List<Trade>> GetOrders(Account account, Ticker ticker);
|
||||||
|
|||||||
@@ -174,7 +174,8 @@ public class EvmProcessor : BaseProcessor
|
|||||||
DateTime? currentDate = null,
|
DateTime? currentDate = null,
|
||||||
bool ioc = true,
|
bool ioc = true,
|
||||||
decimal? stopLossPrice = null,
|
decimal? stopLossPrice = null,
|
||||||
decimal? takeProfitPrice = null)
|
decimal? takeProfitPrice = null,
|
||||||
|
decimal? allowedSlippage = null)
|
||||||
{
|
{
|
||||||
Trade trade;
|
Trade trade;
|
||||||
if (reduceOnly)
|
if (reduceOnly)
|
||||||
@@ -197,7 +198,7 @@ public class EvmProcessor : BaseProcessor
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
trade = await _evmManager.IncreasePosition(account, ticker, direction, price, quantity, leverage,
|
trade = await _evmManager.IncreasePosition(account, ticker, direction, price, quantity, leverage,
|
||||||
stopLossPrice, takeProfitPrice);
|
stopLossPrice, takeProfitPrice, allowedSlippage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return trade;
|
return trade;
|
||||||
|
|||||||
@@ -641,7 +641,8 @@ public class EvmManager : IEvmManager
|
|||||||
decimal quantity,
|
decimal quantity,
|
||||||
decimal? leverage,
|
decimal? leverage,
|
||||||
decimal? stopLossPrice = null,
|
decimal? stopLossPrice = null,
|
||||||
decimal? takeProfitPrice = null)
|
decimal? takeProfitPrice = null,
|
||||||
|
decimal? allowedSlippage = null)
|
||||||
{
|
{
|
||||||
Trade trade = null;
|
Trade trade = null;
|
||||||
|
|
||||||
@@ -664,7 +665,8 @@ public class EvmManager : IEvmManager
|
|||||||
quantity,
|
quantity,
|
||||||
leverage = leverage ?? 1.0m,
|
leverage = leverage ?? 1.0m,
|
||||||
stopLossPrice = stopLossPrice,
|
stopLossPrice = stopLossPrice,
|
||||||
takeProfitPrice = takeProfitPrice
|
takeProfitPrice = takeProfitPrice,
|
||||||
|
allowedSlippage = allowedSlippage.HasValue ? (double)allowedSlippage.Value : (double?)null
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a trade object using the returned hash
|
// Create a trade object using the returned hash
|
||||||
|
|||||||
@@ -643,7 +643,8 @@ const openPositionSchema = z.object({
|
|||||||
direction: z.enum(Object.keys(TradeDirection) as [string, ...string[]]),
|
direction: z.enum(Object.keys(TradeDirection) as [string, ...string[]]),
|
||||||
price: z.number().positive().optional(),
|
price: z.number().positive().optional(),
|
||||||
quantity: z.number().positive(),
|
quantity: z.number().positive(),
|
||||||
leverage: z.number().positive()
|
leverage: z.number().positive(),
|
||||||
|
allowedSlippage: z.number().min(0).max(100).optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
// Schema for cancel-orders request
|
// Schema for cancel-orders request
|
||||||
@@ -774,7 +775,8 @@ export const openGmxPositionImpl = async (
|
|||||||
leverage: number,
|
leverage: number,
|
||||||
price?: number,
|
price?: number,
|
||||||
stopLossPrice?: number,
|
stopLossPrice?: number,
|
||||||
takeProfitPrice?: number
|
takeProfitPrice?: number,
|
||||||
|
allowedSlippage?: number
|
||||||
): Promise<string> => {
|
): Promise<string> => {
|
||||||
return executeWithFallback(
|
return executeWithFallback(
|
||||||
async (sdk, retryCount) => {
|
async (sdk, retryCount) => {
|
||||||
@@ -852,12 +854,18 @@ export const openGmxPositionImpl = async (
|
|||||||
const leverageBps = BigInt((leverage || 1) * 10000);
|
const leverageBps = BigInt((leverage || 1) * 10000);
|
||||||
const limitPrice = price ? numberToBigint(price, 30) : undefined;
|
const limitPrice = price ? numberToBigint(price, 30) : undefined;
|
||||||
|
|
||||||
|
// Use provided slippage or default to 0.5% (50 basis points)
|
||||||
|
// Convert percentage to basis points (e.g., 0.5% = 50 bps)
|
||||||
|
const slippageBps = allowedSlippage != null
|
||||||
|
? Math.floor(allowedSlippage * 100) // Convert percentage to basis points
|
||||||
|
: 50; // Default 0.5% = 50 basis points
|
||||||
|
|
||||||
const params: PositionIncreaseParams = {
|
const params: PositionIncreaseParams = {
|
||||||
payAmount: collateralAmount,
|
payAmount: collateralAmount,
|
||||||
marketAddress: marketInfo.marketTokenAddress,
|
marketAddress: marketInfo.marketTokenAddress,
|
||||||
payTokenAddress: collateralToken.address,
|
payTokenAddress: collateralToken.address,
|
||||||
collateralTokenAddress: collateralToken.address,
|
collateralTokenAddress: collateralToken.address,
|
||||||
allowedSlippageBps: 55, // 0.55% slippage
|
allowedSlippageBps: slippageBps,
|
||||||
leverage: leverageBps,
|
leverage: leverageBps,
|
||||||
skipSimulation: true,
|
skipSimulation: true,
|
||||||
referralCodeForTxn: encodeReferralCode("kaigen_ai"),
|
referralCodeForTxn: encodeReferralCode("kaigen_ai"),
|
||||||
@@ -971,7 +979,8 @@ export async function openGmxPosition(
|
|||||||
quantity?: number,
|
quantity?: number,
|
||||||
leverage?: number,
|
leverage?: number,
|
||||||
stopLossPrice?: number,
|
stopLossPrice?: number,
|
||||||
takeProfitPrice?: number
|
takeProfitPrice?: number,
|
||||||
|
allowedSlippage?: number
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
// Validate the request parameters
|
// Validate the request parameters
|
||||||
@@ -984,7 +993,8 @@ export async function openGmxPosition(
|
|||||||
quantity,
|
quantity,
|
||||||
leverage,
|
leverage,
|
||||||
stopLossPrice,
|
stopLossPrice,
|
||||||
takeProfitPrice
|
takeProfitPrice,
|
||||||
|
allowedSlippage
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get client for the address
|
// Get client for the address
|
||||||
@@ -999,7 +1009,8 @@ export async function openGmxPosition(
|
|||||||
leverage,
|
leverage,
|
||||||
price,
|
price,
|
||||||
stopLossPrice,
|
stopLossPrice,
|
||||||
takeProfitPrice
|
takeProfitPrice,
|
||||||
|
allowedSlippage
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user