Sviluppo TradingBot
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Alpaca.Markets;
|
||||
using DesktopBot.Engine;
|
||||
using DesktopBot.Models;
|
||||
using DesktopBot.Services;
|
||||
|
||||
namespace DesktopBot.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// ViewModel del pannello Bot Manager.
|
||||
/// Contiene un unico bot BTC/USD fisso, precaricato all'avvio.
|
||||
/// L'utente può soltanto avviarlo e fermarlo.
|
||||
/// </summary>
|
||||
public class BotsManagerViewModel : BaseViewModel
|
||||
{
|
||||
private readonly ITradingService _tradingService;
|
||||
|
||||
// ── Collezione (sempre 1 elemento: il bot BTC/USD fisso) ─────────────
|
||||
public ObservableCollection<BotInstanceViewModel> Bots { get; }
|
||||
= new ObservableCollection<BotInstanceViewModel>();
|
||||
|
||||
/// <summary>Shortcut diretto al bot fisso BTC/USD.</summary>
|
||||
public BotInstanceViewModel BtcBot => Bots.FirstOrDefault();
|
||||
|
||||
// ── Grafico prezzi BTC/USD ─────────────────────────────────────────
|
||||
public PriceChartViewModel ChartVM { get; }
|
||||
|
||||
// ── Stato UI ─────────────────────────────────────────────────────────
|
||||
private string _statusMessage;
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => SetProperty(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
// ── Comandi ──────────────────────────────────────────────────────────
|
||||
public ICommand StartBotCommand { get; }
|
||||
public ICommand StopBotCommand { get; }
|
||||
public ICommand SaveAllCommand { get; }
|
||||
|
||||
// ── Ctor ─────────────────────────────────────────────────────────────
|
||||
public BotsManagerViewModel(ITradingService tradingService)
|
||||
{
|
||||
_tradingService = tradingService ?? throw new ArgumentNullException(nameof(tradingService));
|
||||
|
||||
ChartVM = new PriceChartViewModel(tradingService);
|
||||
|
||||
StartBotCommand = new RelayCommand(_ => BtcBot?.StartBot(), _ => BtcBot != null && !BtcBot.IsRunning);
|
||||
StopBotCommand = new RelayCommand(_ => BtcBot?.ForceStop(), _ => BtcBot != null && BtcBot.IsRunning);
|
||||
SaveAllCommand = new RelayCommand(_ => SaveAll());
|
||||
|
||||
EnsureBtcBotExists();
|
||||
|
||||
// Avvia streaming grafico in background
|
||||
_ = ChartVM.StartStreamingAsync();
|
||||
}
|
||||
|
||||
// ── Preload bot BTC/USD fisso ─────────────────────────────────────────
|
||||
private void EnsureBtcBotExists()
|
||||
{
|
||||
// Tenta di caricare da disco
|
||||
var saved = BotInstanceStore.Load();
|
||||
var btcModel = saved.FirstOrDefault(m =>
|
||||
string.Equals(m.Symbol, "BTCUSD", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (btcModel == null)
|
||||
{
|
||||
// Prima esecuzione: crea il bot BTC/USD con parametri ottimali
|
||||
btcModel = CreateBtcUsdBot();
|
||||
BotInstanceStore.Save(new[] { btcModel });
|
||||
}
|
||||
|
||||
var vm = new BotInstanceViewModel(btcModel, _tradingService);
|
||||
// Il bot fisso non può essere rimosso — ignoriamo RemoveRequested
|
||||
Bots.Add(vm);
|
||||
StatusMessage = "Bot BTC/USD caricato — pronto all'avvio.";
|
||||
}
|
||||
|
||||
private static BotInstance CreateBtcUsdBot()
|
||||
{
|
||||
var config = new BotConfiguration
|
||||
{
|
||||
Symbol = "BTCUSD",
|
||||
Quantity = 1,
|
||||
CheckIntervalSeconds = 60,
|
||||
AnalysisTimeFrame = BarTimeFrame.Minute,
|
||||
HistoricalBarCount = 200,
|
||||
|
||||
// EMA ottimizzate per 1min BTC
|
||||
FastEmaPeriod = 5,
|
||||
SlowEmaPeriod = 20,
|
||||
|
||||
// RSI
|
||||
RsiPeriod = 14,
|
||||
RsiOversoldThreshold = 30,
|
||||
RsiOverboughtThreshold = 70,
|
||||
|
||||
// MACD
|
||||
MacdFastPeriod = 8,
|
||||
MacdSlowPeriod = 21,
|
||||
MacdSignalPeriod = 5,
|
||||
|
||||
// Keltner / RVOL
|
||||
KeltnerPeriod = 20,
|
||||
KeltnerMultiplier = 2.0m,
|
||||
RvolMinThreshold = 2.0m,
|
||||
AtrStopMultiplier = 1.5m,
|
||||
|
||||
// Kalman
|
||||
KalmanDelta = 5e-6,
|
||||
KalmanObservationVariance = 1.0,
|
||||
KalmanEntryZScore = 1.8,
|
||||
KalmanExitZScore = 0.3,
|
||||
|
||||
// Risk
|
||||
StopLossPercentage = 0.02m,
|
||||
TakeProfitPercentage = 0.04m,
|
||||
MaxPositionSizePercent = 0.10m,
|
||||
|
||||
// Algoritmo BTC/USD avanzato (dispatch automatico nell'engine)
|
||||
Strategy = TradingStrategy.VOLATILITY_BREAKOUT,
|
||||
RecommendedStrategy = TradingStrategy.VOLATILITY_BREAKOUT,
|
||||
IsLocked = true,
|
||||
LockedAt = DateTime.Now
|
||||
};
|
||||
|
||||
var model = new BotInstance
|
||||
{
|
||||
Name = "BTC/USD — Algoritmo Avanzato",
|
||||
BadgeColor = "#F7931A", // arancione Bitcoin
|
||||
Config = config,
|
||||
Notes = "Bot predefinito BTC/USD. Algoritmo multi-segnale: Regime Detector + Kalman + ATR Sizing.",
|
||||
CreatedAt = DateTime.Now,
|
||||
IsEnabled = true
|
||||
};
|
||||
|
||||
// Blocca asset e config (bot fisso)
|
||||
model.Symbol = "BTCUSD";
|
||||
model.AssetName = "Bitcoin / US Dollar";
|
||||
model.AssetClass = "crypto";
|
||||
model.LockToAsset();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
// ── Persistenza ──────────────────────────────────────────────────────
|
||||
public void SaveAll()
|
||||
{
|
||||
BotInstanceStore.Save(Bots.Select(vm => vm.Model));
|
||||
StatusMessage = $"Salvato — {DateTime.Now:HH:mm:ss}";
|
||||
}
|
||||
|
||||
// ── Start / Stop esposto ai comandi ───────────────────────────────────
|
||||
private async Task StartAllAsync()
|
||||
{
|
||||
if (BtcBot != null && !BtcBot.IsRunning)
|
||||
BtcBot.StartBot();
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void StopAll()
|
||||
{
|
||||
if (BtcBot?.IsRunning == true)
|
||||
BtcBot.ForceStop();
|
||||
StatusMessage = "Bot fermato.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user