Skip to main content

Overview

The accounts module (server/accounts.ts) provides comprehensive account management including CRUD operations, metrics calculation, payouts, and bulk operations on accounts and instruments.

Account Operations

setupAccountAction

Create or update a trading account with full configuration.
server/accounts.ts:218
export async function setupAccountAction(
  account: Account
): Promise<Account>
account
Account
required
Account object with configuration. Can include:
  • number: Account number (required)
  • propfirm: Prop firm name
  • startingBalance: Initial balance
  • drawdownThreshold: Max allowed drawdown
  • profitTarget: Target profit
  • isPerformance: Whether this is a performance account
  • groupId: Optional group assignment
  • considerBuffer: Whether to consider buffer in calculations
account
Account
The saved account with payouts and group relations loaded
Example
import { setupAccountAction } from '@/server/accounts'

const account = await setupAccountAction({
  number: 'PROP-12345',
  propfirm: 'FTMO',
  startingBalance: 100000,
  drawdownThreshold: 10000,
  profitTarget: 10000,
  isPerformance: false,
  considerBuffer: true
})

console.log('Account created:', account.number)
If an account with the same number already exists for the user, it will be updated instead of creating a duplicate.

createAccountAction

Create a minimal account with just an account number.
server/accounts.ts:520
export async function createAccountAction(
  accountNumber: string
): Promise<Account>
accountNumber
string
required
The account number
account
Account
The created account with default values
Example
import { createAccountAction } from '@/server/accounts'

const account = await createAccountAction('PROP-67890')
// Account created with default values:
// - propfirm: ''
// - drawdownThreshold: 0
// - profitTarget: 0
// - isPerformance: false
// - payoutCount: 0

getAccountsAction

Retrieve all accounts for the authenticated user.
server/accounts.ts:347
export async function getAccountsAction(): Promise<Account[]>
accounts
Account[]
Array of accounts with payouts included
Example
import { getAccountsAction } from '@/server/accounts'

const accounts = await getAccountsAction()

accounts.forEach(account => {
  console.log(`${account.number}: ${account.propfirm}`)
  console.log(`Payouts: ${account.payouts.length}`)
})

deleteAccountAction

Delete a trading account.
server/accounts.ts:335
export async function deleteAccountAction(
  account: Account
): Promise<void>
account
Account
required
The account object to delete
Example
import { deleteAccountAction } from '@/server/accounts'

await deleteAccountAction(account)
// Account and associated data deleted
Deleting an account does NOT automatically delete associated trades. Use removeAccountFromTradesAction or removeAccountsFromTradesAction to delete trades.

renameAccountAction

Rename an account number (updates account, trades, and payouts).
server/accounts.ts:133
export async function renameAccountAction(
  oldAccountNumber: string,
  newAccountNumber: string
): Promise<void>
oldAccountNumber
string
required
Current account number
newAccountNumber
string
required
New account number
Example
import { renameAccountAction } from '@/server/accounts'

try {
  await renameAccountAction('OLD-123', 'NEW-456')
  // Account number updated everywhere:
  // - Account table
  // - All trades
  // - All payouts
} catch (error) {
  if (error.message.includes('already have an account')) {
    console.error('New account number already in use')
  }
}
This operation uses a database transaction to ensure all updates succeed together or all fail.

Trade Operations

fetchGroupedTradesAction

Fetch all trades for a user, grouped by account and instrument.
server/accounts.ts:32
export async function fetchGroupedTradesAction(
  userId: string
): Promise<FetchTradesResult>
userId
string
required
The user ID to fetch trades for
groupedTrades
Record<string, Record<string, Trade[]>>
Trades grouped by account number, then by instrument
flattenedTrades
Trade[]
All trades in a flat array
Example
import { fetchGroupedTradesAction } from '@/server/accounts'

const { groupedTrades, flattenedTrades } = await fetchGroupedTradesAction(userId)

// Access trades by account and instrument
const esTradesInAccount1 = groupedTrades['PROP-123']['ES']

// Or work with all trades
console.log(`Total trades: ${flattenedTrades.length}`)

removeAccountFromTradesAction

Delete all trades and the account for a specific account number.
server/accounts.ts:78
export async function removeAccountFromTradesAction(
  accountNumber: string
): Promise<void>
accountNumber
string
required
The account number to remove
Example
import { removeAccountFromTradesAction } from '@/server/accounts'

await removeAccountFromTradesAction('PROP-123')
// All trades and the account deleted

removeAccountsFromTradesAction

Delete multiple accounts and their trades in one operation.
server/accounts.ts:60
export async function removeAccountsFromTradesAction(
  accountNumbers: string[]
): Promise<void>
accountNumbers
string[]
required
Array of account numbers to remove
Example
import { removeAccountsFromTradesAction } from '@/server/accounts'

await removeAccountsFromTradesAction(['PROP-123', 'PROP-456'])
// All specified accounts and trades deleted

deleteTradesByIdsAction

Delete specific trades by their IDs.
server/accounts.ts:205
export async function deleteTradesByIdsAction(
  tradeIds: string[]
): Promise<void>
tradeIds
string[]
required
Array of trade IDs to delete
Example
import { deleteTradesByIdsAction } from '@/server/accounts'

await deleteTradesByIdsAction(['trade_123', 'trade_456', 'trade_789'])

Instrument Operations

deleteInstrumentGroupAction

Delete all trades for a specific instrument in an account.
server/accounts.ts:90
export async function deleteInstrumentGroupAction(
  accountNumber: string,
  instrumentGroup: string,
  userId: string
): Promise<void>
accountNumber
string
required
The account number
instrumentGroup
string
required
Instrument prefix (e.g., ‘ES’, ‘NQ’)
userId
string
required
User ID for verification
Example
import { deleteInstrumentGroupAction } from '@/server/accounts'

// Delete all ES futures trades
await deleteInstrumentGroupAction('PROP-123', 'ES', userId)
Uses startsWith matching, so ‘ES’ will match ‘ES’, ‘ESH24’, ‘ESM24’, etc.

renameInstrumentAction

Rename an instrument across all trades in an account.
server/accounts.ts:470
export async function renameInstrumentAction(
  accountNumber: string,
  oldInstrumentName: string,
  newInstrumentName: string
): Promise<void>
accountNumber
string
required
The account number
oldInstrumentName
string
required
Current instrument name
newInstrumentName
string
required
New instrument name
Example
import { renameInstrumentAction } from '@/server/accounts'

// Rename ES to NQ for all trades
await renameInstrumentAction('PROP-123', 'ES', 'NQ')

updateCommissionForGroupAction

Update commission for all trades in an instrument group.
server/accounts.ts:106
export async function updateCommissionForGroupAction(
  accountNumber: string,
  instrumentGroup: string,
  newCommission: number
): Promise<void>
accountNumber
string
required
The account number
instrumentGroup
string
required
Instrument prefix
newCommission
number
required
Commission per contract
Example
import { updateCommissionForGroupAction } from '@/server/accounts'

// Update ES commission to $2.50 per contract
await updateCommissionForGroupAction('PROP-123', 'ES', 2.50)
// Each trade's commission = 2.50 * quantity
Commission is automatically calculated as: newCommission × trade.quantity

Metrics Calculation

calculateAccountBalanceAction

Calculate current balance for accounts based on trades and starting balance.
server/accounts.ts:546
export async function calculateAccountBalanceAction(
  accounts: Account[],
  processedTrades?: Trade[]
): Promise<Account[]>
accounts
Account[]
required
Array of accounts to calculate balance for
processedTrades
Trade[]
Optional pre-fetched trades (improves performance)
accounts
Account[]
Accounts with balanceToDate property populated
Example
import { calculateAccountBalanceAction, getAccountsAction } from '@/server/accounts'

const accounts = await getAccountsAction()
const accountsWithBalance = await calculateAccountBalanceAction(accounts)

accountsWithBalance.forEach(account => {
  console.log(`${account.number}: $${account.balanceToDate}`)
})
Balance Calculation:
balance = startingBalance + (sum of trade PnL - sum of commissions)

calculateAccountMetricsAction

Calculate comprehensive metrics including consistency, trading days, and daily performance.
server/accounts.ts:636
export async function calculateAccountMetricsAction(
  accounts: Account[]
): Promise<Account[]>
accounts
Account[]
required
Array of accounts to calculate metrics for
accounts
Account[]
Accounts with metrics and dailyMetrics properties populated
Example
import { calculateAccountMetricsAction } from '@/server/accounts'

const accountsWithMetrics = await calculateAccountMetricsAction(accounts)

accountsWithMetrics.forEach(account => {
  console.log(`Account: ${account.number}`)
  console.log(`Win Rate: ${account.metrics.winRate}%`)
  console.log(`Consistency: ${account.metrics.consistency}%`)
  console.log(`Avg Win: $${account.metrics.avgWin}`)
  console.log(`Trading Days: ${account.metrics.tradingDays}`)
  
  // Daily metrics available
  account.dailyMetrics.forEach(day => {
    console.log(`${day.date}: $${day.pnl}`)
  })
})
Computed Metrics:
  • Win rate and loss rate
  • Average win and average loss
  • Profit factor
  • Consistency score
  • Trading days count
  • Daily PnL breakdown
This function fetches trades internally for optimal performance and uses shared computation logic with the client.

Payout Management

savePayoutAction

Create or update a payout record.
server/accounts.ts:378
export async function savePayoutAction(
  payout: Payout
): Promise<Payout>
payout
Payout
required
Payout object with:
  • id: Unique ID (generated if creating new)
  • accountNumber: Associated account
  • amount: Payout amount
  • date: Payout date
  • status: Payout status
payout
Payout
The saved payout record
Example
import { savePayoutAction } from '@/server/accounts'

const payout = await savePayoutAction({
  id: crypto.randomUUID(),
  accountNumber: 'PROP-123',
  amount: 5000,
  date: new Date('2024-03-15'),
  status: 'PENDING'
})

console.log('Payout created:', payout.id)

deletePayoutAction

Delete a payout and decrement the account’s payout count.
server/accounts.ts:430
export async function deletePayoutAction(
  payoutId: string
): Promise<boolean>
payoutId
string
required
The payout ID to delete
success
boolean
Whether deletion was successful
Example
import { deletePayoutAction } from '@/server/accounts'

try {
  await deletePayoutAction('payout_123')
  console.log('Payout deleted')
} catch (error) {
  console.error('Failed to delete payout:', error)
}

Account Reset

checkAndResetAccountsAction

Check for accounts with reset dates and reset them if the date has passed.
server/accounts.ts:495
export async function checkAndResetAccountsAction(): Promise<void>
Example
import { checkAndResetAccountsAction } from '@/server/accounts'

// Run daily (e.g., in a cron job)
await checkAndResetAccountsAction()
// Accounts with resetDate <= today will have resetDate cleared
This should be called periodically (e.g., daily cron job) to automatically reset accounts.

Cache Management

Account operations automatically update relevant cache tags:
updateTag(`trades-${userId}`)      // Trade data changed
updateTag(`user-data-${userId}`)   // Account data changed
This ensures the UI stays synchronized with database changes.

Best Practices

Pass pre-fetched trades to calculateAccountBalanceAction to avoid redundant queries:
const trades = await fetchGroupedTradesAction(userId)
const accountsWithBalance = await calculateAccountBalanceAction(
  accounts,
  trades.flattenedTrades
)
Always include userId in queries to prevent unauthorized access:
const account = await prisma.account.findFirst({
  where: {
    id: accountId,
    userId: await getUserId() // Always verify ownership
  }
})

Trade Operations

Manage trades, tags, and images

Subscriptions

Manage user subscriptions and billing

Build docs developers (and LLMs) love