# How Price Is Calculated in Poly Data Trades: A Deep Dive into the Live-Trade Processor

> Discover how Poly Data calculates trade prices by dividing USDC-filled amounts by non-USDC token amounts. Learn the live-trade processor's logic for ratio direction.

- Repository: [warproxxx/poly_data](https://github.com/warproxxx/poly_data)
- Tags: deep-dive
- Published: 2026-04-21

---

**Poly Data calculates trade prices by dividing the USDC-filled amount by the non-USDC token amount, with the ratio direction determined by which side of the trade receives USDC.**

This article explains the exact price calculation logic used in the `warproxxx/poly_data` repository. The computation happens inside the `get_processed_df` function in [`update_utils/process_live.py`](https://github.com/warproxxx/poly_data/blob/main/update_utils/process_live.py), where raw on-chain order fill data gets transformed into human-readable trade prices denominated in USDC.

---

## Where the Price Calculation Lives

The core price logic is implemented in [`update_utils/process_live.py`](https://github.com/warproxxx/poly_data/blob/main/update_utils/process_live.py) at lines 91–95. This file contains the **Live-trade processor**, which ingests raw Polygon order fill events and produces a cleaned dataset with computed price columns.

The `get_processed_df` function performs several transformations in sequence:

1. Normalizes token amounts by dividing by 10⁶ (USDC and most tokens use 6 decimals)
2. Identifies which side of the trade is USDC
3. Determines trade direction (BUY vs SELL)
4. **Computes the price ratio based on which party received USDC**

---

## The Price Formula: USDC per Token

The price calculation uses a conditional expression that checks whether the **taker** received USDC:

```python
price = pl.when(pl.col("takerAsset") == "USDC") \
           .then(pl.col("takerAmountFilled") / pl.col("makerAmountFilled")) \
           .otherwise(pl.col("makerAmountFilled") / pl.col("takerAmountFilled")) \
           .cast(pl.Float64) \
           .alias("price")

```

This logic implements two cases:

| Scenario | Taker Direction | Price Formula | Result |
|----------|---------------|-------------|--------|
| Taker receives USDC | SELL | `takerAmountFilled / makerAmountFilled` | USDC received per token sold |
| Maker receives USDC | BUY | `makerAmountFilled / takerAmountFilled` | USDC paid per token bought |

The **price always represents the exchange rate of the non-USDC token in USDC terms**, regardless of which party initiated the trade.

---

## Step-by-Step Processing Pipeline

### 1. Amount Normalization

Before price calculation, raw on-chain amounts are converted to human-readable units:

```python

# Raw amounts are in base units (1e6 for USDC)

makerAmountFilled = event["makerAmountFilled"] / 1_000_000
takerAmountFilled = event["takerAmountFilled"] / 1_000_000

```

### 2. USDC Side Detection

The pipeline identifies which asset is USDC to set up the price ratio correctly:

```python

# Identify which side is USDC and set trade direction

is_taker_usdc = pl.col("takerAsset") == "USDC"
maker_direction = pl.when(is_taker_usdc).then("SELL").otherwise("BUY")
taker_direction = pl.when(is_taker_usdc).then("BUY").otherwise("SELL")

```

### 3. Price Computation

The final price column is computed using the conditional logic shown earlier, then cast to `Float64` for precision.

---

## Working Code Example

Here's a minimal reproduction of the price calculation using Polars:

```python
import polars as pl

# Simulated trade data (amounts already normalized)

trades = pl.DataFrame({
    "makerAsset": ["USDC", "WETH", "USDC"],
    "takerAsset": ["WETH", "USDC", "DAI"],
    "makerAmountFilled": [500.0, 2.0, 1000.0],   # e.g., 500 USDC, 2 WETH, 1000 USDC

    "takerAmountFilled": [0.25, 3000.0, 2000.0],  # e.g., 0.25 WETH, 3000 USDC, 2000 DAI

})

# Apply Poly Data's price calculation

price_df = trades.with_columns(
    pl.when(pl.col("takerAsset") == "USDC")
      .then(pl.col("takerAmountFilled") / pl.col("makerAmountFilled"))
      .otherwise(pl.col("makerAmountFilled") / pl.col("takerAmountFilled"))
      .alias("price")
)

print(price_df.select(["makerAsset", "takerAsset", "price"]))

```

**Output:**

```

shape: (3, 3)
┌────────────┬────────────┬────────┐
│ makerAsset ┆ takerAsset ┆ price  │
│ ---        ┆ ---        ┆ ---    │
│ str        ┆ str        ┆ f64    │
╞════════════╪════════════╪════════╡
│ USDC       ┆ WETH       ┆ 2000.0 │  # 500 USDC / 0.25 WETH = 2000 USDC/WETH

│ WETH       ┆ USDC       ┆ 1500.0 │  # 3000 USDC / 2 WETH = 1500 USDC/WETH

│ USDC       ┆ DAI        ┆ 0.5    │  # 1000 USDC / 2000 DAI = 0.5 USDC/DAI

└────────────┴────────────┴────────┘

```

---

## Key Files in the Price Calculation Pipeline

| File | Purpose | Key Function |
|------|---------|--------------|
| [`update_utils/process_live.py`](https://github.com/warproxxx/poly_data/blob/main/update_utils/process_live.py) | Core live-trade processing | `get_processed_df` — contains the price calculation at lines 91–95 |
| [`poly_utils/utils.py`](https://github.com/warproxxx/poly_data/blob/main/poly_utils/utils.py) | Market metadata helpers | `get_markets` — provides token-pair mappings used before price calc |
| [`update_utils/update_markets.py`](https://github.com/warproxxx/poly_data/blob/main/update_utils/update_markets.py) | Market data synchronization | Ensures token symbols are current for USDC detection |

---

## Summary

- **Price calculation location**: [`update_utils/process_live.py`](https://github.com/warproxxx/poly_data/blob/main/update_utils/process_live.py), lines 91–95, inside `get_processed_df`
- **Core formula**: Ratio of USDC amount to non-USDC token amount, with direction determined by which party received USDC
- **Taker receives USDC**: `price = takerAmountFilled / makerAmountFilled`
- **Maker receives USDC**: `price = makerAmountFilled / takerAmountFilled`
- **Normalization**: All amounts are divided by 10⁶ before calculation to handle USDC's 6-decimal precision
- **Output**: Price always represents **USDC per token** for the non-USDC asset

---

## Frequently Asked Questions

### How does Poly Data handle tokens with different decimal places?

The current implementation assumes 6 decimal places (dividing by 10⁶) since the pipeline is optimized for USDC-centric markets. For tokens with different decimals, you would need to extend the normalization step in [`process_live.py`](https://github.com/warproxxx/poly_data/blob/main/process_live.py) to read each token's `decimals` field from the contract or metadata before dividing.

### What happens if neither side of the trade is USDC?

The price calculation logic in `get_processed_df` expects one side to be USDC for the ratio to produce a meaningful price. If neither `makerAsset` nor `takerAsset` equals "USDC", the `otherwise` branch would still execute (`makerAmountFilled / takerAmountFilled`), but the resulting "price" would lack a stable reference unit and likely be filtered out or flagged in downstream analysis.

### Can I modify the price calculation to use a different base currency?

Yes. To use a different base currency (e.g., WETH or DAI), modify the conditional in [`process_live.py`](https://github.com/warproxxx/poly_data/blob/main/process_live.py) at lines 91–95. Change `pl.col("takerAsset") == "USDC"` to your target asset, and ensure the ratio direction aligns with your chosen base. You may also need to update the normalization factor if the new base token uses a different decimal precision than 6.