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>
371 lines
22 KiB
XML
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=""
|
|
Style="{StaticResource VerticalTabButton}"
|
|
IsChecked="True"
|
|
Checked="TabAsteAttive_Checked"/>
|
|
|
|
<RadioButton x:Name="TabCerca"
|
|
Content="Cerca"
|
|
Tag=""
|
|
Style="{StaticResource VerticalTabButton}"
|
|
Checked="TabCerca_Checked"/>
|
|
|
|
<RadioButton x:Name="TabProdotti"
|
|
Content="Prodotti"
|
|
Tag=""
|
|
Style="{StaticResource VerticalTabButton}"
|
|
Checked="TabProdotti_Checked"/>
|
|
|
|
<RadioButton x:Name="TabBrowser"
|
|
Content="Browser"
|
|
Tag=""
|
|
Style="{StaticResource VerticalTabButton}"
|
|
Checked="TabBrowser_Checked"/>
|
|
|
|
<RadioButton x:Name="TabPuntateGratis"
|
|
Content="Puntate"
|
|
Tag=""
|
|
Style="{StaticResource VerticalTabButton}"
|
|
Checked="TabPuntateGratis_Checked"/>
|
|
|
|
<RadioButton x:Name="TabDatiStatistici"
|
|
Content="Storico"
|
|
Tag=""
|
|
Style="{StaticResource VerticalTabButton}"
|
|
Checked="TabDatiStatistici_Checked"/>
|
|
|
|
<RadioButton x:Name="TabEsporta"
|
|
Content="Esporta"
|
|
Tag=""
|
|
Style="{StaticResource VerticalTabButton}"
|
|
Checked="TabEsporta_Checked"/>
|
|
|
|
<RadioButton x:Name="TabApprendimento"
|
|
Content="Apprendimento"
|
|
Tag=""
|
|
Style="{StaticResource VerticalTabButton}"
|
|
Checked="TabApprendimento_Checked"/>
|
|
|
|
<RadioButton x:Name="TabImpostazioni"
|
|
Content="Impostazioni"
|
|
Tag=""
|
|
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=""/>
|
|
</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. 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. Il dato sta in data.php e non scade: le aste registrate prima che l'applicazione sapesse leggerlo non sono perse, basta richiederle. È quello che il sito mostra come «Puntate utilizzate» sulla pagina dell'asta chiusa. 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=""/>
|
|
</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=""/>
|
|
</Button>
|
|
<Button Style="{StaticResource IconButton}" ToolTip="Apri la cartella dei dati"
|
|
Click="OpenStatsFolderButton_Click">
|
|
<TextBlock FontFamily="Segoe MDL2 Assets" Text=""/>
|
|
</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=""/>
|
|
</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="" 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> |