Skip to main content
Deltalytix offers multiple ways to import your trading data, including CSV imports with AI-powered field mapping and manual trade entry.

CSV Import with AI Mapping

Overview

The AI-powered CSV import automatically maps your CSV columns to Deltalytix fields, saving you time and reducing errors.

Supported Platforms

Rithmic Performance

Import from Rithmic performance reports

NinjaTrader

Import NinjaTrader performance data

Quantower

Import Quantower trading history

TradeZella

Import from TradeZella exports

Topstep

Import Topstep funded account data

ATAS

Import ATAS platform data

Import Process

1

Upload CSV File

Drag and drop your CSV file or click to browse:
<div className="dropzone">
  <p>Drag and drop your files here</p>
  <p>or click to browse your files</p>
</div>
Supported formats: .csv, .xlsx, .xls
2

Select Header Row

Choose the row containing column headers. The system automatically detects headers in most cases.
3

AI Column Mapping

Let AI automatically map your columns:The AI analyzes your data and maps columns to required fields:
  • Instrument/Symbol
  • Entry Date
  • Close Date
  • Quantity
  • Entry Price
  • Close Price
  • P&L
  • Commission (optional)
  • Side/Direction (optional)
4

Review and Adjust

Review the AI mappings and adjust if needed. Required fields are marked with an asterisk (*).
5

Select Account

Choose an existing account or create a new one for the imported trades.

AI Field Mapping

The AI mapping system uses sample data to intelligently map columns:
// Column mapping component
const { object, submit, isLoading } = useObject({
  api: '/api/ai/mappings',
  schema: mappingSchema,
  onFinish({ object }) {
    if (object) {
      Object.entries(object).forEach(([destinationColumn, headerValue]) => {
        // Map AI-suggested column to destination field
        const headerIndex = headers.findIndex(h => h === headerValue);
        if (headerIndex !== -1) {
          const uniqueId = createUniqueColumnId(headerValue, headerIndex);
          newMappings[uniqueId] = destinationColumn;
        }
      });
    }
  }
});

// Trigger AI mapping
submit({ 
  fieldColumns: headers, 
  firstRows: sampleData 
});

Manual Column Mapping

You can also manually map columns if AI suggestions need adjustment:
<Select 
  onValueChange={(value) => handleMapping(uniqueId, value)} 
  value={mappings[uniqueId] || ""}
>
  <SelectTrigger>
    <SelectValue placeholder="Select one" />
  </SelectTrigger>
  <SelectContent>
    {destinationColumns.map((column) => (
      <SelectItem value={column}>
        {column}
        {columnConfig[column].required && (
          <span className="text-yellow-500">*</span>
        )}
      </SelectItem>
    ))}
  </SelectContent>
</Select>

Required Fields

These fields must be mapped for successful import:
  • Instrument: Trading symbol (ES, NQ, etc.)
  • Entry Date: When the position was opened
  • Close Date: When the position was closed
  • Quantity: Number of contracts traded
  • Entry Price: Opening price
  • Close Price: Closing price
  • P&L: Profit or loss for the trade

Optional Fields

  • Account Number: Trading account identifier
  • Entry ID: Order ID for entry
  • Close ID: Order ID for exit
  • Time in Position: Duration of the trade
  • Side: Long or Short
  • Commission: Trading fees

Column Configuration

const columnConfig: ColumnConfig = {
  "instrument": { 
    defaultMapping: ["symbol", "ticker"], 
    required: true 
  },
  "entryDate": { 
    defaultMapping: ["buydate", "entrydate"], 
    required: true 
  },
  "closeDate": { 
    defaultMapping: ["selldate", "exitdate"], 
    required: true 
  },
  "quantity": { 
    defaultMapping: ["qty", "amount"], 
    required: true 
  },
  "entryPrice": { 
    defaultMapping: ["buyprice", "entryprice"], 
    required: true 
  },
  "closePrice": { 
    defaultMapping: ["sellprice", "exitprice"], 
    required: true 
  },
  "pnl": { 
    defaultMapping: ["pnl", "profit"], 
    required: true 
  },
  "commission": { 
    defaultMapping: ["commission", "fee"], 
    required: false 
  }
};

Manual Trade Entry

When to Use Manual Entry

  • Adding individual trades not captured by broker exports
  • Testing the platform with sample data
  • Recording trades from platforms without export features
  • Making corrections to imported data

Adding a Trade Manually

  1. Navigate to Import → Manual Entry
  2. Click Add Trade
  3. Fill in the trade details:
interface TradeFormData {
  instrument: string
  side: 'long' | 'short'
  quantity: number
  entryPrice: number
  closePrice: number | null
  entryDate: string
  closeDate: string | null
  pnl: number
  timeInPosition: number | null
  commission: number | null
}

Manual Trade Entry Form

Manual trade entry form
The form includes:
  • Instrument: Symbol name (e.g., ES, NQ)
  • Side: Long or Short position
  • Quantity: Number of contracts
  • Entry Price: Opening price
  • Close Price: Closing price (optional for open positions)
  • Entry Date: Date and time of entry
  • Close Date: Date and time of exit (optional)
  • P&L: Profit/loss amount
  • Time in Position: Duration in seconds (auto-calculated)
  • Commission: Trading fees (auto-suggested if available)

Auto-Calculations

Commission Estimation

The system suggests commissions based on previous trades:
const existingCommissions = useMemo(() => {
  const commissions: { [key: string]: number } = {}
  existingTrades
    .filter(trade => accountNumbers.includes(trade.accountNumber))
    .forEach(trade => {
      if (trade.instrument && trade.commission && trade.quantity) {
        commissions[trade.instrument] = trade.commission / trade.quantity
      }
    })
  return commissions
}, [existingTrades, accountNumbers])

let commission = formData.commission
if (!commission && existingCommissions[formData.instrument]) {
  commission = existingCommissions[formData.instrument] * formData.quantity
}

Time in Position

Automatically calculated from entry and close dates:
let timeInPosition = formData.timeInPosition
if (!timeInPosition && formData.entryDate && formData.closeDate) {
  const entry = new Date(formData.entryDate)
  const close = new Date(formData.closeDate)
  timeInPosition = Math.floor((close.getTime() - entry.getTime()) / 1000)
}

Managing Manual Trades

The manual trade table allows you to:
  • Edit: Modify trade details
  • Delete: Remove individual trades
  • View Summary: See total P&L and commissions
<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Instrument</TableHead>
      <TableHead>Side</TableHead>
      <TableHead>Quantity</TableHead>
      <TableHead>Entry Price</TableHead>
      <TableHead>Close Price</TableHead>
      <TableHead>PnL</TableHead>
      <TableHead>Actions</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    {processedTrades.map((trade) => (
      <TableRow key={trade.id}>
        {/* Trade data */}
        <TableCell>
          <Button onClick={() => handleEdit(index)}>
            <Edit2 className="h-4 w-4" />
          </Button>
          <Button onClick={() => handleDelete(index)}>
            <Trash2 className="h-4 w-4" />
          </Button>
        </TableCell>
      </TableRow>
    ))}
  </TableBody>
</Table>

Commission Management

After importing, you may need to confirm or update commission rates:
Commissions are calculated as “round turn” - the total cost for both entry and exit.

Setting Commissions

  1. After import, you’ll see a commission prompt for instruments without commission data
  2. Enter the round turn commission per contract
  3. Click Apply Commissions
Example:
  • If your broker charges $2.50 per side
  • Enter $5.00 as the round turn commission

Data Preview

Before finalizing the import, review your trades:
<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Instrument</TableHead>
      <TableHead>Entry Date</TableHead>
      <TableHead>Close Date</TableHead>
      <TableHead>Quantity</TableHead>
      <TableHead>PnL</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    {csvData.slice(1, 4).map((row, index) => (
      <TableRow key={index}>
        {/* Preview data */}
      </TableRow>
    ))}
  </TableBody>
</Table>
The preview shows the first 100 trades. All trades will be imported when you click Save.

Best Practices

  1. Backup Your Data: Keep original CSV files as backups
  2. Verify Mappings: Always review AI-suggested mappings
  3. Check Dates: Ensure dates are in the correct timezone
  4. Commission Accuracy: Set accurate commission rates for better analytics
  5. Account Organization: Use consistent account naming

Troubleshooting

Import Errors

Required Fields Not Mapped
  • Ensure all required fields are mapped
  • Check that your CSV contains the necessary data
Duplicate Trades Detected
  • The system prevents duplicate imports
  • Check if trades were already imported
Invalid Date Format
  • Dates should be in ISO format or recognizable date format
  • Use the format preview to verify dates are parsed correctly
No Trades Added
  • Verify CSV data is properly formatted
  • Check that rows contain actual trade data
  • Ensure all required fields have values

Broker Sync

Set up automatic broker synchronization

Account Management

Organize imported trades by account

Build docs developers (and LLMs) love