DEV Community

Cover image for How a Forex Trading Cost Calculator Works: Spread, Commission and Swap in Python
Amanda Vance
Amanda Vance

Posted on

How a Forex Trading Cost Calculator Works: Spread, Commission and Swap in Python

People often ask what happens under the hood when they type numbers into an automated forex trading fee calculator. This post answers that by building the same underlying calculation engine from scratch in Python.

The formulas below represent the standard mathematical models used across institutional and retail markets. The prices in the examples are static figures for illustration, not live API quotes.

The Three Costs of a Trade

According to foreign exchange turnover data tracked by institutions like the Bank for International Settlements (BIS), retail currency volume continues to scale across both dealer networks and ECN venues. Every trade executed across these networks carries up to three distinct costs:

  1. Spread: The gap between the bid and ask price. A trader pays this the exact moment they execute the order.
  2. Commission: A fixed fee per lot, charged predominantly on raw or ECN-style accounts. Brokers usually quote this per "round turn," meaning it covers both opening and closing the position.
  3. Swap: The rollover charge (or credit) for holding a position past the daily settlement cutoff. A breakdown of the underlying rate differentials is detailed in Investopedia's currency swap guide.

Everything else—platform subscription fees, deposit and withdrawal fees, and inactivity charges—sits outside the execution itself, so the calculator ignores them.

Step 1: Pip Size and Pip Value

A pip is the standardized unit for measuring exchange-rate price moves. As outlined in Investopedia's explanation of pips, for most currency pairs, a pip equals 0.0001. For pairs quoted against the Japanese Yen (JPY), it equals 0.01.

Pip value depends entirely on the position's lot size and the quote currency (the second currency in the pair). One standard lot equals 100,000 units of the base currency. To report everything cleanly in USD, the code below converts the quote currency utilizing a small static rate dictionary. We structure the data structures using standard Python dataclasses:

from dataclasses import dataclass

# Illustrative static prices for the examples below.
RATES = {
    "EURUSD": 1.1000, "GBPUSD": 1.3000, "USDJPY": 150.00, "USDCHF": 0.9000,
    "USDCAD": 1.3500, "AUDUSD": 0.6500, "NZDUSD": 0.6000,
    "EURJPY": 165.00, "GBPJPY": 195.00, "EURGBP": 0.8462,
}
LOT = 100_000

def pip_size(pair: str) -> float:
    return 0.01 if pair.endswith("JPY") else 0.0001

def to_usd(currency: str) -> float:
    """USD value of one unit of `currency`, using the table above."""
    if currency == "USD":
        return 1.0
    if f"{currency}USD" in RATES:
        return RATES[f"{currency}USD"]
    return 1.0 / RATES[f"USD{currency}"]

def pip_value_usd(pair: str, lots: float) -> float:
    quote = pair[3:]
    return LOT * pip_size(pair) * lots * to_usd(quote)

def notional_usd(pair: str, lots: float) -> float:
    return LOT * lots * to_usd(pair[:3])

def rollovers(days: int, start_weekday: int) -> int:
    """Nights charged. Weekday 0 = Monday. Wednesday night counts triple."""
    nights = 0
    for d in range(days):
        wd = (start_weekday + d) % 7
        if wd in (5, 6):          # Saturday, Sunday: no rollover
            continue
        nights += 3 if wd == 2 else 1
    return nights

Enter fullscreen mode Exit fullscreen mode

The only part requiring care is the to_usd function. For a pair like GBPJPY, the quote currency is Yen. The code finds USDJPY in the dictionary and mathematically inverts it. A production-ready calculator would pull live quotes via an exchange API rather than a static dictionary.

Step 2: The Cost Formulas

With the pip value established, calculating each specific cost requires just one line of arithmetic:

  • Spread cost = spread in pips × pip value
  • Commission = commission per lot × lots
  • Swap cost = swap in pips per night × pip value × nights charged

Total cost equals the sum of the three. Dividing that total cost by the pip value reveals the "break-even distance"—the exact number of pips the market price must move in your favor just to bring the trade's P&L back to zero.

@dataclass
class Costs:
    spread: float
    commission: float
    swap_cost: float
    total: float
    break_even_pips: float
    pct_of_notional: float

def trading_cost(pair, lots, spread_pips, commission_per_lot=0.0,
                 swap_pips_per_night=0.0, days=0, start_weekday=0) -> Costs:

    pv = pip_value_usd(pair, lots)
    spread = spread_pips * pv
    commission = commission_per_lot * lots

    # Broker swap: negative usually means a charge, so cost is its opposite
    swap_cost = -swap_pips_per_night * pv * rollovers(days, start_weekday) + 0.0 
    total = spread + commission + swap_cost

    return Costs(
        spread=spread,
        commission=commission,
        swap_cost=swap_cost,
        total=total,
        break_even_pips=total / pv,
        pct_of_notional=100 * total / notional_usd(pair, lots),
    )

Enter fullscreen mode Exit fullscreen mode

Step 3: Counting Swap Nights

Swap calculations often trip up developers because the number of nights held does not match calendar days. Standard spot FX trades settle on a $T+2$ basis, as explained in the Corporate Finance Institute guide to forex rollover.

Weekends carry no rollover execution of their own. To compensate, brokers charge a "triple swap" on a designated weekday (almost universally Wednesday) to account for settlement rollover across Saturday and Sunday. The rollovers function defined above handles both conditions.

A trade opened on Tuesday and held for three days hits Tuesday, Wednesday (which counts three times), and Thursday—totaling 5 nights of swap charges.

Conversely, a trade opened on Friday and held for five days hits Friday night, skips Saturday and Sunday entirely, then hits Monday and Tuesday—totaling just 3 nights. In a test run, rollovers(5, 4) returns 3.

Brokers typically quote swap rates as signed values where a negative figure represents a debit. The code flips the sign so that charges register as positive costs while interest credits reduce the net fee.

Worked Examples

These are the exact numbers the Python script outputs. You can manually verify each calculation.

1. Standard Account: EUR/USD, 1 lot, 1.2 pip spread

  • Pip value: $10.00
  • Spread cost: 1.2 × 10 = $12.00
  • Total: $12.00, break-even 1.2 pips (0.0109% of total trade value)

2. ECN Account: EUR/USD, 1 lot, 0.1 pip spread, $7 round-turn commission

  • Spread cost: 0.1 × 10 = $1.00
  • Commission: $7.00
  • Total: $8.00, break-even 0.8 pips (0.0073% of total trade value)

The ECN account runs cheaper in this scenario, which is typical when executing a full 1.0 lot of trading volume. That spread advantage narrows significantly on fractional micro-lots if a brokerage enforces minimum ticket commissions.

3. GBP/JPY: 0.5 lot, 1.5 pip spread, swap of -0.8 pips a night, held 3 days from Tuesday

  • Pip value: 100,000 × 0.01 × 0.5 ÷ 150 = $3.33
  • Spread cost: 1.5 × 3.33 = $5.00
  • Swap: 0.8 × 3.33 × 5 nights = $13.33
  • Total: $18.33, break-even 5.5 pips

In this swing scenario, the holding costs exceed the initial spread. This demonstrates why rollover rates dictate long-term holding strategies while having minimal impact on intraday scalps.

What the Calculator Leaves Out

A few variables change real-world execution costs that cannot be hardcoded into a static script:

  • Volatility and Liquidity Spikes: Spreads widen rapidly around Tier-1 macroeconomic releases and during the daily 5:00 PM EST rollover. The inputs in this script represent median averages rather than guaranteed fills.
  • Broker Rounding: Brokerage platforms round internal pip fractions and daily interest debits differently, creating minor cent-level discrepancies against manual calculations.
  • Swap-Free Accounts: Islamic or swap-free accounts replace variable interest debits with fixed administrative fees or eliminate overnight holding costs under specific conditions.

To evaluate these variables in a live interface, use the browser-based BrokerCatalogue fee calculator. It processes the pair, position sizing, account structure, spread, commission, and swap rates directly, displaying the net cost, percentage impact, and required break-even pip distance.

Try it

Copy the Python script, configure the RATES dictionary with current market quotes, and run trading_cost using your broker's published schedule to compare fee profiles across multiple platforms.

Top comments (1)

Collapse
 
suppdevbot profile image
DEV SUPPORTS •
You need to verify your account.
Enter fullscreen mode Exit fullscreen mode

tr.ee/dev-to