Overview

Roxom APIs use standardized decimal formatting to ensure precision and consistency across all financial data. Understanding these formats is crucial for accurate calculations and data interpretation.

Precision Standards

All monetary and price values in Roxom APIs follow these precision standards:
Data TypeDecimal PlacesExample
Prices812345.67890123
Quantities81000.50000000
Balances89999.99999999
Percentages415.2500
Rates80.00012345

String Representation

All numerical values are returned as strings to prevent precision loss during JSON parsing.

Example Response

{
  "balance": "1234.56789012",
  "price": "45.67800000",
  "quantity": "100.00000000",
  "feeRate": "0.00100000"
}

Parsing Guidelines

JavaScript/TypeScript

// ❌ Don't use parseFloat (precision loss)
const price = parseFloat("12.34567890"); // 12.345678899999999

// ✅ Use a decimal library
import Decimal from 'decimal.js';
const price = new Decimal("12.34567890"); // Exact precision

// ✅ Or use BigInt for integer calculations
const priceInSatoshis = BigInt("1234567890"); // For 8 decimal places

Python

# ❌ Don't use float (precision loss)
price = float("12.34567890")  # 12.345678899999999

# ✅ Use Decimal for exact precision
from decimal import Decimal
price = Decimal("12.34567890")  # Exact precision

# Example calculation
quantity = Decimal("100.50000000")
total = price * quantity  # Exact result

Java

// ❌ Don't use double (precision loss)
double price = Double.parseDouble("12.34567890");

// ✅ Use BigDecimal for exact precision
import java.math.BigDecimal;
BigDecimal price = new BigDecimal("12.34567890");

// Example calculation with proper scale
BigDecimal quantity = new BigDecimal("100.50000000");
BigDecimal total = price.multiply(quantity);

Currency Pairs and Precision

Different trading pairs may have specific precision requirements:

Major Pairs (8 decimal places)

{
  "BTC/USD": {
    "price": "45000.12345678",
    "minQuantity": "0.00000001"
  }
}

Minor Pairs (6 decimal places)

{
  "ETH/USDT": {
    "price": "3000.123456",
    "minQuantity": "0.000001"
  }
}

Formatting for Display

When displaying values to users, consider appropriate rounding:
// For prices - show relevant decimal places
function formatPrice(priceString, symbol) {
  const price = new Decimal(priceString);
  
  if (symbol.includes('USD')) {
    return price.toFixed(2); // $45,000.12
  } else if (symbol.includes('BTC')) {
    return price.toFixed(8); // 0.12345678 BTC
  }
}

// For balances - avoid trailing zeros
function formatBalance(balanceString) {
  return new Decimal(balanceString).toString(); // Removes trailing zeros
}

Validation

Always validate decimal inputs before sending to the API:
from decimal import Decimal, InvalidOperation

def validate_decimal(value, max_places=8):
    try:
        decimal_value = Decimal(str(value))
        
        # Check decimal places
        if decimal_value.as_tuple().exponent < -max_places:
            raise ValueError(f"Too many decimal places (max {max_places})")
            
        return str(decimal_value)
    except InvalidOperation:
        raise ValueError("Invalid decimal format")

# Example usage
try:
    valid_price = validate_decimal("12.34567890")  # ✅ Valid
    invalid_price = validate_decimal("12.123456789")  # ❌ Too many decimals
except ValueError as e:
    print(f"Validation error: {e}")

Common Pitfalls

Next Steps

Market Data

Learn how decimal formatting applies to market data endpoints