> For the complete documentation index, see [llms.txt](https://docs.nexus.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nexus.xyz/api-reference/es-419/guides/portfolio.md).

# Portafolio y estado de la cuenta

Estado consolidado de la cuenta, saldo disponible para retirar, tabla de comisiones, posiciones enriquecidas y la serie de tiempo del portafolio, en los SDK y la CLI.

Los endpoints del portafolio responden cuatro preguntas sobre una cuenta: cuánto vale ahora mismo, qué se puede retirar, qué se le cobra y cómo ha rendido a lo largo del tiempo. Son un pequeño conjunto de endpoints REST autenticados más campos de riesgo enriquecidos por posición. Todas las interfaces (los SDK de Rust, TypeScript y Python y la CLI) llegan a las mismas rutas del gateway documentado en [APIs y límites de solicitudes](https://docs.nexus.xyz/exchange/apis-and-rates).

Si estás construyendo una vista de portafolio, lee [Cómo leer estos valores de forma segura](#reading-these-values-safely) antes de mostrar nada. Varios campos admiten null a propósito, una convención de signo es fácil de invertir, y una implementación ingenua con dos llamadas tendrá una condición de carrera en producción.

### Cómo obtenerlo

```bash
npm install @nexus-xyz/exchange-ts    # TypeScript
cargo add nexus-exchange              # Rust
pip install nexus-exchange            # Python
```

La CLI se distribuye a través de las versiones de [`nexus-exchange-cli`](https://github.com/nexus-xyz/nexus-exchange-cli). Consulta la [descripción general de las interfaces](/api-reference/es-419/readme.md) para ver los cuatro clientes.

### Autenticación

Cada ruta de esta página es de alcance de cuenta y requiere una clave de API HMAC. No hay ninguna variante pública o sin autenticación. Las solicitudes llevan `X-API-Key`, `X-Timestamp` y `X-Signature`, y la marca de tiempo debe estar dentro de 30 segundos respecto a la hora del servidor. Los SDK y la CLI firman por ti. El flujo completo, con cURL ejecutable, está en el [Inicio rápido](https://docs.nexus.xyz/exchange/trading/quickstart).

Mantén el secreto de la API fuera del código fuente y del historial del shell. Se muestra una sola vez al crearlo y no se puede recuperar después. Los ejemplos de abajo lo leen del entorno.

### Cómo elegir una red

Hoy el Exchange funciona en Nexus Testnet, y después llegará mainnet. Selecciona la red al construir el cliente. Consulta [Redes](/api-reference/es-419/guides/networks.md) para ver cómo lo hace cada interfaz y cómo se vinculan las claves de API a una red, y [APIs y límites de solicitudes](https://docs.nexus.xyz/exchange/apis-and-rates) para la URL base actual. La clave HMAC que requieren estas rutas está limitada a la red en la que se creó.

### Referencia

| Método | Ruta                                        | Auth | Descripción                                                                               |
| ------ | ------------------------------------------- | ---- | ----------------------------------------------------------------------------------------- |
| GET    | `/account/state`                            | HMAC | Resumen del portafolio **y** todas las posiciones abiertas, en una sola lectura coherente |
| GET    | `/account/summary`                          | HMAC | Solo el resumen del portafolio, el mismo objeto que incluye `/account/state`              |
| GET    | `/account/fees`                             | HMAC | Tabla efectiva de comisiones de la cuenta                                                 |
| GET    | `/account/portfolio-history?window=&limit=` | HMAC | Series de tiempo de patrimonio, PnL acumulado y volumen acumulado                         |

Puntos de entrada por SDK:

| Interfaz   | Estado consolidado      | Tabla de comisiones    | Serie de tiempo                                    |
| ---------- | ----------------------- | ---------------------- | -------------------------------------------------- |
| Rust       | `fetch_account_state()` | `fetch_account_fees()` | `fetch_portfolio_history(window, limit)`           |
| Python     | `fetch_account_state()` | `fetch_account_fees()` | `fetch_portfolio_history(window, limit)`           |
| TypeScript | `getAccountState()`     | `getAccountFees()`     | `getPortfolioHistory({ window, limit })`           |
| CLI        | `nexus account state`   | `nexus account fees`   | `nexus account portfolio-history --window --limit` |

### Estado consolidado de la cuenta

`GET /account/state` devuelve los agregados del portafolio y todas las posiciones abiertas construidos a partir de **una sola** lectura del lado del servidor. Como ambas mitades provienen de la misma instantánea, `summary.open_positions_count` siempre es igual a la longitud de `positions`.

El resumen incluye `collateral`, `total_equity`, `total_unrealized_pnl`, `total_realized_pnl_24h`, `total_volume_24h`, `open_positions_count`, `open_orders_count`, `margin_used`, `available_margin` y `withdrawable`.

**`withdrawable`** es el saldo que puede salir de la cuenta: el margen libre según el motor, que es la fuente de referencia, con un piso de cero, `max(0, available_margin)`. El margen libre ya descuenta del patrimonio el margen inicial de cada posición y cada reserva de órdenes previa a la operación, así que este es el monto del que puede disponer un retiro. No es `total_equity` ni `collateral`. Una cuenta en pérdida se acota a `"0"` y nunca se informa negativa. El valor proviene de la vista de margen de referencia del motor, así que cuando esa vista no está disponible, el endpoint **falla cerrado con `502`** en lugar de devolver un número estimado localmente.

### Tabla de comisiones

`GET /account/fees` informa lo que la plataforma le cobra hoy a la cuenta. Es la tasa vigente de la tabla, que aplica de aquí en adelante, no un promedio realizado sobre ejecuciones pasadas.

| Campo                  | Notas                                                                                                |
| ---------------------- | ---------------------------------------------------------------------------------------------------- |
| `maker_fee_bps`        | Puntos básicos principales. Puede ser negativo; cero es un centinela cuando `schedule=unknown`       |
| `taker_fee_bps`        | Puntos básicos principales; cero es un centinela cuando `schedule=unknown`                           |
| `tier`                 | Actualmente siempre `base`; todavía no hay niveles por cuenta                                        |
| `schedule`             | `per_market`, `reference` o `unknown`; trátalo como una cadena abierta                               |
| `markets`              | Tasas de los mercados del búfer de ejecuciones retenido; ordenadas por `market_id`                   |
| `volume_30d`           | Nocional operado móvil de 30 días, cadena decimal. Aproximado, consulta el indicador de abajo        |
| `volume_30d_estimated` | `true` cuando `volume_30d` puede **quedarse corto** (el búfer de ejecuciones de origen estaba lleno) |
| `discounts`            | Descuentos activos. Actualmente siempre vacío                                                        |

Cuando `schedule` es `per_market`, usa las filas `markets` devueltas como las tasas de referencia. El par de nivel superior es solo su resumen modal determinista. El búfer de ejecuciones en memoria, que tiene un tope, puede reiniciarse o expulsar mercados antiguos, así que una fila ausente no es evidencia de que la cuenta nunca operó ese mercado. `reference` significa que el búfer retenido no tiene ningún mercado con una tabla replicada y que el par de nivel superior es la tasa modal determinista de todos los mercados replicados de la plataforma. En ambos cálculos modales gana el par con más ocurrencias, y los empates se resuelven a favor del par `(maker_fee_bps, taker_fee_bps)` lexicográficamente menor. `unknown` significa que los parámetros de mercado no están disponibles. `markets` está vacío y ambos valores principales en bps son centinelas de cero, no una tabla sin comisiones. Hoy no existe ningún nivel ni programa de descuentos por cuenta. Trata `schedule` como abierto, y no ramifiques tu lógica según una forma de descuento que no existe.

### Serie de tiempo del portafolio

`GET /account/portfolio-history` devuelve el patrimonio, el PnL de trading acumulado y el nocional operado acumulado a lo largo de una ventana, con submuestreo del lado del servidor. Los puntos van **del más antiguo al más reciente**.

| `window` | Cadencia | Máx. de puntos | Rango   |
| -------- | -------- | -------------- | ------- |
| `day`    | 5 min    | 288            | 24 h    |
| `week`   | 1 h      | 168            | 7 d     |
| `month`  | 6 h      | 120            | 30 d    |
| `all`    | 1 d      | 366            | \~1 año |

Omitir `window` da `day`. Un valor fuera de ese conjunto se rechaza con `400` (`invalid_window`). Si el parámetro se repite, se usa el primer valor. `limit` debe estar entre `1` y `366`. Dentro de ese rango, acota el resultado y se **ajusta** a la capacidad de la ventana en lugar de rechazarse, así que pedir 366 puntos de `day` devuelve 288 en lugar de un error. Fuera de ese rango, la solicitud se rechaza con `400`.

La respuesta devuelve la `window` y el `cadence_ms` que se sirvieron. Léelos de vuelta en lugar de suponer los valores que enviaste, para que los ejes de tu gráfico usen los valores servidos.

Cada punto lleva `timestamp_ms`, `equity`, `pnl` y `volume`. `pnl` y `volume` son **acumulados hasta esa muestra**, no por intervalo. Para graficar la actividad por intervalo, calcula tú mismo la diferencia entre puntos adyacentes.

### Campos enriquecidos de posición

Las posiciones que devuelve `/account/state` (y `/positions`) llevan detalle de riesgo por posición junto con `symbol`, `side`, `size`, `entryPrice`, `unrealizedPnl` y `realizedPnl`:

| Campo           | Significado                                                                        |
| --------------- | ---------------------------------------------------------------------------------- |
| `notional`      | `abs(size) × mark price`                                                           |
| `initialMargin` | Margen inicial mantenido contra la posición, según el modelo de margen cruzado     |
| `roe`           | Rendimiento sobre el margen inicial: `unrealizedPnl / initialMargin`               |
| `max_leverage`  | Apalancamiento máximo que permite el mercado, según sus parámetros de riesgo       |
| `leverage`      | El multiplicador de apalancamiento de la cuenta para esta posición                 |
| `funding_paid`  | Financiamiento acumulado de la posición. Consulta la convención de signo más abajo |

**Los nombres son el vocabulario unificado de CCXT**, así que un cliente `ccxt.nexus()` lee esta forma directamente. Los campos sin equivalente en CCXT conservan la escritura propia de la plataforma: `size`, `roe`, `max_leverage`, `funding_paid`. `GET /account` no tiene esta forma. Se retransmite desde el motor de emparejamiento y responde un objeto más acotado con los nombres propios del motor.

El servidor calcula estos valores en la ruta de lectura de baja latencia en lugar de consultar al motor de emparejamiento, lo que mantiene el endpoint rápido. La contrapartida es que, cuando uno de sus datos no está disponible en esa ruta, el campo es `null` y un `<field>_error` acompañante lleva un motivo legible por máquina en lugar de un número inventado.

**`leverage` actualmente siempre es `null`,** con `leverage_error` definido como `margin_state_not_mirrored`. Derivarlo requiere la configuración de apalancamiento de la cuenta o su margen asignado, y ninguno de los dos está disponible en la ruta de lectura. No lo reconstruyas a partir de `initialMargin`. Esa expresión se reduce a `1 / initial_margin_rate`, que es una constante por mercado y no el apalancamiento real de la posición, así que sería incorrecta para todas las posiciones del mercado.

**`funding_paid` es positivo cuando se paga.** Un valor positivo significa que la posición *pagó* financiamiento, y un valor negativo significa que *recibió* financiamiento. Siempre está presente, es `"0"` antes de que se acumule cualquier financiamiento y está limitado por el historial de financiamiento que retiene la plataforma. Invertir este signo convierte un costo en un ingreso en una pantalla de PnL, así que escribe una prueba para esto.

### Cómo leer estos valores de forma segura

**Los valores monetarios son cadenas decimales, no números.** `equity`, `pnl`, `volume`, `withdrawable`, `notional` y los demás son decimales de precisión arbitraria serializados como cadenas para que no haya pérdida. Analízalos con un tipo decimal. Pasarlos por un float (`parseFloat`, `float()`, `as f64`) vuelve a introducir el error de redondeo que la codificación como cadena existe para evitar. Los campos de apalancamiento (`leverage`, `max_leverage`) son números JSON genuinos.

**Los campos derivados tienen tres estados, no dos.** Cada uno de los cinco campos calculados de la posición (`notional`, `initialMargin`, `roe`, `leverage` y `max_leverage`) puede ser:

1. **un valor**: calculado y definitivo;
2. **`null`**: informado, pero no calculable, y el `<field>_error` asociado dice por qué;
3. **ausente**: el servidor es anterior al campo.

Reducir cualquiera de estos a `0` inventa datos. "No informado", "no calculable" y "cero" son tres respuestas distintas para un usuario que pregunta cuánto vale su posición, y solo una de ellas es un número. Muestra los casos faltantes como un vacío explícito (la CLI imprime `-`) y muestra el `<field>_error` cuando lo tengas. Lo mismo se aplica a `withdrawable`. Es opcional en el esquema, así que un despliegue anterior puede omitirlo, y usar `"0"` como valor predeterminado le diría a alguien que no tiene nada disponible cuando el servidor nunca informó el valor.

Esos cinco son exactamente los campos que llevan un `<field>_error` acompañante. `funding_paid` no es uno de ellos. Siempre está presente, así que no hay un `funding_paid_error` según el cual ramificar.

**Prefiere `/account/state` a dos llamadas.** Obtener `/account/summary` y `/positions` por separado son dos solicitudes independientes contra una cuenta en vivo. Una ejecución que llega entre ellas devuelve un agregado que no coincide con la lista de posiciones (`open_positions_count` dice tres, el arreglo tiene cuatro), y esto ocurre con cualquier carga real. El endpoint consolidado respalda ambas mitades con una sola lectura coherente.

**Maneja los códigos de falla por separado.** `401` es un problema de credenciales o de reloj. Verifica que `X-Timestamp` esté dentro de 30 segundos respecto a la hora del servidor antes de suponer que la clave es incorrecta. `429` significa que superaste el presupuesto de solicitudes; consulta [Límites de solicitudes](/api-reference/es-419/guides/rate-limits.md) y aplica un backoff en lugar de reintentar de inmediato. Tres rutas de esta página (`/account/summary`, `/fills` y `/account/portfolio-history`) cuestan **cinco** unidades de ese presupuesto cada una en lugar de una, así que consultarlas en un ciclo cerrado agota la asignación de 20/s de quien llama con nivel Pro cinco veces más rápido de lo que sugiere un conteo de solicitudes. `/account/state` cuesta una y devuelve juntos el resumen y las posiciones, que es la forma más barata de leer ambos. Un `502` en `/account/state` y `/account/summary` significa que la vista de margen de referencia del motor no estaba accesible y el servidor se negó a adivinar. Reintenta, y no recurras a un `withdrawable` calculado localmente.

### Ejemplo

```bash
export NEXUS_API_KEY=nx_7f3a1b...          # the key ID is not secret

# Prompt for the secret instead of typing it inline — an `export
# NEXUS_API_SECRET=...` would leave it in your shell history.
read -rs NEXUS_API_SECRET && export NEXUS_API_SECRET

nexus account state
nexus account fees
nexus account portfolio-history --window week
```

```typescript
import { Client, Network } from "@nexus-xyz/exchange-ts";

const client = new Client({
  network: Network.Testnet,
  apiKey: process.env.NEXUS_API_KEY!,
  apiSecret: process.env.NEXUS_API_SECRET!,
});

// One coherent read: open_positions_count cannot disagree with positions.length.
const { summary, positions } = await client.getAccountState();

// Absent is not zero — say so rather than defaulting.
console.log(`withdrawable: ${summary.withdrawable ?? "<not reported>"}`);

for (const p of positions) {
  // null carries a reason in the companion field; absent carries nothing.
  const roe = p.roe ?? (p.roe_error ? `<${p.roe_error}>` : "<not reported>");
  // Paid-positive: a positive funding_paid means this position paid.
  console.log(`${p.symbol} ${p.side} ${p.size}  roe=${roe}  funding_paid=${p.funding_paid}`);
}

// The response echoes what was served — read it back, don't assume.
const history = await client.getPortfolioHistory({ window: "week" });
console.log(`${history.window} @ ${history.cadence_ms}ms, ${history.points.length} points`);
```

```json
{
  "summary": {
    "collateral": "25000.00",
    "total_equity": "25500.00",
    "total_unrealized_pnl": "500.00",
    "margin_used": "1075.00",
    "available_margin": "24425.00",
    "withdrawable": "24425.00",
    "open_positions_count": 1,
    "open_orders_count": 0
  },
  "positions": [
    {
      "symbol": "BTC-USDX-PERP",
      "side": "Long",
      "size": "0.25",
      "entryPrice": "84000.00",
      "unrealizedPnl": "500.00",
      "notional": "21500.00",
      "initialMargin": "1075.00",
      "roe": "0.4651",
      "max_leverage": 20,
      "leverage": null,
      "leverage_error": "margin_state_not_mirrored",
      "funding_paid": "3.21"
    }
  ]
}
```

Los números de arriba son coherentes entre sí. Con un precio de marca de `86000`, `notional` es `0.25 × 86000`, `unrealizedPnl` es `0.25 × (86000 − 84000)`, `initialMargin` es `notional × 1/max_leverage`, `roe` es `unrealizedPnl / initialMargin`, y `withdrawable` es igual a `total_equity − margin_used` del resumen porque no hay órdenes abiertas que reserven margen. Observa las dos escrituras en esa última frase. `margin_used` en el objeto SUMMARY es el agregado de la cuenta y conserva su nombre. `initialMargin` en una posición es el requisito por posición.

Los ejemplos ejecutables de punta a punta están en los repositorios de los SDK: [`examples/portfolio.ts`](https://github.com/nexus-xyz/nexus-exchange-ts/blob/main/examples/portfolio.ts) y [`examples/portfolio.rs`](https://github.com/nexus-xyz/nexus-exchange-rs/blob/main/examples/portfolio.rs).

### Relacionado

* [APIs y límites de solicitudes](https://docs.nexus.xyz/exchange/apis-and-rates)
* [Exchange REST](https://docs.nexus.xyz/exchange/apis-and-rates/exchange-rest)
* [Límites de solicitudes](/api-reference/es-419/guides/rate-limits.md)
* [Descripción general de las interfaces](/api-reference/es-419/readme.md)
* [Inicio rápido](https://docs.nexus.xyz/exchange/trading/quickstart)

> **Estado:** versión preliminar de desarrollo en testnet. Estas rutas se incluyen en la especificación OpenAPI v0.7.2 y están vigentes en v0.9.90. Fija una versión de la especificación en producción y revisa las notas de versión de cada SDK antes de actualizar. `/account/fees` no tiene hoy ningún nivel ni programa de descuentos por cuenta, y `leverage` informa `null` hasta que se replique el estado de margen que necesita. Las credenciales y los saldos de testnet no tienen valor en el mundo real.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nexus.xyz/api-reference/es-419/guides/portfolio.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
