Add Genetic workers

This commit is contained in:
2025-07-10 19:15:57 +07:00
parent c2c181e417
commit 0b4f2173e0
20 changed files with 1752 additions and 3 deletions

View File

@@ -226,6 +226,120 @@ public class BacktestController : BaseController
}
}
/// <summary>
/// Runs a genetic algorithm optimization with the specified configuration.
/// This endpoint saves the genetic request to the database and returns the request ID.
/// The actual genetic algorithm execution will be handled by a background service.
/// </summary>
/// <param name="request">The genetic algorithm request containing configuration and parameters.</param>
/// <returns>The genetic request with ID for tracking progress.</returns>
[HttpPost]
[Route("Genetic")]
public async Task<ActionResult<GeneticRequest>> RunGenetic([FromBody] RunGeneticRequest request)
{
if (request == null)
{
return BadRequest("Genetic request is required");
}
if (request.EligibleIndicators == null || !request.EligibleIndicators.Any())
{
return BadRequest("At least one eligible indicator is required");
}
if (request.StartDate >= request.EndDate)
{
return BadRequest("Start date must be before end date");
}
if (request.PopulationSize <= 0 || request.Generations <= 0)
{
return BadRequest("Population size and generations must be greater than 0");
}
if (request.MutationRate < 0 || request.MutationRate > 1)
{
return BadRequest("Mutation rate must be between 0 and 1");
}
try
{
var user = await GetUser();
// Create genetic request using the Backtester service
var geneticRequest = _backtester.CreateGeneticRequest(
user,
request.Ticker,
request.Timeframe,
request.StartDate,
request.EndDate,
request.Balance,
request.PopulationSize,
request.Generations,
request.MutationRate,
request.SelectionMethod,
request.ElitismPercentage,
request.MaxTakeProfit,
request.EligibleIndicators);
// TODO: Trigger background genetic algorithm execution
// This will be implemented in the next step with a background service
return Ok(geneticRequest);
}
catch (Exception ex)
{
return StatusCode(500, $"Error creating genetic request: {ex.Message}");
}
}
/// <summary>
/// Retrieves all genetic requests for the authenticated user.
/// </summary>
/// <returns>A list of genetic requests with their current status.</returns>
[HttpGet]
[Route("Genetic")]
public async Task<ActionResult<IEnumerable<GeneticRequest>>> GetGeneticRequests()
{
var user = await GetUser();
var geneticRequests = _backtester.GetGeneticRequestsByUser(user);
return Ok(geneticRequests);
}
/// <summary>
/// Retrieves a specific genetic request by ID for the authenticated user.
/// </summary>
/// <param name="id">The ID of the genetic request to retrieve.</param>
/// <returns>The requested genetic request with current status and results.</returns>
[HttpGet]
[Route("Genetic/{id}")]
public async Task<ActionResult<GeneticRequest>> GetGeneticRequest(string id)
{
var user = await GetUser();
var geneticRequest = _backtester.GetGeneticRequestByIdForUser(user, id);
if (geneticRequest == null)
{
return NotFound($"Genetic request with ID {id} not found or doesn't belong to the current user.");
}
return Ok(geneticRequest);
}
/// <summary>
/// Deletes a specific genetic request by ID for the authenticated user.
/// </summary>
/// <param name="id">The ID of the genetic request to delete.</param>
/// <returns>An ActionResult indicating the outcome of the operation.</returns>
[HttpDelete]
[Route("Genetic/{id}")]
public async Task<ActionResult> DeleteGeneticRequest(string id)
{
var user = await GetUser();
_backtester.DeleteGeneticRequestByIdForUser(user, id);
return Ok();
}
/// <summary>
/// Notifies subscribers about the backtesting results via SignalR.
/// </summary>

View File

@@ -0,0 +1,69 @@
using static Managing.Common.Enums;
namespace Managing.Api.Models.Requests;
/// <summary>
/// Request model for running a genetic algorithm optimization
/// </summary>
public class RunGeneticRequest
{
/// <summary>
/// The ticker to optimize for
/// </summary>
public Ticker Ticker { get; set; }
/// <summary>
/// The timeframe to use for optimization
/// </summary>
public Timeframe Timeframe { get; set; }
/// <summary>
/// The start date for the backtest period
/// </summary>
public DateTime StartDate { get; set; }
/// <summary>
/// The end date for the backtest period
/// </summary>
public DateTime EndDate { get; set; }
/// <summary>
/// The starting balance for the backtest
/// </summary>
public decimal Balance { get; set; }
/// <summary>
/// The population size for the genetic algorithm
/// </summary>
public int PopulationSize { get; set; }
/// <summary>
/// The number of generations to evolve
/// </summary>
public int Generations { get; set; }
/// <summary>
/// The mutation rate (0.0 - 1.0)
/// </summary>
public double MutationRate { get; set; }
/// <summary>
/// The selection method to use
/// </summary>
public string SelectionMethod { get; set; } = "tournament";
/// <summary>
/// The percentage of elite individuals to preserve (1-50)
/// </summary>
public int ElitismPercentage { get; set; } = 15;
/// <summary>
/// The maximum take profit percentage
/// </summary>
public double MaxTakeProfit { get; set; } = 4.0;
/// <summary>
/// The list of eligible indicators to include in optimization
/// </summary>
public List<IndicatorType> EligibleIndicators { get; set; } = new();
}