返回博客

什么是外汇中的点(Pip)?开发者的点、点子(Pipette)与外汇数学指南(2026)

V
Vlado Grigirov
May 10, 2026
Currency API Exchange Rates Forex Education Developer Guide Pips Finexly

什么是外汇中的点(Pip)?开发者的点、点子(Pipette)与外汇数学指南(2026)

如果你正在构建交易机器人、仓位计算器、风险面板或任何与外汇相关的产品,你很快会遇到这个问题:什么是外汇中的点(pip),如何在代码中计算它的价值? 一旦搞错,你的盈亏就会偏离,止损会在错误的水平触发,用户对此不会有耐心。

本指南从开发者的角度解释点、点子(pipette)以及完整的点值公式,附带 JavaScript、Python、PHP 和 cURL 的可复制代码示例。读完之后,你将拥有一个可工作的点值计算器,它从 Finexly API 文档 拉取实时汇率,并处理教科书未涵盖的每个边界情况。

什么是点?快速定义

点(pip)("percentage in point" 或 "price interest point" 的缩写)是货币对的最小标准化价格变动单位。对于大多数货币对,这是报价的第四位小数——0.0001 的变动。对于以日元报价的货币对,这是第二位小数——0.01 的变动。

具体例子:

  • EUR/USD 从 1.0850 移动到 1.08511 个点(USD 每 EUR 变动 0.0001)。
  • GBP/USD 从 1.2640 移动到 1.265515 个点
  • USD/JPY 从 154.20 移动到 154.3010 个点(JPY 每 USD 变动 0.10)。
  • AUD/JPY 从 99.45 移动到 99.40−5 个点

点是外汇市场用来表示"价格变动了多少"的通用单位——比原始小数有用得多,因为它在绝对价格水平差异巨大的货币对之间统一了表达方式。

点 vs 点子 vs Points

现代经纪商和数据提供商在标准点之外多报价一位小数。这个额外的数字称为点子(pipette)分数点(fractional pip) 或简称 point。一个点子等于十分之一个点

货币对点的大小点子大小报价示例
EUR/USD0.00010.000011.08507
GBP/USD0.00010.000011.26482
USD/JPY0.010.001154.215
EUR/JPY0.010.001167.482
当经纪商显示 EUR/USD 为 1.08507 时,末尾的 7 是点子——交易平台上通常以较小字体或上标渲染。作为开发者,请仔细处理这种区别:如果你对包含点子的报价使用字符串算术计算价格差,除非正确缩放,否则你会少报点数移动 10 倍。

一条安全规则:始终先归一化为数值类型,然后乘以或除以该货币对的点大小常量。

为什么不同货币对的点大小不同

JPY 货币对的两位小数点并非任意选择。日元相对于大多数储备货币的单位价值很小——2026 年 1 USD ≈ 154 JPY,因此报价到四位小数会产生在视觉上微不足道的价格变动和不可读的交易梯。截断到两位小数可以让价格变动在视觉上与其他主要货币对相称。

同样的逻辑适用于少数其他"低单位价值"的报价货币(韩元、匈牙利福林等)——它们通常以 0.011 的点大小报价。当你构建多货币对系统时,永远不要将 0.0001 硬编码为点大小常量。始终按货币对查找。

一个适用于大多数货币对的实用检测规则:

function getPipSize(pair) {
  // pair example: "EURUSD" or "EUR/USD"
  const quote = pair.replace("/", "").slice(3, 6).toUpperCase();
  const twoDecimalQuotes = new Set(["JPY", "HUF", "KRW"]);
  return twoDecimalQuotes.has(quote) ? 0.01 : 0.0001;
}

console.log(getPipSize("EURUSD")); // 0.0001
console.log(getPipSize("USD/JPY")); // 0.01
console.log(getPipSize("EURHUF")); // 0.01

对于生产系统,你会需要一个按 ISO 4217 货币代码索引的完整点大小表——参见我们的 ISO 4217 货币代码完整开发者指南 了解完整列表。

点值公式

任何盈亏计算的核心问题:对于 N 单位基础货币的仓位,当货币对移动一个点时,我的账户余额变化多少?

通用公式:

pip_value_in_quote_currency = pip_size × position_size
pip_value_in_account_currency = pip_value_in_quote_currency × (quote_to_account_rate)

根据账户货币与所交易货币对的关系,分为三种情况。

情况 1:账户货币 = 报价货币

最简单的情况。如果你在 USD 账户上交易 EUR/USD,每个点都是固定的美元金额,无需进一步转换。

pip_value = pip_size × position_size

对于 USD 账户上 100,000 单位(一个标准手)的 EUR/USD:

0.0001 × 100,000 = 每点 10 USD

这就是教科书上"每标准手每点 10 美元"的说法——只有当报价货币与账户货币匹配时才成立。

情况 2:账户货币 = 基础货币

如果你在 USD 账户上交易 USD/CHF,点的变动以 CHF 计价,必须使用该货币对的当前 ask 汇率转换回 USD。

pip_value_in_quote = pip_size × position_size
pip_value_in_account = pip_value_in_quote / current_rate

当 USD/CHF = 0.9050 时,对于 100,000 单位的 USD/CHF:

0.0001 × 100,000 = 10 CHF
10 CHF / 0.9050 = 每点 11.05 USD

情况 3:交叉货币对(两边都不是账户货币)

最棘手的情况。你在 USD 账户上交易 EUR/JPY。点的变动以 JPY 计价,要用 USD 表示,你需要 JPY 与 USD 之间的转换汇率。

pip_value_in_quote = pip_size × position_size
pip_value_in_account = pip_value_in_quote × (account_per_quote_rate)

当 USD/JPY = 154.20 时,对于 100,000 单位的 EUR/JPY:

0.01 × 100,000 = 1,000 JPY
1,000 JPY / 154.20 = 每点 6.49 USD

注意我们使用的是 USD/JPY 汇率,不是 EUR/JPY 汇率,因为我们是从 JPY 转换到 USD,不是从 EUR 转换到任何东西。

用 Finexly API 构建点值计算器

让我们把上面的公式连接到一个真实、实时的汇率 API,这样计算器会随着市场变动保持准确。在 Finexly 注册免费 API 密钥——每月 1,000 次请求,无需信用卡,对于这样的计算器来说足够了。完整的请求参考在 Finexly API 文档 中。

JavaScript (Node.js)

const FINEXLY_API_KEY = process.env.FINEXLY_API_KEY;
const BASE_URL = "https://finexly.com/api";

// Two-decimal-pip currencies. Extend as needed.
const TWO_DECIMAL_PIP_QUOTES = new Set(["JPY", "HUF", "KRW"]);

function pipSize(quoteCcy) {
  return TWO_DECIMAL_PIP_QUOTES.has(quoteCcy) ? 0.01 : 0.0001;
}

async function getRate(base, quote) {
  const res = await fetch(
    `${BASE_URL}/latest?base=${base}&symbols=${quote}&api_key=${FINEXLY_API_KEY}`
  );
  const json = await res.json();
  return json.rates[quote];
}

async function calcPipValue({ pair, positionSize, accountCcy }) {
  const base = pair.slice(0, 3).toUpperCase();
  const quote = pair.slice(3, 6).toUpperCase();
  const pip = pipSize(quote);
  const pipValueInQuote = pip * positionSize;

  if (accountCcy === quote) {
    return pipValueInQuote;
  }
  if (accountCcy === base) {
    const rate = await getRate(base, quote);
    return pipValueInQuote / rate;
  }
  // Cross: convert quote -> account via account/quote rate
  const rate = await getRate(accountCcy, quote);
  return pipValueInQuote / rate;
}

// Example: 100,000 units of EUR/JPY on a USD account
calcPipValue({
  pair: "EURJPY",
  positionSize: 100_000,
  accountCcy: "USD",
}).then((v) => console.log(`Pip value: ${v.toFixed(2)} USD`));

Python

import os
import requests

FINEXLY_API_KEY = os.environ["FINEXLY_API_KEY"]
BASE_URL = "https://finexly.com/api"
TWO_DECIMAL_PIP_QUOTES = {"JPY", "HUF", "KRW"}

def pip_size(quote_ccy: str) -> float:
    return 0.01 if quote_ccy in TWO_DECIMAL_PIP_QUOTES else 0.0001

def get_rate(base: str, quote: str) -> float:
    r = requests.get(
        f"{BASE_URL}/latest",
        params={"base": base, "symbols": quote, "api_key": FINEXLY_API_KEY},
        timeout=10,
    )
    r.raise_for_status()
    return r.json()["rates"][quote]

def calc_pip_value(pair: str, position_size: float, account_ccy: str) -> float:
    base, quote = pair[:3].upper(), pair[3:6].upper()
    pip = pip_size(quote)
    pip_in_quote = pip * position_size

    if account_ccy == quote:
        return pip_in_quote
    if account_ccy == base:
        return pip_in_quote / get_rate(base, quote)
    # Cross
    return pip_in_quote / get_rate(account_ccy, quote)

if __name__ == "__main__":
    value = calc_pip_value("EURJPY", 100_000, "USD")
    print(f"Pip value: {value:.2f} USD")

PHP

<?php
$apiKey = getenv('FINEXLY_API_KEY');
$baseUrl = 'https://finexly.com/api';
$twoDecimalPipQuotes = ['JPY', 'HUF', 'KRW'];

function pipSize(string $quoteCcy): float {
    global $twoDecimalPipQuotes;
    return in_array($quoteCcy, $twoDecimalPipQuotes, true) ? 0.01 : 0.0001;
}

function getRate(string $base, string $quote): float {
    global $apiKey, $baseUrl;
    $url = "$baseUrl/latest?base=$base&symbols=$quote&api_key=$apiKey";
    $body = file_get_contents($url);
    $data = json_decode($body, true);
    return $data['rates'][$quote];
}

function calcPipValue(string $pair, float $positionSize, string $accountCcy): float {
    $base = strtoupper(substr($pair, 0, 3));
    $quote = strtoupper(substr($pair, 3, 3));
    $pipInQuote = pipSize($quote) * $positionSize;

    if ($accountCcy === $quote) return $pipInQuote;
    if ($accountCcy === $base)  return $pipInQuote / getRate($base, $quote);
    return $pipInQuote / getRate($accountCcy, $quote);
}

echo number_format(calcPipValue('EURJPY', 100000, 'USD'), 2) . " USD\n";

cURL

如果你只需要原始汇率插入到自己的点计算中:

curl "https://finexly.com/api/latest?base=USD&symbols=JPY&api_key=YOUR_KEY"
# {"base":"USD","rates":{"JPY":154.20},"timestamp":1746...}

仅这一个汇率就足够使用上述公式将 JPY 点变动转换为 USD。

开发者常犯的点数学陷阱

点看起来简单。但 bug 很微妙。需要注意五件事:

1. 点算术中的浮点漂移。 JavaScript 中 0.1 + 0.2 !== 0.3,同一类问题在你将多笔交易的点盈亏相加时会困扰你。对于任何到达生产环境的代码——尤其是金融计算——内部使用整数点计数(非 JPY 货币对将价格乘以 10_000,JPY 货币对乘以 100),或使用 decimal.js 或 Python 的 decimal.Decimal 等十进制库。

2. 将 0.0001 硬编码为点大小。 一旦用户交易 JPY 货币对就会出错。始终从按货币对的表中查找点大小。

3. 在比较价格时混淆点和点子。1.08502 这样的 5 位小数 EUR/USD 报价相对于 1.08501 看起来是 1.08502 个点的移动,但实际上只是 1 个点子 = 0.1 个点。归一化为浮点数并除以点大小。

4. 在情况 3 中使用过期汇率进行账户货币转换。 对开放仓位的点值计算应使用当前汇率,而不是仓位开立时的汇率。如果缓存汇率,请将 TTL 设置得足够短,以使转换保持准确——参见 货币 API 缓存与错误处理最佳实践 了解经过生产验证的模式。

5. 忘记 bid/ask 不对称性。 经纪商使用 bid 关闭多头,使用 ask 关闭空头来转换盈亏。对于只需要估算的面向最终用户的计算器,中间汇率即可。对于执行系统,使用适当的一侧。

要更深入了解 bid/ask 拆分,请参阅我们关于 即期汇率 vs 远期汇率 的文章,对于交叉货币对转换,请参阅 交叉汇率详解

一目了然:常见货币对的点值

对于以 USD 计价的账户交易一个标准手(100,000 单位),以下是 2026 年 5 月指示性汇率下典型的点值。将它们视为合理性检查,而非教条——对于影响真实账户的任何事情,从 Finexly 货币转换器 或 API 拉取实时汇率。

货币对点大小点值(1 手,USD 账户)
EUR/USD0.000110.00 USD
GBP/USD0.000110.00 USD
USD/CHF0.0001~11.05 USD
USD/JPY0.01~6.49 USD
EUR/JPY0.01~6.49 USD
AUD/USD0.000110.00 USD
EUR/GBP0.0001~12.61 USD
作为做外汇工作的开发者,有两种模式值得记住:USD 报价货币对每个标准手每点始终正好 10 美元,而 JPY 报价货币对在其一半左右徘徊,随 USD/JPY 漂移。

常见问题

外汇中的点用简单的话来说是什么? 点是货币对价格的最小标准化变动——大多数货币对通常是第四位小数(0.0001),日元货币对是第二位小数(0.01)。它是外汇市场衡量价格变动的通用单位。

如何在代码中计算点值? 将点大小乘以仓位大小得到报价货币中的点值,然后使用当前汇率转换为账户货币。三种情况(报价 = 账户、基础 = 账户、交叉)在上面的 JavaScript、Python 和 PHP 示例中都展示了。

点和点子有什么区别? 点子是点的十分之一——一些经纪商和数据源添加的小数位以获得更紧的价差。如果 EUR/USD 上的一个点是 0.0001,那么一个点子就是 0.00001

为什么 EUR/USD 上一个点等于约 10 美元? 因为一个标准手是 100,000 单位,非 JPY 货币对的点大小是 0.0001100,000 × 0.0001 = 10 个报价货币单位。当报价货币是 USD 时,那就是直接 10 美元。

我需要付费 API 来构建点值计算器吗? 不需要。Finexly 的免费计划 每月给你 1,000 次请求,覆盖 170+ 种货币——对于个人点计算器或低流量的副项目足够了。对于更大流量,请参见我们的 价格计划

加密货币对的点大小不同吗? 加密货币对不遵循标准的 FX 点惯例。BTC/USD 经常根据交易场所报价到 2 或 4 位小数,"1 个点"由场所定义。对于纯加密的盈亏,使用绝对价格差而不是点。

准备好构建了吗?

你现在拥有了公式、三个可工作的代码示例和让大多数人栽跟头的 bug 列表。最后一块是不会在计算中途漂移的实时汇率。

获取免费的 Finexly API 密钥——无需信用卡。从每月 1,000 次免费请求开始,170+ 种货币,亚 50 毫秒延迟,仅在需要时升级。你的点值计算器值得拥有与背后数学一样准确的汇率。

Vlado Grigirov

Senior Currency Markets Analyst & Financial Strategist

Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...

View full profile →