224 lines
8.1 KiB
C#
224 lines
8.1 KiB
C#
using System;
|
|
using System.Reflection;
|
|
using System.Windows.Input;
|
|
using DesktopBot.Models;
|
|
using DesktopBot.Services;
|
|
|
|
namespace DesktopBot.ViewModels
|
|
{
|
|
/// <summary>
|
|
/// ViewModel per la schermata di configurazione credenziali Alpaca e logging
|
|
/// </summary>
|
|
public class SettingsViewModel : BaseViewModel
|
|
{
|
|
private readonly ITradingService _tradingService;
|
|
private readonly Action<string, string, bool> _onCredentialsSaved;
|
|
private readonly Action<LoggingConfiguration> _onLoggingConfigSaved;
|
|
private LoggingSettingsViewModel _loggingSettings;
|
|
|
|
private string _apiKey;
|
|
private string _apiSecret;
|
|
private bool _isPaper = true;
|
|
private string _statusMessage;
|
|
private bool _isConnecting;
|
|
private bool _isConnected;
|
|
|
|
public string ApiKey
|
|
{
|
|
get => _apiKey;
|
|
set => SetProperty(ref _apiKey, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Il secret non è bindabile direttamente (PasswordBox non supporta binding).
|
|
/// Viene impostato dal code-behind tramite questa proprietà.
|
|
/// </summary>
|
|
public string ApiSecret
|
|
{
|
|
get => _apiSecret;
|
|
set => SetProperty(ref _apiSecret, value);
|
|
}
|
|
|
|
public bool IsPaper
|
|
{
|
|
get => _isPaper;
|
|
set => SetProperty(ref _isPaper, value);
|
|
}
|
|
|
|
public string StatusMessage
|
|
{
|
|
get => _statusMessage;
|
|
set => SetProperty(ref _statusMessage, value);
|
|
}
|
|
|
|
public bool IsConnecting
|
|
{
|
|
get => _isConnecting;
|
|
set => SetProperty(ref _isConnecting, value);
|
|
}
|
|
|
|
public bool IsConnected
|
|
{
|
|
get => _isConnected;
|
|
set => SetProperty(ref _isConnected, value);
|
|
}
|
|
|
|
/// <summary>ViewModel per la configurazione dei log</summary>
|
|
public LoggingSettingsViewModel LoggingSettings
|
|
{
|
|
get => _loggingSettings;
|
|
set => SetProperty(ref _loggingSettings, value);
|
|
}
|
|
|
|
public ICommand SaveCommand { get; }
|
|
public ICommand TestConnectionCommand { get; }
|
|
public ICommand DeleteCredentialsCommand { get; }
|
|
public ICommand SaveLoggingCommand { get; }
|
|
public ICommand ResetLoggingCommand { get; }
|
|
|
|
// ── Informazioni applicazione ──────────────────────────────────────────
|
|
public string AppVersion { get; } = Assembly.GetExecutingAssembly()
|
|
.GetName().Version?.ToString() ?? "1.0.0.0";
|
|
public string BuildDate { get; } = System.IO.File.GetLastWriteTime(
|
|
Assembly.GetExecutingAssembly().Location)
|
|
.ToString("dd/MM/yyyy HH:mm");
|
|
public string Author { get; } = "Alberto Balbo";
|
|
public string Framework { get; } = ".NET Framework 4.8.1";
|
|
public string Description { get; } = "Trading Bot automatico per Alpaca Markets API v2. " +
|
|
"Supporta paper trading e live trading con strategia EMA Crossover + RSI.";
|
|
|
|
public SettingsViewModel(ITradingService tradingService,
|
|
Action<string, string, bool> onCredentialsSaved,
|
|
Action<LoggingConfiguration> onLoggingConfigSaved = null)
|
|
{
|
|
_tradingService = tradingService;
|
|
_onCredentialsSaved = onCredentialsSaved;
|
|
_onLoggingConfigSaved = onLoggingConfigSaved;
|
|
|
|
SaveCommand = new RelayCommand(
|
|
_ => SaveCredentials(),
|
|
_ => !string.IsNullOrWhiteSpace(ApiKey) && !string.IsNullOrWhiteSpace(ApiSecret)
|
|
);
|
|
|
|
TestConnectionCommand = new RelayCommand(
|
|
async _ => await TestConnectionAsync(),
|
|
_ => !string.IsNullOrWhiteSpace(ApiKey) && !string.IsNullOrWhiteSpace(ApiSecret) && !IsConnecting
|
|
);
|
|
|
|
DeleteCredentialsCommand = new RelayCommand(_ => DeleteCredentials());
|
|
|
|
SaveLoggingCommand = new RelayCommand(_ => SaveLoggingConfiguration());
|
|
ResetLoggingCommand = new RelayCommand(_ => ResetLoggingConfiguration());
|
|
|
|
// Carica credenziali esistenti (mostra solo la key, non il secret)
|
|
var saved = CredentialService.LoadCredentials();
|
|
if (saved != null)
|
|
{
|
|
ApiKey = saved.ApiKey;
|
|
ApiSecret = saved.ApiSecret;
|
|
IsPaper = saved.IsPaper;
|
|
StatusMessage = "✓ Credenziali caricate da configurazione salvata";
|
|
IsConnected = true;
|
|
}
|
|
else
|
|
{
|
|
StatusMessage = "Inserisci le credenziali API di Alpaca";
|
|
}
|
|
|
|
// Inizializza logging settings con configurazione di default
|
|
LoggingSettings = new LoggingSettingsViewModel(new LoggingConfiguration());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Imposta la configurazione di logging iniziale dal bot
|
|
/// </summary>
|
|
public void SetLoggingConfiguration(LoggingConfiguration config)
|
|
{
|
|
LoggingSettings = new LoggingSettingsViewModel(config);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva la configurazione di logging
|
|
/// </summary>
|
|
private void SaveLoggingConfiguration()
|
|
{
|
|
var updatedConfig = LoggingSettings.GetUpdatedConfig();
|
|
_onLoggingConfigSaved?.Invoke(updatedConfig);
|
|
StatusMessage = "✓ Configurazione log salvata";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ripristina i limiti di logging ai valori di default
|
|
/// </summary>
|
|
private void ResetLoggingConfiguration()
|
|
{
|
|
LoggingSettings.ResetToDefaults();
|
|
StatusMessage = "✓ Limiti log ripristinati ai valori di default";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva le credenziali cifrate e notifica il ViewModel principale
|
|
/// </summary>
|
|
private void SaveCredentials()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(ApiKey) || string.IsNullOrWhiteSpace(ApiSecret))
|
|
{
|
|
StatusMessage = "⚠ API Key e Secret sono obbligatori";
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
CredentialService.SaveCredentials(ApiKey, ApiSecret, IsPaper);
|
|
_tradingService.Initialize(ApiKey, ApiSecret, IsPaper);
|
|
_onCredentialsSaved?.Invoke(ApiKey, ApiSecret, IsPaper);
|
|
StatusMessage = "✓ Credenziali salvate e connessione configurata";
|
|
IsConnected = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
StatusMessage = $"✗ Errore nel salvataggio: {ex.Message}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Testa la connessione alle API Alpaca con le credenziali inserite
|
|
/// </summary>
|
|
private async System.Threading.Tasks.Task TestConnectionAsync()
|
|
{
|
|
IsConnecting = true;
|
|
IsConnected = false;
|
|
StatusMessage = "⟳ Test connessione in corso...";
|
|
|
|
try
|
|
{
|
|
_tradingService.Initialize(ApiKey, ApiSecret, IsPaper);
|
|
var equity = await _tradingService.GetAvailableEquityAsync();
|
|
StatusMessage = $"✓ Connessione riuscita! Equity disponibile: ${equity:N2}";
|
|
IsConnected = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
StatusMessage = $"✗ Connessione fallita: {ex.Message}";
|
|
IsConnected = false;
|
|
}
|
|
finally
|
|
{
|
|
IsConnecting = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elimina le credenziali salvate
|
|
/// </summary>
|
|
private void DeleteCredentials()
|
|
{
|
|
CredentialService.DeleteCredentials();
|
|
ApiKey = string.Empty;
|
|
ApiSecret = string.Empty;
|
|
IsConnected = false;
|
|
StatusMessage = "Credenziali eliminate. Inserisci nuove credenziali.";
|
|
}
|
|
}
|
|
}
|