Sviluppo TradingBot
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
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.";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user