using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Services;
using Managing.Application.Trading.Commands;
using Managing.Domain.MoneyManagements;
using Managing.Domain.Trades;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using static Managing.Common.Enums;
namespace Managing.Api.Controllers;
///
/// Controller for trading operations such as opening and closing positions, and retrieving trade information.
/// Requires authorization for access.
///
[ApiController]
[Authorize]
[Route("[controller]")]
public class TradingController : BaseController
{
private readonly ICommandHandler _openTradeCommandHandler;
private readonly ICommandHandler _closeTradeCommandHandler;
private readonly ITradingService _tradingService;
private readonly IMoneyManagementService _moneyManagementService;
private readonly IMediator _mediator;
private readonly ILogger _logger;
///
/// Initializes a new instance of the class.
///
/// Logger for logging information.
/// Command handler for opening trades.
/// Command handler for closing trades.
/// Service for trading operations.
/// Mediator for handling commands and requests.
public TradingController(
ILogger logger,
ICommandHandler openTradeCommandHandler,
ICommandHandler closeTradeCommandHandler,
ITradingService tradingService,
IMediator mediator, IMoneyManagementService moneyManagementService,
IUserService userService) : base(userService)
{
_logger = logger;
_openTradeCommandHandler = openTradeCommandHandler;
_closeTradeCommandHandler = closeTradeCommandHandler;
_tradingService = tradingService;
_mediator = mediator;
_moneyManagementService = moneyManagementService;
}
///
/// Retrieves a list of positions based on the initiator type.
///
/// The initiator of the position (e.g., User, System).
/// A list of positions.
[HttpGet("GetPositions")]
public async Task>> GetPositions(PositionInitiator positionInitiator)
{
var result = await _mediator.Send(new GetPositionsCommand(positionInitiator));
return Ok(result);
}
///
/// Retrieves a specific trade by account name, ticker, and exchange order ID.
///
/// The name of the account.
/// The ticker symbol of the trade.
/// The exchange order ID of the trade.
/// The requested trade.
[HttpGet("GetTrade")]
public async Task> GetTrade(string accountName, Ticker ticker, string exchangeOrderId)
{
var result = await _mediator.Send(new GetTradeCommand(accountName, exchangeOrderId, ticker));
return Ok(result);
}
///
/// Retrieves a list of trades for a given account and ticker.
///
/// The name of the account.
/// The ticker symbol of the trades.
/// A list of trades.
[HttpGet("GetTrades")]
public async Task> GetTrades(string accountName, Ticker ticker)
{
var result = await _mediator.Send(new GetTradesCommand(ticker, accountName));
return Ok(result);
}
///
/// Closes a position identified by its unique identifier.
///
/// The unique identifier of the position to close.
/// The closed position.
[HttpPost("ClosePosition")]
public async Task> ClosePosition(string identifier)
{
var position = _tradingService.GetPositionByIdentifier(identifier);
var result = await _closeTradeCommandHandler.Handle(new ClosePositionCommand(position));
return Ok(result);
}
///
/// Opens a new position based on the provided parameters.
///
/// The name of the account to open the position for.
/// The name of the money management strategy to use.
/// The direction of the trade (Buy or Sell).
/// The ticker symbol for the trade.
/// The risk level for the trade.
/// Indicates whether the trade is for paper trading.
/// The money management strategy details (optional).
/// The opening price for the trade (optional).
/// The opened position.
[HttpPost("OpenPosition")]
public async Task> Trade(
string accountName,
string moneyManagementName,
TradeDirection direction,
Ticker ticker,
RiskLevel riskLevel,
bool isForPaperTrading,
MoneyManagement? moneyManagement = null,
decimal? openPrice = null)
{
if (string.IsNullOrEmpty(accountName))
{
throw new ArgumentException($"'{nameof(accountName)}' cannot be null or empty.", nameof(accountName));
}
if (string.IsNullOrEmpty(moneyManagementName) && moneyManagement == null)
{
throw new ArgumentException($"'{nameof(moneyManagementName)}' cannot be null or empty.",
nameof(moneyManagementName));
}
if (moneyManagement != null)
{
var user = await GetUser();
moneyManagement = await _moneyManagementService.GetMoneyMangement(user, moneyManagementName);
}
var command = new OpenPositionRequest(
accountName,
moneyManagement,
direction,
ticker,
PositionInitiator.User,
DateTime.UtcNow,
isForPaperTrading: isForPaperTrading,
price: openPrice);
var result = await _openTradeCommandHandler.Handle(command);
return Ok(result);
}
}