Documentation
¶
Overview ¶
Package db provides database utilities including migration runner
Index ¶
- Constants
- func PtrFloat64(f float64) *float64
- func SetMigrationsDir(dir string)
- type AgentAnalytics
- type AgentStatus
- type ClosedPositionReturn
- type ConfidenceBucket
- type DB
- func (db *DB) AggregateSessionStats(ctx context.Context, sessionID uuid.UUID) error
- func (db *DB) BulkUpdateUnrealizedPnL(ctx context.Context, updates []UnrealizedPnLUpdate) error
- func (db *DB) CleanupStaleOrders(ctx context.Context, sessionID uuid.UUID, olderThan time.Duration) (int64, error)
- func (db *DB) Close()
- func (db *DB) ClosePolymarketPosition(ctx context.Context, id uuid.UUID, realizedPnl float64) error
- func (db *DB) ClosePosition(ctx context.Context, id uuid.UUID, exitPrice float64, exitReason string, ...) error
- func (db *DB) ClosePositionTx(ctx context.Context, tx pgx.Tx, id uuid.UUID, exitPrice float64, ...) error
- func (db *DB) CountActiveSessions(ctx context.Context) (int, error)
- func (db *DB) CountAllTrades(ctx context.Context) (int, error)
- func (db *DB) CountOrders(ctx context.Context) (int, error)
- func (db *DB) CreatePosition(ctx context.Context, position *Position) error
- func (db *DB) CreatePositionTx(ctx context.Context, tx pgx.Tx, position *Position) error
- func (db *DB) CreateSession(ctx context.Context, session *TradingSession) error
- func (db *DB) ExecuteWithCircuitBreaker(operation func() (interface{}, error)) (interface{}, error)
- func (db *DB) FindSimilarDecisions(ctx context.Context, symbol string, contextJSON []byte, limit int) ([]*LLMDecision, error)
- func (db *DB) GetAgentStatus(ctx context.Context, name string) (*AgentStatus, error)
- func (db *DB) GetAllAgentStatuses(ctx context.Context) ([]*AgentStatus, error)
- func (db *DB) GetAllClosedPositions(ctx context.Context) ([]*Position, error)
- func (db *DB) GetAllOpenPositions(ctx context.Context) ([]*Position, error)
- func (db *DB) GetCircuitBreaker() *risk.CircuitBreakerManager
- func (db *DB) GetClosedFeesBySessionIDs(ctx context.Context, sessionIDs []uuid.UUID) (float64, error)
- func (db *DB) GetClosedPositionReturns(ctx context.Context) ([]ClosedPositionReturn, error)
- func (db *DB) GetDecisionAnalytics(ctx context.Context, since time.Time) (*DecisionAnalytics, error)
- func (db *DB) GetDecisionsWithOutcomes(ctx context.Context, limit int) ([]DecisionWithOutcome, error)
- func (db *DB) GetExposureBySymbol(ctx context.Context) ([]SymbolExposure, error)
- func (db *DB) GetLLMDecisionStats(ctx context.Context, agentName string, since time.Time) (map[string]interface{}, error)
- func (db *DB) GetLLMDecisionsByAgent(ctx context.Context, agentName string, limit int) ([]*LLMDecision, error)
- func (db *DB) GetLLMDecisionsBySymbol(ctx context.Context, symbol string, limit int) ([]*LLMDecision, error)
- func (db *DB) GetLatestPositionBySymbol(ctx context.Context, symbol string) (*Position, error)
- func (db *DB) GetOpenPolymarketPositions(ctx context.Context) ([]*PolymarketPosition, error)
- func (db *DB) GetOpenPolymarketPositionsBySession(ctx context.Context, sessionID uuid.UUID) ([]*PolymarketPosition, error)
- func (db *DB) GetOpenPositionBySymbol(ctx context.Context, sessionID uuid.UUID, symbol string) (*Position, error)
- func (db *DB) GetOpenPositionBySymbolTx(ctx context.Context, tx pgx.Tx, sessionID uuid.UUID, symbol string) (*Position, error)
- func (db *DB) GetOpenPositions(ctx context.Context, sessionID uuid.UUID) ([]*Position, error)
- func (db *DB) GetOpenPositionsTx(ctx context.Context, tx pgx.Tx, sessionID uuid.UUID) ([]*Position, error)
- func (db *DB) GetOrchestratorState(ctx context.Context) (*OrchestratorState, error)
- func (db *DB) GetOrder(ctx context.Context, orderID uuid.UUID) (*Order, error)
- func (db *DB) GetOrderByID(ctx context.Context, orderID uuid.UUID) (*Order, error)
- func (db *DB) GetOrdersBySession(ctx context.Context, sessionID uuid.UUID) ([]*Order, error)
- func (db *DB) GetOrdersByStatus(ctx context.Context, status OrderStatus) ([]*Order, error)
- func (db *DB) GetOrdersBySymbol(ctx context.Context, symbol string) ([]*Order, error)
- func (db *DB) GetPairPerformance(ctx context.Context) ([]PairPerformance, error)
- func (db *DB) GetPolymarketMarket(ctx context.Context, id string) (*PolymarketMarket, error)
- func (db *DB) GetPolymarketPortfolioSummary(ctx context.Context) (*PolymarketPortfolioSummary, error)
- func (db *DB) GetPolymarketPortfolioSummaryBySession(ctx context.Context, sessionID uuid.UUID) (*PolymarketPortfolioSummary, error)
- func (db *DB) GetPolymarketPosition(ctx context.Context, id uuid.UUID) (*PolymarketPosition, error)
- func (db *DB) GetPolymarketPredictions(ctx context.Context, resolvedOnly bool) ([]*PolymarketPrediction, error)
- func (db *DB) GetPolymarketTrades(ctx context.Context, limit int) ([]*PolymarketTrade, error)
- func (db *DB) GetPolymarketTradesBySession(ctx context.Context, sessionID uuid.UUID, limit int) ([]*PolymarketTrade, error)
- func (db *DB) GetPosition(ctx context.Context, id uuid.UUID) (*Position, error)
- func (db *DB) GetPositionBySymbolAndSession(ctx context.Context, symbol string, sessionID uuid.UUID) (*Position, error)
- func (db *DB) GetPositionsBySession(ctx context.Context, sessionID uuid.UUID) ([]*Position, error)
- func (db *DB) GetRecentOrders(ctx context.Context, limit int) ([]*Order, error)
- func (db *DB) GetRecentOrdersPaginated(ctx context.Context, limit, offset int) ([]*Order, error)
- func (db *DB) GetSession(ctx context.Context, sessionID uuid.UUID) (*TradingSession, error)
- func (db *DB) GetSessionIDWithMostSnapshots(ctx context.Context, sessionIDs []uuid.UUID) (uuid.UUID, error)
- func (db *DB) GetSessionTx(ctx context.Context, tx pgx.Tx, sessionID uuid.UUID) (*TradingSession, error)
- func (db *DB) GetSessionsBySymbol(ctx context.Context, symbol string) ([]*TradingSession, error)
- func (db *DB) GetSuccessfulLLMDecisions(ctx context.Context, agentName string, limit int) ([]*LLMDecision, error)
- func (db *DB) GetTradesByOrderID(ctx context.Context, orderID uuid.UUID) ([]*Trade, error)
- func (db *DB) GetUnresolvedDecisions(ctx context.Context) ([]LLMDecision, error)
- func (db *DB) GetUnresolvedPolymarketPredictions(ctx context.Context) ([]*PolymarketPrediction, error)
- func (db *DB) Health(ctx context.Context) error
- func (db *DB) InsertEquitySnapshot(ctx context.Context, sessionID uuid.UUID, ...) error
- func (db *DB) InsertEquitySnapshotTx(ctx context.Context, tx pgx.Tx, sessionID uuid.UUID, ...) error
- func (db *DB) InsertLLMDecision(ctx context.Context, decision *LLMDecision) error
- func (db *DB) InsertOrder(ctx context.Context, order *Order) error
- func (db *DB) InsertOrderTx(ctx context.Context, tx pgx.Tx, order *Order) error
- func (db *DB) InsertPolymarketMarket(ctx context.Context, m *PolymarketMarket) error
- func (db *DB) InsertPolymarketPosition(ctx context.Context, p *PolymarketPosition) error
- func (db *DB) InsertPolymarketPrediction(ctx context.Context, p *PolymarketPrediction) error
- func (db *DB) InsertPolymarketTrade(ctx context.Context, t *PolymarketTrade) error
- func (db *DB) InsertTrade(ctx context.Context, trade *Trade) error
- func (db *DB) InsertTradeTx(ctx context.Context, tx pgx.Tx, trade *Trade) error
- func (db *DB) IsTradingPaused(ctx context.Context) (bool, error)
- func (db *DB) LinkDecisionToOrder(ctx context.Context, decisionID uuid.UUID, orderID uuid.UUID) error
- func (db *DB) LinkDecisionToPosition(ctx context.Context, decisionID uuid.UUID, positionID uuid.UUID) error
- func (db *DB) ListActiveSessions(ctx context.Context) ([]*TradingSession, error)
- func (db *DB) ListActiveSessionsPaginated(ctx context.Context, limit, offset int) ([]*TradingSession, error)
- func (db *DB) ListAllTrades(ctx context.Context, limit, offset int) ([]*Trade, error)
- func (db *DB) ListEquitySnapshots(ctx context.Context, sessionID uuid.UUID, limit int) ([]*EquitySnapshot, error)
- func (db *DB) ListPolymarketMarkets(ctx context.Context, activeOnly bool) ([]*PolymarketMarket, error)
- func (db *DB) PartialClosePosition(ctx context.Context, id uuid.UUID, closeQuantity, exitPrice float64, ...) (*Position, error)
- func (db *DB) PartialClosePositionTx(ctx context.Context, tx pgx.Tx, existingPos *Position, ...) (*Position, error)
- func (db *DB) Ping(ctx context.Context) error
- func (db *DB) Pool() *pgxpool.Pool
- func (db *DB) ResolveDecisionsFromPositions(ctx context.Context) (int, error)
- func (db *DB) ResolvePrediction(ctx context.Context, id uuid.UUID, outcome float64, pnl float64) error
- func (db *DB) SetCircuitBreaker(cb *risk.CircuitBreakerManager)
- func (db *DB) SetOrchestratorPaused(ctx context.Context, pausedBy, pauseReason string) error
- func (db *DB) SetOrchestratorResumed(ctx context.Context) error
- func (db *DB) SetPool(pool *pgxpool.Pool)
- func (db *DB) StopSession(ctx context.Context, sessionID uuid.UUID, finalCapital float64) error
- func (db *DB) UpdateDecisionOutcome(ctx context.Context, decisionID uuid.UUID, outcome string, pnl float64) error
- func (db *DB) UpdateLLMDecisionOutcome(ctx context.Context, id uuid.UUID, outcome string, pnl float64) error
- func (db *DB) UpdateOrderPositionID(ctx context.Context, orderID uuid.UUID, positionID uuid.UUID) error
- func (db *DB) UpdateOrderPositionIDTx(ctx context.Context, tx pgx.Tx, orderID uuid.UUID, positionID uuid.UUID) error
- func (db *DB) UpdateOrderStatus(ctx context.Context, orderID uuid.UUID, status OrderStatus, ...) error
- func (db *DB) UpdateOrderStatusTx(ctx context.Context, tx pgx.Tx, orderID uuid.UUID, status OrderStatus, ...) error
- func (db *DB) UpdatePolymarketPosition(ctx context.Context, p *PolymarketPosition) error
- func (db *DB) UpdatePosition(ctx context.Context, position *Position) error
- func (db *DB) UpdatePositionAveraging(ctx context.Context, id uuid.UUID, newEntryPrice, newQuantity float64, ...) error
- func (db *DB) UpdatePositionAveragingTx(ctx context.Context, tx pgx.Tx, id uuid.UUID, ...) error
- func (db *DB) UpdatePositionQuantity(ctx context.Context, id uuid.UUID, newQuantity float64, additionalFees float64) error
- func (db *DB) UpdateSessionStats(ctx context.Context, sessionID uuid.UUID, stats SessionStats) error
- func (db *DB) UpdateUnrealizedPnL(ctx context.Context, id uuid.UUID, currentPrice float64) error
- func (db *DB) UpsertAgentStatus(ctx context.Context, agent *AgentStatus) error
- func (db *DB) UpsertPolymarketMarket(ctx context.Context, m *PolymarketMarket) error
- func (db *DB) WithTx(ctx context.Context, opts pgx.TxOptions, fn func(tx pgx.Tx) error) error
- type DecisionAnalytics
- type DecisionWithOutcome
- type EquitySnapshot
- type LLMDecision
- type Migration
- type Migrator
- type OrchestratorState
- type Order
- type OrderSide
- type OrderStatus
- type OrderType
- type PairPerformance
- type PolymarketMarket
- type PolymarketPortfolioSummary
- type PolymarketPosition
- type PolymarketPrediction
- type PolymarketTrade
- type Position
- type PositionSide
- type SessionStats
- type StrategyRecord
- type StrategyRepository
- func (r *StrategyRepository) Delete(ctx context.Context, id string) error
- func (r *StrategyRepository) GetActive(ctx context.Context) (*strategy.StrategyConfig, error)
- func (r *StrategyRepository) GetByID(ctx context.Context, id string) (*strategy.StrategyConfig, error)
- func (r *StrategyRepository) GetHistory(ctx context.Context, strategyID string, limit int) ([]*strategy.StrategyConfig, error)
- func (r *StrategyRepository) List(ctx context.Context, limit, offset int) ([]*strategy.StrategyConfig, error)
- func (r *StrategyRepository) Save(ctx context.Context, s *strategy.StrategyConfig) error
- func (r *StrategyRepository) SaveAndActivate(ctx context.Context, s *strategy.StrategyConfig) error
- func (r *StrategyRepository) SaveHistory(ctx context.Context, strategyID string, s *strategy.StrategyConfig, ...) error
- func (r *StrategyRepository) SetActive(ctx context.Context, id string) error
- type SymbolExposure
- type Trade
- type TradingMode
- type TradingSession
- type UnrealizedPnLUpdate
Constants ¶
const MaxFilteredOrders = 1000
MaxFilteredOrders caps the number of rows returned by filter-based order queries. Full pagination for filtered queries is a TODO follow-up.
Variables ¶
This section is empty.
Functions ¶
func PtrFloat64 ¶
PtrFloat64 returns a pointer to f. Useful for optional float64 struct fields.
func SetMigrationsDir ¶
func SetMigrationsDir(dir string)
SetMigrationsDir sets the directory containing migration files
Types ¶
type AgentAnalytics ¶
type AgentAnalytics struct {
AgentName string `json:"agent_name"`
TotalDecisions int `json:"total_decisions"`
Wins int `json:"wins"`
Losses int `json:"losses"`
Pending int `json:"pending"`
WinRate float64 `json:"win_rate"`
AvgConfidence float64 `json:"avg_confidence"`
AvgPnl float64 `json:"avg_pnl"`
TotalPnl float64 `json:"total_pnl"`
}
AgentAnalytics holds per-agent decision statistics.
type AgentStatus ¶
type AgentStatus struct {
ID string `db:"id" json:"id"`
Name string `db:"agent_name" json:"agent_name"`
Type string `db:"agent_type" json:"agent_type"`
Status string `db:"status" json:"status"`
PID *int `db:"pid" json:"pid,omitempty"`
StartedAt *time.Time `db:"started_at" json:"started_at,omitempty"`
LastHeartbeat *time.Time `db:"last_heartbeat" json:"last_heartbeat,omitempty"`
TotalSignals int `db:"total_signals" json:"total_signals"`
AvgConfidence *float64 `db:"avg_confidence" json:"avg_confidence,omitempty"`
ErrorCount int `db:"error_count" json:"error_count"`
LastError *string `db:"last_error" json:"last_error,omitempty"`
Config any `db:"config" json:"config,omitempty"`
Metadata any `db:"metadata" json:"metadata,omitempty"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
AgentStatus represents an agent's status
type ClosedPositionReturn ¶
ClosedPositionReturn holds the minimal fields needed to compute fractional returns for VaR calculations: realized_pnl / (entry_price * quantity).
type ConfidenceBucket ¶
type ConfidenceBucket struct {
BucketLow float64 `json:"bucket_low"`
BucketHigh float64 `json:"bucket_high"`
Count int `json:"count"`
WinRate float64 `json:"win_rate"`
AvgPnl float64 `json:"avg_pnl"`
}
ConfidenceBucket holds calibration data for a confidence range.
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB wraps the PostgreSQL connection pool
func New ¶
New creates a new database connection pool using DATABASE_URL or Vault credentials. Pool size defaults to 25 connections; pass a non-nil *appconfig.DatabaseConfig to override via database.pool_size in the application config.
func (*DB) AggregateSessionStats ¶
AggregateSessionStats recalculates session statistics from completed trades. All four counters (total_trades, winning_trades, losing_trades, total_pnl) are derived from closed positions (exit_time IS NOT NULL) so the win-rate denominator is consistent: win_rate = winning_trades / total_trades. Previously total_trades counted FILLED/PARTIALLY_FILLED orders while the win/loss counts used positions, causing a denominator mismatch. TODO: Executor-placed orders (via NATS decisions) bypass the API and don't carry session_id. Those positions won't be counted here until the order-executor MCP tool accepts a session_id parameter.
func (*DB) BulkUpdateUnrealizedPnL ¶
func (db *DB) BulkUpdateUnrealizedPnL(ctx context.Context, updates []UnrealizedPnLUpdate) error
BulkUpdateUnrealizedPnL updates unrealized_pnl for many positions in a single round-trip using UNNEST to expand parallel arrays into a VALUES-like virtual table, then joins against it.
PERF-002 (#135): replaces the prior N+1 pattern (position_manager.go looping over open positions and calling UpdateUnrealizedPnL per row, each doing SELECT + UPDATE) with one UPDATE. Callers compute the unrealized P&L in-process from known entry_price/side/quantity — this method does NOT recompute it, so it is also safe to use when callers already hold the authoritative values in memory.
Rows whose id is not in the positions table are silently skipped. Closed positions are excluded via the exit_time IS NULL filter.
func (*DB) CleanupStaleOrders ¶
func (db *DB) CleanupStaleOrders(ctx context.Context, sessionID uuid.UUID, olderThan time.Duration) (int64, error)
CleanupStaleOrders marks old NEW orders as CANCELED if they've been stuck for longer than the given duration. This handles orphaned tracking records from the API handler that were never executed. Only orders belonging to the given session are affected (session-scoped).
func (*DB) ClosePolymarketPosition ¶
func (*DB) ClosePosition ¶
func (db *DB) ClosePosition(ctx context.Context, id uuid.UUID, exitPrice float64, exitReason string, fees float64) error
ClosePosition closes a position with exit price and reason.
PERF-003 (#136): single UPDATE that computes realized_pnl server-side using a CASE on side, replacing the prior SELECT-then-UPDATE pattern. The WHERE clause includes exit_time IS NULL so a double-close attempt returns rowsAffected=0 and is rejected, preserving the original "already closed" semantics in one round-trip instead of two.
Fee semantics (unified in #218):
- ClosePosition (this function) ACCUMULATES via `fees = fees + $4` and deducts the full accumulated total `(fees + $4)` from realized_pnl so the net P&L reflects both entry and exit costs.
- ClosePositionTx OVERWRITES via `fees = $5` with a caller-computed entry+exit total and deducts the same total from realized_pnl.
- Both paths now produce identical realized_pnl for the same trade.
func (*DB) ClosePositionTx ¶
func (db *DB) ClosePositionTx(ctx context.Context, tx pgx.Tx, id uuid.UUID, exitPrice float64, exitReason string, fees float64) error
ClosePositionTx fully closes a position inside an existing transaction. Uses the entry_price and quantity already on the position row to compute realized P&L. Open/closed state is determined by exit_time IS NULL — there is no status column.
fees is the total fees attributable to this position's closed portion (entry fees already recorded on the row plus any exit commission). The column is SET (not added) because the caller (handlePaperTrade) computes proportionalFees = existingPos.Fees * (closeQty / existingPos.Quantity), which is already a slice of the entry fees stored in the column. Using fees=fees+$5 would double-count those entry fees.
func (*DB) CountActiveSessions ¶
CountActiveSessions returns the total number of active (not stopped) trading sessions.
func (*DB) CountAllTrades ¶
CountAllTrades returns an approximate count of trade fill records using pg_class statistics. This is O(1) instead of O(n) — avoids a full sequential COUNT(*) scan on every request. The estimate is sourced from pg_class.reltuples which is updated by ANALYZE/autovacuum. If the table has never been analyzed (reltuples = -1), the function returns 0. to_regclass('public.trades') is used instead of current_schema() to avoid a wrong result when TimescaleDB adds _timescaledb_internal (or another schema) to search_path, which would make current_schema() return something other than 'public'.
func (*DB) CountOrders ¶
CountOrders returns the total number of orders in the database. Used by handleListOrders to populate the total_count response field for paginated queries (QA-007 / #150).
NOTE: SELECT COUNT(*) on a large table requires a full sequential or index scan. For a high-frequency trading system this table can grow large; consider an estimated count (pg_class.reltuples) or a materialized counter if latency becomes a concern at scale.
func (*DB) CreatePosition ¶
CreatePosition inserts a new position into the database.
The `fees` column is included in the INSERT so the entry-side fee the caller already paid (commission, slippage, exchange fee) is preserved on the row. Without this, ClosePosition's `fees = fees + $4` accumulator starts from 0 instead of the entry fee and the closed-position record under-reports total trading cost — bug observed in TestClosePosition where fees of 1.0 + 0.5 resolved to 0.5 instead of 1.5.
func (*DB) CreatePositionTx ¶
CreatePositionTx inserts a new position into the database within an existing transaction.
func (*DB) CreateSession ¶
func (db *DB) CreateSession(ctx context.Context, session *TradingSession) error
CreateSession creates a new trading session
func (*DB) ExecuteWithCircuitBreaker ¶
ExecuteWithCircuitBreaker executes a database operation with circuit breaker protection This wraps database calls to prevent cascading failures during database outages
func (*DB) FindSimilarDecisions ¶
func (db *DB) FindSimilarDecisions(ctx context.Context, symbol string, contextJSON []byte, limit int) ([]*LLMDecision, error)
FindSimilarDecisions finds decisions with similar market conditions (for T185) This uses the context JSONB field to find similar situations
func (*DB) GetAgentStatus ¶
GetAgentStatus retrieves a specific agent's status
func (*DB) GetAllAgentStatuses ¶
func (db *DB) GetAllAgentStatuses(ctx context.Context) ([]*AgentStatus, error)
GetAllAgentStatuses retrieves all agents' statuses
func (*DB) GetAllClosedPositions ¶
GetAllClosedPositions returns positions closed within the last varLookbackDays days across all sessions, ordered by exit_time DESC. See varLookbackDays for a discussion of the scope trade-off.
func (*DB) GetAllOpenPositions ¶
GetAllOpenPositions retrieves all open positions (no session filter)
func (*DB) GetCircuitBreaker ¶
func (db *DB) GetCircuitBreaker() *risk.CircuitBreakerManager
GetCircuitBreaker returns the circuit breaker manager for this database This allows external code to use the same circuit breaker instance
func (*DB) GetClosedFeesBySessionIDs ¶
func (db *DB) GetClosedFeesBySessionIDs(ctx context.Context, sessionIDs []uuid.UUID) (float64, error)
GetClosedFeesBySessionIDs returns the sum of fees from closed positions belonging to the specified sessions. If sessionIDs is empty, returns 0 immediately without querying. Uses a single SQL aggregate instead of loading all rows.
func (*DB) GetClosedPositionReturns ¶
func (db *DB) GetClosedPositionReturns(ctx context.Context) ([]ClosedPositionReturn, error)
GetClosedPositionReturns fetches only the columns required for VaR return calculations (realized_pnl, entry_price, quantity) from positions closed within the last varLookbackDays days. This projects fewer columns than GetAllClosedPositions, reducing per-row data transfer for the risk/metrics endpoint (issue #143). See varLookbackDays for a discussion of the scope trade-off.
func (*DB) GetDecisionAnalytics ¶
func (db *DB) GetDecisionAnalytics(ctx context.Context, since time.Time) (*DecisionAnalytics, error)
GetDecisionAnalytics returns aggregated analytics about decision accuracy.
func (*DB) GetDecisionsWithOutcomes ¶
func (db *DB) GetDecisionsWithOutcomes(ctx context.Context, limit int) ([]DecisionWithOutcome, error)
GetDecisionsWithOutcomes returns recent decisions joined with their linked orders/positions.
func (*DB) GetExposureBySymbol ¶
func (db *DB) GetExposureBySymbol(ctx context.Context) ([]SymbolExposure, error)
GetExposureBySymbol returns the total open-position exposure (quantity * entry_price) grouped by symbol using SQL GROUP BY. Exposure is calculated at cost-basis, not mark-to-market.
func (*DB) GetLLMDecisionStats ¶
func (db *DB) GetLLMDecisionStats(ctx context.Context, agentName string, since time.Time) (map[string]interface{}, error)
GetLLMDecisionStats returns statistics about LLM decisions
func (*DB) GetLLMDecisionsByAgent ¶
func (db *DB) GetLLMDecisionsByAgent(ctx context.Context, agentName string, limit int) ([]*LLMDecision, error)
GetLLMDecisionsByAgent retrieves recent decisions for a specific agent
func (*DB) GetLLMDecisionsBySymbol ¶
func (db *DB) GetLLMDecisionsBySymbol(ctx context.Context, symbol string, limit int) ([]*LLMDecision, error)
GetLLMDecisionsBySymbol retrieves recent decisions for a specific symbol
func (*DB) GetLatestPositionBySymbol ¶
GetLatestPositionBySymbol retrieves the latest position for a symbol (any session)
func (*DB) GetOpenPolymarketPositions ¶
func (db *DB) GetOpenPolymarketPositions(ctx context.Context) ([]*PolymarketPosition, error)
func (*DB) GetOpenPolymarketPositionsBySession ¶
func (db *DB) GetOpenPolymarketPositionsBySession(ctx context.Context, sessionID uuid.UUID) ([]*PolymarketPosition, error)
GetOpenPolymarketPositionsBySession returns open positions belonging to a specific session.
func (*DB) GetOpenPositionBySymbol ¶
func (db *DB) GetOpenPositionBySymbol(ctx context.Context, sessionID uuid.UUID, symbol string) (*Position, error)
GetOpenPositionBySymbol returns the most recent open position for a given session+symbol, or (nil, nil) if none exists. This is the non-transactional counterpart of GetOpenPositionBySymbolTx — used by read-only pre-validation checks (e.g. the SELL oversell guard in handlePlaceOrder, QA-005 / #148) where a FOR UPDATE lock is unnecessary because the caller only needs a snapshot, not a durable reservation.
func (*DB) GetOpenPositionBySymbolTx ¶
func (db *DB) GetOpenPositionBySymbolTx(ctx context.Context, tx pgx.Tx, sessionID uuid.UUID, symbol string) (*Position, error)
GetOpenPositionBySymbolTx retrieves the most recent open position for a symbol within a session using an existing transaction, providing a consistent read within the transaction boundary. Returns (nil, nil) when no open position is found.
func (*DB) GetOpenPositions ¶
func (*DB) GetOpenPositionsTx ¶
func (db *DB) GetOpenPositionsTx(ctx context.Context, tx pgx.Tx, sessionID uuid.UUID) ([]*Position, error)
GetOpenPositionsTx reads open positions inside an existing transaction. DB-008 (#132): used by the equity snapshot so the read and the snapshot INSERT see the same data within one atomic unit.
func (*DB) GetOrchestratorState ¶
func (db *DB) GetOrchestratorState(ctx context.Context) (*OrchestratorState, error)
GetOrchestratorState retrieves the current orchestrator state Returns the most recent state record
func (*DB) GetOrderByID ¶
GetOrderByID is an alias for GetOrder
func (*DB) GetOrdersBySession ¶
GetOrdersBySession retrieves all orders for a specific session
func (*DB) GetOrdersByStatus ¶
GetOrdersByStatus retrieves all orders with a specific status
func (*DB) GetOrdersBySymbol ¶
GetOrdersBySymbol retrieves all orders for a specific symbol
func (*DB) GetPairPerformance ¶
func (db *DB) GetPairPerformance(ctx context.Context) ([]PairPerformance, error)
GetPairPerformance returns realized PnL and trade count grouped by symbol using SQL GROUP BY, covering all closed positions where realized_pnl is not NULL.
func (*DB) GetPolymarketMarket ¶
func (*DB) GetPolymarketPortfolioSummary ¶
func (db *DB) GetPolymarketPortfolioSummary(ctx context.Context) (*PolymarketPortfolioSummary, error)
func (*DB) GetPolymarketPortfolioSummaryBySession ¶
func (db *DB) GetPolymarketPortfolioSummaryBySession(ctx context.Context, sessionID uuid.UUID) (*PolymarketPortfolioSummary, error)
GetPolymarketPortfolioSummaryBySession returns the portfolio summary scoped to a single session.
func (*DB) GetPolymarketPosition ¶
func (*DB) GetPolymarketPredictions ¶
func (*DB) GetPolymarketTrades ¶
func (*DB) GetPolymarketTradesBySession ¶
func (db *DB) GetPolymarketTradesBySession(ctx context.Context, sessionID uuid.UUID, limit int) ([]*PolymarketTrade, error)
GetPolymarketTradesBySession returns trades whose position belongs to the given session.
func (*DB) GetPosition ¶
GetPosition retrieves a position by ID
func (*DB) GetPositionBySymbolAndSession ¶
func (db *DB) GetPositionBySymbolAndSession(ctx context.Context, symbol string, sessionID uuid.UUID) (*Position, error)
GetPositionBySymbolAndSession retrieves a position by symbol and session
func (*DB) GetPositionsBySession ¶
GetPositionsBySession retrieves all positions (including closed) for a session
func (*DB) GetRecentOrders ¶
GetRecentOrders returns the most recent orders, limited by limit. limit=0 returns zero rows (preserving original LIMIT 0 semantics). The guard below prevents delegating to GetRecentOrdersPaginated with limit=0, which would use NULLIF($1, 0) → LIMIT NULL (unbounded). Use a positive limit for paginated access, or GetRecentOrdersPaginated with limit=0 for unbounded results. Deprecated: prefer GetRecentOrdersPaginated for new callers.
func (*DB) GetRecentOrdersPaginated ¶
GetRecentOrdersPaginated retrieves recent orders with limit/offset pagination. limit=0 means no limit (returns all rows).
func (*DB) GetSession ¶
func (*DB) GetSessionIDWithMostSnapshots ¶
func (db *DB) GetSessionIDWithMostSnapshots(ctx context.Context, sessionIDs []uuid.UUID) (uuid.UUID, error)
GetSessionIDWithMostSnapshots returns the session ID that has the most equity snapshot data points (highest COUNT(*)) among the provided session IDs. This allows callers to find the richest data set for drawdown/Sharpe computation with a single round-trip instead of issuing one query per session (N+1). Returns (uuid.UUID{}, nil) when sessionIDs is empty.
func (*DB) GetSessionTx ¶
func (db *DB) GetSessionTx(ctx context.Context, tx pgx.Tx, sessionID uuid.UUID) (*TradingSession, error)
GetSessionTx reads a trading session inside an existing transaction. DB-008 (#132): used by the equity snapshot to ensure the session read and the snapshot INSERT see the same data.
func (*DB) GetSessionsBySymbol ¶
GetSessionsBySymbol retrieves all trading sessions for a specific symbol
func (*DB) GetSuccessfulLLMDecisions ¶
func (db *DB) GetSuccessfulLLMDecisions(ctx context.Context, agentName string, limit int) ([]*LLMDecision, error)
GetSuccessfulLLMDecisions retrieves decisions with positive outcomes for learning
func (*DB) GetTradesByOrderID ¶
GetTradesByOrderID retrieves all trades for an order
func (*DB) GetUnresolvedDecisions ¶
func (db *DB) GetUnresolvedDecisions(ctx context.Context) ([]LLMDecision, error)
GetUnresolvedDecisions returns decisions linked to orders/positions that have no outcome yet.
func (*DB) GetUnresolvedPolymarketPredictions ¶
func (db *DB) GetUnresolvedPolymarketPredictions(ctx context.Context) ([]*PolymarketPrediction, error)
GetUnresolvedPolymarketPredictions returns predictions that haven't been resolved yet.
func (*DB) InsertEquitySnapshot ¶
func (db *DB) InsertEquitySnapshot(ctx context.Context, sessionID uuid.UUID, equity, realizedPnL, unrealizedPnL float64) error
InsertEquitySnapshot writes a new equity snapshot for the given session. Best-effort: callers should log on error but not fail the trade.
func (*DB) InsertEquitySnapshotTx ¶
func (db *DB) InsertEquitySnapshotTx(ctx context.Context, tx pgx.Tx, sessionID uuid.UUID, equity, realizedPnL, unrealizedPnL float64) error
InsertEquitySnapshotTx writes an equity snapshot inside an existing transaction. DB-008 (#132): the paper-trade handler previously called InsertEquitySnapshot outside any transaction, creating a torn-write window where concurrent trades could modify session state between the reads (GetSessionTx, GetOpenPositionsTx) and the INSERT. This Tx variant participates in a short ReadCommitted snapshot transaction that wraps all three operations — separate from the already-committed trade transaction because the snapshot needs to see the committed trade + aggregated stats.
func (*DB) InsertLLMDecision ¶
func (db *DB) InsertLLMDecision(ctx context.Context, decision *LLMDecision) error
InsertLLMDecision records an LLM decision in the database
func (*DB) InsertOrder ¶
InsertOrder inserts a new order into the database
func (*DB) InsertOrderTx ¶
InsertOrderTx inserts a new order into the database within an existing transaction.
func (*DB) InsertPolymarketMarket ¶
func (db *DB) InsertPolymarketMarket(ctx context.Context, m *PolymarketMarket) error
func (*DB) InsertPolymarketPosition ¶
func (db *DB) InsertPolymarketPosition(ctx context.Context, p *PolymarketPosition) error
func (*DB) InsertPolymarketPrediction ¶
func (db *DB) InsertPolymarketPrediction(ctx context.Context, p *PolymarketPrediction) error
func (*DB) InsertPolymarketTrade ¶
func (db *DB) InsertPolymarketTrade(ctx context.Context, t *PolymarketTrade) error
func (*DB) InsertTrade ¶
InsertTrade inserts a new trade (fill) into the database
func (*DB) InsertTradeTx ¶
InsertTradeTx inserts a new trade (fill) into the database within an existing transaction.
func (*DB) IsTradingPaused ¶
IsTradingPaused checks if trading is currently paused This is a convenience method that returns just the boolean status
func (*DB) LinkDecisionToOrder ¶
func (db *DB) LinkDecisionToOrder(ctx context.Context, decisionID uuid.UUID, orderID uuid.UUID) error
LinkDecisionToOrder links a decision to an order via the decision_id column.
func (*DB) LinkDecisionToPosition ¶
func (db *DB) LinkDecisionToPosition(ctx context.Context, decisionID uuid.UUID, positionID uuid.UUID) error
LinkDecisionToPosition links a decision to a position.
func (*DB) ListActiveSessions ¶
func (db *DB) ListActiveSessions(ctx context.Context) ([]*TradingSession, error)
ListActiveSessions retrieves all active (not stopped) trading sessions. It delegates to ListActiveSessionsPaginated with limit=0 (unlimited).
func (*DB) ListActiveSessionsPaginated ¶
func (db *DB) ListActiveSessionsPaginated(ctx context.Context, limit, offset int) ([]*TradingSession, error)
ListActiveSessionsPaginated retrieves active (not stopped) trading sessions with limit/offset pagination. limit=0 means no limit (returns all rows).
func (*DB) ListAllTrades ¶
ListAllTrades returns recent trade fills across all orders, newest first. For fills by specific order, use GetTradesByOrderID in orders.go instead.
func (*DB) ListEquitySnapshots ¶
func (db *DB) ListEquitySnapshots(ctx context.Context, sessionID uuid.UUID, limit int) ([]*EquitySnapshot, error)
ListEquitySnapshots returns the most-recent [limit] equity snapshots for the given session, in chronological order (oldest-to-newest among the returned records). When limit=0 all snapshots are returned (no LIMIT clause is added; LIMIT 0 in PostgreSQL returns zero rows, not all rows). Note: because we fetch with ORDER BY DESC, only the TAIL of the session's history is returned when limit>0, not the oldest rows. Use this for recent-trend calculations (drawdown, Sharpe on recent returns). Returns an empty slice (not nil) when no snapshots exist.
func (*DB) ListPolymarketMarkets ¶
func (*DB) PartialClosePosition ¶
func (db *DB) PartialClosePosition(ctx context.Context, id uuid.UUID, closeQuantity, exitPrice float64, exitReason string, fees float64) (*Position, error)
PartialClosePosition partially closes a position and returns a new position for the closed part
func (*DB) PartialClosePositionTx ¶
func (db *DB) PartialClosePositionTx(ctx context.Context, tx pgx.Tx, existingPos *Position, closeQty, exitPrice float64, exitReason string, closeFees float64) (*Position, error)
PartialClosePositionTx partially closes a position inside an existing transaction. Creates a new closed position row for the closed portion and reduces the open position's quantity. existingPos must be the tx-locked position (from GetOpenPositionBySymbolTx). Returns the updated open position (in-memory; not re-fetched from DB).
func (*DB) ResolveDecisionsFromPositions ¶
ResolveDecisionsFromPositions finds unresolved decisions linked to closed positions and resolves them.
func (*DB) ResolvePrediction ¶
func (*DB) SetCircuitBreaker ¶
func (db *DB) SetCircuitBreaker(cb *risk.CircuitBreakerManager)
SetCircuitBreaker sets a custom circuit breaker manager This is useful for sharing circuit breakers across components
func (*DB) SetOrchestratorPaused ¶
SetOrchestratorPaused updates the orchestrator state to paused Uses database-level locking to prevent race conditions on concurrent pause operations
func (*DB) SetOrchestratorResumed ¶
SetOrchestratorResumed updates the orchestrator state to resumed (not paused) Uses database-level locking to prevent race conditions on concurrent resume operations
func (*DB) StopSession ¶
StopSession marks a trading session as stopped
func (*DB) UpdateDecisionOutcome ¶
func (db *DB) UpdateDecisionOutcome(ctx context.Context, decisionID uuid.UUID, outcome string, pnl float64) error
UpdateDecisionOutcome updates the outcome and P&L of a decision.
func (*DB) UpdateLLMDecisionOutcome ¶
func (db *DB) UpdateLLMDecisionOutcome(ctx context.Context, id uuid.UUID, outcome string, pnl float64) error
UpdateLLMDecisionOutcome updates the outcome and P&L of a decision
func (*DB) UpdateOrderPositionID ¶
func (db *DB) UpdateOrderPositionID(ctx context.Context, orderID uuid.UUID, positionID uuid.UUID) error
UpdateOrderPositionID links an order to a position using the connection pool. Use this from code paths that don't already have a transaction open (e.g. position_manager.OnOrderFilled). For transactional callers, prefer UpdateOrderPositionIDTx.
func (*DB) UpdateOrderPositionIDTx ¶
func (db *DB) UpdateOrderPositionIDTx(ctx context.Context, tx pgx.Tx, orderID uuid.UUID, positionID uuid.UUID) error
UpdateOrderPositionIDTx links an order to a position within an existing transaction. This is called after a position is created/updated so the orders.position_id FK is populated.
func (*DB) UpdateOrderStatus ¶
func (db *DB) UpdateOrderStatus(ctx context.Context, orderID uuid.UUID, status OrderStatus, executedQty, executedQuoteQty float64, filledAt, canceledAt *time.Time, errorMsg *string) error
UpdateOrderStatus updates an order's status and related fields
func (*DB) UpdateOrderStatusTx ¶
func (db *DB) UpdateOrderStatusTx(ctx context.Context, tx pgx.Tx, orderID uuid.UUID, status OrderStatus, executedQty, executedQuoteQty float64, filledAt, canceledAt *time.Time, errorMsg *string) error
UpdateOrderStatusTx updates an order's status and executed fields within an existing transaction.
func (*DB) UpdatePolymarketPosition ¶
func (db *DB) UpdatePolymarketPosition(ctx context.Context, p *PolymarketPosition) error
func (*DB) UpdatePosition ¶
UpdatePosition updates an existing position
func (*DB) UpdatePositionAveraging ¶
func (db *DB) UpdatePositionAveraging(ctx context.Context, id uuid.UUID, newEntryPrice, newQuantity float64, additionalFees float64) error
UpdatePositionAveraging updates entry price and quantity when adding to a position
func (*DB) UpdatePositionAveragingTx ¶
func (db *DB) UpdatePositionAveragingTx(ctx context.Context, tx pgx.Tx, id uuid.UUID, newEntryPrice, newQuantity float64, additionalFees float64) error
UpdatePositionAveragingTx updates entry price and quantity when adding to a position, within an existing transaction.
func (*DB) UpdatePositionQuantity ¶
func (db *DB) UpdatePositionQuantity(ctx context.Context, id uuid.UUID, newQuantity float64, additionalFees float64) error
UpdatePositionQuantity updates the quantity of an open position (for partial closes)
func (*DB) UpdateSessionStats ¶
func (db *DB) UpdateSessionStats(ctx context.Context, sessionID uuid.UUID, stats SessionStats) error
UpdateSessionStats updates trading session statistics
func (*DB) UpdateUnrealizedPnL ¶
UpdateUnrealizedPnL updates the unrealized P&L for an open position.
Prefer BulkUpdateUnrealizedPnL when updating more than one position at a time — this method issues a SELECT followed by an UPDATE for each call and is only retained for the single-position test path.
func (*DB) UpsertAgentStatus ¶
func (db *DB) UpsertAgentStatus(ctx context.Context, agent *AgentStatus) error
UpsertAgentStatus inserts or updates an agent's status
func (*DB) UpsertPolymarketMarket ¶
func (db *DB) UpsertPolymarketMarket(ctx context.Context, m *PolymarketMarket) error
type DecisionAnalytics ¶
type DecisionAnalytics struct {
TotalDecisions int `json:"total_decisions"`
ResolvedDecisions int `json:"resolved_decisions"`
OverallWinRate float64 `json:"overall_win_rate"`
OverallAvgPnl float64 `json:"overall_avg_pnl"`
ByAgent []AgentAnalytics `json:"by_agent"`
ConfidenceCalibration []ConfidenceBucket `json:"confidence_calibration"`
}
DecisionAnalytics holds overall decision analytics.
type DecisionWithOutcome ¶
type DecisionWithOutcome struct {
LLMDecision
OrderID *uuid.UUID `json:"order_id,omitempty"`
PositionID *uuid.UUID `json:"position_id,omitempty"`
OrderSide *string `json:"order_side,omitempty"`
OrderPrice *float64 `json:"order_price,omitempty"`
PosPnl *float64 `json:"position_pnl,omitempty"`
}
DecisionWithOutcome represents a decision joined with its outcome data.
type EquitySnapshot ¶
type EquitySnapshot struct {
ID uuid.UUID `db:"id"`
SessionID uuid.UUID `db:"session_id"`
Equity float64 `db:"equity"`
RealizedPnL float64 `db:"realized_pnl"`
UnrealizedPnL float64 `db:"unrealized_pnl"`
RecordedAt time.Time `db:"recorded_at"`
}
EquitySnapshot records account equity at a point in time. One row is written after each paper trade (open or close).
type LLMDecision ¶
type LLMDecision struct {
ID uuid.UUID `json:"id"`
SessionID *uuid.UUID `json:"session_id,omitempty"`
DecisionType string `json:"decision_type"` // 'signal', 'risk_approval', 'position_sizing', etc.
Symbol string `json:"symbol"`
Prompt string `json:"prompt"`
PromptEmbedding []float32 `json:"prompt_embedding,omitempty"` // 1536-dim OpenAI embeddings
Response string `json:"response"`
Model string `json:"model"`
TokensUsed int `json:"tokens_used"`
LatencyMs int `json:"latency_ms"`
Outcome *string `json:"outcome,omitempty"` // 'SUCCESS', 'FAILURE', 'PENDING'
PnL *float64 `json:"pnl,omitempty"` // Profit/Loss if outcome is known
Context []byte `json:"context,omitempty"` // JSONB - market conditions, indicators, etc.
AgentName string `json:"agent_name"`
Confidence float64 `json:"confidence"`
CreatedAt time.Time `json:"created_at"`
}
LLMDecision represents a decision made by an LLM
type Migrator ¶
type Migrator struct {
// contains filtered or unexported fields
}
Migrator handles database migrations
func NewMigrator ¶
NewMigrator creates a new migration runner
type OrchestratorState ¶
type OrchestratorState struct {
ID int `json:"id"`
Paused bool `json:"paused"`
PausedAt *time.Time `json:"paused_at,omitempty"`
ResumedAt *time.Time `json:"resumed_at,omitempty"`
PausedBy *string `json:"paused_by,omitempty"`
PauseReason *string `json:"pause_reason,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
CreatedAt time.Time `json:"created_at"`
}
OrchestratorState represents the orchestrator's current state
type Order ¶
type Order struct {
ID uuid.UUID `json:"id"`
SessionID *uuid.UUID `json:"session_id"`
PositionID *uuid.UUID `json:"position_id"`
ExchangeOrderID *string `json:"exchange_order_id"`
Symbol string `json:"symbol"`
Exchange string `json:"exchange"`
Side OrderSide `json:"side"`
Type OrderType `json:"type"`
Status OrderStatus `json:"status"`
Price *float64 `json:"price"`
StopPrice *float64 `json:"stop_price"`
Quantity float64 `json:"quantity"`
ExecutedQuantity float64 `json:"executed_quantity"`
ExecutedQuoteQuantity float64 `json:"executed_quote_quantity"`
// AveragePrice is computed in-memory during order execution; it is not persisted to the database (no average_price column).
AveragePrice float64 `json:"average_price"`
TimeInForce *string `json:"time_in_force"`
PlacedAt time.Time `json:"placed_at"`
FilledAt *time.Time `json:"filled_at"`
CanceledAt *time.Time `json:"canceled_at"`
ErrorMessage *string `json:"error_message"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Order represents a database order record
type OrderSide ¶
type OrderSide string
OrderSide represents buy or sell (database enum)
func ConvertOrderSide ¶
ConvertOrderSide converts application order side to database enum
type OrderStatus ¶
type OrderStatus string
OrderStatus represents order status (database enum)
const ( OrderStatusNew OrderStatus = "NEW" OrderStatusPartiallyFilled OrderStatus = "PARTIALLY_FILLED" OrderStatusFilled OrderStatus = "FILLED" OrderStatusCanceled OrderStatus = "CANCELED" OrderStatusRejected OrderStatus = "REJECTED" )
func ConvertOrderStatus ¶
func ConvertOrderStatus(status string) OrderStatus
ConvertOrderStatus converts application order status to database enum
type OrderType ¶
type OrderType string
OrderType represents order type (database enum)
func ConvertOrderType ¶
ConvertOrderType converts application order type to database enum
type PairPerformance ¶
type PairPerformance struct {
Symbol string `db:"symbol"`
RealizedPnL float64 `db:"realized_pnl"`
TradeCount int `db:"trade_count"`
}
PairPerformance holds aggregated realized PnL and trade count for a single trading pair.
type PolymarketMarket ¶
type PolymarketMarket struct {
ID string `db:"id" json:"id"`
Question string `db:"question" json:"question"`
Category *string `db:"category" json:"category"`
YesPrice *float64 `db:"yes_price" json:"yes_price"`
NoPrice *float64 `db:"no_price" json:"no_price"`
Volume *float64 `db:"volume" json:"volume"`
EndDate *time.Time `db:"end_date" json:"end_date"`
Active bool `db:"active" json:"active"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
PolymarketMarket represents a tracked Polymarket market.
type PolymarketPortfolioSummary ¶
type PolymarketPortfolioSummary struct {
TotalCostBasis float64
PositionCount int
OpenPositions []*PolymarketPosition
}
PolymarketPortfolioSummary aggregates portfolio info.
type PolymarketPosition ¶
type PolymarketPosition struct {
ID uuid.UUID `db:"id" json:"id"`
SessionID uuid.UUID `db:"session_id" json:"session_id"`
MarketID string `db:"market_id" json:"market_id"`
Side string `db:"side" json:"side"`
AvgPrice float64 `db:"avg_price" json:"avg_price"`
CostBasis float64 `db:"cost_basis" json:"cost_basis"`
Status string `db:"status" json:"status"`
OpenedAt time.Time `db:"opened_at" json:"opened_at"`
ClosedAt *time.Time `db:"closed_at" json:"closed_at"`
RealizedPnl *float64 `db:"realized_pnl" json:"realized_pnl"`
Metadata interface{} `db:"metadata" json:"metadata"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
PolymarketPosition represents a paper trading position.
type PolymarketPrediction ¶
type PolymarketPrediction struct {
ID uuid.UUID `db:"id"`
MarketID string `db:"market_id"`
PredictedProb float64 `db:"predicted_prob"`
MarketPrice float64 `db:"market_price"`
Edge float64 `db:"edge"`
Confidence float64 `db:"confidence"`
Category *string `db:"category"`
Reasoning *string `db:"reasoning"`
Outcome *float64 `db:"outcome"`
Resolved bool `db:"resolved"`
Pnl *float64 `db:"pnl"`
CreatedAt time.Time `db:"created_at"`
ResolvedAt *time.Time `db:"resolved_at"`
}
PolymarketPrediction represents a prediction record.
type PolymarketTrade ¶
type PolymarketTrade struct {
ID uuid.UUID `db:"id" json:"id"`
PositionID uuid.UUID `db:"position_id" json:"position_id"`
MarketID string `db:"market_id" json:"market_id"`
Question string `db:"question" json:"question"`
Action string `db:"action" json:"action"`
Side string `db:"side" json:"side"`
Amount float64 `db:"amount" json:"amount"`
Price float64 `db:"price" json:"price"`
Timestamp time.Time `db:"timestamp" json:"timestamp"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
}
PolymarketTrade represents a paper trade.
type Position ¶
type Position struct {
ID uuid.UUID `db:"id"`
SessionID *uuid.UUID `db:"session_id"`
Symbol string `db:"symbol"`
Exchange string `db:"exchange"`
Side PositionSide `db:"side"`
EntryPrice float64 `db:"entry_price"`
ExitPrice *float64 `db:"exit_price"`
Quantity float64 `db:"quantity"`
EntryTime time.Time `db:"entry_time"`
ExitTime *time.Time `db:"exit_time"`
StopLoss *float64 `db:"stop_loss"`
TakeProfit *float64 `db:"take_profit"`
RealizedPnL *float64 `db:"realized_pnl"`
UnrealizedPnL *float64 `db:"unrealized_pnl"`
Fees float64 `db:"fees"`
EntryReason *string `db:"entry_reason"`
ExitReason *string `db:"exit_reason"`
Metadata interface{} `db:"metadata"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
}
Position represents a trading position
type PositionSide ¶
type PositionSide string
PositionSide represents the side of a position
const ( PositionSideLong PositionSide = "LONG" PositionSideShort PositionSide = "SHORT" PositionSideFlat PositionSide = "FLAT" )
func ConvertPositionSide ¶
func ConvertPositionSide(side string) PositionSide
ConvertPositionSide converts a string to PositionSide
type SessionStats ¶
type SessionStats struct {
TotalTrades int
WinningTrades int
LosingTrades int
TotalPnL float64
MaxDrawdown float64
SharpeRatio *float64
}
SessionStats holds session statistics
type StrategyRecord ¶
type StrategyRecord struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
SchemaVersion string `json:"schema_version"`
Config []byte `json:"config"`
IsActive bool `json:"is_active"`
Author string `json:"author"`
Version string `json:"version"`
Tags []string `json:"tags"`
Source string `json:"source"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
StrategyRecord represents a strategy record in the database
type StrategyRepository ¶
type StrategyRepository struct {
// contains filtered or unexported fields
}
StrategyRepository handles database operations for strategies
func NewStrategyRepository ¶
func NewStrategyRepository(db *DB) *StrategyRepository
NewStrategyRepository creates a new strategy repository
func (*StrategyRepository) Delete ¶
func (r *StrategyRepository) Delete(ctx context.Context, id string) error
Delete removes a strategy from the database
func (*StrategyRepository) GetActive ¶
func (r *StrategyRepository) GetActive(ctx context.Context) (*strategy.StrategyConfig, error)
GetActive retrieves the currently active strategy
func (*StrategyRepository) GetByID ¶
func (r *StrategyRepository) GetByID(ctx context.Context, id string) (*strategy.StrategyConfig, error)
GetByID retrieves a strategy by its ID
func (*StrategyRepository) GetHistory ¶
func (r *StrategyRepository) GetHistory(ctx context.Context, strategyID string, limit int) ([]*strategy.StrategyConfig, error)
GetHistory retrieves version history for a strategy
func (*StrategyRepository) List ¶
func (r *StrategyRepository) List(ctx context.Context, limit, offset int) ([]*strategy.StrategyConfig, error)
List retrieves all strategies with optional filtering
func (*StrategyRepository) Save ¶
func (r *StrategyRepository) Save(ctx context.Context, s *strategy.StrategyConfig) error
Save creates or updates a strategy in the database
func (*StrategyRepository) SaveAndActivate ¶
func (r *StrategyRepository) SaveAndActivate(ctx context.Context, s *strategy.StrategyConfig) error
SaveAndActivate saves a strategy and sets it as active
func (*StrategyRepository) SaveHistory ¶
func (r *StrategyRepository) SaveHistory(ctx context.Context, strategyID string, s *strategy.StrategyConfig, changedBy, reason string) error
SaveHistory saves a version of the strategy to history
type SymbolExposure ¶
SymbolExposure holds the cost-basis exposure for a single symbol across all open positions.
type Trade ¶
type Trade struct {
ID uuid.UUID `json:"id"`
OrderID uuid.UUID `json:"order_id"`
ExchangeTradeID *string `json:"exchange_trade_id"`
Symbol string `json:"symbol"`
Exchange string `json:"exchange"`
Side OrderSide `json:"side"`
Price float64 `json:"price"`
Quantity float64 `json:"quantity"`
QuoteQuantity float64 `json:"quote_quantity"`
Commission float64 `json:"commission"`
CommissionAsset *string `json:"commission_asset"`
ExecutedAt time.Time `json:"executed_at"`
IsMaker bool `json:"is_maker"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
Trade represents a database trade record (fill)
type TradingMode ¶
type TradingMode string
TradingMode represents trading mode (database enum)
const ( TradingModeLive TradingMode = "LIVE" TradingModePaper TradingMode = "PAPER" )
type TradingSession ¶
type TradingSession struct {
ID uuid.UUID `json:"id"`
Mode TradingMode `json:"mode"`
Symbol string `json:"symbol"`
Exchange string `json:"exchange"`
StartedAt time.Time `json:"started_at"`
StoppedAt *time.Time `json:"stopped_at"`
InitialCapital float64 `json:"initial_capital"`
FinalCapital *float64 `json:"final_capital"`
TotalTrades int `json:"total_trades"`
WinningTrades int `json:"winning_trades"`
LosingTrades int `json:"losing_trades"`
TotalPnL float64 `json:"total_pnl"`
MaxDrawdown float64 `json:"max_drawdown"`
SharpeRatio *float64 `json:"sharpe_ratio"`
Config map[string]interface{} `json:"config,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
TradingSession represents a database trading session record
type UnrealizedPnLUpdate ¶
UnrealizedPnLUpdate is one row in a bulk unrealized-P&L update.