Add ui fee into TradingBot.cs
This commit is contained in:
@@ -205,6 +205,7 @@ namespace Managing.Application.Backtesting
|
|||||||
var growthPercentage = TradingHelpers.GetGrowthFromInitalBalance(config.BotTradingBalance, finalPnl);
|
var growthPercentage = TradingHelpers.GetGrowthFromInitalBalance(config.BotTradingBalance, finalPnl);
|
||||||
var hodlPercentage = TradingHelpers.GetHodlPercentage(candles[0], candles.Last());
|
var hodlPercentage = TradingHelpers.GetHodlPercentage(candles[0], candles.Last());
|
||||||
|
|
||||||
|
var fees = bot.GetTotalFees();
|
||||||
var scoringParams = new BacktestScoringParams(
|
var scoringParams = new BacktestScoringParams(
|
||||||
sharpeRatio: (double)stats.SharpeRatio,
|
sharpeRatio: (double)stats.SharpeRatio,
|
||||||
maxDrawdownPc: (double)stats.MaxDrawdownPc,
|
maxDrawdownPc: (double)stats.MaxDrawdownPc,
|
||||||
@@ -212,7 +213,7 @@ namespace Managing.Application.Backtesting
|
|||||||
hodlPercentage: (double)hodlPercentage,
|
hodlPercentage: (double)hodlPercentage,
|
||||||
winRate: winRate,
|
winRate: winRate,
|
||||||
totalPnL: (double)finalPnl,
|
totalPnL: (double)finalPnl,
|
||||||
fees: (double)bot.GetTotalFees(),
|
fees: (double)fees,
|
||||||
tradeCount: bot.Positions.Count,
|
tradeCount: bot.Positions.Count,
|
||||||
maxDrawdownRecoveryTime: stats.MaxDrawdownRecoveryTime
|
maxDrawdownRecoveryTime: stats.MaxDrawdownRecoveryTime
|
||||||
);
|
);
|
||||||
@@ -225,7 +226,7 @@ namespace Managing.Application.Backtesting
|
|||||||
WinRate = winRate,
|
WinRate = winRate,
|
||||||
GrowthPercentage = growthPercentage,
|
GrowthPercentage = growthPercentage,
|
||||||
HodlPercentage = hodlPercentage,
|
HodlPercentage = hodlPercentage,
|
||||||
Fees = bot.GetTotalFees(),
|
Fees = fees,
|
||||||
WalletBalances = bot.WalletBalances.ToList(),
|
WalletBalances = bot.WalletBalances.ToList(),
|
||||||
Statistics = stats,
|
Statistics = stats,
|
||||||
OptimizedMoneyManagement = optimizedMoneyManagement,
|
OptimizedMoneyManagement = optimizedMoneyManagement,
|
||||||
|
|||||||
@@ -1031,9 +1031,6 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
// Add PnL (could be positive or negative)
|
// Add PnL (could be positive or negative)
|
||||||
Config.BotTradingBalance += position.ProfitAndLoss.Realized;
|
Config.BotTradingBalance += position.ProfitAndLoss.Realized;
|
||||||
|
|
||||||
// Subtract fees
|
|
||||||
Config.BotTradingBalance -= GetPositionFees(position);
|
|
||||||
|
|
||||||
Logger.LogInformation(
|
Logger.LogInformation(
|
||||||
$"💰 **Balance Updated**\nNew bot trading balance: `${Config.BotTradingBalance:F2}`");
|
$"💰 **Balance Updated**\nNew bot trading balance: `${Config.BotTradingBalance:F2}`");
|
||||||
}
|
}
|
||||||
@@ -1146,51 +1143,50 @@ public class TradingBot : Bot, ITradingBot
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates the total fees paid by the trading bot for each position.
|
/// Calculates the total fees paid by the trading bot for each position.
|
||||||
|
/// Includes UI fees (0.1% of position size) and network fees ($0.50 for opening).
|
||||||
|
/// Closing fees are handled by oracle, so no network fee for closing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Returns the total fees paid as a decimal value.</returns>
|
/// <returns>Returns the total fees paid as a decimal value.</returns>
|
||||||
public decimal GetTotalFees()
|
public decimal GetTotalFees()
|
||||||
{
|
{
|
||||||
decimal fees = 0;
|
decimal totalFees = 0;
|
||||||
foreach (var position in Positions.Where(p => p.Open.Fee > 0))
|
|
||||||
|
foreach (var position in Positions.Where(p => p.Open.Price > 0 && p.Open.Quantity > 0))
|
||||||
{
|
{
|
||||||
fees += position.Open.Fee;
|
totalFees += CalculatePositionFees(position);
|
||||||
fees += position.StopLoss.Status == TradeStatus.Filled ? position.StopLoss.Fee : 0;
|
|
||||||
fees += position.TakeProfit1.Status == TradeStatus.Filled ? position.TakeProfit1.Fee : 0;
|
|
||||||
|
|
||||||
if (position.IsFinished() &&
|
|
||||||
position.StopLoss.Status != TradeStatus.Filled && position.TakeProfit1.Status != TradeStatus.Filled)
|
|
||||||
fees += position.Open.Fee;
|
|
||||||
|
|
||||||
if (position.TakeProfit2 != null)
|
|
||||||
fees += position.TakeProfit2.Fee;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fees;
|
return totalFees;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates the total fees for a specific position
|
/// Calculates the total fees for a specific position based on GMX V2 fee structure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="position">The position to calculate fees for</param>
|
/// <param name="position">The position to calculate fees for</param>
|
||||||
/// <returns>The total fees for the position</returns>
|
/// <returns>The total fees for the position</returns>
|
||||||
private decimal GetPositionFees(Position position)
|
private decimal CalculatePositionFees(Position position)
|
||||||
{
|
{
|
||||||
decimal fees = 0;
|
decimal fees = 0;
|
||||||
|
|
||||||
fees += position.Open.Fee;
|
// Calculate position size in USD (leverage is already included in quantity calculation)
|
||||||
fees += position.StopLoss.Status == TradeStatus.Filled ? position.StopLoss.Fee : 0;
|
var positionSizeUsd = position.Open.Price * position.Open.Quantity;
|
||||||
fees += position.TakeProfit1.Status == TradeStatus.Filled ? position.TakeProfit1.Fee : 0;
|
|
||||||
|
|
||||||
if (position.IsFinished() &&
|
// UI Fee: 0.1% of position size paid BOTH on opening AND closing
|
||||||
position.StopLoss.Status != TradeStatus.Filled && position.TakeProfit1.Status != TradeStatus.Filled)
|
var uiFeeRate = 0.001m; // 0.1%
|
||||||
fees += position.Open.Fee;
|
var uiFeeOpen = positionSizeUsd * uiFeeRate; // Fee paid on opening
|
||||||
|
var uiFeeClose = positionSizeUsd * uiFeeRate; // Fee paid on closing
|
||||||
|
var totalUiFees = uiFeeOpen + uiFeeClose; // Total: 0.2% of position size
|
||||||
|
fees += totalUiFees;
|
||||||
|
|
||||||
if (position.TakeProfit2 != null)
|
// Network Fee: $0.50 for opening position only
|
||||||
fees += position.TakeProfit2.Status == TradeStatus.Filled ? position.TakeProfit2.Fee : 0;
|
// Closing is handled by oracle, so no network fee for closing
|
||||||
|
var networkFeeForOpening = 0.50m;
|
||||||
|
fees += networkFeeForOpening;
|
||||||
|
|
||||||
return fees;
|
return fees;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task ToggleIsForWatchOnly()
|
public async Task ToggleIsForWatchOnly()
|
||||||
{
|
{
|
||||||
Config.IsForWatchingOnly = !Config.IsForWatchingOnly;
|
Config.IsForWatchingOnly = !Config.IsForWatchingOnly;
|
||||||
|
|||||||
@@ -332,6 +332,13 @@ const BacktestRowDetails: React.FC<IBacktestRowDetailsProps> = ({
|
|||||||
maximumFractionDigits: 2
|
maximumFractionDigits: 2
|
||||||
})}
|
})}
|
||||||
></CardText>
|
></CardText>
|
||||||
|
<CardText
|
||||||
|
title="Total Fees"
|
||||||
|
content={"$" + backtest.fees.toLocaleString('en-US', {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2
|
||||||
|
})}
|
||||||
|
></CardText>
|
||||||
<CardText
|
<CardText
|
||||||
title="Recommended Cooldown"
|
title="Recommended Cooldown"
|
||||||
content={cooldownRecommendations.percentile75 + " candles"}
|
content={cooldownRecommendations.percentile75 + " candles"}
|
||||||
|
|||||||
Reference in New Issue
Block a user