Lots, pips and position size, explained

What lots, pips and points mean on MT4 and MT5, how to work out pip value, and how to size a position from a risk amount and a stop distance in Python.

A price chart with an entry line and a stop line, a measured gap between them, and a stack of lot blocks beside it.

Every order you send to MetaTrader has a size, and the size decides how much money each move in price is worth. Get it wrong by a factor of ten and a normal losing trade becomes a large one. It happens more often than it should, usually because a pip, a point and a tick got mixed up.

This post explains the units MetaTrader 4 (MT4) and MetaTrader 5 (MT5) use for size and price: lots, contract size, pips, points and ticks. Then it shows how to turn “I am willing to lose this much if my stop is hit” into a volume, with a worked example and a short Python function.

How much you risk on a trade is your decision. This post only shows the arithmetic.

Lots and contract size

A lot is MetaTrader’s unit of trade size. The volume field of every order is in lots.

On most currency pairs, one lot is 100,000 units of the base currency (the first currency in the pair, so euros in EURUSD). That number is the symbol’s contract size. Traders use a few names for common sizes:

NameLotsUnits on a 100,000 contract
Standard lot1.00100,000
Mini lot0.1010,000
Micro lot0.011,000

The names only make sense for currency pairs. Other symbols have their own contract sizes, set by the broker. A gold contract is often 100 ounces, an index might be 1 or 10 times the index value, and a crypto symbol might be 1 coin. Never assume 100,000. Read the contract size from the symbol’s specification.

Volume limits and steps

Each symbol also has three volume rules:

  • Minimum volume, often 0.01 lots.
  • Maximum volume per order.
  • Volume step, the increment sizes must follow, often 0.01.

An order for 0.137 lots on a symbol with a step of 0.01 is invalid. The broker refuses it with an “invalid volume” error rather than rounding it for you. So round in your own code, and round down, so the rounded size never risks more than you intended.

Pips, points and ticks

These three words describe price steps, and they are not the same thing.

  • A point is the smallest price step a symbol is quoted in. It follows the number of decimal places (the symbol’s digits). On a five-digit EURUSD quote such as 1.08453, one point is 0.00001.
  • A pip is the traditional unit for currency moves. On most pairs it is the fourth decimal place, 0.0001. On pairs quoted against the Japanese yen it is the second decimal place, 0.01.
  • A tick is the smallest step the price can actually move, the tick size. For most currency pairs it equals one point. For some indices and commodities it is larger, such as 0.25 or 0.5.

Most brokers now quote currency pairs with one extra digit, which is why you see five-digit and three-digit prices:

QuoteExamplePointPipPoints per pip
5-digitEURUSD 1.084530.000010.000110
3-digitUSDJPY 151.2370.0010.0110
4-digit (older)EURUSD 1.08450.00010.00011

This is where the factor of ten comes from. MetaTrader settings such as stops level, freeze level and slippage are in points. Traders talk in pips. A “20 pip stop” is 200 points on a five-digit quote. If your code passes 20 where the field expects points, the stop is ten times closer than you meant.

Pips are a convention for currency pairs. For gold, indices or crypto there is no agreed pip, so work in price units or points instead.

Pip value and tick value

Pip value is how much money one pip is worth for a given size. For one standard lot of EURUSD on an account in US dollars:

pip value = contract size x pip = 100,000 x 0.0001 = 10 USD per lot

So 0.10 lots is worth 1 USD per pip and 0.01 lots is worth 0.10 USD per pip.

That simple sum only works when the second currency of the pair (the profit currency) is the same as your account currency. For USDJPY the profit currency is the yen, so the value of a pip must be converted:

pip value = 100,000 x 0.01 / 151.237 = about 6.61 USD per lot

That value moves as the USDJPY rate moves. Conversions like this are easy to get subtly wrong, which is why MetaTrader works it out for you as the tick value: the money, in your account currency, that one tick is worth for one lot. MT5 even reports two versions, one for a profitable move and one for a losing move, because the conversion rate differs slightly between them.

With tick size and tick value you no longer need to care about pips, currencies or contract types. The same formula works for every symbol:

money per lot for a move of D = D / tick size x tick value

Sizing a position from risk and stop distance

Sizing a position means answering one question: what volume makes the loss at my stop equal to the amount I chose to risk?

You need three inputs:

  1. The risk amount, in account currency. You decide this.
  2. The stop distance, the price gap between your entry and your stop loss.
  3. The symbol’s tick size, tick value and volume rules.

Then:

loss per lot = stop distance / tick size x tick value
volume       = risk amount / loss per lot, rounded down to the volume step

A worked example

Say the account is in US dollars and you want to buy EURUSD with a stop 25 pips below your entry. For the example, the risk amount is 100 USD. The symbol specification says:

  • tick size 0.00001, tick value 1.00 USD (one lot, one tick),
  • minimum volume 0.01, maximum 100, step 0.01.

Step by step:

  1. Stop distance: 25 pips x 0.0001 = 0.0025 in price.
  2. Ticks to the stop: 0.0025 / 0.00001 = 250 ticks.
  3. Loss per lot at the stop: 250 x 1.00 = 250 USD.
  4. Volume: 100 / 250 = 0.40 lots.
  5. Round down to the step of 0.01: 0.40 lots.

Check it the long way: 0.40 lots is 40,000 euros, and a 0.0025 move on 40,000 is 100 USD.

Change the stop to 33 pips and the raw answer is 0.303 lots, which rounds down to 0.30. The real risk is then slightly under 100 USD, which is the safe side of the rounding.

When the size is too small

If the raw volume is below the minimum, you can’t place the trade at that risk. Rounding up to the minimum would risk more than you chose. A careful program skips the trade and logs why, rather than silently trading a bigger size.

What the stop distance does not cover

The sum assumes the stop fills exactly at its price. It may not. A stop loss becomes a market order when it is triggered, and in a fast market or over a weekend gap it can fill further away. The spread also matters: a buy closes at the bid, so the bid has to reach your stop. Commission and swap come on top. Treat the result as the loss in normal conditions, not a ceiling.

A Python function for position size

The function below does the arithmetic and the rounding. It is generic: pass in the values from your symbol specification.

import math

def position_size(risk_money: float, stop_distance: float,
                  tick_size: float, tick_value: float,
                  min_volume: float, max_volume: float, volume_step: float) -> float:
    """Volume in lots that loses about risk_money if price moves stop_distance
    against the position. Returns 0.0 if even the minimum volume risks more."""
    if risk_money <= 0 or stop_distance <= 0:
        raise ValueError("risk and stop distance must be positive")
    if tick_size <= 0 or tick_value <= 0:
        raise ValueError("tick size and tick value must be known and positive")

    loss_per_lot = stop_distance / tick_size * tick_value
    raw = risk_money / loss_per_lot

    steps = math.floor(raw / volume_step + 1e-9)  # round down, allow float noise
    volume = round(steps * volume_step, 8)

    if volume < min_volume:
        return 0.0
    return min(volume, max_volume)


# The worked example: 100 USD risk, 25 pip stop on EURUSD.
print(position_size(100, 0.0025, 0.00001, 1.0, 0.01, 100, 0.01))  # 0.4
print(position_size(100, 0.0033, 0.00001, 1.0, 0.01, 100, 0.01))  # 0.3

Two details are deliberate. The small 1e-9 stops floating point noise from turning 40.0 steps into 39.999 and losing a step. The final round turns 0.30000000000000004 into 0.3, so the volume you send is clean.

Use the tick value for a losing move when the platform gives you one, because the stop loss is a losing move. Read the values close to the time of the trade, since tick value changes whenever the profit currency differs from the account currency.

Doing this with Tickwire

On Tickwire the inputs come from two calls, for MT4 and MT5 accounts alike:

  • GET /users/current/accounts/<ACCOUNT_ID>/symbols/EURUSD/specification returns contractSize, tickSize, point, digits, minVolume, maxVolume and volumeStep, plus pipSize for currency pairs.
  • GET /users/current/accounts/<ACCOUNT_ID>/symbols/EURUSD/current-price returns bid, ask, profitTickValue and lossTickValue, in the account currency for one lot.
import os
import requests

BASE = "https://api.tickwire.io/users/current/accounts/" + os.environ["TW_ACCOUNT"]
HEAD = {"auth-token": os.environ["TW_KEY"]}

spec = requests.get(f"{BASE}/symbols/EURUSD/specification", headers=HEAD, timeout=10).json()
price = requests.get(f"{BASE}/symbols/EURUSD/current-price", headers=HEAD, timeout=10).json()

volume = position_size(100, 25 * spec["pipSize"], spec["tickSize"], price["lossTickValue"],
                       spec["minVolume"], spec["maxVolume"], spec["volumeStep"])

Broker symbol names can carry a suffix, so list them with GET .../symbols first. An order whose volume breaks the symbol’s rules comes back rejected with an invalid volume code, and nothing reaches the market. Tickwire has no built-in size or loss limits: those rules belong in your code, or in a pre-trade hook if an AI agent places the orders.

The quickstart shows a first order end to end, and MT4 and MT5 lists the few differences between the platforms.

Key points

  • volume is in lots, and a lot is the symbol’s contract size, which is not always 100,000.
  • A point is the smallest quoted step, a pip is a currency convention, a tick is the smallest real move. On five-digit and three-digit quotes, one pip is ten points.
  • Settings like stops level and slippage are in points, not pips.
  • Pip value depends on the profit currency. Tick value already converts it to your account currency.
  • Volume = risk amount / (stop distance / tick size x tick value), rounded down to the step.
  • If the result is below the minimum volume, skip the trade instead of rounding up.
  • A stop can fill beyond its price, so the risk amount is a normal case, not a limit.
  • Practise on a demo account before you risk money, and check the size of every trade your code sends.

Trading carries risk, and you can lose money. This post explains software and how it behaves; it is not investment advice.

Try it on your own account

7-day free trial. See pricing or read the quickstart.