using Predictalytics.Domain.Enums;
using System.ComponentModel.DataAnnotations.Schema;
namespace Predictalytics.Domain.Entities;
///
/// Represents a single trade executed by a trader on a prediction market.
///
public class Trade
{
public long Id { get; set; }
/// Foreign key to the trader who made this trade.
public int TraderId { get; set; }
/// Platform where the trade occurred.
public PlatformType Platform { get; set; }
///
/// Platform-specific trade ID for deduplication.
/// Format: "{txHash}_{assetId}_{side}" (max ~143 chars for new trades).
/// Legacy trades may include wallet address as 2nd segment.
///
public string PlatformTradeId { get; set; } = string.Empty;
///
/// Platform-specific market identifier string (conditionId on Polymarket, address on Limitless).
/// Kept as VARCHAR(66) for cross-referencing during import and reconciliation.
/// After full linking, prefer DbMarketId.
///
public string MarketId { get; set; } = string.Empty;
///
/// Foreign key to the internal Markets table. Populated during import when the market is known.
/// Null for trades whose market has not yet been synced.
///
public int? DbMarketId { get; set; }
///
/// Platform-specific token/asset ID (clobTokenId on Polymarket). Links to MarketOutcome.TokenId.
/// Kept as VARCHAR(66) until MarketOutcomeId is resolved.
///
public string AssetId { get; set; } = string.Empty;
/// Foreign key to the resolved MarketOutcome (nullable until resolved via market sync).
public int? MarketOutcomeId { get; set; }
/// The outcome the trader bet on (e.g. "Yes", "No").
public string Outcome { get; set; } = string.Empty;
/// Buy or Sell.
public TradeSide Side { get; set; }
/// Price per share at execution (0.00 to 1.00 on Polymarket).
public decimal Price { get; set; }
/// Number of shares/tokens traded.
public decimal Size { get; set; }
/// Total notional value in USD.
public decimal Amount { get; set; }
/// When the trade was executed on the platform.
public DateTime ExecutedAt { get; set; }
/// Transaction hash (for blockchain-based platforms).
public string? TransactionHash { get; set; }
/// USDC size of the trade (raw currency size traded).
[Column(TypeName = "decimal(18,6)")]
public decimal? UsdcSize { get; set; }
/// Outcome index traded.
public int? OutcomeIndex { get; set; }
// ── Context Enrichment (AI Strategy Detection) ───────────
/// Market price 1 minute before trade execution.
[Column(TypeName = "decimal(18,4)")]
public decimal? PreTradePrice1m { get; set; }
/// Market price 1 minute after trade execution.
[Column(TypeName = "decimal(18,4)")]
public decimal? PostTradePrice1m { get; set; }
/// Indicates if high-res price context was fetched.
public bool IsContextEnriched { get; set; }
///
/// For aggregated trades (compacted history or HF trader hourly bucket), this stores
/// the number of original trades that were grouped into this single row. Null means 1.
///
public int? AggregatedCount { get; set; }
// ── Transient (not persisted) ──────────────────────────────────────────
///
/// Wallet address of the trader, set by the provider during data ingestion.
/// NOT stored in the database — used transiently for trader discovery in MarketHistoryWorker.
///
[NotMapped]
public string? TransientWallet { get; set; }
///
/// Transient reference to the trader's display name from the platform, used to opportunistically
/// update the local name if it's currently a placeholder or empty.
///
[NotMapped]
public string? TransientDisplayName { get; set; }
// ── Navigation ────────────────────────────────────────────────────────
public Trader Trader { get; set; } = null!;
public MarketOutcome? MarketOutcome { get; set; }
/// Analytics context containing high-resolution price data and slippage (if collected).
public TradeContext? Context { get; set; }
public Market? DbMarket { get; set; }
}