id(); $table->string('model_version', 64)->unique()->comment('Deterministic hash of FeatureSpec'); $table->json('features_json')->comment('Serialised feature spec used for this run'); $table->json('coefficients_json')->nullable()->comment('Trained coefficients, null for non-parametric models like NaiveBaseline'); $table->date('train_start'); $table->date('train_end'); $table->date('eval_start'); $table->date('eval_end'); $table->decimal('directional_accuracy', 5, 2)->nullable()->comment('% of eval weeks where direction class was correct'); $table->decimal('mae_pence', 5, 2)->nullable()->comment('Mean absolute error in pence × 100'); $table->json('calibration_table')->nullable()->comment('{bin_low..bin_high → empirical_hit_rate}'); $table->boolean('leak_suspected')->default(false)->comment('Secondary smell test: directional_accuracy > 75'); $table->dateTime('ran_at'); $table->timestamps(); $table->index(['ran_at']); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('backtests'); } };