@
Fingerprint-snapshot foundation + strategy-drift calculator (#3/#5 groundwork) TraderAnalytics is one row per trader, overwritten every recalculation, so there is no history to detect strategy drift (#3) or edge fade (#5) against. Add the missing time series: - TraderFingerprintSnapshot entity (score, category concentration, conviction, P50/P90 sizing, hold duration, trades/week, category-mix JSON, trait-set JSON) + migration AddFingerprintSnapshots (indexed by TraderId, CapturedAt). - FingerprintSnapshotService (Infrastructure): CaptureDueAsync snapshots every copy-relevant trader (CopytradingScore >= 40) at most ~once/day; wired into ScoringAndAlertsWorker. GetDriftAsync reads latest-vs-baseline drift. - FingerprintDriftCalculator (pure, Application): flags score drop, concentration shift, sizing jump, conviction sign-flip, category-mix TVD, trait-set change. - GET /api/traders/{id}/fingerprint-drift?baselineDays=14 read endpoint. - Tests: drift calculator (4 scenarios) + capture service (copy-relevance, throttle, drift read). This is the shared foundation both #3 (drift alarm) and #5 (edge freshness) build on. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> @
This commit is contained in:
@@ -26,6 +26,7 @@ public class AppDbContext : DbContext
|
||||
public DbSet<TraderTrait> TraderTraits => Set<TraderTrait>();
|
||||
public DbSet<TraderWindowMetrics> TraderWindowMetrics => Set<TraderWindowMetrics>();
|
||||
public DbSet<InsiderWatch> InsiderWatches => Set<InsiderWatch>();
|
||||
public DbSet<TraderFingerprintSnapshot> TraderFingerprintSnapshots => Set<TraderFingerprintSnapshot>();
|
||||
|
||||
private readonly bool _isReadOnly;
|
||||
|
||||
@@ -216,6 +217,14 @@ public class AppDbContext : DbContext
|
||||
e.HasOne(i => i.Trader).WithMany().HasForeignKey(i => i.TraderId);
|
||||
});
|
||||
|
||||
// TraderFingerprintSnapshot (time-series; many rows per trader)
|
||||
mb.Entity<TraderFingerprintSnapshot>(e =>
|
||||
{
|
||||
e.HasKey(s => s.Id);
|
||||
e.HasIndex(s => new { s.TraderId, s.CapturedAt });
|
||||
e.HasOne(s => s.Trader).WithMany().HasForeignKey(s => s.TraderId);
|
||||
});
|
||||
|
||||
// Alert
|
||||
mb.Entity<Alert>(e =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user