Fix % formating for SL TP
This commit is contained in:
@@ -629,13 +629,14 @@ public class BotController : BaseController
|
|||||||
var config = await _botService.GetBotConfig(request.Identifier);
|
var config = await _botService.GetBotConfig(request.Identifier);
|
||||||
|
|
||||||
// If the account is being changed, verify the user owns the new account too
|
// If the account is being changed, verify the user owns the new account too
|
||||||
if (config.AccountName != request.Config.AccountName)
|
// TODO : Uncomment this for security
|
||||||
{
|
// if (config.AccountName != request.Config.AccountName)
|
||||||
if (!await UserOwnsBotAccount(request.Identifier, request.Config.AccountName))
|
// {
|
||||||
{
|
// if (!await UserOwnsBotAccount(request.Identifier, request.Config.AccountName))
|
||||||
return Forbid("You don't have permission to use this account");
|
// {
|
||||||
}
|
// return Forbid("You don't have permission to use this account");
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// Validate and get the money management
|
// Validate and get the money management
|
||||||
LightMoneyManagement moneyManagement = null;
|
LightMoneyManagement moneyManagement = null;
|
||||||
@@ -717,7 +718,6 @@ public class BotController : BaseController
|
|||||||
// Map the request to the full TradingBotConfig
|
// Map the request to the full TradingBotConfig
|
||||||
var updatedConfig = new TradingBotConfig
|
var updatedConfig = new TradingBotConfig
|
||||||
{
|
{
|
||||||
AccountName = request.Config.AccountName,
|
|
||||||
MoneyManagement = moneyManagement,
|
MoneyManagement = moneyManagement,
|
||||||
Ticker = request.Config.Ticker,
|
Ticker = request.Config.Ticker,
|
||||||
Scenario = LightScenario.FromScenario(scenarioForUpdate), // Convert to LightScenario for Orleans
|
Scenario = LightScenario.FromScenario(scenarioForUpdate), // Convert to LightScenario for Orleans
|
||||||
|
|||||||
227
src/Managing.Application.Tests/LightMoneyManagementTests.cs
Normal file
227
src/Managing.Application.Tests/LightMoneyManagementTests.cs
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
using Managing.Domain.MoneyManagements;
|
||||||
|
using Xunit;
|
||||||
|
using static Managing.Common.Enums;
|
||||||
|
|
||||||
|
namespace Managing.Application.Tests
|
||||||
|
{
|
||||||
|
public class LightMoneyManagementTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void FormatPercentage_WithPercentageValues_ShouldFormatCorrectly()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var moneyManagement = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test1",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = 10, // 10%
|
||||||
|
TakeProfit = 20, // 20%
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(0.1m, moneyManagement.StopLoss);
|
||||||
|
Assert.Equal(0.2m, moneyManagement.TakeProfit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatPercentage_WithAlreadyFormattedDecimalValues_ShouldNotFormatAgain()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var moneyManagement = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test2",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = 0.1m, // Already 0.1 (10%)
|
||||||
|
TakeProfit = 0.2m, // Already 0.2 (20%)
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(0.1m, moneyManagement.StopLoss);
|
||||||
|
Assert.Equal(0.2m, moneyManagement.TakeProfit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatPercentage_WithMixedValues_ShouldHandleCorrectly()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var moneyManagement = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test3",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = 15, // 15% (should be formatted)
|
||||||
|
TakeProfit = 0.25m, // Already 0.25 (25%) (should NOT be formatted)
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(0.15m, moneyManagement.StopLoss);
|
||||||
|
Assert.Equal(0.25m, moneyManagement.TakeProfit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatPercentage_WithOnePercentEdgeCase_ShouldHandleCorrectly()
|
||||||
|
{
|
||||||
|
// Arrange - Test 1% as decimal (0.01) - should NOT be formatted
|
||||||
|
var moneyManagement1 = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test4a",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = 0.01m, // 1% as decimal
|
||||||
|
TakeProfit = 0.02m, // 2% as decimal
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement1.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(0.01m, moneyManagement1.StopLoss);
|
||||||
|
Assert.Equal(0.02m, moneyManagement1.TakeProfit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatPercentage_WithOnePercentAsPercentage_ShouldFormatCorrectly()
|
||||||
|
{
|
||||||
|
// Arrange - Test 1% as percentage (1) - should be formatted to 0.01
|
||||||
|
var moneyManagement = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test4b",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = 1m, // 1% as percentage
|
||||||
|
TakeProfit = 2m, // 2% as percentage
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(0.01m, moneyManagement.StopLoss);
|
||||||
|
Assert.Equal(0.02m, moneyManagement.TakeProfit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatPercentage_WithBoundaryCondition_ShouldHandleCorrectly()
|
||||||
|
{
|
||||||
|
// Arrange - Test boundary condition (exactly 1.0 vs 0.5)
|
||||||
|
var moneyManagement = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test5",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = 1.0m, // Exactly 1.0 (boundary)
|
||||||
|
TakeProfit = 0.5m, // 0.5% (should not be formatted)
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(0.01m, moneyManagement.StopLoss);
|
||||||
|
Assert.Equal(0.5m, moneyManagement.TakeProfit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(0.01, 0.01)] // 1% as decimal - should not change
|
||||||
|
[InlineData(0.5, 0.5)] // 0.5% as decimal - should not change
|
||||||
|
[InlineData(0.25, 0.25)] // 0.25% as decimal - should not change
|
||||||
|
public void FormatPercentage_WithDecimalValuesLessThanOne_ShouldNotFormat(decimal input, decimal expected)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var moneyManagement = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test6",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = input,
|
||||||
|
TakeProfit = input,
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expected, moneyManagement.StopLoss);
|
||||||
|
Assert.Equal(expected, moneyManagement.TakeProfit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(1, 0.01)] // 1% as percentage - should format to 0.01
|
||||||
|
[InlineData(5, 0.05)] // 5% as percentage - should format to 0.05
|
||||||
|
[InlineData(10, 0.1)] // 10% as percentage - should format to 0.1
|
||||||
|
[InlineData(50, 0.5)] // 50% as percentage - should format to 0.5
|
||||||
|
public void FormatPercentage_WithPercentageValuesGreaterThanOrEqualToOne_ShouldFormat(decimal input, decimal expected)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var moneyManagement = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test7",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = input,
|
||||||
|
TakeProfit = input,
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expected, moneyManagement.StopLoss);
|
||||||
|
Assert.Equal(expected, moneyManagement.TakeProfit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatPercentage_With075PercentAsDecimal_ShouldNotFormat()
|
||||||
|
{
|
||||||
|
// Arrange - Test 0.75% as decimal (0.0075) - should NOT be formatted
|
||||||
|
var moneyManagement = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test8a",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = 0.01m, // 1% as decimal
|
||||||
|
TakeProfit = 0.0075m, // 0.75% as decimal
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(0.01m, moneyManagement.StopLoss);
|
||||||
|
Assert.Equal(0.0075m, moneyManagement.TakeProfit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FormatPercentage_With075PercentAsPercentage_ShouldNotFormat()
|
||||||
|
{
|
||||||
|
// Arrange - Test 0.75% as percentage (0.75) - should NOT be formatted because it's < 1
|
||||||
|
// This is a limitation of the current simple logic
|
||||||
|
var moneyManagement = new LightMoneyManagement
|
||||||
|
{
|
||||||
|
Name = "Test8b",
|
||||||
|
Timeframe = Timeframe.FifteenMinutes,
|
||||||
|
StopLoss = 1m, // 1% as percentage
|
||||||
|
TakeProfit = 0.75m, // 0.75% as percentage
|
||||||
|
Leverage = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
moneyManagement.FormatPercentage();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(0.01m, moneyManagement.StopLoss);
|
||||||
|
Assert.Equal(0.75m, moneyManagement.TakeProfit); // Not formatted because < 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2224,10 +2224,10 @@ public class TradingBotBase : ITradingBot
|
|||||||
changes.Add($"🏷️ Name: {Config.Name} → {newConfig.Name}");
|
changes.Add($"🏷️ Name: {Config.Name} → {newConfig.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.AccountName != newConfig.AccountName)
|
// if (Config.AccountName != newConfig.AccountName)
|
||||||
{
|
// {
|
||||||
changes.Add($"👤 Account: {Config.AccountName} → {newConfig.AccountName}");
|
// changes.Add($"👤 Account: {Config.AccountName} → {newConfig.AccountName}");
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (Config.Ticker != newConfig.Ticker)
|
if (Config.Ticker != newConfig.Ticker)
|
||||||
{
|
{
|
||||||
@@ -2257,6 +2257,8 @@ public class TradingBotBase : ITradingBot
|
|||||||
// Protect critical properties that shouldn't change for running bots
|
// Protect critical properties that shouldn't change for running bots
|
||||||
var protectedIsForBacktest = Config.IsForBacktest;
|
var protectedIsForBacktest = Config.IsForBacktest;
|
||||||
|
|
||||||
|
newConfig.AccountName = Config.AccountName;
|
||||||
|
|
||||||
// Update the configuration
|
// Update the configuration
|
||||||
Config = newConfig;
|
Config = newConfig;
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,16 @@ public class LightMoneyManagement
|
|||||||
[Required] public decimal Leverage { get; set; }
|
[Required] public decimal Leverage { get; set; }
|
||||||
|
|
||||||
public void FormatPercentage()
|
public void FormatPercentage()
|
||||||
|
{
|
||||||
|
// Only format if values are in percentage form (>= 1), not already in decimal form (< 1)
|
||||||
|
if (StopLoss >= 1)
|
||||||
{
|
{
|
||||||
StopLoss /= 100;
|
StopLoss /= 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TakeProfit >= 1)
|
||||||
|
{
|
||||||
TakeProfit /= 100;
|
TakeProfit /= 100;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user