Balance for bot (#20)

* Add bot balance

* Update amount to trade

* fix initial trading balance

* Update MM modal

* fix backtest

* stop bot if no more balance

* Add constant for minimum trading

* Add constant
This commit is contained in:
Oda
2025-04-28 16:52:42 +02:00
committed by GitHub
parent 967e8410dc
commit 204bd87e6a
39 changed files with 600 additions and 546 deletions

View File

@@ -134,7 +134,6 @@ public static class TradingBox
moneyManagement.StopLoss = stoplossPercentage.Average();
moneyManagement.TakeProfit = takeProfitsPercentage.Average();
moneyManagement.BalanceAtRisk = originMoneyManagement.BalanceAtRisk * 100;
moneyManagement.Timeframe = originMoneyManagement.Timeframe;
moneyManagement.Leverage = originMoneyManagement.Leverage;
moneyManagement.Name = "Optimized";
@@ -196,32 +195,32 @@ public static class TradingBox
public static decimal GetTotalVolumeTraded(List<Position> positions)
{
decimal totalVolume = 0;
foreach (var position in positions)
{
// Add entry volume
totalVolume += position.Open.Quantity * position.Open.Price;
// Add exit volumes from stop loss or take profits if they were executed
if (position.StopLoss.Status == TradeStatus.Filled)
{
totalVolume += position.StopLoss.Quantity * position.StopLoss.Price;
}
if (position.TakeProfit1.Status == TradeStatus.Filled)
{
totalVolume += position.TakeProfit1.Quantity * position.TakeProfit1.Price;
}
if (position.TakeProfit2 != null && position.TakeProfit2.Status == TradeStatus.Filled)
{
totalVolume += position.TakeProfit2.Quantity * position.TakeProfit2.Price;
}
}
return totalVolume;
}
/// <summary>
/// Calculates the volume traded in the last 24 hours
/// </summary>
@@ -231,38 +230,38 @@ public static class TradingBox
{
decimal last24hVolume = 0;
DateTime cutoff = DateTime.UtcNow.AddHours(-24);
foreach (var position in positions)
{
// Check if any part of this position was traded in the last 24 hours
// Add entry volume if it was within the last 24 hours
if (position.Open.Date >= cutoff)
{
last24hVolume += position.Open.Quantity * position.Open.Price;
}
// Add exit volumes if they were executed within the last 24 hours
if (position.StopLoss.Status == TradeStatus.Filled && position.StopLoss.Date >= cutoff)
{
last24hVolume += position.StopLoss.Quantity * position.StopLoss.Price;
}
if (position.TakeProfit1.Status == TradeStatus.Filled && position.TakeProfit1.Date >= cutoff)
{
last24hVolume += position.TakeProfit1.Quantity * position.TakeProfit1.Price;
}
if (position.TakeProfit2 != null && position.TakeProfit2.Status == TradeStatus.Filled &&
if (position.TakeProfit2 != null && position.TakeProfit2.Status == TradeStatus.Filled &&
position.TakeProfit2.Date >= cutoff)
{
last24hVolume += position.TakeProfit2.Quantity * position.TakeProfit2.Price;
}
}
return last24hVolume;
}
/// <summary>
/// Gets the win/loss counts from positions
/// </summary>
@@ -272,7 +271,7 @@ public static class TradingBox
{
int wins = 0;
int losses = 0;
foreach (var position in positions)
{
// Only count finished positions
@@ -288,10 +287,10 @@ public static class TradingBox
}
}
}
return (wins, losses);
}
/// <summary>
/// Calculates the ROI for the last 24 hours
/// </summary>
@@ -302,25 +301,26 @@ public static class TradingBox
decimal profitLast24h = 0;
decimal investmentLast24h = 0;
DateTime cutoff = DateTime.UtcNow.AddHours(-24);
foreach (var position in positions)
{
// Only count positions that were opened or closed within the last 24 hours
if (position.IsFinished() &&
(position.Open.Date >= cutoff ||
(position.StopLoss.Status == TradeStatus.Filled && position.StopLoss.Date >= cutoff) ||
if (position.IsFinished() &&
(position.Open.Date >= cutoff ||
(position.StopLoss.Status == TradeStatus.Filled && position.StopLoss.Date >= cutoff) ||
(position.TakeProfit1.Status == TradeStatus.Filled && position.TakeProfit1.Date >= cutoff) ||
(position.TakeProfit2 != null && position.TakeProfit2.Status == TradeStatus.Filled && position.TakeProfit2.Date >= cutoff)))
(position.TakeProfit2 != null && position.TakeProfit2.Status == TradeStatus.Filled &&
position.TakeProfit2.Date >= cutoff)))
{
profitLast24h += position.ProfitAndLoss != null ? position.ProfitAndLoss.Realized : 0;
investmentLast24h += position.Open.Quantity * position.Open.Price;
}
}
// Avoid division by zero
if (investmentLast24h == 0)
return 0;
return (profitLast24h / investmentLast24h) * 100;
}
@@ -339,10 +339,10 @@ public static class TradingBox
.Where(p => p.IsFinished() && p.ProfitAndLoss != null)
.Sum(p => p.ProfitAndLoss.Realized);
}
// Convert time filter to a DateTime
DateTime cutoffDate = DateTime.UtcNow;
switch (timeFilter)
{
case "24H":
@@ -361,17 +361,18 @@ public static class TradingBox
cutoffDate = DateTime.UtcNow.AddYears(-1);
break;
}
// Include positions that were closed within the time range
return positions
.Where(p => p.IsFinished() && p.ProfitAndLoss != null &&
(p.Date >= cutoffDate ||
(p.StopLoss.Status == TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
(p.TakeProfit1.Status == TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
(p.TakeProfit2 != null && p.TakeProfit2.Status == TradeStatus.Filled && p.TakeProfit2.Date >= cutoffDate)))
(p.Date >= cutoffDate ||
(p.StopLoss.Status == TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
(p.TakeProfit1.Status == TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
(p.TakeProfit2 != null && p.TakeProfit2.Status == TradeStatus.Filled &&
p.TakeProfit2.Date >= cutoffDate)))
.Sum(p => p.ProfitAndLoss.Realized);
}
/// <summary>
/// Calculates ROI for positions within a specific time range
/// </summary>
@@ -385,10 +386,10 @@ public static class TradingBox
{
return 0;
}
// Convert time filter to a DateTime
DateTime cutoffDate = DateTime.UtcNow;
if (timeFilter != "Total")
{
switch (timeFilter)
@@ -410,29 +411,30 @@ public static class TradingBox
break;
}
}
// Filter positions in the time range
var filteredPositions = timeFilter == "Total"
var filteredPositions = timeFilter == "Total"
? positions.Where(p => p.IsFinished() && p.ProfitAndLoss != null)
: positions.Where(p => p.IsFinished() && p.ProfitAndLoss != null &&
(p.Date >= cutoffDate ||
(p.StopLoss.Status == TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
(p.TakeProfit1.Status == TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
(p.TakeProfit2 != null && p.TakeProfit2.Status == TradeStatus.Filled && p.TakeProfit2.Date >= cutoffDate)));
(p.Date >= cutoffDate ||
(p.StopLoss.Status == TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
(p.TakeProfit1.Status == TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
(p.TakeProfit2 != null && p.TakeProfit2.Status == TradeStatus.Filled &&
p.TakeProfit2.Date >= cutoffDate)));
// Calculate investment and profit
decimal totalInvestment = filteredPositions.Sum(p => p.Open.Quantity * p.Open.Price);
decimal totalProfit = filteredPositions.Sum(p => p.ProfitAndLoss.Realized);
// Calculate ROI
if (totalInvestment == 0)
{
return 0;
}
return (totalProfit / totalInvestment) * 100;
}
/// <summary>
/// Gets the win/loss counts from positions in a specific time range
/// </summary>
@@ -443,7 +445,7 @@ public static class TradingBox
{
// Convert time filter to a DateTime
DateTime cutoffDate = DateTime.UtcNow;
if (timeFilter != "Total")
{
switch (timeFilter)
@@ -465,19 +467,20 @@ public static class TradingBox
break;
}
}
// Filter positions in the time range
var filteredPositions = timeFilter == "Total"
var filteredPositions = timeFilter == "Total"
? positions.Where(p => p.IsFinished())
: positions.Where(p => p.IsFinished() &&
(p.Date >= cutoffDate ||
(p.StopLoss.Status == TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
(p.TakeProfit1.Status == TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
(p.TakeProfit2 != null && p.TakeProfit2.Status == TradeStatus.Filled && p.TakeProfit2.Date >= cutoffDate)));
(p.Date >= cutoffDate ||
(p.StopLoss.Status == TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
(p.TakeProfit1.Status == TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
(p.TakeProfit2 != null && p.TakeProfit2.Status == TradeStatus.Filled &&
p.TakeProfit2.Date >= cutoffDate)));
int wins = 0;
int losses = 0;
foreach (var position in filteredPositions)
{
if (position.ProfitAndLoss != null && position.ProfitAndLoss.Realized > 0)
@@ -489,7 +492,7 @@ public static class TradingBox
losses++;
}
}
return (wins, losses);
}
}