diff --git a/src/Managing.Api/Controllers/DataController.cs b/src/Managing.Api/Controllers/DataController.cs
index 3f082106..8e4b590f 100644
--- a/src/Managing.Api/Controllers/DataController.cs
+++ b/src/Managing.Api/Controllers/DataController.cs
@@ -632,7 +632,8 @@ public class DataController : ControllerBase
Identifier = strategy.Identifier,
WalletBalances = walletBalances,
Ticker = strategy.Ticker,
- MasterAgentName = strategy.MasterBotUser?.AgentName
+ MasterAgentName = strategy.MasterBotUser?.AgentName,
+ BotTradingBalance = strategy.BotTradingBalance
};
}
diff --git a/src/Managing.Api/Controllers/LlmController.cs b/src/Managing.Api/Controllers/LlmController.cs
index d02bb899..9a421a80 100644
--- a/src/Managing.Api/Controllers/LlmController.cs
+++ b/src/Managing.Api/Controllers/LlmController.cs
@@ -57,23 +57,28 @@ public class LlmController : BaseController
var availableTools = await _mcpService.GetAvailableToolsAsync();
request.Tools = availableTools.ToList();
- // Add system message to clarify that tools are optional and the LLM can respond directly
- // Check if a system message already exists
- var hasSystemMessage = request.Messages.Any(m => m.Role == "system");
- if (!hasSystemMessage)
+ // Add or prepend system message to ensure LLM knows it can respond directly
+ // Remove any existing system messages first to ensure our directive is clear
+ var existingSystemMessages = request.Messages.Where(m => m.Role == "system").ToList();
+ foreach (var msg in existingSystemMessages)
{
- var systemMessage = new LlmMessage
- {
- Role = "system",
- Content = "You are a helpful AI assistant with expertise in quantitative finance, algorithmic trading, and financial mathematics. " +
- "You can answer questions directly using your knowledge. " +
- "Tools are available for specific operations (backtesting, agent management, market data retrieval, etc.) but are optional. " +
- "Use tools only when they are needed for the specific task. " +
- "For general questions, explanations, calculations, or discussions, respond directly without using tools."
- };
- request.Messages.Insert(0, systemMessage);
+ request.Messages.Remove(msg);
}
+ // Add explicit system message at the beginning
+ var systemMessage = new LlmMessage
+ {
+ Role = "system",
+ Content = "You are an expert AI assistant specializing in quantitative finance, algorithmic trading, and financial mathematics. " +
+ "You have full knowledge and can answer ANY question directly using your training data and expertise. " +
+ "IMPORTANT: You MUST answer general questions, explanations, calculations, and discussions directly without using tools. " +
+ "Tools are ONLY for specific system operations like backtesting, agent management, or retrieving real-time market data. " +
+ "For questions about financial concepts, mathematical formulas (like Black-Scholes), trading strategies, or any theoretical knowledge, " +
+ "you MUST provide a direct answer using your knowledge. Do NOT refuse to answer or claim you can only use tools. " +
+ "Only use tools when the user explicitly needs to perform a system operation (e.g., 'run a backtest', 'get market data', 'manage agents')."
+ };
+ request.Messages.Insert(0, systemMessage);
+
// Send chat request to LLM
var response = await _llmService.ChatAsync(user, request);
diff --git a/src/Managing.Api/Models/Responses/UserStrategyDetailsViewModel.cs b/src/Managing.Api/Models/Responses/UserStrategyDetailsViewModel.cs
index 37a7c669..09e82f2d 100644
--- a/src/Managing.Api/Models/Responses/UserStrategyDetailsViewModel.cs
+++ b/src/Managing.Api/Models/Responses/UserStrategyDetailsViewModel.cs
@@ -112,5 +112,11 @@ namespace Managing.Api.Models.Responses
/// The agent name of the master bot's owner (for copy trading bots)
///
public string MasterAgentName { get; set; }
+
+ ///
+ /// The trading balance allocated to this bot
+ ///
+ [Required]
+ public decimal BotTradingBalance { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Managing.Mcp/McpService.cs b/src/Managing.Mcp/McpService.cs
index 535a7ed6..40d56ecc 100644
--- a/src/Managing.Mcp/McpService.cs
+++ b/src/Managing.Mcp/McpService.cs
@@ -48,6 +48,8 @@ public class McpService : IMcpService
"get_bundle_backtest_by_id" => await _backtestMcpTools.ExecuteGetBundleBacktestById(user, parameters),
"delete_bundle_backtest" => await _backtestMcpTools.ExecuteDeleteBundleBacktest(user, parameters),
"run_backtest" => await _backtestMcpTools.ExecuteRunBacktest(user, parameters),
+ "run_bundle_backtest" => await _backtestMcpTools.ExecuteRunBundleBacktest(user, parameters),
+ "analyze_bundle_backtest" => await _backtestMcpTools.ExecuteAnalyzeBundleBacktest(user, parameters),
// Data tools
"get_tickers" => await _dataMcpTools.ExecuteGetTickers(user, parameters),
diff --git a/src/Managing.Mcp/McpTools/BacktestMcpTools.cs b/src/Managing.Mcp/McpTools/BacktestMcpTools.cs
index 2b3b57e3..f3fdf36d 100644
--- a/src/Managing.Mcp/McpTools/BacktestMcpTools.cs
+++ b/src/Managing.Mcp/McpTools/BacktestMcpTools.cs
@@ -359,6 +359,95 @@ public class BacktestMcpTools : BaseMcpTool
DefaultValue = true
}
}
+ },
+ new McpToolDefinition
+ {
+ Name = "run_bundle_backtest",
+ Description = "Runs a new bundle backtest with multiple tickers and money management variants. Creates a bundle backtest request that will generate multiple backtest jobs.",
+ Parameters = new Dictionary
+ {
+ ["name"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "Display name for the bundle backtest",
+ Required = true
+ },
+ ["timeframe"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "The timeframe for the backtest (e.g., 'FiveMinutes', 'FifteenMinutes', 'OneHour', 'FourHours', 'OneDay')",
+ Required = true
+ },
+ ["startDate"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "Start date for the backtest in ISO 8601 format (e.g., '2024-01-01T00:00:00Z')",
+ Required = true
+ },
+ ["endDate"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "End date for the backtest in ISO 8601 format (e.g., '2024-12-31T23:59:59Z')",
+ Required = true
+ },
+ ["balance"] = new McpParameterDefinition
+ {
+ Type = "number",
+ Description = "Starting balance for the backtest (must be greater than zero)",
+ Required = true
+ },
+ ["tickers"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "Comma-separated list of tickers to test (e.g., 'BTC,ETH,SOL')",
+ Required = true
+ },
+ ["moneyManagementVariants"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "JSON array of money management variants. Each variant should have a 'moneyManagement' object with 'stopLoss', 'takeProfit', 'leverage', 'name', and 'timeframe' properties. Example: [{\"moneyManagement\":{\"stopLoss\":2.5,\"takeProfit\":5.0,\"leverage\":1,\"name\":\"Conservative\",\"timeframe\":\"OneHour\"}}]",
+ Required = true
+ },
+ ["scenarioName"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "The name of the trading scenario/strategy to use (alternative to scenarioJson)",
+ Required = false
+ },
+ ["scenarioJson"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "JSON object representing the scenario configuration with 'name', 'indicators' array, and optional 'lookbackPeriod' (alternative to scenarioName)",
+ Required = false
+ },
+ ["tradingType"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "Trading type (Spot, Futures, BacktestSpot, BacktestFutures, Paper). Defaults to BacktestSpot",
+ Required = false
+ },
+ ["saveAsTemplate"] = new McpParameterDefinition
+ {
+ Type = "boolean",
+ Description = "Whether to save only as a template without running (defaults to false)",
+ Required = false,
+ DefaultValue = false
+ }
+ }
+ },
+ new McpToolDefinition
+ {
+ Name = "analyze_bundle_backtest",
+ Description = "Analyzes a bundle backtest by retrieving all associated backtests and aggregating statistics including averages, best/worst performers, and breakdown by ticker.",
+ Parameters = new Dictionary
+ {
+ ["id"] = new McpParameterDefinition
+ {
+ Type = "string",
+ Description = "The ID of the bundle backtest request to analyze",
+ Required = true
+ }
+ }
}
};
}
@@ -543,4 +632,82 @@ public class BacktestMcpTools : BaseMcpTool
name,
save);
}
+
+ public async Task