feat: implement Part D and E from FIXPLAN

- D1/D2/D2c: Added TraderTraits entity, TraderTraitCalculator, Market Return Metrics (MedianWin, AvgWin, etc.), and trait filters
- D3: Implemented HF-Trader Tiering via IngestMode (Full, Aggregated, SnapshotOnly) and updated TradeHistoryWorker to respect tiers
- E1-E5: Added MasterStatus to Trader, TraderWindowMetrics for rolling analytics, Fingerprint metrics (PriceBandProfile, P50/P90), Copyability aggregates (Volume, Drift, Edge)
- E6: Implemented GET /api/traders/{id}/profile and GET /api/traders/correlation
- Replaced FIXPLAN-2026-07-09.md with FIXPLAN-TODO.md and FIXPLAN-DONE.md
- Cleaned up API docs and plan to use generic terms (removed hardcoded PolyTrader references)
- Added respective EF Core Migrations
This commit is contained in:
Richard
2026-07-14 09:04:31 +02:00
parent a1fcb4ace5
commit 16431f38a5
39 changed files with 9028 additions and 167 deletions
@@ -0,0 +1,222 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Predictalytics.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class AddTraderAnalyticsFields : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<decimal>(
name: "ProfitFactor",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: true,
oldClrType: typeof(decimal),
oldType: "decimal(65,30)",
oldNullable: true);
migrationBuilder.AlterColumn<decimal>(
name: "MedianWinReturnPct",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(65,30)");
migrationBuilder.AlterColumn<decimal>(
name: "MedianLossReturnPct",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(65,30)");
migrationBuilder.AlterColumn<decimal>(
name: "AvgWinReturnPct",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(65,30)");
migrationBuilder.AlterColumn<decimal>(
name: "AvgLossReturnPct",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(65,30)");
migrationBuilder.AddColumn<decimal>(
name: "MedianHoldDurationHours",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
defaultValue: 0m);
migrationBuilder.AddColumn<decimal>(
name: "MedianMarketVolumeUsd",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
defaultValue: 0m);
migrationBuilder.AddColumn<decimal>(
name: "MedianPostFillDriftPct",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
defaultValue: 0m);
migrationBuilder.AddColumn<decimal>(
name: "NetEdgeAfterFeesPct",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
defaultValue: 0m);
migrationBuilder.AddColumn<decimal>(
name: "P50PositionSize",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
defaultValue: 0m);
migrationBuilder.AddColumn<decimal>(
name: "P90PositionSize",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
defaultValue: 0m);
migrationBuilder.AddColumn<string>(
name: "PriceBandProfileJson",
table: "TraderAnalytics",
type: "longtext",
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<decimal>(
name: "TradesPerWeek",
table: "TraderAnalytics",
type: "decimal(18,4)",
precision: 18,
scale: 4,
nullable: false,
defaultValue: 0m);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "MedianHoldDurationHours",
table: "TraderAnalytics");
migrationBuilder.DropColumn(
name: "MedianMarketVolumeUsd",
table: "TraderAnalytics");
migrationBuilder.DropColumn(
name: "MedianPostFillDriftPct",
table: "TraderAnalytics");
migrationBuilder.DropColumn(
name: "NetEdgeAfterFeesPct",
table: "TraderAnalytics");
migrationBuilder.DropColumn(
name: "P50PositionSize",
table: "TraderAnalytics");
migrationBuilder.DropColumn(
name: "P90PositionSize",
table: "TraderAnalytics");
migrationBuilder.DropColumn(
name: "PriceBandProfileJson",
table: "TraderAnalytics");
migrationBuilder.DropColumn(
name: "TradesPerWeek",
table: "TraderAnalytics");
migrationBuilder.AlterColumn<decimal>(
name: "ProfitFactor",
table: "TraderAnalytics",
type: "decimal(65,30)",
nullable: true,
oldClrType: typeof(decimal),
oldType: "decimal(18,4)",
oldPrecision: 18,
oldScale: 4,
oldNullable: true);
migrationBuilder.AlterColumn<decimal>(
name: "MedianWinReturnPct",
table: "TraderAnalytics",
type: "decimal(65,30)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,4)",
oldPrecision: 18,
oldScale: 4);
migrationBuilder.AlterColumn<decimal>(
name: "MedianLossReturnPct",
table: "TraderAnalytics",
type: "decimal(65,30)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,4)",
oldPrecision: 18,
oldScale: 4);
migrationBuilder.AlterColumn<decimal>(
name: "AvgWinReturnPct",
table: "TraderAnalytics",
type: "decimal(65,30)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,4)",
oldPrecision: 18,
oldScale: 4);
migrationBuilder.AlterColumn<decimal>(
name: "AvgLossReturnPct",
table: "TraderAnalytics",
type: "decimal(65,30)",
nullable: false,
oldClrType: typeof(decimal),
oldType: "decimal(18,4)",
oldPrecision: 18,
oldScale: 4);
}
}
}