db

package
v0.0.0-...-6deb405 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 12, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package db provides database utilities including migration runner

Index

Constants

View Source
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

func PtrFloat64(f float64) *float64

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

type ClosedPositionReturn struct {
	RealizedPnL float64
	EntryPrice  float64
	Quantity    float64
}

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

func New(ctx context.Context, cfg ...*appconfig.DatabaseConfig) (*DB, error)

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

func (db *DB) AggregateSessionStats(ctx context.Context, sessionID uuid.UUID) error

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) Close

func (db *DB) Close()

Close closes the database connection pool

func (*DB) ClosePolymarketPosition

func (db *DB) ClosePolymarketPosition(ctx context.Context, id uuid.UUID, realizedPnl float64) error

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

func (db *DB) CountActiveSessions(ctx context.Context) (int, error)

CountActiveSessions returns the total number of active (not stopped) trading sessions.

func (*DB) CountAllTrades

func (db *DB) CountAllTrades(ctx context.Context) (int, error)

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

func (db *DB) CountOrders(ctx context.Context) (int, error)

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

func (db *DB) CreatePosition(ctx context.Context, position *Position) error

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

func (db *DB) CreatePositionTx(ctx context.Context, tx pgx.Tx, position *Position) error

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

func (db *DB) ExecuteWithCircuitBreaker(operation func() (interface{}, error)) (interface{}, error)

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

func (db *DB) GetAgentStatus(ctx context.Context, name string) (*AgentStatus, error)

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

func (db *DB) GetAllClosedPositions(ctx context.Context) ([]*Position, error)

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

func (db *DB) GetAllOpenPositions(ctx context.Context) ([]*Position, error)

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

func (db *DB) GetLatestPositionBySymbol(ctx context.Context, symbol string) (*Position, error)

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 *DB) GetOpenPositions(ctx context.Context, sessionID uuid.UUID) ([]*Position, error)

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) GetOrder

func (db *DB) GetOrder(ctx context.Context, orderID uuid.UUID) (*Order, error)

GetOrder retrieves an order by ID

func (*DB) GetOrderByID

func (db *DB) GetOrderByID(ctx context.Context, orderID uuid.UUID) (*Order, error)

GetOrderByID is an alias for GetOrder

func (*DB) GetOrdersBySession

func (db *DB) GetOrdersBySession(ctx context.Context, sessionID uuid.UUID) ([]*Order, error)

GetOrdersBySession retrieves all orders for a specific session

func (*DB) GetOrdersByStatus

func (db *DB) GetOrdersByStatus(ctx context.Context, status OrderStatus) ([]*Order, error)

GetOrdersByStatus retrieves all orders with a specific status

func (*DB) GetOrdersBySymbol

func (db *DB) GetOrdersBySymbol(ctx context.Context, symbol string) ([]*Order, error)

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 *DB) GetPolymarketMarket(ctx context.Context, id string) (*PolymarketMarket, error)

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 *DB) GetPolymarketPosition(ctx context.Context, id uuid.UUID) (*PolymarketPosition, error)

func (*DB) GetPolymarketPredictions

func (db *DB) GetPolymarketPredictions(ctx context.Context, resolvedOnly bool) ([]*PolymarketPrediction, error)

func (*DB) GetPolymarketTrades

func (db *DB) GetPolymarketTrades(ctx context.Context, limit int) ([]*PolymarketTrade, error)

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

func (db *DB) GetPosition(ctx context.Context, id uuid.UUID) (*Position, error)

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

func (db *DB) GetPositionsBySession(ctx context.Context, sessionID uuid.UUID) ([]*Position, error)

GetPositionsBySession retrieves all positions (including closed) for a session

func (*DB) GetRecentOrders

func (db *DB) GetRecentOrders(ctx context.Context, limit int) ([]*Order, error)

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

func (db *DB) GetRecentOrdersPaginated(ctx context.Context, limit, offset int) ([]*Order, error)

GetRecentOrdersPaginated retrieves recent orders with limit/offset pagination. limit=0 means no limit (returns all rows).

func (*DB) GetSession

func (db *DB) GetSession(ctx context.Context, sessionID uuid.UUID) (*TradingSession, error)

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

func (db *DB) GetSessionsBySymbol(ctx context.Context, symbol string) ([]*TradingSession, error)

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

func (db *DB) GetTradesByOrderID(ctx context.Context, orderID uuid.UUID) ([]*Trade, error)

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) Health

func (db *DB) Health(ctx context.Context) error

Health checks database connectivity

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

func (db *DB) InsertOrder(ctx context.Context, order *Order) error

InsertOrder inserts a new order into the database

func (*DB) InsertOrderTx

func (db *DB) InsertOrderTx(ctx context.Context, tx pgx.Tx, order *Order) error

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

func (db *DB) InsertTrade(ctx context.Context, trade *Trade) error

InsertTrade inserts a new trade (fill) into the database

func (*DB) InsertTradeTx

func (db *DB) InsertTradeTx(ctx context.Context, tx pgx.Tx, trade *Trade) error

InsertTradeTx inserts a new trade (fill) into the database within an existing transaction.

func (*DB) IsTradingPaused

func (db *DB) IsTradingPaused(ctx context.Context) (bool, error)

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

func (db *DB) ListAllTrades(ctx context.Context, limit, offset int) ([]*Trade, error)

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 *DB) ListPolymarketMarkets(ctx context.Context, activeOnly bool) ([]*PolymarketMarket, error)

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) Ping

func (db *DB) Ping(ctx context.Context) error

Ping checks the database connection

func (*DB) Pool

func (db *DB) Pool() *pgxpool.Pool

Pool returns the underlying connection pool

func (*DB) ResolveDecisionsFromPositions

func (db *DB) ResolveDecisionsFromPositions(ctx context.Context) (int, error)

ResolveDecisionsFromPositions finds unresolved decisions linked to closed positions and resolves them.

func (*DB) ResolvePrediction

func (db *DB) ResolvePrediction(ctx context.Context, id uuid.UUID, outcome float64, pnl float64) error

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

func (db *DB) SetOrchestratorPaused(ctx context.Context, pausedBy, pauseReason string) error

SetOrchestratorPaused updates the orchestrator state to paused Uses database-level locking to prevent race conditions on concurrent pause operations

func (*DB) SetOrchestratorResumed

func (db *DB) SetOrchestratorResumed(ctx context.Context) error

SetOrchestratorResumed updates the orchestrator state to resumed (not paused) Uses database-level locking to prevent race conditions on concurrent resume operations

func (*DB) SetPool

func (db *DB) SetPool(pool *pgxpool.Pool)

SetPool sets the connection pool (used by tests)

func (*DB) StopSession

func (db *DB) StopSession(ctx context.Context, sessionID uuid.UUID, finalCapital float64) error

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

func (db *DB) UpdatePosition(ctx context.Context, position *Position) error

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

func (db *DB) UpdateUnrealizedPnL(ctx context.Context, id uuid.UUID, currentPrice float64) error

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

func (*DB) WithTx

func (db *DB) WithTx(ctx context.Context, opts pgx.TxOptions, fn func(tx pgx.Tx) error) error

WithTx runs fn inside a single pgx transaction using the provided TxOptions. It commits on success and rolls back on any error or panic. The caller must not commit or roll back tx.

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 Migration

type Migration struct {
	Version     int
	Description string
	SQL         string
	Filename    string
}

Migration represents a database migration

type Migrator

type Migrator struct {
	// contains filtered or unexported fields
}

Migrator handles database migrations

func NewMigrator

func NewMigrator(db *sql.DB) *Migrator

NewMigrator creates a new migration runner

func (*Migrator) Migrate

func (m *Migrator) Migrate(ctx context.Context) error

Migrate runs all pending migrations

func (*Migrator) Status

func (m *Migrator) Status(ctx context.Context) error

Status shows the current migration status

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)

const (
	OrderSideBuy  OrderSide = "BUY"
	OrderSideSell OrderSide = "SELL"
)

func ConvertOrderSide

func ConvertOrderSide(side string) OrderSide

ConvertOrderSide converts application order side to database enum

func (OrderSide) ToDBSide

func (s OrderSide) ToDBSide() string

ToDBSide returns the uppercase string representation of the side suitable for database storage. For db.OrderSide values this is already uppercase, but the method provides a uniform API across OrderSide types.

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)

const (
	OrderTypeMarket OrderType = "MARKET"
	OrderTypeLimit  OrderType = "LIMIT"
)

func ConvertOrderType

func ConvertOrderType(orderType string) OrderType

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"`
	Shares      float64     `db:"shares" json:"shares"`
	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"`
	Shares     float64   `db:"shares" json:"shares"`
	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

GetActive retrieves the currently active strategy

func (*StrategyRepository) GetByID

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

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

func (*StrategyRepository) SetActive

func (r *StrategyRepository) SetActive(ctx context.Context, id string) error

SetActive sets a strategy as the active strategy

type SymbolExposure

type SymbolExposure struct {
	Symbol   string  `db:"symbol"`
	Exposure float64 `db:"exposure"`
}

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

type UnrealizedPnLUpdate struct {
	ID            uuid.UUID
	UnrealizedPnL float64
}

UnrealizedPnLUpdate is one row in a bulk unrealized-P&L update.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL