Files
Mimante/Mimante/Tests/BiddingHoursTests.cs
T
Alby96andClaude Opus 5 8b9691d692 Sospendi le puntate nella fascia oraria in cui costano il doppio
Su 6060 aste concluse con prezzo e valore noti, la stessa asta non costa uguale a
tutte le ore. Prezzo di chiusura mediano in percentuale del valore del prodotto:
4,6% alle 12 e 5,3% fra le 10 e le 13, contro 8,6% a mezzanotte e 9,7% alle 9. Le
puntate necessarie per vincere seguono la stessa curva: 21-24 nelle ore buone,
26-29 in quelle cattive. Quasi il doppio del costo per lo stesso oggetto.

Il motivo e' che di notte Bidoo sospende le puntate: restano poche aste in corso e
la concorrenza si concentra li'. Le ore di confine, mezzanotte e le nove, sono le
peggiori, perche' c'e' ancora qualcosa da giocare e ci sono tutti addosso.

La fascia predefinita e' 00:00-10:00. Sospende le puntate, NON il monitoraggio:
l'asta resta in stato Attiva, continua a essere seguita e riprende a puntare da
sola alla fine della fascia. E' voluto: le aste lunghe attraversano la fascia, e
fermarle davvero significherebbe perderle invece che risparmiare. Ogni puntata
saltata scrive nel registro il motivo e l'orario di ripresa.

Tre livelli di override, dal piu' specifico al piu' generale: la singola asta
scavalca il prodotto, il prodotto scavalca le impostazioni generali. Un null non
vuol dire "no" ma "non ho un'opinione", ed e' la differenza che permette di
spegnere il filtro su una sola asta senza toccare il resto.

Una fascia a cavallo di mezzanotte (22-6) funziona; inizio uguale a fine vuol dire
filtro spento, che e' l'unica lettura sensata visto che l'alternativa sarebbe non
puntare mai.

Backtest della regola sul duello, completato su tutte le soglie. Sui dossier veri
in cui il bot ha puntato: 13 aste, 366 puntate, zero vittorie. Con soglia 5 le
puntate sarebbero state 49, risparmiate 317 (86,6%), nessuna vittoria persa. Il
risultato tiene da soglia 2 a soglia 10, che e' quanto ci si puo' aspettare da un
campione in cui non si era vinto niente.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 15:50:06 +02:00

93 lines
3.0 KiB
C#

using System;
using AutoBidder.Utilities;
using Xunit;
namespace AutoBidder.Tests;
/// <summary>
/// Fascia oraria sospesa.
///
/// <para>La proprieta' da difendere e' che la fascia <b>non fermi l'asta</b>: salta la
/// puntata e basta, perche' le aste lunghe attraversano la fascia e fermarle davvero
/// significherebbe perderle. Qui si prova il calcolo della fascia; che lo stato resti
/// Attiva e' garantito da come la regola e' collegata, non da questo file.</para>
///
/// <para>I numeri che motivano il predefinito 0-10: su 6060 aste concluse la chiusura
/// mediana e' il 4,6% del valore alle 12 e il 5,3% fra le 10 e le 13, contro l'8,6% a
/// mezzanotte e il 9,7% alle 9.</para>
/// </summary>
public class BiddingHoursTests
{
[Theory]
[InlineData(0, true)] // mezzanotte: la peggiore, 8,6%
[InlineData(3, true)]
[InlineData(9, true)] // ultima ora dentro: 9,7%
[InlineData(10, false)] // si riparte: 4,9%
[InlineData(12, false)] // la migliore: 4,6%
[InlineData(23, false)]
public void La_fascia_predefinita_va_da_mezzanotte_alle_dieci(int ora, bool sospesa)
{
Assert.Equal(sospesa,
BiddingHours.IsQuiet(ora, BiddingHours.DefaultStart, BiddingHours.DefaultEnd));
}
[Fact]
public void Inizio_incluso_e_fine_esclusa()
{
Assert.True(BiddingHours.IsQuiet(1, 1, 5));
Assert.True(BiddingHours.IsQuiet(4, 1, 5));
Assert.False(BiddingHours.IsQuiet(5, 1, 5));
}
[Theory]
[InlineData(22, true)]
[InlineData(23, true)]
[InlineData(0, true)]
[InlineData(5, true)]
[InlineData(6, false)]
[InlineData(12, false)]
public void Una_fascia_a_cavallo_di_mezzanotte_funziona(int ora, bool sospesa)
{
Assert.Equal(sospesa, BiddingHours.IsQuiet(ora, 22, 6));
}
[Fact]
public void Inizio_uguale_a_fine_significa_filtro_spento()
{
// L'alternativa sarebbe non puntare mai, che non e' quello che intende nessuno
// scrivendo due volte la stessa ora.
for (var ora = 0; ora < 24; ora++)
Assert.False(BiddingHours.IsQuiet(ora, 3, 3));
}
[Theory]
[InlineData(24, 0)]
[InlineData(25, 1)]
[InlineData(-1, 23)]
public void Le_ore_fuori_scala_si_riportano_dentro(int fuori, int atteso)
{
// Un valore scritto a mano nelle impostazioni non deve produrre una fascia che
// non sospende mai o che sospende sempre.
Assert.Equal(BiddingHours.IsQuiet(atteso, 0, 10), BiddingHours.IsQuiet(fuori, 0, 10));
}
[Fact]
public void La_spiegazione_dice_la_fascia_e_che_riprende_da_sola()
{
var testo = BiddingHours.Spiegazione(0, 10);
Assert.Contains("00:00-10:00", testo);
Assert.Contains("resta attiva", testo);
}
[Fact]
public void La_versione_con_data_usa_solo_l_ora()
{
var dentro = new DateTime(2026, 8, 7, 3, 45, 0);
var fuori = new DateTime(2026, 8, 7, 15, 45, 0);
Assert.True(BiddingHours.IsQuiet(dentro, 0, 10));
Assert.False(BiddingHours.IsQuiet(fuori, 0, 10));
}
}