Files
Mimante/Mimante/MainWindow.xaml
T
Alby96andClaude Fable 5.1 7993ca44a0 Database SQLite al posto dei dossier, gestore del rischio, decisioni in shadow, rete neurale, bandit e simulatore
Le aste non si salvano più in un file JSON per asta più tre archivi da tenere allineati:
un solo database SQLite (winsqlite3.dll di Windows via P/Invoke, nessun pacchetto) con
prodotti, aste, puntate, interrogazioni coalescenti, reset con profondità del ciclo,
nostre puntate, decisioni del motore, misure di rete, puntatori, sessioni e contabilità.
Scrittura in coda su un thread dedicato, letture in WAL. Per scelta dell'utente si parte
da zero: il database si riempie man mano che si osservano le aste; i vecchi dossier
restano leggibili per un'importazione futura ma non si scrivono più. Storico, schede,
apprendimento, rigiocata ed esportazioni leggono tutti da lì.

Il documento di progetto (Modifiche.txt) tradotto in C# senza librerie:
- RiskManager: kill-switch (file KILL_SWITCH, anche dalla barra), HALT persistente per
  stop-loss e drawdown, tetto del giorno, aste in gioco insieme, contabilità in euro.
- Theory: valore atteso con fee, spedizione, valore reale per prodotto (nuova colonna
  nella scheda Prodotti) e copertura «Compralo Ora»; null-model; sopravvivenza empirica e
  Kaplan-Meier dai reset; arrivi di Poisson.
- Shadow per asta: in Osserva il cecchino arriva allo stesso istante, registra cosa
  avrebbe fatto e non punta; alla chiusura ogni decisione riceve l'esito, e ShadowReport
  confronta le policy sugli stessi istanti con intervallo di confidenza sul ROI.
- NeuralNet (MLP, Adam) come sfidante del logistico, scelto dal Brier prequenziale;
  ThompsonBandit come seconda policy che impara dagli esiti delle decisioni;
  PennyAuctionEnv con avversari tarati sul database e QLearningAgent conservativo;
  SimulationLab per il confronto fra policy; esportazione CSV delle decisioni con
  reason_detail. Tutto nella scheda Apprendimento.

Ml/LEGGIMI.md riscritto con le avvertenze su termini d'uso, quadro legale e realtà
economica, lo schema del database e lo stato delle milestone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 11:00:49 +02:00

371 lines
22 KiB
XML

<Window x:Class="AutoBidder.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:AutoBidder.Controls"
Title="AutoBidder 4.0"
Height="800"
Width="1400"
WindowStartupLocation="CenterScreen"
Background="{DynamicResource Brush.Bg}">
<!-- L'icona della finestra usa automaticamente ApplicationIcon dell'exe
(robusto anche in modalità single-file self-contained). -->
<!-- Stili centralizzati in Themes/Controls.xaml -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Vertical Sidebar -->
<Border Grid.Column="0" Background="{DynamicResource Brush.Surface}" BorderBrush="{DynamicResource Brush.Border}" BorderThickness="0,0,1,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Navigation Tabs -->
<StackPanel Grid.Row="0" Margin="0,20,0,0">
<!-- Le icone sono glifi Segoe MDL2: monocromatici, seguono il colore
della voce attiva e restano nitidi a ogni scala, cosa che le
emoji a colori non fanno. -->
<RadioButton x:Name="TabAsteAttive"
Content="Aste"
Tag="&#xE8FD;"
Style="{StaticResource VerticalTabButton}"
IsChecked="True"
Checked="TabAsteAttive_Checked"/>
<RadioButton x:Name="TabCerca"
Content="Cerca"
Tag="&#xE721;"
Style="{StaticResource VerticalTabButton}"
Checked="TabCerca_Checked"/>
<RadioButton x:Name="TabProdotti"
Content="Prodotti"
Tag="&#xE734;"
Style="{StaticResource VerticalTabButton}"
Checked="TabProdotti_Checked"/>
<RadioButton x:Name="TabBrowser"
Content="Browser"
Tag="&#xE774;"
Style="{StaticResource VerticalTabButton}"
Checked="TabBrowser_Checked"/>
<RadioButton x:Name="TabPuntateGratis"
Content="Puntate"
Tag="&#xE719;"
Style="{StaticResource VerticalTabButton}"
Checked="TabPuntateGratis_Checked"/>
<RadioButton x:Name="TabDatiStatistici"
Content="Storico"
Tag="&#xE9D9;"
Style="{StaticResource VerticalTabButton}"
Checked="TabDatiStatistici_Checked"/>
<RadioButton x:Name="TabEsporta"
Content="Esporta"
Tag="&#xEDE1;"
Style="{StaticResource VerticalTabButton}"
Checked="TabEsporta_Checked"/>
<RadioButton x:Name="TabApprendimento"
Content="Apprendimento"
Tag="&#xE945;"
Style="{StaticResource VerticalTabButton}"
Checked="TabApprendimento_Checked"/>
<RadioButton x:Name="TabImpostazioni"
Content="Impostazioni"
Tag="&#xE713;"
Style="{StaticResource VerticalTabButton}"
Checked="TabImpostazioni_Checked"/>
</StackPanel>
<!-- User Info Panel - SOPRA AutoBidder - SEMPRE VISIBILE -->
<Border x:Name="SidebarUserInfoPanel"
Grid.Row="1"
Background="{DynamicResource Brush.SurfaceAlt}"
BorderBrush="{DynamicResource Brush.Border}"
BorderThickness="0,1,0,1"
Padding="15,12">
<StackPanel>
<!-- Riga 1: Username (o "Non connesso") -->
<StackPanel Orientation="Horizontal" Margin="0,0,0,4">
<TextBlock x:Name="SidebarUsernameText"
Text="Non connesso"
Foreground="{DynamicResource Brush.Danger}"
FontSize="11"
FontWeight="SemiBold"
TextTrimming="CharacterEllipsis"
Cursor="Hand"
MouseLeftButtonDown="SidebarUsername_Click"
ToolTip="Click per gestire la connessione"/>
</StackPanel>
<!-- Riga 2: ID (visibile solo quando connesso) -->
<StackPanel x:Name="SidebarUserDetailsPanel"
Orientation="Vertical"
Visibility="Collapsed">
<TextBlock x:Name="SidebarUserIdText"
Text="ID: 6707664"
Foreground="{DynamicResource Brush.TextFaint}"
FontSize="9"/>
</StackPanel>
</StackPanel>
</Border>
<!-- App Title & Logo (Bottom) -->
<Border Grid.Row="2" Background="Transparent" Padding="15,14" BorderBrush="{DynamicResource Brush.Border}" BorderThickness="0,1,0,0">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="⚡" FontSize="14" Margin="0,0,8,0" VerticalAlignment="Center"
Foreground="{DynamicResource Brush.Accent}"/>
<TextBlock Text="AutoBidder"
FontSize="13"
FontWeight="SemiBold"
Foreground="{DynamicResource Brush.TextMuted}"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
</Grid>
</Border>
<!-- Content Area -->
<Grid Grid.Column="1" Background="{DynamicResource Brush.Bg}">
<!-- Aste Attive Panel -->
<controls:AuctionMonitorControl x:Name="AuctionMonitor"
Visibility="Visible"
GridStartCommand="{Binding GridStartCommand}"
GridPauseCommand="{Binding GridPauseCommand}"
GridStopCommand="{Binding GridStopCommand}"
GridBidCommand="{Binding GridBidCommand}"
StartClicked="AuctionMonitor_StartClicked"
PauseAllClicked="AuctionMonitor_PauseAllClicked"
StopClicked="AuctionMonitor_StopClicked"
KillSwitchChanged="AuctionMonitor_KillSwitchChanged"
ExportClicked="AuctionMonitor_ExportClicked"
AddUrlClicked="AuctionMonitor_AddUrlClicked"
RemoveUrlClicked="AuctionMonitor_RemoveUrlClicked"
RemoveAllClicked="AuctionMonitor_RemoveAllClicked"
RemoveFinishedClicked="AuctionMonitor_RemoveFinishedClicked"
MoveUpClicked="AuctionMonitor_MoveUpClicked"
MoveDownClicked="AuctionMonitor_MoveDownClicked"
AuctionSelectionChanged="AuctionMonitor_AuctionSelectionChanged"
CopyUrlClicked="AuctionMonitor_CopyUrlClicked"
OpenAuctionInternalClicked="AuctionMonitor_OpenAuctionInternalClicked"
OpenAuctionExternalClicked="AuctionMonitor_OpenAuctionExternalClicked"
ExportAuctionClicked="AuctionMonitor_ExportAuctionClicked"
ResetSettingsClicked="AuctionMonitor_ResetSettingsClicked"
ClearBiddersClicked="AuctionMonitor_ClearBiddersClicked"
ClearLogClicked="AuctionMonitor_ClearLogClicked"
ClearGlobalLogClicked="AuctionMonitor_ClearGlobalLogClicked"
RefreshProductInfoClicked="AuctionMonitor_RefreshProductInfoClicked"
BidBeforeDeadlineMsChanged="AuctionMonitor_BidBeforeDeadlineMsChanged"
MinPriceChanged="AuctionMonitor_MinPriceChanged"
MaxPriceChanged="AuctionMonitor_MaxPriceChanged"
MaxClicksChanged="AuctionMonitor_MaxClicksChanged"
MaxSpendChanged="AuctionMonitor_MaxSpendChanged"
BreakEvenChanged="AuctionMonitor_BreakEvenChanged"/>
<!-- Browser Panel -->
<controls:BrowserControl x:Name="Browser"
Visibility="Collapsed"
BrowserBackClicked="Browser_BrowserBackClicked"
BrowserForwardClicked="Browser_BrowserForwardClicked"
BrowserRefreshClicked="Browser_BrowserRefreshClicked"
BrowserHomeClicked="Browser_BrowserHomeClicked"
BrowserAddAuctionClicked="Browser_BrowserAddAuctionClicked"
CatalogCategoryChanged="Browser_CatalogCategoryChanged"
CatalogRefreshClicked="Browser_CatalogRefreshClicked"
CatalogSearchChanged="Browser_CatalogSearchChanged"
CatalogAutoRefreshChanged="Browser_CatalogAutoRefreshChanged"/>
<!-- Prodotti Panel -->
<controls:ProductsControl x:Name="Products"
Visibility="Collapsed"
RefreshClicked="Products_RefreshClicked"
ScanNowClicked="Products_ScanNowClicked"
ReapplyClicked="Products_ReapplyClicked"
RemoveClicked="Products_RemoveClicked"
ClearClicked="Products_ClearClicked"
ApplySuggestedClicked="Products_ApplySuggestedClicked"
ApplyAllSuggestedClicked="Products_ApplyAllSuggestedClicked"
ProductLimitsEdited="Products_ProductLimitsEdited"
ProductSelectionChanged="Products_ProductSelectionChanged"/>
<!-- Puntate Panel -->
<controls:FreeBidsControl x:Name="FreeBids"
Visibility="Collapsed"
RefreshBalanceClicked="FreeBids_RefreshBalanceClicked"
CheckNowClicked="FreeBids_CheckNowClicked"
OpenExternalClicked="FreeBids_OpenExternalClicked"
OpenInternalClicked="FreeBids_OpenInternalClicked"
OpenVouchersClicked="FreeBids_OpenVouchersClicked"
OpenBuyBidsClicked="FreeBids_OpenBuyBidsClicked"
ResetCountersClicked="FreeBids_ResetCountersClicked"
ClaimPromoClicked="FreeBids_ClaimPromoClicked"
HarvestClicked="FreeBids_HarvestClicked"
OpenPromoSourceClicked="FreeBids_OpenPromoSourceClicked"
ForgetPromosClicked="FreeBids_ForgetPromosClicked"
OpenConfigClicked="FreeBids_OpenConfigClicked"
OptionsChanged="FreeBids_OptionsChanged"/>
<!-- Esporta Panel -->
<controls:ExportControl x:Name="Export"
Visibility="Collapsed"
ExportRequested="Export_ExportRequested"
OpenExportFolderClicked="Export_OpenFolderClicked"
OpenLastFileClicked="Export_OpenLastFileClicked"
ClearExportsClicked="Export_ClearExportsClicked"/>
<!-- Apprendimento Panel -->
<controls:LearningControl x:Name="Learning" Visibility="Collapsed"/>
<!-- Storico Panel -->
<Grid x:Name="StatisticsPanel" Visibility="Collapsed" Background="{DynamicResource Brush.Bg}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Barra strumenti -->
<Border Grid.Row="0" Background="{DynamicResource Brush.Surface}" Padding="10,7"
BorderBrush="{DynamicResource Brush.Border}" BorderThickness="0,0,0,1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
<Button Style="{StaticResource IconButton}" ToolTip="Ricarica lo storico"
Click="ReloadStatisticsButton_Click">
<TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE72C;"/>
</Button>
<TextBlock Text="Storico aste" FontWeight="SemiBold" Margin="8,0,0,0"
FontSize="{StaticResource Font.Size.Lg}"
Foreground="{DynamicResource Brush.Text}" VerticalAlignment="Center"/>
<Border Width="1" Background="{DynamicResource Brush.Border}" Margin="10,4"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<Border Style="{StaticResource Pill}" ToolTip="Aste registrate">
<TextBlock x:Name="StatsPillRecords" Text="0 aste"
FontSize="{StaticResource Font.Size.Sm}"
Foreground="{DynamicResource Brush.TextMuted}"/>
</Border>
<Border Style="{StaticResource Pill}" ToolTip="Aste vinte">
<TextBlock x:Name="StatsPillWon" Text="0 vinte"
FontSize="{StaticResource Font.Size.Sm}"
Foreground="{DynamicResource Brush.Gold}"/>
</Border>
</StackPanel>
<!-- La lettura per prodotto vive nella scheda Prodotti, insieme ai
limiti: qui resta lo storico asta per asta. -->
<StackPanel Grid.Column="3" Orientation="Horizontal" VerticalAlignment="Center">
<Button x:Name="CleanupStatsButton"
Style="{StaticResource SmallRoundedButton}"
Background="{DynamicResource Brush.SurfaceAlt}"
Foreground="{DynamicResource Brush.Text}"
Content="Pulisci dati incompleti" Margin="0,0,8,0"
ToolTip="Analizza lo storico e toglie le aste che non superano i controlli che scegli tu.&#10;&#10;Il conto si aggiorna mentre scegli, e prima di scrivere viene salvata una copia dello storico."
Click="CleanupStatsButton_Click"/>
<Button x:Name="BackfillWinnerBidsButton"
Style="{StaticResource SmallRoundedButton}"
Background="{DynamicResource Brush.SurfaceAlt}"
Foreground="{DynamicResource Brush.Text}"
Content="Recupera puntate dei vincitori" Margin="0,0,8,0"
ToolTip="Chiede al server quante puntate ha speso il vincitore di ogni asta già conclusa.&#10;&#10;Il dato sta in data.php e non scade: le aste registrate prima che l&apos;applicazione sapesse leggerlo non sono perse, basta richiederle. È quello che il sito mostra come «Puntate utilizzate» sulla pagina dell&apos;asta chiusa.&#10;&#10;Va piano di proposito, una richiesta alla volta in corsia di fondo: non deve rubare banda alle aste in corso."
Click="BackfillWinnerBidsButton_Click"/>
<Button Style="{StaticResource IconButton}"
ToolTip="Esporta tutto in CSV (foglio di calcolo)"
Click="ExportStatsCsvButton_Click">
<TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE9F9;"/>
</Button>
<Button Style="{StaticResource IconButton}"
ToolTip="Esporta tutto in JSON (con serie prezzi e puntate per utente)"
Click="ExportStatsJsonButton_Click">
<TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE8B5;"/>
</Button>
<Button Style="{StaticResource IconButton}" ToolTip="Apri la cartella dei dati"
Click="OpenStatsFolderButton_Click">
<TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE838;"/>
</Button>
<Button Style="{StaticResource IconButton}"
Foreground="{DynamicResource Brush.Danger}"
ToolTip="Azzera le statistiche registrate: scegli cosa (storico, prodotti, misure, esportazioni, archivi vecchi, apprendimento). Lo storico viene prima copiato nei backup."
Click="ClearStatsButton_Click">
<TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE74D;"/>
</Button>
</StackPanel>
</Grid>
</Border>
<Grid Grid.Row="1" Margin="12">
<!-- Storico asta per asta -->
<Border x:Name="StatsAuctionsPane"
Background="{DynamicResource Brush.Surface}"
BorderBrush="{DynamicResource Brush.Border}" BorderThickness="1" CornerRadius="12">
<DataGrid x:Name="StatsDetailGrid" AutoGenerateColumns="False" IsReadOnly="True"
Background="Transparent" Margin="4">
<DataGrid.Columns>
<DataGridTextColumn Header="Chiusa il" Binding="{Binding EndedAtDisplay}" Width="Auto" MinWidth="94"/>
<DataGridTextColumn Header="Nome" Binding="{Binding Name}" Width="*" MinWidth="160"/>
<DataGridTextColumn Header="Prezzo finale" Binding="{Binding FinalPriceDisplay}" Width="Auto" MinWidth="94"/>
<DataGridTextColumn Header="Vincitore" Binding="{Binding Winner}" Width="Auto" MinWidth="110"/>
<DataGridTextColumn Header="Tue puntate" Binding="{Binding MyBidsUsed}" Width="Auto" MinWidth="90"/>
<DataGridTextColumn Header="Punt. vincitore" Binding="{Binding WinnerBidsDisplay}" Width="Auto" MinWidth="104"/>
<DataGridTextColumn Header="Valore" Binding="{Binding BuyNowDisplay}" Width="Auto" MinWidth="70"/>
<DataGridTextColumn Header="Esito" Binding="{Binding Outcome}" Width="Auto" MinWidth="64"/>
</DataGrid.Columns>
</DataGrid>
</Border>
<!-- Stato vuoto -->
<StackPanel x:Name="StatsEmptyState" VerticalAlignment="Center" HorizontalAlignment="Center"
Visibility="Collapsed">
<TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE9D9;" FontSize="34"
HorizontalAlignment="Center"
Foreground="{DynamicResource Brush.TextFaint}"/>
<TextBlock x:Name="StatsSummaryText" Text="Nessuna asta conclusa registrata."
Margin="0,10,0,0" HorizontalAlignment="Center"
Foreground="{DynamicResource Brush.TextMuted}"/>
<TextBlock Text="Lo storico si popola da solo man mano che le aste monitorate terminano."
Margin="0,4,0,0" HorizontalAlignment="Center"
FontSize="{StaticResource Font.Size.Sm}"
Foreground="{DynamicResource Brush.TextFaint}"/>
</StackPanel>
</Grid>
</Grid>
<!-- Settings Panel -->
<controls:SettingsControl x:Name="Settings"
Visibility="Collapsed"
SaveDefaultsClicked="Settings_SaveDefaultsClicked"
CancelDefaultsClicked="Settings_CancelDefaultsClicked"
ConnectSessionClicked="Settings_ConnectSessionClicked"
DisconnectSessionClicked="Settings_DisconnectSessionClicked"
OpenBrowserLoginClicked="Settings_OpenBrowserLoginClicked"
ComputeBidLeadAdviceClicked="Settings_ComputeBidLeadAdviceClicked"
ClearBidLeadStatsClicked="Settings_ClearBidLeadStatsClicked"
BrowseDataFolderClicked="Settings_BrowseDataFolderClicked"
BrowseStatsFolderClicked="Settings_BrowseStatsFolderClicked"
OpenDataFolderClicked="Settings_OpenDataFolderClicked"
OpenStatsFolderClicked="Settings_OpenStatsFolderClicked"
BrowseLogFolderClicked="Settings_BrowseLogFolderClicked"
OpenLogFolderClicked="Settings_OpenLogFolderClicked"
BrowseDatabaseFileClicked="Settings_BrowseDatabaseFileClicked"
OpenDatabaseFolderClicked="Settings_OpenDatabaseFolderClicked"
KillSwitchChanged="Settings_KillSwitchChanged"/>
</Grid>
</Grid>
</Window>