# What is Pear Protocol?

Pear Protocol is a decentralized trading layer for executing and managing pair trades efficiently across DeFi.

By connecting to top on-chain trading engines like Hyperliquid and SYMM - Pear enables users to take and manage **simultaneous long and short positions**—with leverage—within a single, streamlined interface.

This solves the fragmented and manual nature of pair trading in crypto, offering:

* **One-click execution** of long/short trades across supported venues
* **Seamless charting** and analysis of any pair
* **Risk transparency,** including PnL, net funding and position metrics in one dashboard
* **TP/SL** on the ratio itself for superior risk management
* **Limit and TWAP orders** to improve execution for pair traders

Whether you're trading narratives (e.g., SOL vs ETH) or exploiting mispricings (e.g., TVL vs FDV), Pear simplifies trade execution and management—giving both retail and professional traders the tools to trade smarter in DeFi.


# Why Pair Trading Matters

It's time for a new paradigm. One where our users make money.

Most traders in crypto lose money.

Not because they’re stupid — but because the game is rigged in ways they can’t always see. Perpetual futures platforms are designed for high churn. Fees, funding, slippage, poor timing — they all compound. Even when you're "right," you can still lose.

And in crypto, you're not just betting *on* something going up. You're often unknowingly betting *against* something else: the market, the macro, the ecosystem's momentum. That’s why directional trading is so hard.

**Pair trading changes that.**

Instead of trying to time the market, you trade *relationships* between assets.

* Long HYPE, short SOL.
* Long BTC, short ETH.
* Long FARTCOIN, short SHIB.

You're not guessing whether the whole market will go up or down. You're betting that one thing will *outperform* another — something far more durable and intuitive, especially in crypto where narratives rotate fast.

Pair trading works in:

* **Bull markets**: When everything’s up, you long the stronger and short the laggard.
* **Bear markets**: When everything’s bleeding, you short the weaker and long the survivor.
* **Sideways chop**: Where relative strength and mean-reversion thrive.

It’s not a magic bullet. You still need a view, discipline, and edge. But it’s a fairer game — one where your *alpha matters more than the beta.*

Pear Protocol exists because this style of trading should be *default*, not niche. We believe the best traders don’t just trade assets — they trade edges. And pair trading is where edge lives.


# Quick start guide

How to start trading on Pear

This short video gives an overview of how to place your first trade on Pear Protocol

{% embed url="<https://youtu.be/BxEI0cCpRAI>" %}
Platform walkthrough
{% endembed %}

{% file src="/files/0UBM8ZrQkaHU5MJIFn5g" %}

{% hint style="info" %}
It is highly recommended that you trade on Pear using a wallet that has not or is not currently placing trades on Hyperliquid directly. This is to avoid any unwanted conflicts in positions that you may already have there.
{% endhint %}


# Execution Logic

Pear is a trading interface. You own your assets at all times.

Pear Protocol is a **trading interface**, not a custody layer or risk engine. It allows traders to seamlessly open and manage **pair trades using perpetual futures** by routing long and short orders to your preferred venues — all from a single, unified front end.

#### 🧠 How it works

* **Venue Routing:**

  When a user places a trade, Pear splits the position into a **long leg** and a **short leg**, and routes each side to the selected venue (e.g. GMX, Hyperliquid, Vertex, or SYMMIO).
* **Synchronized Execution:**

  Both legs are executed at the **same timestamp**, enabling operational efficiency and minimizing execution mismatch — critical for effective pair trading.
* **Perpetual Instruments:**

  All instruments traded via Pear are **perpetual futures**, with configurable leverage, margin allocation, and side-specific sizing.

#### 🔐 Fund Flow & Custody

* **GMX:**

  You trade directly from your connected wallet. Pear signs and submits transactions that interact with GMX contracts on your behalf.
* **Hyperliquid / Vertex / SYMMIO:**

  You deposit funds into the protocol-specific trading engine. Pear then acts as a **management and execution layer**, allowing you to view, open, and close positions without ever holding custody of assets.

> Pear does **not** hold or custody user funds.&#x20;


# 1. Narrative Based Trading

**Narrative trading**

In crypto, narratives tend to shift rapidly, driving trends such as Decentralized Finance (DeFi), the Bitcoin ETF, or the latest "flavor-of-the-month" blockchain. These narratives often lead to capital rotation from one trend to another. By recognizing early signs of emerging narratives, traders can capitalize on them using pair trading.

For instance, suppose a new blockchain gains traction after influential accounts on social media start discussing it. A potential pair trade might involve using the new blockchain as the long leg while shorting an existing blockchain that is losing relevance or mindshare. Keeping both legs within the same category (e.g., Layer 1 blockchains) provides a degree of protection against external factors, such as an overall market downturn, by focusing on relative performance rather than absolute price movement.

By understanding and applying these strategies, traders can leverage both statistical and narrative-driven opportunities for profitable pair trading.


# 2. Fundamental trading

Fundamental approaches focus on exploiting market inefficiencies by identifying price discrepancies between related assets. For example, consider two Layer 1 blockchains with different market cap valuations. If Blockchain A has more users, higher total value locked (TVL), greater trading volume, and broader adoption than Blockchain B, yet Blockchain B has a higher market cap, this discrepancy could present an opportunity.

A pair trade in this scenario would involve betting on the growth of Blockchain A (long leg) relative to Blockchain B (short leg).

This approach relies heavily on data analysis and metrics to identify undervalued or overvalued assets within a similar category, making it ideal for traders who prefer a thesis-driven approach.


# 3. Technical Trading (Charting)

Technical trading is largely based on charts and looking for opportunities to enter pair trades that look like they have significant upside. For example, a trader might look at a pair like long BTC / short XRP on multiple timeframes (4hr / 1D / 1W) and draw lines for moving averages and support and resistance levels. From there they would evaluate the chart and conclude if there is a trend that they would like to ride. This approach is often combined with the other two approaches above.


# 4. Statistical Arbitrage

Statistical arbitrage is an advanced pair-trading concept and involves finding mean reversion opportunities between two assets. Mean reversion is when one asset has moved (deviated) meaningfully from the other but they tend to converge again. For example, if BTC kept falling but SOL kept rising that would mean that BTC/SOL has fallen. A trader who believes these assets are correlated can go long BTC/SOL for when this happens.


# Considerations

When Pair-trading, there are a number of factors to consider, including:

* Choosing which asset to long
* Choosing which asset to short
* Selecting leverage
* Entry level and when to take profit
* Liquidation levels
* Fundamental analysis
* Technical analysis

More advanced factors to consider include:

* Net funding costs
* Slippage
* Correlation between the two assets
* Rebalancing the long and short exposure (beta)
* and many others...

#### Net Funding

Traders will likely pay funding on one leg, and receive funding on the other leg. We have provided the ability to dynamically observe the net funding rates directly on the platform when you chart any 2 pairs.

#### Slippage

Sometimes one asset will have more liquidity than another leg. Users must consider slippage when entering and exiting a trade, especially once you are trading significant size outside of the top 20 cryptocurrencies.

#### Correlation Between Two Assets

Pair trading has a rich academic history, grounded in statistics. Generally speaking, people look to trade two assets that are closely correlated but where they either expect some deviation between the two assets, or a mean reversion of some sort. Pear is working on tooling to analyze correlation between the offered pairs.

#### Rebalancing

Rebalancing the long and short exposure (beta) - By default each trade starts off ‘dollar-neutral’ at inception, meaning if a  trader opens a $1000 trade then $500 will be long exposure, and $500 will be short exposure.&#x20;

As the trade goes in the trader's favor, the  value of the long will rise to say $550, whilst the value of the short may fall to $480 (resulting in a +$50 - $20 = +$30 gain) for the user.&#x20;

At this stage, the user is net long the market ($550 vs $480). To rebalance their ‘beta’, an advanced trader would take some profit on the long leg and add it to the short leg, but for most traders this will not be a consideration and they’ll just look to close both trades outright at the same time.

**Pear has added the flexibility to choose what % you are long and short at inception (e.g. 60%/40% vs. 50%/50%), as well as the ability to partially close trades.**


# Hyperliquid

Pear functions as a **non-custodial trading front-end** on Hyperliquid. We route your paired perpetual futures orders through **builder codes**, ensuring both legs (long & short) are executed efficiently and transparently—while you always maintain full fund control on Arbitrum.

***

#### 🛠️ Technical Workflow

1. **Builder Code Setup**
   * Each order dispatched through Pear includes a builder payload:

     `{"b": <PearBuilderAddress>, "f": <fee_in_tenths_of_bps>}`.
   * Users initially execute an `ApproveBuilderFee` transaction on Arbitrum to authorize Pear's builder address and max fee — fully on-chain\
     <https://hyperliquid.gitbook.io/hyperliquid-docs/trading/builder-codes>
2. **Perpetual Futures via Hyperliquid**
   * Pear supports fully **on-chain perp execution** on Hyperliquid’s orderbook. Both legs of a pair trade are **perps denominated in USDC** and executed on Arbitrum through Hyperliquid’s Layer‑1 solution routing.
3. **Atomic, Timestamp-Synced Execution**
   * Pear orchestrates simultaneous dispatch of long and short orders in the **same block**, ensuring near-identical execution time for each leg.
4. **Non-Custodial Flow**
   * You deposit collateral directly into Hyperliquid. Pear never holds your funds—it only manages and routes order creation, monitoring, and closure.
   * Your trades merely include Pear’s builder code for attribution and fee tracking.

#### 🧭 Step-by-Step Flow via Arbitrum

1. **Approve Permissions**: User submits `ApproveBuilderFee` transaction (one-time).
2. **Open Pair Trade**: User designs trade (e.g. long BTC, short ETH) via Pear.
3. **Routing Orders**: Pear formats two transactions, each including builder code, and sends to Hyperliquid on Arbitrum.
4. **Execution by Hyperliquid**: Both orders enter HypCore in the same block, executed and margin managed by Hyperliquid.
5. **Monitoring & Management**: Pear tracks positions via Hyperliquid API; users can view real-time PnL, funding, and close or adjust positions—all via Pear UI.


# SYMM

Instead of relying on virtual automated market maker pools (vAMM), or a central limit order book (CLOB), both of which execute orders against pre-committed liquidity, users of this product express their trading intentions, which will be executed by external solvers. Liquidity is thus coming directly from market makers, and this process is facilitated by SYMMIO as the Execution Engine.

\
**Architecture Overview**

SYMMIO has pioneered the concept of AMFQ (Automated Market for Quotes) perps, or rather, a way to trade perps in an OTC manner directly against a Solver/Market Maker (MM).&#x20;

Solvers stream indicative trade quotes (bid-offers on all the assets). Users then submit specific quotes, detailing their desired trade size, direction, leverage, and other parameters. In response, the solver decides whether to fill the trader’s order.\
\
Upon agreement on price and fees, both parties deposit collateral into the fully audited SYMMIO bilateral trade agreement contract. This contract is akin to a peer-to-peer OTC trade, which is subject to liquidation from either side if the collateral isn't maintained. Crucially, this agreement is trustless and symmetric between the counterparties. Only the trader has the authority to ‘close’ the position, barring any liquidation scenarios by third-party ‘keepers’.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXdIVaZmstMkEUuVherg0WJkWv-E3WqUglCbwqfDYfVuqECClzWBA9Dz29EbehbAjVtASk3tMl-1djVhVZfxHj_7v45jkBFugYQi5dJ0XtZ9fG3SmFrKV7f-dLonVj3I5HQbe1fuY5-mq2L15hNYQInR_g8?key=hT4EGBzEaBRGzSpAlfr5eg" alt=""><figcaption></figcaption></figure>

Process

1. Users connect their wallet, deposit USDC into the trading engine, which automatically creates a sub-account for the user. In this example, we’ll be connecting and depositing $100 USDC. Like any other smart contract, you must first approve, then deposit and allocate this USDC to your account.
2. This will then load the Account Overview, and you’re ready to trade. Details of what each of these parameters mean are in the Account Information - Key Terms and Definitions section of our docs.
3. A trader submits the trade details (intent) of their desired trade (e.g. long $BTC / short $ETH)
4. The solver (market maker) provides an offer with conditions for the trade (price, slippage, fees, funding rates, collateral, etc.). This step happens automatically and in real time. No capital is committed by the solver at this time.
5. Once satisfied with the conditions of the trade, the trader sends a “Request to Trade” to the solver, including locking their required collateral.
6. The solver then observes the request and chooses to accept it, depositing their equal collateral into the contract.
7. This forms a “bilateral agreement” between the solver and the trader. It is an isolated and perfectly symmetrical contract, and depending on the price movement of the position, one party is obligated to pay the other party as PnL. This bilateral agreement exists in perpetuity until either (1) the trader closes the position, or (2) one of the parties is liquidated (automatically executed by a neutral third party based on margin health).
8. The solver can then “hedge” their position exposure (in this example, it would be long 1 BTC) on any number of sources, including a CEX, another DEX, an OTC desk, non-linear options, or even spot holdings. The solver can also net his positions with other positions or with other solvers in the network (future implementation).

{% hint style="info" %}
Note: Step 8 takes place off-chain and the solver is solely responsible for managing their hedging strategy. Because collateral is locked into the Bilateral Agreement and completely isolated from external factors, users do not have to make any trust assumptions regarding the solvency of the solver on-chain.
{% endhint %}

**Account Information - Key Terms and Definitions**

The Account Overview shows you all the relevant information to monitor and manage your risk. This is also where you can Deposit more collateral, or withdraw.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXd4OvbH7aGVAmtoH-QTNJQu69JRq6HOoiZ1NtZf0GrZQZrsxGsJweVyEpOvYSRf-w_uHj3G8VIYeqCKJ_kmZjUwp9WjjwfXn5nNHz2H8rWJ_MuwX_IdVK7XJGATLd9s74nlaNRakO8HwtVnKr1BwFuIrKU?key=hT4EGBzEaBRGzSpAlfr5eg" alt="" width="375"><figcaption></figcaption></figure>

<mark style="color:blue;">Account Health</mark>

* Represented as a percentage, it indicates the health of a trader's sub-account.
* When the Equity Balance matches the Maintenance Margin, you will risk liquidation.

Formula:&#x20;

*`AccountHealth = (EquityBalance - MaintenanceMargin ) / (allocatedBalance - maintenanceMargin)`*

<mark style="color:blue;">Equity Balance</mark>

* A combination of a trader's dedicated account balance and UPNL, this metric indicates the probable future balance.
* If it dips to the amount of the Maintenance Margin, liquidation ensues.

Formula: `EquityBalance = AllocatedBalance + UPNL`<br>

<mark style="color:blue;">Unrealised Profit and Loss (uPnL)</mark>

* UPNL showcases potential gains or losses that would result if a trader closed their active position(s).
* It's calculated by evaluating the difference in USD terms between the average entry price and the prevailing index price.

<mark style="color:blue;">Maintenance Margin (CVA)</mark>

* Considered the trader's "security deposit." If the equity balance (which combines account balance and UPNL) drops to this mark, liquidation is imminent.
* This margin is locked and non-transferable, encompassing all open positions.<br>

<mark style="color:blue;">Allocated Balance</mark>

* Represents funds assigned by traders for a specific Margin Sub-Account.
* These funds can either initiate margin positions or be available for withdraw.

\ <mark style="color:blue;">Locked Margin</mark>

* The Initial Margin feeds into the Locked Margin. The Locked Margin represents margins engaged across all live positions.
* While part of a trader's Equity, the Locked Margin acts as a buffer, deterring excessive position openings.<br>

<mark style="color:blue;">Available for Margin</mark>

* Denotes the account balance still accessible for Requests and Orders.

Formula: `AvailableForOrders = EquityBalance - LockedMargin - MaintenanceMargin`

**Account Information - Trade example**

Let’s build an example, where a user has deposited $100 into the Account.

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXfiDueV-rQXFRP8HC88FImr68_jl6vwbS68BS66boAe0ZY3PMpH463dweKfhe6HMHHBYIEuPsatFmK3QRxXc9C3HWBv4_ZavxuNhNRY5zl0uyYBHdqN801ikAiM6r-aJYWn-IoJ3A8ZjK0JLuuVSfoGCx4J?key=hT4EGBzEaBRGzSpAlfr5eg)

The user then goes to open a trade that is long MATIC/ short SUSHI for $50 with 3x leverage<br>

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXfIfNDmLA9K3koDYL7VXDCiYSDMcHmxTiJF7Q3AJdBwFpSW4m6lxiYIXakptZVy1TsPTJm_WInemTw7hiT9psnc2uu9vXIDU_vlJy4zANikk5FdPAOe8AZeeh3Lofs5v-ChAuBqgyBUGeaM0MxQvmGQvqLw?key=hT4EGBzEaBRGzSpAlfr5eg)![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXeYpiZyLpaE8ChEun4mpjm19yCAIsVZgwP_Qox6EZRGPilk4YOO2ZTMEchfsvyHa40rGuPMh7sjZvRFTRregs4cOMqB8BL5GOUNOkJyAst_IiMPRm4-6pz4om-SFgban0gQ5i9JaOCdLTL2unwPJodWjFs?key=hT4EGBzEaBRGzSpAlfr5eg)

Note that because of minimum trade sizes, the locked value is slightly less than $50 ($49.5), the remaining $0.50 remains in the users wallet.

Users can now view their updated Account Overview. Here are the calculations:

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXeSyG613E6yrztbkJqqyEcfAJ1a-Qktfgrhr3f-8FwLNiOA6U7XuIvtfGXQ1wG1v42DzDJiTuK3tR1q4TEDMov6iV8fpx2fn6dlXhknbFCkKwriuOft9GbAreMw3TlRwDi5bTpMJ_FWBw3hDm1fwXh7A84?key=hT4EGBzEaBRGzSpAlfr5eg)

\
`uPnL = PnL on open positions`

uPnL = +$0.15<br>

`Equity Balance = Allocated Balance + uPnL - fees paid ($0.09)`

Equity Balance = $99.91 + $0.0218 = $100.064

CVA = Set aside by the Solver for [each trade](https://docs.symm.io/building-on-symm-io/liquidity-providers-hedgers/hedger-example-flow/example-settings/rasa-capital/cva-calculations) (and thus varies)

CVA = $3.16 <br>

`Locked Margin = The initial $50 that was used to put on the trade - CVA - fees - uPnL`

Locked Margin = $50 - $3.16 - $0.09 - $0.15\
Locked Margin = $46.6

`Available for Orders = EquityBalance - LockedMargin -MaintenanceMargin`

Available for Orders = $100.06 - 46.6 - 3.16

Available for Orders = $50.3

**Liquidations**<br>

A liquidation event occurs when a trader's account and positions are forcibly closed by a liquidator due to insufficient margin in their account to cover unrealized losses.

This happens when the trader's positions move against them to the point where the Equity Balance falls below the Maintenance Margin (CVA).

In the event of liquidation, the entirety of the account CVA is paid to the Solver.

{% hint style="info" %}
Warning: Accounts a Pear x SYMM operate in cross-margin. Meaning Equity Balance takes into consideration the entire account balance, and liquidations will result in the entire account balance to be lost. Users can create isolated sub-accounts to better manage their liquidation risk.
{% endhint %}

\
**Technical Information**

#### Readme: <https://github.com/SYMM-IO/protocol-core>

{% hint style="info" %}
We use a Binance API to pull in data for the charts and other elements. A list of restricted countries is available here: <https://www.binance.com/en/legal/list-of-prohibited-countries>
{% endhint %}


# Overview

Pear Protocol provides a developer-friendly API for building pair/basket trading on top of Hyperliquid Exchange. Integrates directly via HyperCore, abstracting away complex execution logic.

Suitable for web apps, mobile apps, bots (e.g., Telegram), or direct API integration.

#### Important: Wallet Separation

Pear builds synthetic positions on top of Hyperliquid's raw positions (see Position Building). This means PnL, entry prices, and position sizes shown in Pear UI will differ from Hyperliquid UI when a user trades on both platforms with the same wallet.

This is a common source of confusion for users. Partners should either:

* Educate users about the difference between Pear's basket-level view and Hyperliquid's asset-level view
* Design UX that clearly communicates this distinction
* Recommend users create a dedicated wallet or Hyperliquid subaccount for pair trading

#### TypeScript SDK

An official SDK is available on npm:

```
npm install @pear-protocol/hyperliquid
```

**Package**: [npmjs.com/package/@pear-protocol/hyperliquid](https://www.npmjs.com/package/@pear-protocol/hyperliquid)

The SDK covers all API functionality plus **charting data** which is not available through the REST API directly.


# Access Management


# Authentication Process

### Authentication

Pear Protocol uses EIP-712 wallet signature authentication combined with JWT tokens. No passwords required — wallet ownership is the identity.

#### Authentication Flow

```mermaid
sequenceDiagram
    participant User
    participant UserWallet as User's Wallet
    participant PearProtocol as Pear Protocol

    Note over User,PearProtocol: 1. EIP-712 authentication (one-time)
    User->>PearProtocol: Request EIP-712 message to sign
    PearProtocol-->>User: EIP-712 message
    User->>UserWallet: Sign EIP-712 message
    UserWallet-->>User: Signed message
    User->>PearProtocol: POST Authenticate API (signed message)
    PearProtocol-->>User: JWT tokens (access + refresh)

    Note over User,PearProtocol: 2. Generate API key
    User->>PearProtocol: POST /api-keys (name: "Trading Bot Key")
    PearProtocol-->>User: API key (store this securely)

    Note over User,PearProtocol: 3. Ongoing usage (no wallet needed)
    User->>PearProtocol: POST Authenticate API (method: "api_key", apiKey)
    PearProtocol-->>User: JWT tokens (access + refresh)
    User->>PearProtocol: API request with Authorization: Bearer <access_token>
    PearProtocol-->>User: API response
```

**Step 1: EIP-712 Authentication**

Request an EIP-712 message via `GET /auth/eip712-message` with your `address` and `clientId`, sign it with your wallet, then send the signature to `POST /auth/authenticate`:

```json
{
  "method": "eip712",
  "address": "0x1234...5678",
  "clientId": "YOUR_CLIENT_ID",
  "details": {
    "signature": "0xabcdef...",
    "timestamp": 1703872800
  }
}
```

On success, the server returns JWT tokens:

| Token         | Default Expiry |
| ------------- | -------------- |
| Access token  | 15 minutes     |
| Refresh token | 30 days        |

**Step 2: Generate API Key**

Using the access token from step 1, create an API key:

`POST /api-keys`

```json
{
  "name": "Trading Bot Key"
}
```

Response:

```json
{
  "id": "key-id",
  "apiKey": "your-api-key-value",
  "name": "Trading Bot Key",
  "createdAt": "2025-05-15T10:00:00.000Z"
}
```

**Store the `apiKey` value immediately** — it is only returned once at creation time.

**Step 3: Authenticate with API Key**

From now on, use the stored API key to get JWT tokens — no wallet interaction needed:

`POST /auth/authenticate`

```json
{
  "method": "api_key",
  "address": "0x1234...5678",
  "clientId": "YOUR_CLIENT_ID",
  "details": {
    "apiKey": "your-api-key-value"
  }
}
```

This returns JWT tokens. Use the access token in all requests:

```
Authorization: Bearer <access_token>
```

#### Client ID

`clientId` is required in all authentication requests (EIP-712 and API key).

* Individual traders: use `APITRADER`.
* Products built on top of the API: contact us to obtain your own Client ID. This lets us track usage and provide partner-specific features.

#### Refresh Token

When the access token expires, call `POST /auth/refresh` with the refresh token to get a new access token without signing again.

#### Logout

Call `POST /auth/logout` with the refresh token to invalidate the session server-side.


# Builder Code

All trades on Pear Protocol are routed through the Pear Protocol builder address:

```
0xA47D4d99191db54A4829cdf3de2417E527c3b042
```

Before making any trades, users must approve the Pear Protocol builder address to charge fees. This is a one-time approval per wallet done directly on Hyperliquid.

#### How It Works

Hyperliquid's builder fee system allows builders (like Pear Protocol) to charge a fee on each order routed through their address. Users must explicitly approve a maximum fee rate for each builder they interact with.

#### Approving the Builder Fee

Send an `approveBuilderFee` action to the Hyperliquid exchange endpoint. This requires an EIP-712 signature from the user's wallet.

Payload to sign:

```json
{
  "type": "approveBuilderFee",
  "hyperliquidChain": "Mainnet",
  "signatureChainId": "0xa4b1",
  "maxFeeRate": "0.01%",
  "builder": "0xA47D4d99191db54A4829cdf3de2417E527c3b042",
  "nonce": 1234567890
}
```

| Field              | Description                                              |
| ------------------ | -------------------------------------------------------- |
| `type`             | Must be `"approveBuilderFee"`                            |
| `hyperliquidChain` | `"Mainnet"` or `"Testnet"`                               |
| `signatureChainId` | `"0xa4b1"` (Arbitrum)                                    |
| `maxFeeRate`       | Maximum fee rate the builder can charge (e.g. `"0.01%"`) |
| `builder`          | Pear Protocol builder address                            |
| `nonce`            | Current timestamp in milliseconds                        |

#### Reference

See the Hyperliquid docs for full details on the exchange endpoint and builder fee approval: <https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-a-builder-fee>


# Agent Wallet Setup

After authenticating and obtaining a set of tokens, the next step is to ensure that Pear Protocol can perform actions on the Hyperliquid Exchange on behalf of the user.

We are using the [API / Agent Wallet](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/nonces-and-api-wallets) provided by Hyperliquid. Each **Single Agent Wallet** is used exclusively by one user, and its private key is securely stored and encrypted within the Pear Protocol system. An Agent Wallet remains valid for 180 days, but it will be rotated every 30 days.

{% @mermaid/diagram content="sequenceDiagram
participant User
participant PearProtocol as Pear Protocol
participant HyperliquidAPI as Hyperliquid API
participant UserWallet as User's Wallet
User->>PearProtocol: Request to integrate with Hyperliquid
Note over PearProtocol: Step 1: Check Agent Wallet
PearProtocol->>HyperliquidAPI: GET Agent Wallet
HyperliquidAPI-->>PearProtocol: Response (status: NOT FOUND/ACTIVE/EXPIRED)
alt Status: ACTIVE
Note over PearProtocol: Existing wallet can be used
PearProtocol->>PearProtocol: Use existing Agent Wallet
else Status: NOT FOUND or EXPIRED
Note over PearProtocol: Step 2: Create Agent Wallet
PearProtocol->>HyperliquidAPI: Create Agent Wallet
HyperliquidAPI-->>PearProtocol: New Agent Wallet address
Note over PearProtocol: Step 3: Prompt User Approval
PearProtocol->>User: Request Agent Wallet approval
User->>UserWallet: Sign authorization message
UserWallet-->>User: Signed message
User->>HyperliquidAPI: Submit Agent Wallet approval directly
HyperliquidAPI-->>User: Approval confirmation
end
Note over PearProtocol: Step 4: Use Agent Wallet
PearProtocol->>HyperliquidAPI: Perform trading actions using Agent Wallet
HyperliquidAPI-->>PearProtocol: Trading results
PearProtocol-->>User: Integration complete, ready for trading
Note over PearProtocol: Agent Wallet Valid for 180 days" %}

Below is the step-by-step guide to integrate Pear Protocol with the Hyperliquid Exchange using an Agent Wallet:

1. **Check Agent Wallet** – Before creating a new Agent Wallet, check whether the user already has one by calling the `GET Agent Wallet` endpoint. The response will include the Agent Wallet address and status:
   * If the status is `NOT FOUND`, it means no wallet has been created.
   * If the status is `ACTIVE`, the existing Agent Wallet can be used.
   * If the status is `EXPIRED`, proceed to step 3 to prompt the user to approve a new Agent Wallet.
2. **Create Agent Wallet** – If no wallet exists or it has expired, Pear Protocol will create a new Agent Wallet for the user by calling the `Create Agent Wallet` endpoint. The response will include the new Agent Wallet address.
3. **Prompt the User to Approve the Agent Wallet** – Once the wallet is created, prompt the user to approve it. This requires the user to sign a message using their own wallet, authorizing Pear Protocol to use the Agent Wallet on their behalf. More details can be found in the [Agent Wallet Approval](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/nonces-and-api-wallets#agent-wallet-approval) section of the documentation.
4. **Use the Agent Wallet** – After the user has approved the Agent Wallet, Pear Protocol can use it to interact with the Hyperliquid Exchange on behalf of the user.


# Important Terms


# Price Ratio

When you hold **one long asset** and **one short asset**, the **Price Ratio** is one of the cleanest ways to visualize their relationship. It’s defined simply as:

$$
\text{Price Ratio} = \frac{\text{Price}*{\text{LONG}}}{\text{Price}*{\text{SHORT}}}
$$

Despite being simple, this ratio does several powerful things at once:

#### **Captures Relative Strength**

Instead of tracking two separate price charts, the ratio collapses the performance of *both* assets into a single line.

* If the ratio **trends upward**, your **long asset is outperforming your short**.
* If it **trends downward**, your **short asset is outperforming your long**.

This is particularly useful when the two assets are highly correlated (e.g., competitors, L1 vs L2 tokens, two DeFi governance tokens, etc.).

#### **Encodes Correlation and Divergences**

When two assets normally move together, deviations in the ratio often indicate:

* A temporary mispricing
* A divergence that may revert
* A possible trading opportunity

For example, if Asset A and Asset B are historically correlated but suddenly one rallies without the other, the ratio will spike — often a sign the spread might snap back.

#### **Creates a Natural Mean-Reversion Indicator**

Because many asset pairs have long-term equilibrium relationships (due to fundamentals or shared market conditions), the price ratio often behaves like an oscillator:

* **Overstretched highs** → long is unusually strong → potential short-the-ratio setup
* **Overstretched lows** → short is unusually strong → potential long-the-ratio setup

This behavior is the foundation of **pair trading**, **stat arb**, and **market-neutral strategies**.


# Weighted Price Ratio

While a simple price ratio works for **one long vs. one short**, traders often use **baskets** of assets: multiple longs and multiple shorts with different weightings. The **Weighted Ratio** generalizes the idea of the price ratio into a combined performance measure for the entire strategy.

$$
\text{Weighted Ratio} = \prod\_{i=1}^{n} \text{Price}\_i^{w\_i}
$$

#### **How It Works**

Each asset price is raised to the power of its allocation weight:

* **Long positions have positive weights**
* **Short positions have negative weights**

So, for the example portfolio:

* 50% Long $HYPE
* 25% Short $ASTER
* 25% Short $XPL (Plasma)

The weighted ratio becomes:

$$
\text{Weighted Ratio} = \text{HYPEUSD}^{0.5} \cdot \text{ASTERUSD}^{-0.25} \cdot \text{XPLUSD}^{-0.25}
$$

This is effectively the geometric return of the portfolio — a mathematically clean way to encode long/short performance.

#### **What It Tells You**

The **absolute value** of the ratio at any moment isn’t very important. What *is* important is **how it changes over time**:

* If the weighted ratio **trends upward**, your basket is performing well:
  * longs are winning
  * shorts are losing
  * or both
* If it **trends downward**, the basket is underperforming.

This makes the weighted ratio a direct measure of **strategy PnL momentum**.

#### Reading the Chart

The absolute number doesn't matter much. What matters is direction:

* **Rising** — longs are outperforming shorts. The trade is working.
* **Falling** — shorts are outperforming longs. The trade is losing.

Using the example above: if the ratio is trending up, HYPE is outperforming the ASTER+XPL basket. Flipping the structure (long ASTER+XPL / short HYPE) would show a downtrend — same information, opposite perspective.

You don't need to track each asset individually. The ratio chart shows the combined P\&L path of the entire strategy in one line.

#### Where the Weights Come From

For open positions, the weights are derived from the weights set when the position was opened. Otherwise, the weights come from what the user specifies.

### Code Example

```typescript
type Token = { symbol: string; weight: number };
type TokenPriceMap = Map<string, { markPrice: number }>;

function computeWeightedRatio(
  longTokens: Token[],
  shortTokens: Token[],
  prices: TokenPriceMap,
): number {
  let ratio = 1;
  for (const t of longTokens) {
    const price = prices.get(t.symbol)?.markPrice ?? 0;
    ratio *= Math.pow(price, t.weight);
  }
  for (const t of shortTokens) {
    const price = prices.get(t.symbol)?.markPrice ?? 0;
    ratio *= Math.pow(price, -t.weight);
  }
  return ratio;
}
```


# Net Funding

Perpetual futures charge or pay a funding rate periodically. In a pair trade, you're paying funding on one side and receiving it on the other. The net funding rate tells you the combined funding cost (or income) of the entire basket.

#### How It Works

* **Long positions pay funding** when the rate is positive (and receive when negative).
* **Short positions receive funding** when the rate is positive (and pay when negative).

The net funding rate is the weighted sum across all assets, with signs flipped to reflect the actual cost to the trader:

* Longs: subtract the funding rate (you're paying it)
* Shorts: add the funding rate (you're receiving it)

A **negative** net funding rate means you're paying to hold the position. A **positive** net funding rate means you're earning by holding it.

#### Code

```typescript
type Token = { symbol: string; weight: number };
type TokenPriceMap = Map<string, { markPrice: number; funding: number }>;

function computeNetFundingRate(
  longTokens: Token[],
  shortTokens: Token[],
  prices: TokenPriceMap,
): number {
  let total = 0;
  for (const t of longTokens) {
    const funding = prices.get(t.symbol)?.funding;
    if (funding !== undefined && t.weight > 0) {
      total += -funding * t.weight;
    }
  }
  for (const t of shortTokens) {
    const funding = prices.get(t.symbol)?.funding;
    if (funding !== undefined && t.weight > 0) {
      total += funding * t.weight;
    }
  }
  return total;
}
```

#### Example

Given a basket: 50% long HYPE (funding: 0.01%), 25% short ASTER (funding: 0.03%), 25% short XPL (funding: -0.02%):

```
net = (-0.01% × 0.5) + (0.03% × 0.25) + (-0.02% × 0.25)
    = -0.005% + 0.0075% + (-0.005%)
    = -0.0025%
```

Slightly negative — you're paying a small amount to hold this basket.


# Synthetic Position

Pear Protocol constructs **synthetic positions** on top of raw Hyperliquid positions. Each basket trade gets its own position with independent sizing, entry prices, PnL, and TP/SL — even when the underlying Hyperliquid account holds a single aggregated position per asset.

#### Synthetic Positions vs Hyperliquid Positions

Hyperliquid tracks one position per asset per account. Pear splits that into baskets.

**Example: One Underlying, Three Baskets**

| Trade   | Long | Short | BTC Size |
| ------- | ---- | ----- | -------- |
| Trade 1 | BTC  | ETH   | 0.5      |
| Trade 2 | BTC  | ALT   | 0.3      |
| Trade 3 | BTC  | STOCK | 0.2      |

**Hyperliquid sees**: 1.0 BTC long (single position, no basket concept)

**Pear sees**: 3 independent positions, each with own entry price, PnL, and TP/SL

Users can track performance per basket, set risk per basket, and close baskets independently.

#### How Fills Become Positions

After execution on Hyperliquid, each fill is processed against existing open positions: first closing exact-match inverse positions, then any partial matches, then merging into same-structure positions or creating new ones. Entry prices use weighted averages on merge.

#### Execution Flag (`pear_execution_flag`)

Every position carries a flag indicating where its fills originated:

| Flag             | Meaning                                                                       |
| ---------------- | ----------------------------------------------------------------------------- |
| `FULLY_PEAR`     | All fills came from Pear orders                                               |
| `FULLY_EXTERNAL` | All fills came from outside Pear (direct Hyperliquid trades, other frontends) |
| `PARTIAL`        | Mix of Pear and external fills touched this position                          |

#### PnL Discrepancy: Pear vs Hyperliquid

Pear calculates PnL at the **basket level**. Hyperliquid calculates at the **asset level**. Different entry price tracking → different displayed PnL until all related positions close.

**Pear**: each basket maintains its own entry price per asset.

```
pnl = direction × (exit_price − basket_entry_price) × size − fees
```

**Hyperliquid**: global weighted average entry across all trades of same asset. Any close uses this global average.

**Example**

User opens same asset long in four baskets:

| Pair            | Entry Price |
| --------------- | ----------- |
| ASSET / SHORT-A | 33.500      |
| ASSET / SHORT-B | 33.700      |
| ASSET / SHORT-C | 33.879      |
| ASSET / SHORT-D | 33.880      |

Hyperliquid global average entry: **33.74**

User closes only ASSET / SHORT-C at **34.298**:

|                 | Entry Used               | PnL per Unit |
| --------------- | ------------------------ | ------------ |
| **Pear**        | 33.879 (basket-specific) | **+0.419**   |
| **Hyperliquid** | 33.74 (global average)   | **+0.558**   |

Neither is wrong — total PnL converges once all positions sharing that asset are fully closed.


# Trade Idea

The Trade Ideas endpoint surfaces pair trading baskets from three sources: actively traded pairs, user watchlists, and AI-generated picks from statistical arbitrage analysis.

#### Endpoint

`GET /markets/v2`

Returns baskets enriched with live market data (open interest, 24h volume) for each asset.

#### Basket Categories

| Category    | Source            | Description                                                                  |
| ----------- | ----------------- | ---------------------------------------------------------------------------- |
| `active`    | Platform activity | Pairs traded in the last 24 hours or held in open positions across all users |
| `watchlist` | User-specific     | Pairs saved to the authenticated user's watchlist                            |
| `ai-picks`  | AI                | AI-generated trade ideas                                                     |

#### Response

```json
{
  "baskets": [
    {
      "longAssets": [
        { "asset": "BTC", "weight": 0.6, "oi": 1500000000, "volume": 800000000 },
        { "asset": "ETH", "weight": 0.4, "oi": 900000000, "volume": 500000000 }
      ],
      "shortAssets": [
        { "asset": "SOL", "weight": 0.5, "oi": 300000000, "volume": 200000000 },
        { "asset": "AVAX", "weight": 0.5, "oi": 50000000, "volume": 30000000 }
      ],
      "category": "active"
    },
    {
      "longAssets": [{ "asset": "ETH", "weight": 1, "oi": 900000000, "volume": 500000000 }],
      "shortAssets": [{ "asset": "BTC", "weight": 1, "oi": 1500000000, "volume": 800000000 }],
      "category": "watchlist"
    },
    {
      "longAssets": [{ "asset": "LINK", "weight": 1, "oi": 120000000, "volume": 80000000 }],
      "shortAssets": [{ "asset": "UNI", "weight": 1, "oi": 40000000, "volume": 25000000 }],
      "category": "ai-picks",
      "name": "DeFi Divergence"
    }
  ]
}
```

#### Asset Fields

| Field    | Description                                                   |
| -------- | ------------------------------------------------------------- |
| `asset`  | Asset ticker symbol                                           |
| `weight` | Weight allocation within its side (weights per side sum to 1) |
| `oi`     | Current open interest in USD                                  |
| `volume` | 24-hour trading volume in USD                                 |

#### How Baskets Are Built

**Active baskets** are derived from two sources:

* Recent fills (last 24 hours) — unique long/short pairs extracted from order fills
* All open positions — pairs currently held by any user on the platform

Duplicate pairs across these sources are deduplicated.

**Watchlist baskets** are loaded from the authenticated user's saved watchlist. Only included when the request has a valid user session.

**AI picks** are fetched from an external statistical arbitrage service. Asset names are resolved against supported Hyperliquid assets (including cross-exchange tickers like `xyz:ASSET`). Baskets with unsupported assets are filtered out.


# Executing Trade


# Basket Trade

A basket trade allows you to execute multiple orders across different assets simultaneously as a single transaction. This is useful for portfolio rebalancing, implementing complex trading strategies, or executing correlated trades with precise timing.

Examples of basket trade: Long BTC + ETH, Short DOGE + SHIB in a single trade

This is possible in our API by specifying multiple `longAssets` and `shortAssets` along with their respective weights when calling the [Positions](/api-integration/api-specification/positions#post-positions)


# Order Type


# Market Order

Market orders execute pair trading positions immediately at current market ratios. By default, the slippage is set to 8%. All assets will be executed in a single transaction.

Market order can be placed using the [Positions](/api-integration/api-specification/positions#post-positions) with `executionType: "MARKET"`.


# Trigger Order

### Trigger Orders

Trigger orders execute pair trading positions when a specified condition is met. Conditions range from pair price ratios to BTC dominance thresholds to prediction market outcomes. Trigger orders are handled internally and off-chain, with oracle price updates occurring every second.

#### Trigger Types

All trigger types use `direction`: `MORE_THAN` or `LESS_THAN`.

| Type                        | Description                                                   | `triggerValue`              |
| --------------------------- | ------------------------------------------------------------- | --------------------------- |
| `PRICE`                     | Fires when the pair's price crosses a threshold               | Target price                |
| `PRICE_LIMIT`               | Limit order placed directly on Hyperliquid at a target price  | Target price                |
| `PRICE_RATIO`               | Fires when the pair's price ratio reaches a target            | Target ratio                |
| `WEIGHTED_RATIO`            | Fires when the weighted ratio across assets reaches a target  | Target ratio                |
| `BTC_DOM`                   | Fires when BTC dominance crosses a threshold                  | Dominance % (e.g. `"62.5"`) |
| `CROSS_ASSET_PRICE`         | Fires when an external asset's price crosses a threshold      | Target price                |
| `PREDICTION_MARKET_OUTCOME` | Fires when a prediction market resolves to a specific outcome | Outcome value               |

#### Oracle Sources

Each trigger type pulls price data from a different source, checked at different intervals:

| Trigger Type                                                  | Oracle Source                     | Check Interval |
| ------------------------------------------------------------- | --------------------------------- | -------------- |
| `PRICE`, `PRICE_RATIO`, `WEIGHTED_RATIO`, `CROSS_ASSET_PRICE` | Hyperliquid mark price (`markPx`) | Every \~500ms  |
| `PREDICTION_MARKET_OUTCOME` (Hyperliquid HIP-4)               | Hyperliquid mid price             | Every 1s       |
| `PREDICTION_MARKET_OUTCOME` (Kalshi)                          | Kalshi last price                 | Every 1s       |
| `BTC_DOM`                                                     | CoinGecko BTC dominance %         | Every 60s      |

#### Placing a Trigger Order

Use `executionType: "TRIGGER"` with the appropriate `triggerType`, `triggerValue`, and `direction`.

**Price ratio trigger** — open when BTC/ETH ratio exceeds 25:

```json
{
  "executionType": "TRIGGER",
  "triggerType": "PRICE_RATIO",
  "triggerValue": "25",
  "direction": "MORE_THAN",
  "leverage": 5,
  "usdValue": 1000,
  "slippage": 0.01,
  "longAssets": [{ "asset": "BTC", "weight": 0.5 }],
  "shortAssets": [{ "asset": "ETH", "weight": 0.5 }]
}
```

**BTC dominance trigger** — open when BTC dominance drops below 60%:

```json
{
  "executionType": "TRIGGER",
  "triggerType": "BTC_DOM",
  "triggerValue": "60",
  "direction": "LESS_THAN",
  "leverage": 3,
  "usdValue": 500,
  "slippage": 0.01,
  "longAssets": [{ "asset": "ETH", "weight": 0.25 }, { "asset": "SOL", "weight": 0.25 }],
  "shortAssets": [{ "asset": "BTC", "weight": 0.5 }]
}
```

**Cross-asset price trigger** — open when ETH crosses above $4,000:

```json
{
  "executionType": "TRIGGER",
  "triggerType": "CROSS_ASSET_PRICE",
  "triggerValue": "4000",
  "direction": "MORE_THAN",
  "assetName": "ETH",
  "leverage": 5,
  "usdValue": 1000,
  "slippage": 0.01,
  "longAssets": [{ "asset": "ETH", "weight": 0.5 }],
  "shortAssets": [{ "asset": "BTC", "weight": 0.5 }]
}
```

**Prediction market trigger** — open when a Hyperliquid prediction market outcome resolves:

```json
{
  "executionType": "TRIGGER",
  "triggerType": "PREDICTION_MARKET_OUTCOME",
  "triggerValue": "0.9",
  "direction": "MORE_THAN",
  "marketCode": "#10",
  "marketSource": "HYPERLIQUID",
  "leverage": 3,
  "usdValue": 500,
  "slippage": 0.01,
  "longAssets": [{ "asset": "BTC", "weight": 0.5 }],
  "shortAssets": [{ "asset": "ETH", "weight": 0.5 }]
}
```

#### Browsing Available Triggers

Use the `GET /triggers` endpoint to discover available trigger conditions. Filter by category with the `category` query parameter:

| Category            | What it returns                                        |
| ------------------- | ------------------------------------------------------ |
| `all`               | All available triggers (default)                       |
| `prediction_market` | Hyperliquid prediction markets with live oracle prices |
| `btcdom`            | Current BTC dominance data from CoinGecko              |

Kalshi prediction markets are available via a separate `GET /triggers/kalshi` endpoint with `category`, `search`, and pagination support.

Each trigger response includes an `oracle` field with the current value and unit (`cent` for prediction markets, `percent` for BTC dominance), so you can assess proximity to your target before placing an order.


# Time-Weighted Average Price

A TWAP (Time-Weighted Average Price) order splits a large order into smaller chunks executed over a duration. Each chunk is a market order — individual chunks and timing are not exposed on-chain (CEX-style shielded execution).

Use `executionType: "TWAP"`. Also works for closing positions via the close API with `executionType: "TWAP"`.

```json
{
  "executionType": "TWAP",
  "leverage": 5,
  "usdValue": 5000,
  "slippage": 0.01,
  "twapDuration": 30,
  "twapIntervalSeconds": 60,
  "randomizeExecution": true,
  "longAssets": [{ "asset": "BTC", "weight": 0.5 }],
  "shortAssets": [{ "asset": "ETH", "weight": 0.5 }]
}
```

**How it works:**

* `twapDuration`: total duration in minutes (required)
* `twapIntervalSeconds`: seconds between chunks (default: 30)
* Number of chunks = `duration / interval`, capped by minimum $11 per asset per chunk
* USD value split equally across chunks
* `randomizeExecution`: adds ±10% jitter to chunk timing to reduce predictability
* Chunks queued via BullMQ and executed as individual market orders
* TP/SL intents are cached and applied after the first chunk creates a position; subsequent chunks merge into it

**Example**: $5,000 over 30 minutes at 60s intervals → 30 chunks of \~$166 each, one every \~60s (±6s with randomization).


# Ladder Order

A ladder order creates multiple trigger orders spread across a range of weighted ratio levels. Instead of entering a full position at one price, the total USD value is distributed evenly across levels that fire as the weighted ratio moves through the range.

Ladder orders are **not limit orders** — each level is a trigger order that executes a market order when the weighted ratio reaches that level.

Use `executionType: "LADDER"` with a `ladderConfig`:

```json
{
  "executionType": "LADDER",
  "leverage": 5,
  "usdValue": 1000,
  "slippage": 0.01,
  "longAssets": [{ "asset": "BTC", "weight": 1 }],
  "shortAssets": [{ "asset": "ETH", "weight": 1 }],
  "ladderConfig": {
    "ratioStart": 40,
    "ratioEnd": 44,
    "numberOfLevels": 5
  }
}
```

This creates 5 trigger orders at weighted ratios **40, 41, 42, 43, 44**, each for **$200** (= $1,000 / 5). All triggers use `WEIGHTED_RATIO` type with `LESS_THAN` direction.

| Level | Trigger Ratio | USD  |
| ----- | ------------- | ---- |
| 1     | 40.0          | $200 |
| 2     | 41.0          | $200 |
| 3     | 42.0          | $200 |
| 4     | 43.0          | $200 |
| 5     | 44.0          | $200 |

Config constraints: `numberOfLevels` must be between 2 and 50.


# Managing Open Position


# Adjust Position Size

Adjust the size of existing positions by increasing or reducing the position amount. This allows for dynamic position management without closing the entire position.

The adjustment amount is a percentage of the current position size in USD value.

We currently support both market and limit orders for position adjustments. For limit orders, the ratio is calculated based on the current ratio of the position.

Adjust position size can be done using [Positions](/api-integration/api-specification/positions#post-positions-positionid-adjust).


# Partially Adjust Position

We also support partial adjustments where only a portion of the position is adjusted. This is useful for traders who want to reduce their exposure without closing the entire position.

When a partial adjustment is made, the system recalculates the position size and updates the margin requirements accordingly. The trader can specify the amount they wish to adjust, and the system will handle the necessary calculations to close and/or increase the position as needed.

The partial adjustment API endpoints are available at : [Positions](/api-integration/api-specification/positions#post-positions-positionid-adjust-advance)


# Close Position

Entire pair trading positions can be closed using either market execution or TWAP (Time-Weighted Average Price) execution.

When closing a position, we reduce the asset's position size based on the specific value of the position being closed. For example, if you hold a BTC/ETH position worth $100 in BTC and a BTC/HYPE position worth $200 in BTC, and you choose to close the BTC/ETH position, we will reduce your BTC holdings by $100—not the total $300 across both positions.

Close position size can be done using [Positions](/api-integration/api-specification/positions#post-positions-positionid-close).


# Take Profit / Stop Loss

### Take Profit & Stop Loss

TP/SL orders automatically close positions when specified conditions are met. They are handled internally and off-chain, with price updates occurring every second.

TP/SL can be included when creating a new position or updated on an existing position via the `PUT /positions/:positionId/risk-parameters` endpoint.

#### Trigger Types

| Type             | Description                                                      | `value`                  |
| ---------------- | ---------------------------------------------------------------- | ------------------------ |
| `PERCENTAGE`     | Triggers based on P\&L % relative to entry                       | TP: profit %; SL: loss % |
| `DOLLAR`         | Triggers based on absolute P\&L in USD                           | TP: profit $; SL: loss $ |
| `POSITION_VALUE` | Triggers when position notional value crosses threshold          | USD value                |
| `PRICE`          | Triggers when primary asset price crosses threshold              | Asset price              |
| `PRICE_RATIO`    | Triggers when long/short price ratio crosses threshold           | Price ratio              |
| `WEIGHTED_RATIO` | Triggers when weighted ratio across all assets crosses threshold | Weighted ratio           |

#### Setting TP/SL on Position Creation

Include `stopLoss` and/or `takeProfit` in the create position payload:

```json
{
  "executionType": "MARKET",
  "leverage": 5,
  "usdValue": 1000,
  "slippage": 0.01,
  "longAssets": [{ "asset": "BTC", "weight": 1 }],
  "shortAssets": [{ "asset": "ETH", "weight": 1 }],
  "stopLoss": { "type": "PERCENTAGE", "value": 10 },
  "takeProfit": { "type": "PERCENTAGE", "value": 25 }
}
```

#### Updating TP/SL on Existing Position

`PUT /positions/:positionId/risk-parameters`

```json
{
  "stopLoss": { "type": "DOLLAR", "value": 100 },
  "takeProfit": { "type": "POSITION_VALUE", "value": 1200 }
}
```

Set to `null` to remove:

```json
{
  "stopLoss": null
}
```

#### Examples by Trigger Type

**Percentage** — close when P\&L hits +25% (TP) or -10% (SL):

```json
{
  "takeProfit": { "type": "PERCENTAGE", "value": 25 },
  "stopLoss": { "type": "PERCENTAGE", "value": 10 }
}
```

**Dollar** — close when P\&L hits +$200 (TP) or -$100 (SL):

```json
{
  "takeProfit": { "type": "DOLLAR", "value": 200 },
  "stopLoss": { "type": "DOLLAR", "value": 100 }
}
```

**Position Value** — close when notional value hits $1,200 (TP) or $800 (SL):

```json
{
  "takeProfit": { "type": "POSITION_VALUE", "value": 1200 },
  "stopLoss": { "type": "POSITION_VALUE", "value": 800 }
}
```

**Price** — close when primary asset price hits $120,000 (TP) or $90,000 (SL):

```json
{
  "takeProfit": { "type": "PRICE", "value": 120000 },
  "stopLoss": { "type": "PRICE", "value": 90000 }
}
```

**Price Ratio** — close when long/short price ratio hits 28 (TP) or 22 (SL):

```json
{
  "takeProfit": { "type": "PRICE_RATIO", "value": 28 },
  "stopLoss": { "type": "PRICE_RATIO", "value": 22 }
}
```

**Weighted Ratio** — close when weighted ratio hits 1.15 (TP) or 0.90 (SL):

```json
{
  "takeProfit": { "type": "WEIGHTED_RATIO", "value": 1.15 },
  "stopLoss": { "type": "WEIGHTED_RATIO", "value": 0.90 }
}
```

#### Trailing Stop

Trailing stops automatically advance the stop loss trigger as the position moves in your favor. The stop trails behind the best observed metric value by a configurable delta percentage.

When the metric (P\&L %, price, ratio, etc.) improves past the `trailingActivationValue`, the stop loss trigger is recalculated as:

* **Long positions**: `triggerValue = currentMetric × (1 - trailingDeltaValue / 100)`
* **Short positions (PRICE type)**: `triggerValue = currentMetric × (1 + trailingDeltaValue / 100)`

The activation value updates each time the stop advances, so it only ever moves in your favor.

**Example** — trailing stop that activates at 5% profit, trails by 3%:

```json
{
  "stopLoss": {
    "type": "PERCENTAGE",
    "value": 5,
    "isTrailing": true,
    "trailingDeltaValue": 3,
    "trailingActivationValue": 5
  }
}
```

If P\&L reaches 10%, the stop loss advances to 10% × (1 - 0.03) = 9.7%. If P\&L later reaches 15%, stop advances to 14.55%. The stop never moves backward.

**Trailing stop with price trigger**:

```json
{
  "stopLoss": {
    "type": "PRICE",
    "value": 95000,
    "isTrailing": true,
    "trailingDeltaValue": 2,
    "trailingActivationValue": 100000
  }
}
```

#### Execution Behavior

* **TP**: triggers when metric reaches or exceeds the target value
* **SL**: triggers when metric falls to or below the target value
* **PRICE type** is side-aware: for short positions, TP triggers when price drops below target, SL triggers when price rises above target
* When triggered, the position is closed via a market order
* Notifications are sent on both successful fills and failures


# Managing Open Order


# Adjust Open Order

Modify pending orders by updating their limit ratio and position size. This allows you to adapt to changing market conditions without canceling and recreating orders.

Adjusting open order can be done using the [Orders](/api-integration/api-specification/orders#put-orders-orderid-adjust)


# Cancel Open Order

Cancel pending orders that have not yet been executed. This removes the order from the system and prevents future execution.

Canceling open order can be done using the [Orders](/api-integration/api-specification/orders#delete-orders-orderid-cancel)


# Cancel TWAP

Cancel TWAP (Time-Weighted Average Price) orders and all their pending execution chunks. This stops the gradual execution process and removes all remaining order chunks.

Canceling TWAP can be done using the [Orders](/api-integration/api-specification/orders#post-orders-orderid-twap-cancel).


# Trade Activity


# Open Position

Open positions are Pear's synthetic basket positions that currently have non-zero asset sizes. Each position represents a basket trade with independent PnL, entry prices, and risk parameters.

Positions with `FULLY_EXTERNAL` execution flag are excluded.

#### Access

* **REST**: `GET /positions`
* **WebSocket**: `open-positions` channel (requires address)

#### What's Computed

Raw position data (entry prices, sizes, weights) is enriched with live Hyperliquid mark prices.

**Per Asset**

| Field           | Description                                                        |
| --------------- | ------------------------------------------------------------------ |
| `unrealizedPnl` | `(markPrice - entryPrice) × size` for longs, inverse for shorts    |
| `marginUsed`    | `markPrice × size / leverage`                                      |
| `targetWeight`  | From original order (normalized), or entry value share as fallback |
| `fundingPaid`   | Cumulative funding paid/received                                   |

**Per Position**

| Field                                | Description                                                      |
| ------------------------------------ | ---------------------------------------------------------------- |
| `entryRatio` / `markRatio`           | Geometric weighted ratio using target weights (see below)        |
| `entryPriceRatio` / `markPriceRatio` | Simple `longPrice / shortPrice`, only for 1-long / 1-short pairs |
| `unrealizedPnl`                      | Sum across all assets                                            |
| `unrealizedPnlPercentage`            | PnL relative to total margin used                                |
| `positionValue`                      | `entryPositionValue + unrealizedPnl`                             |
| `takeProfit` / `stopLoss`            | Active risk parameters if set                                    |

**Weighted Ratio Calculation**

`entryRatio` and `markRatio` use a geometric weighted product with each asset's **target weight** as the exponent:

```
entryRatio = ∏(longEntryPrice ^ targetWeight) × ∏(shortEntryPrice ^ -targetWeight)
markRatio  = ∏(longMarkPrice  ^ targetWeight) × ∏(shortMarkPrice  ^ -targetWeight)
```

Target weight comes from original order weights (normalized). If not set, falls back to asset's share of total entry value. This means the ratio reflects the basket's intended allocation, not actual filled proportions which may drift due to price movement or partial fills.


# Open Order

Open orders are pending orders that have not yet fully executed.

#### Access

* **REST**: `GET /orders/open`
* **WebSocket**: `open-orders` channel (requires address)

#### What Counts as Open

Only orders with status `OPEN` or `PARTIALLY_FILLED` and type `TRIGGER`, `TP`, or `SL` are returned. MARKET orders execute immediately and never appear here. TWAP orders have their own monitoring channel (`twap-details`).

#### Response Shape

Each open order contains:

* `orderId` — unique order identifier
* `orderType` — `TRIGGER`, `TP`, or `SL`
* `status` — `OPEN` or `PARTIALLY_FILLED`
* `positionId` — linked position (for TP/SL orders)
* `parameters` — order-type-specific config (leverage, USD value, trigger conditions, etc.)
* `longAssets` / `shortAssets` — each with `asset`, `weight`, `size` (planned), and `filledSize` (executed so far)
* `createdAt` / `updatedAt`

#### Order Types in Open Orders

| Type      | When it appears                                                                             | Triggered by                             |
| --------- | ------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `TRIGGER` | User placed a conditional order waiting for price/ratio/BTC dom/prediction market condition | Oracle condition met                     |
| `TP`      | Take profit set on an open position                                                         | Position ROI or price reaching threshold |
| `SL`      | Stop loss set on an open position                                                           | Position ROI or price reaching threshold |

#### Lifecycle

```
OPEN → PROCESSING → EXECUTED
                  → FAILED
     → PARTIALLY_FILLED → EXECUTED
     → CANCELLED
```

* `OPEN`: order created, waiting for trigger condition
* `PARTIALLY_FILLED`: some fills received (e.g., TWAP chunks or partial execution)
* `PROCESSING`: trigger condition met, execution in progress
* `EXECUTED`: fully filled
* `FAILED`: execution error (e.g., insufficient margin, liquidity)
* `CANCELLED`: user cancelled or system cancelled

#### Real-Time Updates

The `open-orders` channel refreshes automatically after trade execution, position close, or TP/SL changes. No manual polling needed — subscribe once and receive updates.


# Monitor TWAP

`GET /orders/twap` and WebSocket `twap-details` return per-order monitoring data, Returns per-order monitoring data

* **Order-level**: total/filled/remaining USD value, status, estimated and actual completion time, remaining chunks count
* **Chunk-level**: each chunk's status (`PENDING` → `SCHEDULED` → `EXECUTING` → `COMPLETED`/`FAILED`/`CANCELLED`), scheduled vs actual execution time, planned USD size, and error message if failed
* **Fill-level**: individual fills per chunk with asset name, price, size, and execution timestamp


# Trade History

Trade history records are created when fills **close** (fully or partially) a position's assets. Each record captures entry price, exit price, size, fees, and realized PnL — scoped to a specific basket position.

Trade history is **not** raw Hyperliquid fills. It's Pear's basket-level interpretation: which basket was closed, at what entry/exit, and what PnL resulted. Entry prices come from the basket's own entry (not Hyperliquid's global average).

Opening a position does not create trade history. Only closing fills — where an existing position asset's size is reduced — generate records. A single close order affecting multiple baskets creates multiple trade history records — one per basket affected.

Records with `FULLY_EXTERNAL` execution flag are excluded from queries.

#### Access

* **REST**: `GET /trade-history` — optional `limit`, `startDate`, `endDate` params
* **WebSocket**: `trade-histories` channel (requires address)

#### Example

Position: Long BTC @ 100,000 (0.01) / Short ETH @ 2,700 (0.15)

Close fills: sell 0.01 BTC @ 105,000, buy 0.15 ETH @ 2,600

| Asset     | Side  | Entry   | Exit    | Size | PnL      |
| --------- | ----- | ------- | ------- | ---- | -------- |
| BTC       | LONG  | 100,000 | 105,000 | 0.01 | +$50     |
| ETH       | SHORT | 2,700   | 2,600   | 0.15 | +$15     |
| **Total** |       |         |         |      | **+$65** |


# Websocket

Websocket connection are exposed at `wss://hl-v2.pearprotocol.io/ws.`

The following channels are available:

1. open-orders
2. trade-histories
3. positions
4. twap-details
5. notifications
6. account-summary
7. market-data

Each channel provides real-time updates for the respective data type. Clients can subscribe to one or more channels to receive live updates.

Currently we only support one address subscription per websocket connection.

### Example Websocket Subscription

```json
{
  "action": "subscribe",
  "address": "0xYourEthereumAddressHere",
  "channels": ["open-orders", "positions"]
}
```


# Error Handling

### Error Handling

All API errors follow a consistent JSON format:

```json
{
  "statusCode": 400,
  "code": "HL_INSUFFICIENT_MARGIN",
  "message": "Not enough margin to place order"
}
```

| Field        | Description                                   |
| ------------ | --------------------------------------------- |
| `statusCode` | HTTP status code                              |
| `code`       | Machine-readable error code (see table below) |
| `message`    | Human-readable error description              |

Some errors include an additional `context` field with extra details.

#### Error Codes

**Position**

| Code                    | Description                     |
| ----------------------- | ------------------------------- |
| `POSITION_NOT_FOUND`    | Position does not exist         |
| `POSITION_NOT_OPEN`     | Position is not in OPEN status  |
| `POSITION_UNAUTHORIZED` | User does not own this position |

**Order**

| Code                   | Description                         |
| ---------------------- | ----------------------------------- |
| `ORDER_NOT_FOUND`      | Order does not exist                |
| `INVALID_ORDER_STATUS` | Order is not in the expected status |
| `INVALID_ORDER_TYPE`   | Unsupported order type              |

**Execution**

| Code                         | Description                                             |
| ---------------------------- | ------------------------------------------------------- |
| `ACTIVE_TRADE_TIMEOUT`       | Another trade is still processing for this address      |
| `UNSUPPORTED_EXECUTION_TYPE` | Invalid execution type                                  |
| `DUPLICATE_TRIGGER`          | A trigger order with the same parameters already exists |
| `HL_CANCEL_FAILED`           | Failed to cancel order on Hyperliquid                   |

**Hyperliquid**

| Code                           | Description                               |
| ------------------------------ | ----------------------------------------- |
| `HL_INSUFFICIENT_MARGIN`       | Not enough margin to place order          |
| `HL_AGENT_WALLET_REVOKED`      | Agent wallet access has been revoked      |
| `HL_TICK_SIZE`                 | Price does not conform to tick size       |
| `HL_MIN_TRADE_VALUE`           | Trade value below minimum                 |
| `HL_REDUCE_ONLY`               | Reduce-only order would increase position |
| `HL_POST_ONLY_WOULD_MATCH`     | Post-only order would match immediately   |
| `HL_IOC_NO_MATCH`              | IOC order found no match                  |
| `HL_BAD_TRIGGER_PRICE`         | Invalid trigger price                     |
| `HL_NO_LIQUIDITY`              | Insufficient liquidity                    |
| `HL_OPEN_INTEREST_CAP`         | Open interest cap reached                 |
| `HL_OPEN_INTEREST_RATE`        | Open interest rate limit hit              |
| `HL_INSUFFICIENT_SPOT_BALANCE` | Not enough spot balance                   |
| `HL_PRICE_TOO_FAR_FROM_ORACLE` | Order price too far from oracle price     |
| `HL_MAX_POSITION_EXCEEDED`     | Maximum position size exceeded            |
| `HL_ORDER_MISSING`             | Order not found on Hyperliquid            |
| `HL_ORDER_FAILED`              | Order execution failed on Hyperliquid     |

**Validation**

| Code                         | Description                                   |
| ---------------------------- | --------------------------------------------- |
| `INVALID_ADDRESS`            | Malformed wallet address                      |
| `MISSING_REQUIRED_FIELD`     | Required field not provided                   |
| `INVALID_FIELD_VALUE`        | Field value out of range or wrong type        |
| `UNSUPPORTED_TRIGGER_TYPE`   | Trigger type not supported for this operation |
| `INVALID_POSITION_STRUCTURE` | Invalid long/short asset configuration        |

**Ladder**

| Code                     | Description                        |
| ------------------------ | ---------------------------------- |
| `INVALID_LADDER_CONFIG`  | Invalid ladder order configuration |
| `LADDER_CREATION_FAILED` | Failed to create ladder order      |

**TWAP**

| Code                           | Description                    |
| ------------------------------ | ------------------------------ |
| `TWAP_DURATION_REQUIRED`       | TWAP duration not specified    |
| `TWAP_INSUFFICIENT_VALUE`      | Order value too small for TWAP |
| `TWAP_CHUNK_SCHEDULING_FAILED` | Failed to schedule TWAP chunks |

**Leverage**

| Code                     | Description                                 |
| ------------------------ | ------------------------------------------- |
| `LEVERAGE_CONFIG_FAILED` | Failed to configure leverage on Hyperliquid |

**Risk Parameters**

| Code                      | Description                 |
| ------------------------- | --------------------------- |
| `INVALID_RISK_PARAMETERS` | Invalid TP/SL configuration |

**Vault**

| Code                          | Description                              |
| ----------------------------- | ---------------------------------------- |
| `VAULT_WALLET_NOT_FOUND`      | Vault wallet does not exist              |
| `VAULT_UNAUTHORIZED`          | User not authorized for this vault       |
| `VAULT_UNSUPPORTED_TOKEN`     | Token not supported for vault operations |
| `VAULT_MISSING_CONFIG`        | Vault configuration incomplete           |
| `VAULT_INITIALIZATION_FAILED` | Failed to initialize vault               |
| `VAULT_CREATION_FAILED`       | Failed to create vault                   |

**Generic**

| Code             | Description             |
| ---------------- | ----------------------- |
| `INTERNAL_ERROR` | Unexpected server error |


# API Specification


# Health

## GET /health

> Health check endpoint

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/health":{"get":{"operationId":"HealthController_getHealth","parameters":[],"responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"uptime":{"type":"number"}}}}}}},"summary":"Health check endpoint","tags":["Health"]}}}}
```


# Agent Wallet

## Get agent wallet status

> Check if an agent wallet exists for the authenticated user and retrieve its status. Agent wallets are used to execute trades on Hyperliquid Exchange on behalf of users and are valid for 180 days with automatic 30-day rotations.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"GetAgentWalletResponseDto":{"type":"object","properties":{"agentWalletAddress":{"type":"string","description":"Agent wallet address for Hyperliquid operations"}},"required":["agentWalletAddress"]}}},"paths":{"/agentWallet":{"get":{"description":"Check if an agent wallet exists for the authenticated user and retrieve its status. Agent wallets are used to execute trades on Hyperliquid Exchange on behalf of users and are valid for 180 days with automatic 30-day rotations.","operationId":"AgentWalletController_getAgentWallet","parameters":[],"responses":{"200":{"description":"Agent wallet found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAgentWalletResponseDto"}}}},"404":{"description":"Agent wallet not found"}},"summary":"Get agent wallet status","tags":["Agent Wallet"]}}}}
```

## Create a new agent wallet

> Create a new agent wallet for the authenticated user. The wallet private key is securely stored and encrypted within Pear Protocol. After creation, the user must approve the wallet through Hyperliquid's agent wallet approval process.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CreateAgentWalletResponseDto":{"type":"object","properties":{"agentWalletAddress":{"type":"string","description":"Newly created agent wallet address - user must approve this on Hyperliquid"},"message":{"type":"string","description":"Next steps instruction for user"}},"required":["agentWalletAddress","message"]}}},"paths":{"/agentWallet":{"post":{"description":"Create a new agent wallet for the authenticated user. The wallet private key is securely stored and encrypted within Pear Protocol. After creation, the user must approve the wallet through Hyperliquid's agent wallet approval process.","operationId":"AgentWalletController_createAgentWallet","parameters":[],"responses":{"201":{"description":"Agent wallet created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAgentWalletResponseDto"}}}}},"summary":"Create a new agent wallet","tags":["Agent Wallet"]}}}}
```


# Authentication

## Authenticate user

> Authenticate a user using EIP712 signature or API key and return access/refresh tokens

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/auth/login":{"post":{"description":"Authenticate a user using EIP712 signature or API key and return access/refresh tokens","operationId":"AuthController_authenticate","parameters":[],"requestBody":{"required":true,"description":"Authentication request with EIP712 signature or API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticateRequestDto"}}}},"responses":{"200":{"description":"Authentication successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticateResponseDto"}}}},"400":{"description":"Bad request - invalid input data"},"401":{"description":"Unauthorized - authentication failed"}},"summary":"Authenticate user","tags":["Authentication"]}}},"components":{"schemas":{"AuthenticateRequestDto":{"type":"object","properties":{"method":{"type":"string","description":"Authentication method","enum":["eip712","api_key","privy_access_token"]},"address":{"type":"string","description":"User wallet address","pattern":"^0x[a-fA-F0-9]{40}$"},"clientId":{"type":"string","description":"Client identifier"},"details":{"description":"Authentication method specific details","oneOf":[{"$ref":"#/components/schemas/EIP712AuthDetailsDto"},{"$ref":"#/components/schemas/ApiKeyAuthDetailsDto"},{"$ref":"#/components/schemas/PrivyAuthDetailsDto"}]}},"required":["method","address","clientId","details"]},"EIP712AuthDetailsDto":{"type":"object","properties":{"signature":{"type":"string","description":"EIP712 signature"},"timestamp":{"type":"number","description":"Unix timestamp used in the signed message"},"chainId":{"type":"number","description":"EIP-155 chain ID used in the EIP712 domain when signing. Optional; falls back to server default (EIP712_CHAIN_ID) for backward compatibility."}},"required":["signature","timestamp"]},"ApiKeyAuthDetailsDto":{"type":"object","properties":{"apiKey":{"type":"string","description":"API key for authentication"}},"required":["apiKey"]},"PrivyAuthDetailsDto":{"type":"object","properties":{"appId":{"type":"string","description":"Privy App ID"},"accessToken":{"type":"string","description":"Privy access token (JWT)"}},"required":["appId","accessToken"]},"AuthenticateResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"JWT access token"},"refreshToken":{"type":"string","description":"Refresh token for obtaining new access tokens"},"tokenType":{"type":"string","description":"Token type"},"expiresIn":{"type":"number","description":"Token expiration time in seconds"},"address":{"type":"string","description":"User wallet address"},"clientId":{"type":"string","description":"Client identifier"}},"required":["accessToken","refreshToken","tokenType","expiresIn","address","clientId"]}}}}
```

## Get EIP712 message to sign

> Generate EIP712 structured data for client-side signing

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/auth/eip712-message":{"get":{"description":"Generate EIP712 structured data for client-side signing","operationId":"AuthController_getEIP712Message","parameters":[{"name":"address","required":true,"in":"query","description":"User wallet address","schema":{"type":"string"}},{"name":"clientId","required":true,"in":"query","description":"Client identifier","schema":{"type":"string"}},{"name":"chainId","required":true,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"EIP712 message generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEIP712MessageResponseDto"}}}},"400":{"description":"Bad request - invalid parameters"}},"summary":"Get EIP712 message to sign","tags":["Authentication"]}}},"components":{"schemas":{"GetEIP712MessageResponseDto":{"type":"object","properties":{"domain":{"type":"object","description":"EIP712 domain"},"types":{"type":"object","description":"EIP712 types"},"primaryType":{"type":"string","description":"Primary type for EIP712 signing"},"message":{"type":"object","description":"Message to sign"},"timestamp":{"type":"number","description":"Unix timestamp used in message"}},"required":["domain","types","primaryType","message","timestamp"]}}}}
```

## Refresh access token

> Use a valid refresh token to obtain a new access token and refresh token

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/auth/refresh":{"post":{"description":"Use a valid refresh token to obtain a new access token and refresh token","operationId":"AuthController_refreshToken","parameters":[],"requestBody":{"required":true,"description":"Refresh token request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenRequestDto"}}}},"responses":{"200":{"description":"Token refresh successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenResponseDto"}}}},"401":{"description":"Unauthorized - invalid or expired refresh token"}},"summary":"Refresh access token","tags":["Authentication"]}}},"components":{"schemas":{"RefreshTokenRequestDto":{"type":"object","properties":{"refreshToken":{"type":"string","description":"Refresh token"}},"required":["refreshToken"]},"RefreshTokenResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"New JWT access token"},"refreshToken":{"type":"string","description":"New refresh token"},"tokenType":{"type":"string","description":"Token type"},"expiresIn":{"type":"number","description":"Token expiration time in seconds"}},"required":["accessToken","refreshToken","tokenType","expiresIn"]}}}}
```

## Logout user

> Invalidate refresh token and log out the user

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/auth/logout":{"post":{"description":"Invalidate refresh token and log out the user","operationId":"AuthController_logout","parameters":[],"requestBody":{"required":true,"description":"Logout request with refresh token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutRequestDto"}}}},"responses":{"200":{"description":"Logout successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutResponseDto"}}}},"401":{"description":"Unauthorized - invalid refresh token"}},"summary":"Logout user","tags":["Authentication"]}}},"components":{"schemas":{"LogoutRequestDto":{"type":"object","properties":{"refreshToken":{"type":"string","description":"Refresh token to invalidate"}},"required":["refreshToken"]},"LogoutResponseDto":{"type":"object","properties":{"message":{"type":"string","description":"Logout status message"}},"required":["message"]}}}}
```


# Orders

## Get all orders

> Retrieve all orders for the authenticated user with optional filtering by status and order type

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PaginatedOrdersResponseDto":{"type":"object","properties":{"data":{"description":"List of orders","type":"array","items":{"$ref":"#/components/schemas/OpenOrderDto"}},"total":{"type":"number","description":"Total number of matching orders"},"page":{"type":"number","description":"Current page number"},"limit":{"type":"number","description":"Items per page"},"totalPages":{"type":"number","description":"Total number of pages"}},"required":["data","total","page","limit","totalPages"]},"OpenOrderDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Order identifier"},"address":{"type":"string","description":"User wallet address"},"clientId":{"type":"string","description":"Client identifier","nullable":true},"positionId":{"type":"string","description":"Associated position identifier","nullable":true},"parameters":{"description":"Order parameters (varies by order type)","oneOf":[{"$ref":"#/components/schemas/MarketOrderParameters"},{"$ref":"#/components/schemas/TriggerOrderParameters"},{"$ref":"#/components/schemas/TwapOrderParameters"},{"$ref":"#/components/schemas/TpSlOrderParameters"},{"$ref":"#/components/schemas/LadderOrderParameters"}]},"orderType":{"type":"string","description":"Order type","enum":["SYNC","MARKET","TRIGGER","TWAP","LADDER","TP","SL","SPOT_MARKET","SPOT_LIMIT","SPOT_TWAP"]},"status":{"type":"string","description":"Order status","enum":["OPEN","PROCESSING","EXECUTED","CANCELLED","FAILED","PARTIALLY_FILLED"]},"longAssets":{"description":"Long assets in the order","type":"array","items":{"$ref":"#/components/schemas/OrderAssetDto"}},"shortAssets":{"description":"Short assets in the order","type":"array","items":{"$ref":"#/components/schemas/OrderAssetDto"}},"createdAt":{"type":"string","description":"Order creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last update timestamp","format":"date-time"}},"required":["orderId","address","clientId","positionId","parameters","orderType","status","longAssets","shortAssets","createdAt","updatedAt"]},"MarketOrderParameters":{"type":"object","properties":{"leverage":{"type":"number","description":"Leverage multiplier"},"usdValue":{"type":"number","description":"Order value in USD"},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"}},"required":["usdValue"]},"TriggerOrderParameters":{"type":"object","properties":{"leverage":{"type":"number","description":"Leverage multiplier"},"usdValue":{"type":"number","description":"Order value in USD"},"triggerType":{"type":"string","description":"Trigger type","enum":["PRICE","PRICE_LIMIT","PRICE_RATIO","WEIGHTED_RATIO","BTC_DOM","CROSS_ASSET_PRICE","PREDICTION_MARKET_OUTCOME","PRICE","PRICE_RATIO","WEIGHTED_RATIO","PERCENTAGE","DOLLAR","POSITION_VALUE"]},"triggerValue":{"description":"Trigger value (price or ratio)","oneOf":[{"type":"number"},{"type":"string"}]},"direction":{"type":"string","description":"Order direction","enum":["MORE_THAN","LESS_THAN"]},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"},"assetName":{"type":"string","description":"Asset name"},"marketCode":{"type":"string","description":"Market code"},"marketName":{"type":"string","description":"Market name"},"marketSource":{"type":"string","description":"Market source","enum":["KALSHI","HYPERLIQUID"]}},"required":["leverage","usdValue","triggerType","triggerValue","direction"]},"TwapOrderParameters":{"type":"object","properties":{"leverage":{"type":"number","description":"Leverage multiplier"},"usdValue":{"type":"number","description":"Order value in USD"},"duration":{"type":"string","description":"TWAP duration (e.g. 5m, 1h, 24h)"},"intervalSeconds":{"type":"number","description":"Interval between chunks in seconds"},"chunkUsdValue":{"type":"number","description":"Calculated base chunk size in USD"},"randomizeExecution":{"type":"boolean","description":"Whether execution timing is randomized"},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"}},"required":["leverage","usdValue","duration","chunkUsdValue"]},"TpSlOrderParameters":{"type":"object","properties":{"triggerType":{"type":"string","description":"TP/SL trigger type","enum":["PERCENTAGE","DOLLAR","POSITION_VALUE","PRICE","PRICE_RATIO","WEIGHTED_RATIO"]},"triggerValue":{"type":"number","description":"Trigger value"},"isTrailing":{"type":"boolean","description":"Whether this is a trailing stop"},"trailingDeltaValue":{"type":"number","description":"Trailing delta value"},"trailingActivationValue":{"type":"number","description":"Trailing activation value"},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"}},"required":["triggerType"]},"LadderOrderParameters":{"type":"object","properties":{"leverage":{"type":"number","description":"Leverage multiplier"},"usdValue":{"type":"number","description":"Order value in USD"},"ratioStart":{"type":"number","description":"Starting ratio"},"ratioEnd":{"type":"number","description":"Ending ratio"},"numberOfLevels":{"type":"number","description":"Number of ladder levels"},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"}},"required":["leverage","usdValue","ratioStart","ratioEnd","numberOfLevels"]},"OrderAssetDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset symbol"},"weight":{"type":"number","description":"Asset weight in order"},"size":{"type":"string","description":"Order size in asset units","nullable":true},"filledSize":{"type":"string","description":"Filled size in asset units","nullable":true}},"required":["asset","weight"]}}},"paths":{"/orders":{"get":{"description":"Retrieve all orders for the authenticated user with optional filtering by status and order type","operationId":"OrdersController_getAllOrders","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (default: 1)","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (default: 50, max: 100)","schema":{"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filter by order status","schema":{"enum":["OPEN","PROCESSING","EXECUTED","CANCELLED","FAILED","PARTIALLY_FILLED"],"type":"string"}},{"name":"orderType","required":false,"in":"query","description":"Filter by order type","schema":{"enum":["SYNC","MARKET","TRIGGER","TWAP","LADDER","TP","SL","SPOT_MARKET","SPOT_LIMIT","SPOT_TWAP"],"type":"string"}}],"responses":{"200":{"description":"Orders retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedOrdersResponseDto"}}}}},"summary":"Get all orders","tags":["Orders"]}}}}
```

## DELETE /orders/{orderId}/cancel

> Cancel a pending order

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CancelOrderResponseDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Order identifier","format":"uuid"},"status":{"type":"string","description":"Order status after cancellation"},"cancelledAt":{"type":"string","description":"Cancellation timestamp","format":"date-time"}},"required":["orderId","status","cancelledAt"]}}},"paths":{"/orders/{orderId}/cancel":{"delete":{"operationId":"OrdersController_cancelOrder","parameters":[{"name":"orderId","required":true,"in":"path","description":"Order identifier","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"Order cancelled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelOrderResponseDto"}}}}},"summary":"Cancel a pending order","tags":["Orders"]}}}}
```

## POST /orders/{orderId}/twap/cancel

> Cancel a TWAP order and all its pending chunks

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CancelTwapResponseDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Order identifier that was cancelled"},"status":{"type":"string","description":"Status of the cancellation operation"},"cancelledAt":{"type":"string","description":"Cancellation timestamp","format":"date-time"}},"required":["orderId","status","cancelledAt"]}}},"paths":{"/orders/{orderId}/twap/cancel":{"post":{"operationId":"OrdersController_cancelTwapOrder","parameters":[{"name":"orderId","required":true,"in":"path","description":"TWAP Order identifier","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"TWAP order cancelled successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelTwapResponseDto"}}}}},"summary":"Cancel a TWAP order and all its pending chunks","tags":["Orders"]}}}}
```

## Get all open orders

> Retrieve all open orders (LIMIT, TP, SL) for the authenticated user with detailed order information including target ratios and asset allocations

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"OpenOrderDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Order identifier"},"address":{"type":"string","description":"User wallet address"},"clientId":{"type":"string","description":"Client identifier","nullable":true},"positionId":{"type":"string","description":"Associated position identifier","nullable":true},"parameters":{"description":"Order parameters (varies by order type)","oneOf":[{"$ref":"#/components/schemas/MarketOrderParameters"},{"$ref":"#/components/schemas/TriggerOrderParameters"},{"$ref":"#/components/schemas/TwapOrderParameters"},{"$ref":"#/components/schemas/TpSlOrderParameters"},{"$ref":"#/components/schemas/LadderOrderParameters"}]},"orderType":{"type":"string","description":"Order type","enum":["SYNC","MARKET","TRIGGER","TWAP","LADDER","TP","SL","SPOT_MARKET","SPOT_LIMIT","SPOT_TWAP"]},"status":{"type":"string","description":"Order status","enum":["OPEN","PROCESSING","EXECUTED","CANCELLED","FAILED","PARTIALLY_FILLED"]},"longAssets":{"description":"Long assets in the order","type":"array","items":{"$ref":"#/components/schemas/OrderAssetDto"}},"shortAssets":{"description":"Short assets in the order","type":"array","items":{"$ref":"#/components/schemas/OrderAssetDto"}},"createdAt":{"type":"string","description":"Order creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last update timestamp","format":"date-time"}},"required":["orderId","address","clientId","positionId","parameters","orderType","status","longAssets","shortAssets","createdAt","updatedAt"]},"MarketOrderParameters":{"type":"object","properties":{"leverage":{"type":"number","description":"Leverage multiplier"},"usdValue":{"type":"number","description":"Order value in USD"},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"}},"required":["usdValue"]},"TriggerOrderParameters":{"type":"object","properties":{"leverage":{"type":"number","description":"Leverage multiplier"},"usdValue":{"type":"number","description":"Order value in USD"},"triggerType":{"type":"string","description":"Trigger type","enum":["PRICE","PRICE_LIMIT","PRICE_RATIO","WEIGHTED_RATIO","BTC_DOM","CROSS_ASSET_PRICE","PREDICTION_MARKET_OUTCOME","PRICE","PRICE_RATIO","WEIGHTED_RATIO","PERCENTAGE","DOLLAR","POSITION_VALUE"]},"triggerValue":{"description":"Trigger value (price or ratio)","oneOf":[{"type":"number"},{"type":"string"}]},"direction":{"type":"string","description":"Order direction","enum":["MORE_THAN","LESS_THAN"]},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"},"assetName":{"type":"string","description":"Asset name"},"marketCode":{"type":"string","description":"Market code"},"marketName":{"type":"string","description":"Market name"},"marketSource":{"type":"string","description":"Market source","enum":["KALSHI","HYPERLIQUID"]}},"required":["leverage","usdValue","triggerType","triggerValue","direction"]},"TwapOrderParameters":{"type":"object","properties":{"leverage":{"type":"number","description":"Leverage multiplier"},"usdValue":{"type":"number","description":"Order value in USD"},"duration":{"type":"string","description":"TWAP duration (e.g. 5m, 1h, 24h)"},"intervalSeconds":{"type":"number","description":"Interval between chunks in seconds"},"chunkUsdValue":{"type":"number","description":"Calculated base chunk size in USD"},"randomizeExecution":{"type":"boolean","description":"Whether execution timing is randomized"},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"}},"required":["leverage","usdValue","duration","chunkUsdValue"]},"TpSlOrderParameters":{"type":"object","properties":{"triggerType":{"type":"string","description":"TP/SL trigger type","enum":["PERCENTAGE","DOLLAR","POSITION_VALUE","PRICE","PRICE_RATIO","WEIGHTED_RATIO"]},"triggerValue":{"type":"number","description":"Trigger value"},"isTrailing":{"type":"boolean","description":"Whether this is a trailing stop"},"trailingDeltaValue":{"type":"number","description":"Trailing delta value"},"trailingActivationValue":{"type":"number","description":"Trailing activation value"},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"}},"required":["triggerType"]},"LadderOrderParameters":{"type":"object","properties":{"leverage":{"type":"number","description":"Leverage multiplier"},"usdValue":{"type":"number","description":"Order value in USD"},"ratioStart":{"type":"number","description":"Starting ratio"},"ratioEnd":{"type":"number","description":"Ending ratio"},"numberOfLevels":{"type":"number","description":"Number of ladder levels"},"reduceOnly":{"type":"boolean","description":"Whether this is a reduce-only order"}},"required":["leverage","usdValue","ratioStart","ratioEnd","numberOfLevels"]},"OrderAssetDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset symbol"},"weight":{"type":"number","description":"Asset weight in order"},"size":{"type":"string","description":"Order size in asset units","nullable":true},"filledSize":{"type":"string","description":"Filled size in asset units","nullable":true}},"required":["asset","weight"]}}},"paths":{"/orders/open":{"get":{"description":"Retrieve all open orders (LIMIT, TP, SL) for the authenticated user with detailed order information including target ratios and asset allocations","operationId":"OrdersController_getOpenOrders","parameters":[],"responses":{"200":{"description":"Open orders retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OpenOrderDto"}}}}},"404":{"description":"No open orders found"}},"summary":"Get all open orders","tags":["Orders"]}}}}
```

## Get TWAP orders with monitoring data

> Retrieve list of TWAP orders with detailed execution progress, chunk status, and fill information

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TwapMonitoringDto":{"type":"object","properties":{"orderId":{"type":"string","description":"TWAP order identifier"},"positionId":{"type":"string","description":"Associated position ID (for close orders)","nullable":true},"address":{"type":"string","description":"User wallet address"},"orderType":{"type":"string","description":"Order type (TWAP)"},"longAssets":{"description":"Long assets in the order","type":"array","items":{"$ref":"#/components/schemas/OrderAssetDto"}},"shortAssets":{"description":"Short assets in the order","type":"array","items":{"$ref":"#/components/schemas/OrderAssetDto"}},"status":{"type":"string","description":"Overall order status","enum":["OPEN","EXECUTING","COMPLETED","PARTIALLY_COMPLETED","FAILED","CANCELLED"]},"totalUsdValue":{"type":"number","description":"Total order value in USD"},"filledUsdValue":{"type":"number","description":"USD value already filled"},"remainingUsdValue":{"type":"number","description":"USD value remaining to fill"},"twapDuration":{"type":"string","description":"TWAP duration setting"},"twapIntervalSeconds":{"type":"number","description":"TWAP interval in seconds (effective)","nullable":true},"twapChunkUsdValue":{"type":"number","description":"Base USD value per TWAP chunk","nullable":true},"randomizeExecution":{"type":"boolean","description":"Whether execution timing is randomized"},"reduceOnly":{"type":"boolean","description":"Is this a reduce-only order (close position)"},"chunks":{"description":"Breakdown of each execution chunk","type":"array","items":{"$ref":"#/components/schemas/TwapChunkStatusDto"}},"estimatedCompletionTime":{"type":"string","description":"Estimated completion time","format":"date-time","nullable":true},"actualCompletionTime":{"type":"string","description":"Actual completion time","format":"date-time","nullable":true},"remainingChunks":{"type":"number","description":"Number of chunks remaining to execute"},"createdAt":{"type":"string","description":"Order creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last update timestamp","format":"date-time"}},"required":["orderId","positionId","address","orderType","longAssets","shortAssets","status","totalUsdValue","filledUsdValue","remainingUsdValue","twapDuration","randomizeExecution","reduceOnly","chunks","estimatedCompletionTime","actualCompletionTime","remainingChunks","createdAt","updatedAt"]},"OrderAssetDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset symbol"},"weight":{"type":"number","description":"Asset weight in order"},"size":{"type":"string","description":"Order size in asset units","nullable":true},"filledSize":{"type":"string","description":"Filled size in asset units","nullable":true}},"required":["asset","weight"]},"TwapChunkStatusDto":{"type":"object","properties":{"chunkId":{"type":"string","description":"TWAP chunk identifier"},"chunkIndex":{"type":"number","description":"Chunk index in sequence"},"scheduledTime":{"type":"string","description":"Scheduled execution time","format":"date-time"},"executedTime":{"type":"string","description":"Actual execution time","format":"date-time","nullable":true},"status":{"type":"string","description":"Chunk execution status","enum":["PENDING","SCHEDULED","EXECUTING","COMPLETED","FAILED","CANCELLED"]},"chunkSize":{"type":"number","description":"Planned chunk size in USD"},"fills":{"description":"Individual fills in this chunk","type":"array","items":{"$ref":"#/components/schemas/ChunkFillDto"}},"errorMessage":{"type":"string","description":"Error message if chunk failed","nullable":true}},"required":["chunkId","chunkIndex","scheduledTime","executedTime","status","chunkSize","fills","errorMessage"]},"ChunkFillDto":{"type":"object","properties":{"fillId":{"type":"string","description":"Fill identifier"},"assetName":{"type":"string","description":"Asset name"},"price":{"type":"number","description":"Fill price"},"size":{"type":"number","description":"Fill size"},"executedAt":{"type":"string","description":"Fill execution timestamp","format":"date-time"}},"required":["fillId","assetName","price","size","executedAt"]}}},"paths":{"/orders/twap":{"get":{"description":"Retrieve list of TWAP orders with detailed execution progress, chunk status, and fill information","operationId":"OrdersController_getTwapOrders","parameters":[],"responses":{"200":{"description":"TWAP orders with monitoring data retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TwapMonitoringDto"}}}}},"404":{"description":"No TWAP orders found"}},"summary":"Get TWAP orders with monitoring data","tags":["Orders"]}}}}
```

## POST /orders/spot

> Execute a spot order

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SpotOrderRequestDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset to buy"},"isBuy":{"type":"boolean","description":"To buy/sell Asset"},"amount":{"type":"number","description":"Asset size to buy","minimum":0.1}},"required":["asset","isBuy","amount"]},"SpotOrderResponseDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Unique identifier for the initial order"},"status":{"type":"string","description":"Current status of the position/order","enum":["OPEN","PROCESSING","EXECUTED","CANCELLED","FAILED","PARTIALLY_FILLED"]},"createdAt":{"type":"string","description":"Creation timestamp","format":"date-time"},"asset":{"type":"string","description":"Spot Asset"},"hyperliquidResult":{"type":"object","description":"Raw response from Hyperliquid"}},"required":["orderId","status","createdAt","asset"]}}},"paths":{"/orders/spot":{"post":{"operationId":"OrdersController_spotOrder","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpotOrderRequestDto"}}}},"responses":{"200":{"description":"Spot order executed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpotOrderResponseDto"}}}}},"summary":"Execute a spot order","tags":["Orders"]}}}}
```

## GET /orders/triggers

> Get prediction triggers (Hyperliquid + BTC dominance)

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TriggersResponseDto":{"type":"object","properties":{"triggers":{"type":"array","items":{"$ref":"#/components/schemas/TriggerDto"}}},"required":["triggers"]},"TriggerDto":{"type":"object","properties":{"id":{"type":"string","description":"Raw market ticker / outcome id"},"category":{"type":"string","enum":["prediction_market","btcdom"]},"source":{"type":"string","enum":["kalshi","hyperliquid","coingecko"]},"oracle":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/OracleValueDto"}]},"metadata":{"description":"Category-specific metadata","oneOf":[{"$ref":"#/components/schemas/MarketTriggerMetaDto"},{"$ref":"#/components/schemas/BtcDomMetaDto"}]}},"required":["id","category","source","metadata"]},"OracleValueDto":{"type":"object","properties":{"value":{"type":"number","description":"Latest oracle value"},"unit":{"type":"string","description":"Unit of the oracle value","enum":["cent","percent"]}},"required":["value","unit"]},"MarketTriggerMetaDto":{"type":"object","properties":{"kind":{"type":"string","enum":["prediction_market","btcdom"]},"type":{"type":"string","enum":["binary","multi"]},"title":{"type":"string"},"status":{"type":"string","enum":["open","closed","settled"],"nullable":true},"expiryTime":{"type":"string","nullable":true,"description":"ISO 8601 expiry time"},"imageUrl":{"type":"string","nullable":true},"popularity":{"type":"number","nullable":true,"description":"Kalshi total volume"},"outcomes":{"type":"array","items":{"$ref":"#/components/schemas/TriggerOutcomeDto"}}},"required":["kind","type","title","outcomes"]},"TriggerOutcomeDto":{"type":"object","properties":{"id":{"type":"string","description":"Tradeable outcome ticker"},"label":{"type":"string","description":"Outcome label"},"oracle":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/OracleValueDto"}]},"yesSubtitle":{"type":"string","nullable":true},"noSubtitle":{"type":"string","nullable":true}},"required":["id","label"]},"BtcDomMetaDto":{"type":"object","properties":{"kind":{"type":"string","enum":["prediction_market","btcdom"]},"btcDominance":{"type":"number"},"ethDominance":{"type":"number"},"totalMarketCapUsd":{"type":"number"},"marketCapChange24hPercent":{"type":"number"},"updatedAt":{"type":"number","description":"Unix timestamp from CoinGecko"}},"required":["kind","btcDominance","ethDominance","totalMarketCapUsd","marketCapChange24hPercent","updatedAt"]}}},"paths":{"/orders/triggers":{"get":{"operationId":"OrdersController_getTriggers","parameters":[{"name":"category","required":false,"in":"query","schema":{"default":"all","type":"string","enum":["prediction_market","btcdom","all"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggersResponseDto"}}}}},"summary":"Get prediction triggers (Hyperliquid + BTC dominance)","tags":["Orders"]}}}}
```

## GET /orders/triggers/kalshi

> Get Kalshi prediction market triggers (paginated)

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"KalshiTriggersResponseDto":{"type":"object","properties":{"triggers":{"type":"array","items":{"$ref":"#/components/schemas/TriggerDto"}},"nextCursor":{"type":"string","nullable":true}},"required":["triggers"]},"TriggerDto":{"type":"object","properties":{"id":{"type":"string","description":"Raw market ticker / outcome id"},"category":{"type":"string","enum":["prediction_market","btcdom"]},"source":{"type":"string","enum":["kalshi","hyperliquid","coingecko"]},"oracle":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/OracleValueDto"}]},"metadata":{"description":"Category-specific metadata","oneOf":[{"$ref":"#/components/schemas/MarketTriggerMetaDto"},{"$ref":"#/components/schemas/BtcDomMetaDto"}]}},"required":["id","category","source","metadata"]},"OracleValueDto":{"type":"object","properties":{"value":{"type":"number","description":"Latest oracle value"},"unit":{"type":"string","description":"Unit of the oracle value","enum":["cent","percent"]}},"required":["value","unit"]},"MarketTriggerMetaDto":{"type":"object","properties":{"kind":{"type":"string","enum":["prediction_market","btcdom"]},"type":{"type":"string","enum":["binary","multi"]},"title":{"type":"string"},"status":{"type":"string","enum":["open","closed","settled"],"nullable":true},"expiryTime":{"type":"string","nullable":true,"description":"ISO 8601 expiry time"},"imageUrl":{"type":"string","nullable":true},"popularity":{"type":"number","nullable":true,"description":"Kalshi total volume"},"outcomes":{"type":"array","items":{"$ref":"#/components/schemas/TriggerOutcomeDto"}}},"required":["kind","type","title","outcomes"]},"TriggerOutcomeDto":{"type":"object","properties":{"id":{"type":"string","description":"Tradeable outcome ticker"},"label":{"type":"string","description":"Outcome label"},"oracle":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/OracleValueDto"}]},"yesSubtitle":{"type":"string","nullable":true},"noSubtitle":{"type":"string","nullable":true}},"required":["id","label"]},"BtcDomMetaDto":{"type":"object","properties":{"kind":{"type":"string","enum":["prediction_market","btcdom"]},"btcDominance":{"type":"number"},"ethDominance":{"type":"number"},"totalMarketCapUsd":{"type":"number"},"marketCapChange24hPercent":{"type":"number"},"updatedAt":{"type":"number","description":"Unix timestamp from CoinGecko"}},"required":["kind","btcDominance","ethDominance","totalMarketCapUsd","marketCapChange24hPercent","updatedAt"]}}},"paths":{"/orders/triggers/kalshi":{"get":{"operationId":"OrdersController_getKalshiTriggers","parameters":[{"name":"category","required":false,"in":"query","description":"Kalshi category (Crypto, Politics, etc.)","schema":{"type":"string"}},{"name":"search","required":false,"in":"query","description":"Search term","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","description":"Pagination cursor","schema":{"type":"string"}},{"name":"pageSize","required":false,"in":"query","description":"Page size","schema":{"default":50,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KalshiTriggersResponseDto"}}}}},"summary":"Get Kalshi prediction market triggers (paginated)","tags":["Orders"]}}}}
```


# Positions

## List processed open positions

> Returns processed open positions for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"OpenPositionProcessedDto":{"type":"object","properties":{"positionId":{"type":"string","description":"Position identifier"},"address":{"type":"string","description":"User wallet address"},"pearExecutionFlag":{"type":"string","description":"Pear execution flag","enum":["FULLY_PEAR","PARTIAL","FULLY_EXTERNAL"]},"stopLoss":{"description":"Stop loss trigger","nullable":true,"allOf":[{"$ref":"#/components/schemas/TpSlThreshold"}]},"takeProfit":{"description":"Take profit trigger","nullable":true,"allOf":[{"$ref":"#/components/schemas/TpSlThreshold"}]},"entryRatio":{"type":"number","description":"Weighted entry ratio"},"markRatio":{"type":"number","description":"Weighted mark ratio"},"entryPriceRatio":{"type":"number","description":"Entry price ratio (only for 1 long x 1 short)"},"markPriceRatio":{"type":"number","description":"Mark price ratio (only for 1 long x 1 short)"},"entryPositionValue":{"type":"number","description":"Total entry USD value"},"positionValue":{"type":"number","description":"Total current USD value"},"marginUsed":{"type":"number","description":"Total margin used"},"unrealizedPnl":{"type":"number","description":"Total unrealized PnL (USD)"},"unrealizedPnlPercentage":{"type":"number","description":"Unrealized PnL percentage relative to margin used"},"longAssets":{"description":"Long assets","type":"array","items":{"$ref":"#/components/schemas/PositionAssetDetailProcessedDto"}},"shortAssets":{"description":"Short assets","type":"array","items":{"$ref":"#/components/schemas/PositionAssetDetailProcessedDto"}},"createdAt":{"type":"string","description":"Creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last update timestamp","format":"date-time"}},"required":["positionId","address","pearExecutionFlag","stopLoss","takeProfit","entryRatio","markRatio","entryPositionValue","positionValue","marginUsed","unrealizedPnl","unrealizedPnlPercentage","longAssets","shortAssets","createdAt","updatedAt"]},"TpSlThreshold":{"type":"object","properties":{"type":{"type":"string","description":"Trigger type","enum":["PERCENTAGE","DOLLAR","POSITION_VALUE","PRICE","PRICE_RATIO","WEIGHTED_RATIO"]},"value":{"type":"number","description":"Trigger value for the specified type"},"isTrailing":{"type":"boolean","description":"Enable trailing behavior for this TP/SL"},"trailingDeltaValue":{"type":"number","description":"Trailing delta value based on trigger type"},"trailingActivationValue":{"type":"number","description":"Activation value to start trailing"}},"required":["type"]},"PositionAssetDetailProcessedDto":{"type":"object","properties":{"coin":{"type":"string","description":"Asset symbol"},"entryPrice":{"type":"number","description":"Entry price"},"actualSize":{"type":"number","description":"Actual size filled"},"leverage":{"type":"number","description":"Leverage applied to this asset"},"marginUsed":{"type":"number","description":"Margin used for this asset (USD)"},"positionValue":{"type":"number","description":"Current USD value"},"unrealizedPnl":{"type":"number","description":"Unrealized PnL (USD)"},"entryPositionValue":{"type":"number","description":"Entry USD value"},"fundingPaid":{"type":"number","description":"Total funding paid/received for this asset (USD)"},"targetWeight":{"type":"number","description":"Target weight of asset in position (decimal, 0-1)"}},"required":["coin","entryPrice","actualSize","leverage","marginUsed","positionValue","unrealizedPnl","entryPositionValue","targetWeight"]}}},"paths":{"/positions":{"get":{"description":"Returns processed open positions for the authenticated user","operationId":"PositionsController_getOpenPositions","parameters":[],"responses":{"200":{"description":"Processed open positions fetched successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OpenPositionProcessedDto"}}}}}},"summary":"List processed open positions","tags":["Positions"]}}}}
```

## Create a new pair trading position with order

> Create a pair trading position with various execution types: MARKET (immediate execution), TRIGGER (conditional execution), TWAP (time-weighted average), or LADDER (multiple ratio levels)

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CreatePositionRequestDto":{"type":"object","properties":{"slippage":{"type":"number","description":"Slippage tolerance percentage (0.01 = 1%)","minimum":0.001,"maximum":0.1},"executionType":{"type":"string","description":"Order execution type","enum":["SYNC","MARKET","TRIGGER","TWAP","LADDER","TP","SL","SPOT_MARKET","SPOT_LIMIT","SPOT_TWAP"]},"leverage":{"type":"number","description":"Applied leverage","minimum":1,"maximum":100},"usdValue":{"type":"number","description":"Position size in USD","minimum":1},"longAssets":{"description":"Long assets configuration - array of assets to go long on. Can be empty for short-only positions.","type":"array","items":{"$ref":"#/components/schemas/PairAssetDto"}},"shortAssets":{"description":"Short assets configuration - array of assets to go short on. Can be empty for long-only positions.","type":"array","items":{"$ref":"#/components/schemas/PairAssetDto"}},"triggerValue":{"type":"string","description":"Required trigger threshold for TRIGGER orders (price, dominance, ratios, etc.)"},"triggerType":{"type":"string","description":"Trigger type for TRIGGER orders (PRICE, PRICE_RATIO, WEIGHTED_RATIO, BTC_DOM, CROSS_ASSET_PRICE, PREDICTION_MARKET_OUTCOME)","enum":["PRICE","PRICE_LIMIT","PRICE_RATIO","WEIGHTED_RATIO","BTC_DOM","CROSS_ASSET_PRICE","PREDICTION_MARKET_OUTCOME"]},"direction":{"type":"string","description":"Direction for TRIGGER orders","enum":["MORE_THAN","LESS_THAN"]},"assetName":{"type":"string","description":"Asset to monitor when triggerType is CROSS_ASSET_PRICE"},"marketCode":{"type":"string","description":"Market code to monitor when triggerType is PREDICTION_MARKET_OUTCOME"},"marketSource":{"type":"string","description":"Market source for prediction market orders","enum":["KALSHI","HYPERLIQUID"]},"twapDuration":{"type":"number","description":"TWAP duration in minutes (required for TWAP orders)"},"twapIntervalSeconds":{"type":"number","description":"TWAP interval in seconds (time between chunks). Defaults to 30 seconds if not provided.","minimum":1,"maximum":3600},"randomizeExecution":{"type":"boolean","description":"Randomize TWAP execution timing","default":false},"ladderConfig":{"description":"Ladder order configuration","allOf":[{"$ref":"#/components/schemas/LadderConfigDto"}]},"stopLoss":{"description":"Stop loss trigger. PERCENTAGE: % change vs entry; DOLLAR: fixed USD change; POSITION_VALUE: % change of position value.","nullable":true,"allOf":[{"$ref":"#/components/schemas/TpSlThreshold"}]},"takeProfit":{"description":"Take profit trigger. PERCENTAGE: % change vs entry; DOLLAR: fixed USD change; POSITION_VALUE: % change of position value.","nullable":true,"allOf":[{"$ref":"#/components/schemas/TpSlThreshold"}]},"referralCode":{"type":"string","description":"Referral code to be attached to user address if user has no referral code"}},"required":["slippage","executionType","leverage","usdValue"]},"PairAssetDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset symbol"},"weight":{"type":"number","description":"Weight allocation for this asset (0.0001 to 1.0). If not provided, weights will be evenly distributed.","minimum":0.0001,"maximum":1}},"required":["asset"]},"LadderConfigDto":{"type":"object","properties":{"ratioStart":{"type":"number","description":"Starting ratio for the ladder","minimum":0.01},"ratioEnd":{"type":"number","description":"Ending ratio for the ladder","minimum":0.01},"numberOfLevels":{"type":"number","description":"Number of levels in the ladder","minimum":2,"maximum":50}},"required":["ratioStart","ratioEnd","numberOfLevels"]},"TpSlThreshold":{"type":"object","properties":{"type":{"type":"string","description":"Trigger type","enum":["PERCENTAGE","DOLLAR","POSITION_VALUE","PRICE","PRICE_RATIO","WEIGHTED_RATIO"]},"value":{"type":"number","description":"Trigger value for the specified type"},"isTrailing":{"type":"boolean","description":"Enable trailing behavior for this TP/SL"},"trailingDeltaValue":{"type":"number","description":"Trailing delta value based on trigger type"},"trailingActivationValue":{"type":"number","description":"Activation value to start trailing"}},"required":["type"]},"CreatePositionResponseDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Unique identifier for the initial order"},"fills":{"description":"Fills returned from Hyperliquid for the order","type":"array","items":{"$ref":"#/components/schemas/ExternalFillDto"}}},"required":["orderId"]},"ExternalFillDto":{"type":"object","properties":{"coin":{"type":"string","description":"Asset symbol"},"px":{"type":"string","description":"Fill price"},"sz":{"type":"string","description":"Fill size"},"side":{"type":"string","description":"Side","enum":["B","A"]},"time":{"type":"number","description":"Timestamp in ms"},"dir":{"type":"string","description":"Direction (e.g. Open Long, Close Short)"},"fee":{"type":"string","description":"Fee amount"},"builderFee":{"type":"string","description":"Builder fee"},"startPosition":{"type":"string","description":"Start position size"},"oid":{"type":"string","description":"Order ID"},"tid":{"type":"string","description":"Trade ID"},"cloid":{"type":"string","description":"Client order ID","nullable":true},"hash":{"type":"string","description":"Transaction hash","nullable":true},"feeToken":{"type":"string","description":"Fee token","nullable":true},"liquidation":{"description":"Liquidation details","nullable":true,"allOf":[{"$ref":"#/components/schemas/ExternalLiquidationDto"}]},"closedPnl":{"type":"object","description":"Closed PnL","nullable":true},"crossed":{"type":"object","description":"Whether fill crossed the spread","nullable":true},"twapId":{"type":"object","description":"TWAP order ID","nullable":true}},"required":["coin","px","sz","side","time","dir","fee"]},"ExternalLiquidationDto":{"type":"object","properties":{"liquidatedUser":{"type":"string","description":"Liquidated user address"},"markPx":{"type":"string","description":"Mark price at liquidation"},"method":{"type":"string","description":"Liquidation method"}},"required":["liquidatedUser","markPx","method"]}}},"paths":{"/positions":{"post":{"description":"Create a pair trading position with various execution types: MARKET (immediate execution), TRIGGER (conditional execution), TWAP (time-weighted average), or LADDER (multiple ratio levels)","operationId":"PositionsController_createPosition","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePositionRequestDto"}}}},"responses":{"201":{"description":"Position order created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePositionResponseDto"}}}}},"summary":"Create a new pair trading position with order","tags":["Positions"]}}}}
```

## Close an entire position

> Close a position using MARKET (immediate execution), TWAP (time-weighted average), or TRIGGER (conditional trigger-close order) execution type

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ClosePositionRequestDto":{"type":"object","properties":{"executionType":{"type":"string","description":"Type of close order","enum":["MARKET","TWAP","TRIGGER"]},"twapDuration":{"type":"number","description":"TWAP duration in minutes - required if executionType is TWAP"},"twapIntervalSeconds":{"type":"number","description":"TWAP interval in seconds (time between close chunks). Defaults to 30 seconds if not provided."},"randomizeExecution":{"type":"boolean","description":"Randomize TWAP execution times - optional for TWAP orders"},"triggerValue":{"type":"string","description":"Trigger threshold for TRIGGER close orders"},"triggerType":{"type":"string","description":"Trigger type for TRIGGER close orders","enum":["PRICE","PRICE_RATIO","WEIGHTED_RATIO","PERCENTAGE","DOLLAR","POSITION_VALUE"]},"direction":{"type":"string","description":"Direction for TRIGGER close orders","enum":["MORE_THAN","LESS_THAN"]},"referralCode":{"type":"string","description":"Referral code to be attached to user address if user has no referral code"}},"required":["executionType"]},"ClosePositionResponseDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Unique identifier for the close order","format":"uuid"},"executionTime":{"type":"string","description":"Execution time for the order"},"orderIds":{"description":"Created trigger order identifiers for TRIGGER close requests","type":"array","items":{"type":"string"}},"chunksScheduled":{"type":"number","description":"Number of TWAP chunks scheduled (only for TWAP orders)"}},"required":["orderId"]}}},"paths":{"/positions/{positionId}/close":{"post":{"description":"Close a position using MARKET (immediate execution), TWAP (time-weighted average), or TRIGGER (conditional trigger-close order) execution type","operationId":"PositionsController_closePosition","parameters":[{"name":"positionId","required":true,"in":"path","description":"Position identifier","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClosePositionRequestDto"}}}},"responses":{"200":{"description":"Position close order created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClosePositionResponseDto"}}}}},"summary":"Close an entire position","tags":["Positions"]}}}}
```

## Close all open positions

> Fetches all open positions and closes them sequentially using MARKET or TWAP execution

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ClosePositionRequestDto":{"type":"object","properties":{"executionType":{"type":"string","description":"Type of close order","enum":["MARKET","TWAP","TRIGGER"]},"twapDuration":{"type":"number","description":"TWAP duration in minutes - required if executionType is TWAP"},"twapIntervalSeconds":{"type":"number","description":"TWAP interval in seconds (time between close chunks). Defaults to 30 seconds if not provided."},"randomizeExecution":{"type":"boolean","description":"Randomize TWAP execution times - optional for TWAP orders"},"triggerValue":{"type":"string","description":"Trigger threshold for TRIGGER close orders"},"triggerType":{"type":"string","description":"Trigger type for TRIGGER close orders","enum":["PRICE","PRICE_RATIO","WEIGHTED_RATIO","PERCENTAGE","DOLLAR","POSITION_VALUE"]},"direction":{"type":"string","description":"Direction for TRIGGER close orders","enum":["MORE_THAN","LESS_THAN"]},"referralCode":{"type":"string","description":"Referral code to be attached to user address if user has no referral code"}},"required":["executionType"]},"CloseAllPositionsResponseDto":{"type":"object","properties":{"results":{"description":"Results for each position close action","type":"array","items":{"$ref":"#/components/schemas/CloseAllPositionsResultDto"}}},"required":["results"]},"CloseAllPositionsResultDto":{"type":"object","properties":{"positionId":{"type":"string","description":"Position identifier"},"success":{"type":"boolean","description":"Whether the close action succeeded"},"orderId":{"type":"string","description":"Order ID created for the close action"},"error":{"type":"string","description":"Error message if the close action failed"}},"required":["positionId","success"]}}},"paths":{"/positions/close-all":{"post":{"description":"Fetches all open positions and closes them sequentially using MARKET or TWAP execution","operationId":"PositionsController_closeAllPositions","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClosePositionRequestDto"}}}},"responses":{"200":{"description":"Close orders created for all positions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloseAllPositionsResponseDto"}}}}},"summary":"Close all open positions","tags":["Positions"]}}}}
```

## POST /positions/{positionId}/adjust

> Adjust position size by reducing or increasing by a specified amount

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"AdjustPositionRequestDto":{"type":"object","properties":{"adjustmentType":{"type":"string","description":"Type of position adjustment (reduce or increase)","enum":["REDUCE","INCREASE"],"default":"REDUCE"},"adjustmentSize":{"type":"number","description":"Percentage of position to adjust (1-100%)","minimum":1,"maximum":100},"executionType":{"type":"string","description":"Type of execution for the adjustment","enum":["MARKET","LIMIT"],"default":"MARKET"},"limitRatio":{"type":"number","description":"Required if executionType is LIMIT"},"referralCode":{"type":"string","description":"Referral code to be attached to user address if user has no referral code"}},"required":["adjustmentType","adjustmentSize","executionType"]},"AdjustPositionResponseDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Unique identifier for the adjustment order","format":"uuid"},"status":{"type":"string","description":"Status of the adjustment order"},"adjustmentType":{"type":"string","description":"Type of adjustment that was made","enum":["REDUCE","INCREASE"]},"adjustmentSize":{"type":"number","description":"Percentage used for position adjustment"},"newSize":{"type":"number","description":"New position size after adjustment"},"executedAt":{"type":"string","description":"Timestamp when the reduction was executed","format":"date-time"}},"required":["orderId","status","adjustmentType","adjustmentSize","newSize","executedAt"]}}},"paths":{"/positions/{positionId}/adjust":{"post":{"operationId":"PositionsController_adjustPosition","parameters":[{"name":"positionId","required":true,"in":"path","description":"Position identifier","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdjustPositionRequestDto"}}}},"responses":{"200":{"description":"Position adjustment order created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdjustPositionResponseDto"}}}}},"summary":"Adjust position size by reducing or increasing by a specified amount","tags":["Positions"]}}}}
```

## POST /positions/{positionId}/adjust-advance

> Adjust position to target absolute sizes per asset (advance)

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"AdjustAdvanceItemDto":{"type":"object","properties":{"longAssets":{"description":"Target long assets with absolute sizes","type":"array","items":{"$ref":"#/components/schemas/AdjustAdvanceAssetDto"}},"shortAssets":{"description":"Target short assets with absolute sizes","type":"array","items":{"$ref":"#/components/schemas/AdjustAdvanceAssetDto"}}},"required":["longAssets","shortAssets"]},"AdjustAdvanceAssetDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset symbol"},"size":{"type":"number","description":"Target absolute size for this asset","minimum":0}},"required":["asset","size"]},"AdjustAdvanceResponseDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Order identifier"},"status":{"type":"string","description":"Order status"},"executedAt":{"type":"string","description":"Execution timestamp"}},"required":["orderId","status","executedAt"]}}},"paths":{"/positions/{positionId}/adjust-advance":{"post":{"operationId":"PositionsController_adjustAdvancePosition","parameters":[{"name":"positionId","required":true,"in":"path","description":"Position identifier","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdjustAdvanceItemDto"}}}}},"responses":{"200":{"description":"Advance adjustment executed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdjustAdvanceResponseDto"}}}}},"summary":"Adjust position to target absolute sizes per asset (advance)","tags":["Positions"]}}}}
```

## POST /positions/{positionId}/adjust-leverage

> Adjust leverage for a position

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"AdjustLeverageRequestDto":{"type":"object","properties":{"leverage":{"type":"number","description":"Applied leverage","minimum":1,"maximum":100}},"required":["leverage"]}}},"paths":{"/positions/{positionId}/adjust-leverage":{"post":{"operationId":"PositionsController_adjustLeverage","parameters":[{"name":"positionId","required":true,"in":"path","description":"Position identifier","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdjustLeverageRequestDto"}}}},"responses":{"200":{"description":"Leverage updated successfully","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Adjust leverage for a position","tags":["Positions"]}}}}
```

## Preview rebalance plan without executing

> Computes weight deltas and returns what would be traded, without placing any orders. Use this to preview before calling the execute endpoint.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"RebalancePositionRequestDto":{"type":"object","properties":{"targetWeights":{"type":"object","description":"Optional target weight overrides per asset coin (decimal, should sum to 1.0 per side). If omitted, uses existing targetWeight from position.","additionalProperties":{"type":"number"}}},"required":["targetWeights"]},"RebalancePlanDto":{"type":"object","properties":{"positionId":{"type":"string","description":"Position ID being rebalanced"},"assets":{"description":"Per-asset rebalance details","type":"array","items":{"$ref":"#/components/schemas/RebalanceAssetPlanDto"}},"canExecute":{"type":"boolean","description":"Whether any asset has a non-skipped trade to execute"}},"required":["positionId","assets","canExecute"]},"RebalanceAssetPlanDto":{"type":"object","properties":{"coin":{"type":"string","description":"Asset ticker symbol"},"side":{"type":"string","description":"Position side","enum":["long","short"]},"currentWeight":{"type":"number","description":"Current weight of asset in position (decimal, 0-1)"},"targetWeight":{"type":"number","description":"Desired target weight (decimal, 0-1)"},"currentValue":{"type":"number","description":"Current notional value in USD"},"targetValue":{"type":"number","description":"Target notional value in USD after rebalance"},"deltaValue":{"type":"number","description":"Difference between target and current value in USD"},"currentSize":{"type":"number","description":"Current position size in asset units"},"newSize":{"type":"number","description":"Position size in asset units after rebalance"},"deltaSize":{"type":"number","description":"Size change required in asset units"},"skipped":{"type":"boolean","description":"Whether this asset will be skipped during rebalance"},"skipReason":{"type":"string","description":"Reason for skipping (e.g. trade below minimum size)"}},"required":["coin","side","currentWeight","targetWeight","currentValue","targetValue","deltaValue","currentSize","newSize","deltaSize","skipped"]}}},"paths":{"/positions/{positionId}/rebalance/plan":{"post":{"description":"Computes weight deltas and returns what would be traded, without placing any orders. Use this to preview before calling the execute endpoint.","operationId":"PositionsController_planRebalance","parameters":[{"name":"positionId","required":true,"in":"path","description":"Position identifier","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RebalancePositionRequestDto"}}}},"responses":{"200":{"description":"Rebalance plan computed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RebalancePlanDto"}}}}},"summary":"Preview rebalance plan without executing","tags":["Positions"]}}}}
```

## Rebalance position assets to target weights

> Computes weight deltas and adjusts asset sizes to match target weights. Uses existing targetWeight from position if no overrides provided.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"RebalancePositionRequestDto":{"type":"object","properties":{"targetWeights":{"type":"object","description":"Optional target weight overrides per asset coin (decimal, should sum to 1.0 per side). If omitted, uses existing targetWeight from position.","additionalProperties":{"type":"number"}}},"required":["targetWeights"]},"RebalancePositionResponseDto":{"type":"object","properties":{"orderId":{"type":"string","description":"Rebalance order ID"},"status":{"type":"string","description":"Execution status"},"executedAt":{"type":"string","description":"ISO 8601 timestamp of execution"},"plan":{"description":"Rebalance plan that was executed","allOf":[{"$ref":"#/components/schemas/RebalancePlanDto"}]}},"required":["orderId","status","executedAt","plan"]},"RebalancePlanDto":{"type":"object","properties":{"positionId":{"type":"string","description":"Position ID being rebalanced"},"assets":{"description":"Per-asset rebalance details","type":"array","items":{"$ref":"#/components/schemas/RebalanceAssetPlanDto"}},"canExecute":{"type":"boolean","description":"Whether any asset has a non-skipped trade to execute"}},"required":["positionId","assets","canExecute"]},"RebalanceAssetPlanDto":{"type":"object","properties":{"coin":{"type":"string","description":"Asset ticker symbol"},"side":{"type":"string","description":"Position side","enum":["long","short"]},"currentWeight":{"type":"number","description":"Current weight of asset in position (decimal, 0-1)"},"targetWeight":{"type":"number","description":"Desired target weight (decimal, 0-1)"},"currentValue":{"type":"number","description":"Current notional value in USD"},"targetValue":{"type":"number","description":"Target notional value in USD after rebalance"},"deltaValue":{"type":"number","description":"Difference between target and current value in USD"},"currentSize":{"type":"number","description":"Current position size in asset units"},"newSize":{"type":"number","description":"Position size in asset units after rebalance"},"deltaSize":{"type":"number","description":"Size change required in asset units"},"skipped":{"type":"boolean","description":"Whether this asset will be skipped during rebalance"},"skipReason":{"type":"string","description":"Reason for skipping (e.g. trade below minimum size)"}},"required":["coin","side","currentWeight","targetWeight","currentValue","targetValue","deltaValue","currentSize","newSize","deltaSize","skipped"]}}},"paths":{"/positions/{positionId}/rebalance":{"post":{"description":"Computes weight deltas and adjusts asset sizes to match target weights. Uses existing targetWeight from position if no overrides provided.","operationId":"PositionsController_rebalancePosition","parameters":[{"name":"positionId","required":true,"in":"path","description":"Position identifier","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RebalancePositionRequestDto"}}}},"responses":{"200":{"description":"Rebalance executed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RebalancePositionResponseDto"}}}}},"summary":"Rebalance position assets to target weights","tags":["Positions"]}}}}
```

## PUT /positions/{positionId}/riskParameters

> Update stop loss and take profit values for a position

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UpdateRiskParametersRequestDto":{"type":"object","properties":{"stopLoss":{"description":"Stop loss configuration. Set to null to remove existing stop loss.","nullable":true,"allOf":[{"$ref":"#/components/schemas/TpSlThreshold"}]},"takeProfit":{"description":"Take profit configuration. Set to null to remove existing take profit.","nullable":true,"allOf":[{"$ref":"#/components/schemas/TpSlThreshold"}]}}},"TpSlThreshold":{"type":"object","properties":{"type":{"type":"string","description":"Trigger type","enum":["PERCENTAGE","DOLLAR","POSITION_VALUE","PRICE","PRICE_RATIO","WEIGHTED_RATIO"]},"value":{"type":"number","description":"Trigger value for the specified type"},"isTrailing":{"type":"boolean","description":"Enable trailing behavior for this TP/SL"},"trailingDeltaValue":{"type":"number","description":"Trailing delta value based on trigger type"},"trailingActivationValue":{"type":"number","description":"Activation value to start trailing"}},"required":["type"]},"UpdateRiskParametersResponseDto":{"type":"object","properties":{"positionId":{"type":"string","description":"Position identifier","format":"uuid"},"stopLoss":{"description":"Updated stop loss configuration","nullable":true,"allOf":[{"$ref":"#/components/schemas/TpSlThreshold"}]},"takeProfit":{"description":"Updated take profit configuration","nullable":true,"allOf":[{"$ref":"#/components/schemas/TpSlThreshold"}]},"updatedAt":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["positionId","stopLoss","takeProfit","updatedAt"]}}},"paths":{"/positions/{positionId}/riskParameters":{"put":{"operationId":"PositionsController_updateRiskParameters","parameters":[{"name":"positionId","required":true,"in":"path","description":"Position identifier","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRiskParametersRequestDto"}}}},"responses":{"200":{"description":"Risk parameters updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRiskParametersResponseDto"}}}}},"summary":"Update stop loss and take profit values for a position","tags":["Positions"]}}}}
```


# Trade History

## Get all trade history

> Retrieve all trade history for the authenticated user with detailed trade information including fees, PnL, and asset-level data

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TradeHistoryDataDto":{"type":"object","properties":{"tradeHistoryId":{"type":"string","description":"Trade history ID"},"positionId":{"type":"string","description":"Associated position ID"},"address":{"type":"string","description":"User wallet address"},"externalFeePaid":{"type":"number","description":"Total fee paid to DEX Engine"},"builderFeePaid":{"type":"number","description":"Total fee paid to builder"},"realizedPnl":{"type":"number","description":"Total realized PnL value"},"realizedPnlPercentage":{"type":"number","description":"Total realized PnL percentage"},"totalValue":{"type":"number","description":"Total trade value in USD"},"totalEntryValue":{"type":"number","description":"Total entry value in USD (sum of size * entry price per asset)"},"entryRatio":{"type":"number","description":"Entry ratio for the trade"},"exitRatio":{"type":"number","description":"Exit ratio for the trade"},"closedLongAssets":{"description":"Long assets in the trade","type":"array","items":{"$ref":"#/components/schemas/TradeHistoryAssetDataDto"}},"closedShortAssets":{"description":"Short assets in the trade","type":"array","items":{"$ref":"#/components/schemas/TradeHistoryAssetDataDto"}},"positionLongAssets":{"description":"List of long token symbols from position at time of trade","type":"array","items":{"type":"string"}},"positionShortAssets":{"description":"List of short token symbols from position at time of trade","type":"array","items":{"type":"string"}},"createdAt":{"type":"string","description":"Trade timestamp"}},"required":["tradeHistoryId","positionId","address","externalFeePaid","builderFeePaid","realizedPnl","realizedPnlPercentage","totalValue","totalEntryValue","entryRatio","exitRatio","closedLongAssets","createdAt"]},"TradeHistoryAssetDataDto":{"type":"object","properties":{"coin":{"type":"string","description":"Asset symbol"},"leverage":{"type":"number","description":"Leverage used for this asset"},"entryPrice":{"type":"number","description":"Entry price for this asset"},"entryWeight":{"type":"number","description":"Entry weight for this asset"},"limitPrice":{"type":"number","description":"Limit price for this asset"},"size":{"type":"number","description":"Trade size for this asset"},"externalFeePaid":{"type":"number","description":"Fee paid to DEX Engine"},"builderFeePaid":{"type":"number","description":"Fee paid to builder"},"realizedPnl":{"type":"number","description":"Realized PnL percentage for this asset"}},"required":["coin","leverage","entryPrice","entryWeight","limitPrice","size","externalFeePaid","builderFeePaid","realizedPnl"]}}},"paths":{"/trade-history":{"get":{"description":"Retrieve all trade history for the authenticated user with detailed trade information including fees, PnL, and asset-level data","operationId":"TradeHistoryController_getTradeHistory","parameters":[{"name":"limit","required":false,"in":"query","description":"Maximum number of records to return (maximum 100).","schema":{"type":"number"}},{"name":"startDate","required":false,"in":"query","description":"Filter trades created on/after this time. Accepts ISO string or ms timestamp.","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"Filter trades created on/before this time. Accepts ISO string or ms timestamp.","schema":{"type":"string"}}],"responses":{"200":{"description":"Trade history retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TradeHistoryDataDto"}}}}},"404":{"description":"No trade history found"}},"summary":"Get all trade history","tags":["Trade History"]}}}}
```


# Accounts

## Get account summary

> Retrieve account summary including margin information and agent wallet details for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"AccountSummaryResponseDto":{"type":"object","properties":{"agentWalletAddress":{"type":"string","description":"Agent wallet address"},"totalClosedTrades":{"type":"number","description":"Total number of closed trades"},"totalTriggerOrderUsdValue":{"type":"number","description":"Total USD value of open trigger orders"},"totalTwapChunkUsdValue":{"type":"number","description":"Total USD value of open TWAP chunks"},"lastSyncedAt":{"type":"number","description":"Last synced timestamp in milliseconds"}},"required":["agentWalletAddress","totalClosedTrades"]}}},"paths":{"/accounts":{"get":{"description":"Retrieve account summary including margin information and agent wallet details for the authenticated user","operationId":"AccountsController_getAccountSummary","parameters":[],"responses":{"200":{"description":"Account summary retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSummaryResponseDto"}}}}},"summary":"Get account summary","tags":["Accounts"]}}}}
```


# API Keys

## Get user API keys

> Get all API keys for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/api-keys":{"get":{"description":"Get all API keys for the authenticated user","operationId":"ApiKeysController_getUserApiKeys","parameters":[],"responses":{"200":{"description":"API keys retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"apiKeys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"lastUsedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Unauthorized - invalid or missing token"}},"summary":"Get user API keys","tags":["API Keys"]}}}}
```

## Create API key

> Create a new API key for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/api-keys":{"post":{"description":"Create a new API key for the authenticated user","operationId":"ApiKeysController_createApiKey","parameters":[],"requestBody":{"required":true,"description":"API key creation request","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Optional name for the API key"}}}}}},"responses":{"201":{"description":"API key created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"apiKey":{"type":"string"},"name":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized - invalid or missing token"}},"summary":"Create API key","tags":["API Keys"]}}}}
```


# Sync

## POST /sync/fills

> Sync external fills into internal state

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SyncFillsRequestDto":{"type":"object","properties":{"user":{"type":"string","description":"User EVM address"},"fills":{"description":"External fills to sync","type":"array","items":{"$ref":"#/components/schemas/ExternalFillDto"}},"assetPositions":{"description":"Current asset positions from clearinghouse state","type":"array","items":{"type":"string"}}},"required":["user","fills"]},"ExternalFillDto":{"type":"object","properties":{"coin":{"type":"string","description":"Asset symbol"},"px":{"type":"string","description":"Fill price"},"sz":{"type":"string","description":"Fill size"},"side":{"type":"string","description":"Side","enum":["B","A"]},"time":{"type":"number","description":"Timestamp in ms"},"dir":{"type":"string","description":"Direction (e.g. Open Long, Close Short)"},"fee":{"type":"string","description":"Fee amount"},"builderFee":{"type":"string","description":"Builder fee"},"startPosition":{"type":"string","description":"Start position size"},"oid":{"type":"string","description":"Order ID"},"tid":{"type":"string","description":"Trade ID"},"cloid":{"type":"string","description":"Client order ID","nullable":true},"hash":{"type":"string","description":"Transaction hash","nullable":true},"feeToken":{"type":"string","description":"Fee token","nullable":true},"liquidation":{"description":"Liquidation details","nullable":true,"allOf":[{"$ref":"#/components/schemas/ExternalLiquidationDto"}]},"closedPnl":{"type":"object","description":"Closed PnL","nullable":true},"crossed":{"type":"object","description":"Whether fill crossed the spread","nullable":true},"twapId":{"type":"object","description":"TWAP order ID","nullable":true}},"required":["coin","px","sz","side","time","dir","fee"]},"ExternalLiquidationDto":{"type":"object","properties":{"liquidatedUser":{"type":"string","description":"Liquidated user address"},"markPx":{"type":"string","description":"Mark price at liquidation"},"method":{"type":"string","description":"Liquidation method"}},"required":["liquidatedUser","markPx","method"]}}},"paths":{"/sync/fills":{"post":{"operationId":"SyncController_syncFills","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncFillsRequestDto"}}}},"responses":{"200":{"description":"Sync completed"}},"summary":"Sync external fills into internal state","tags":["Sync"]}}}}
```


# Notifications

## GET /notifications

> Get notifications for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/notifications":{"get":{"operationId":"NotificationsController_getNotifications","parameters":[{"name":"limit","required":false,"in":"query","description":"Maximum number of records to return (maximum 100)","schema":{"type":"number"}},{"name":"startDate","required":false,"in":"query","description":"Filter notifications created on/after this time (ISO or ms)","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"Filter notifications created on/before this time (ISO or ms)","schema":{"type":"string"}}],"responses":{"200":{"description":"Notifications retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"summary":"Get notifications for the authenticated user","tags":["Notifications"]}}}}
```

## POST /notifications/read

> Mark a notification by id as read or all up to a timestamp (ms)

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"MarkNotificationsReadDto":{"type":"object","properties":{"id":{"type":"string","description":"Notification id to mark as read (takes precedence if provided)."},"timestamp":{"type":"number","description":"Unix timestamp in milliseconds. Marks notifications created at or before this time as read."}}}}},"paths":{"/notifications/read":{"post":{"operationId":"NotificationsController_markRead","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkNotificationsReadDto"}}}},"responses":{"200":{"description":"Number of notifications updated","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Mark a notification by id as read or all up to a timestamp (ms)","tags":["Notifications"]}}}}
```


# Watchlist

## GET /watchlist

> Get the authenticated user watchlist baskets

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"WatchlistResponseDto":{"type":"object","properties":{"items":{"description":"List of watchlist baskets","type":"array","items":{"$ref":"#/components/schemas/WatchlistBasketDto"}}},"required":["items"]},"WatchlistBasketDto":{"type":"object","properties":{"id":{"type":"string","description":"Basket ID"},"longAssets":{"description":"Long assets in the basket","type":"array","items":{"$ref":"#/components/schemas/WatchlistAssetDto"}},"shortAssets":{"description":"Short assets in the basket","type":"array","items":{"$ref":"#/components/schemas/WatchlistAssetDto"}}},"required":["id","longAssets","shortAssets"]},"WatchlistAssetDto":{"type":"object","properties":{"asset":{"type":"string"},"weight":{"type":"number"}},"required":["asset","weight"]}}},"paths":{"/watchlist":{"get":{"operationId":"WatchlistController_getWatchlist","parameters":[],"responses":{"200":{"description":"Current list of baskets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistResponseDto"}}}}},"summary":"Get the authenticated user watchlist baskets","tags":["Watchlist"]}}}}
```

## POST /watchlist

> Toggle a basket (pair) in the user watchlist: if exact pair exists, remove it; otherwise, add it. Order and casing are preserved.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ToggleWatchlistDto":{"type":"object","properties":{"longAssets":{"description":"Long assets for the basket (order preserved)","type":"array","items":{"$ref":"#/components/schemas/WatchlistAssetDto"}},"shortAssets":{"description":"Short assets for the basket (order preserved)","type":"array","items":{"$ref":"#/components/schemas/WatchlistAssetDto"}}},"required":["longAssets","shortAssets"]},"WatchlistAssetDto":{"type":"object","properties":{"asset":{"type":"string"},"weight":{"type":"number"}},"required":["asset","weight"]},"WatchlistResponseDto":{"type":"object","properties":{"items":{"description":"List of watchlist baskets","type":"array","items":{"$ref":"#/components/schemas/WatchlistBasketDto"}}},"required":["items"]},"WatchlistBasketDto":{"type":"object","properties":{"id":{"type":"string","description":"Basket ID"},"longAssets":{"description":"Long assets in the basket","type":"array","items":{"$ref":"#/components/schemas/WatchlistAssetDto"}},"shortAssets":{"description":"Short assets in the basket","type":"array","items":{"$ref":"#/components/schemas/WatchlistAssetDto"}}},"required":["id","longAssets","shortAssets"]}}},"paths":{"/watchlist":{"post":{"operationId":"WatchlistController_toggle","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToggleWatchlistDto"}}}},"responses":{"200":{"description":"Updated list of baskets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistResponseDto"}}}}},"summary":"Toggle a basket (pair) in the user watchlist: if exact pair exists, remove it; otherwise, add it. Order and casing are preserved.","tags":["Watchlist"]}}}}
```


# Legacy Support

## GET /legacysupport/metric

> Get legacy metrics (daily and total) for compatibility with pear-backend metric service

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/legacysupport/metric":{"get":{"operationId":"LegacySupportController_getLegacyMetrics","parameters":[{"name":"timestamp","required":false,"in":"query","description":"Start of day timestamp (in seconds). Defaults to previous day window.","schema":{"type":"number"}}],"responses":{"200":{"description":"Legacy metrics fetched successfully","content":{"application/json":{"schema":{"type":"object","properties":{"totalVolume":{"type":"number"},"totalUsers":{"type":"number"},"dailyVolume":{"type":"number"},"dailyFees":{"type":"number"},"totalFees":{"type":"number"}}}}}}},"summary":"Get legacy metrics (daily and total) for compatibility with pear-backend metric service","tags":["Legacy Support"]}}}}
```

## GET /legacysupport/weeklyVolume

> Get weekly and monthly volumes for legacy support

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/legacysupport/weeklyVolume":{"get":{"operationId":"LegacySupportController_getLegacyWeeklyVolume","parameters":[{"name":"timestamp","required":false,"in":"query","description":"Start of day timestamp (in seconds). Aligns end of windows the same as /metric.","schema":{"type":"number"}}],"responses":{"200":{"description":"Weekly and monthly volumes"}},"summary":"Get weekly and monthly volumes for legacy support","tags":["Legacy Support"]}}}}
```

## GET /legacysupport/stats/hyperliquid

> Get hyperliquid user stats for legacy support (V2)

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/legacysupport/stats/hyperliquid":{"get":{"operationId":"LegacySupportController_getLegacyHyperliquidStats","parameters":[{"name":"address","required":true,"in":"query","description":"User address","schema":{"type":"string"}},{"name":"period","required":false,"in":"query","description":"Period label (e.g., daily)","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"Start date ISO string","schema":{"type":"string"}}],"responses":{"200":{"description":"Hyperliquid user stats"}},"summary":"Get hyperliquid user stats for legacy support (V2)","tags":["Legacy Support"]}}}}
```

## GET /legacysupport/dailyStats

> Get legacy daily stats (volume, fees, users, new\_traders) for compatibility with pear-backend /statsData

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/legacysupport/dailyStats":{"get":{"operationId":"LegacySupportController_getLegacyDailyStats","parameters":[{"name":"period","required":false,"in":"query","description":"Period label, e.g., daily","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"Start date ISO string","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"End date ISO string","schema":{"type":"string"}}],"responses":{"200":{"description":"Daily stats array"}},"summary":"Get legacy daily stats (volume, fees, users, new_traders) for compatibility with pear-backend /statsData","tags":["Legacy Support"]}}}}
```


# Portfolio

## Get portfolio summary buckets and overall metrics

> Returns bucketed volume, open interest snapshot, win/loss trade counts, and overall metrics derived from trade history, trade history assets, and current open positions. Records marked as FULLY\_EXTERNAL are excluded. When startDate or endDate is provided, only period-scoped overall metrics are returned.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PortfolioResponseDto":{"type":"object","properties":{"intervals":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/PortfolioIntervalsDto"}]},"overall":{"$ref":"#/components/schemas/PortfolioOverallDto"}},"required":["overall"]},"PortfolioIntervalsDto":{"type":"object","properties":{"oneDay":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioBucketDto"}},"oneWeek":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioBucketDto"}},"oneMonth":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioBucketDto"}},"oneYear":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioBucketDto"}},"all":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioBucketDto"}}},"required":["oneDay","oneWeek","oneMonth","oneYear","all"]},"PortfolioBucketDto":{"type":"object","properties":{"periodStart":{"type":"string","description":"Period start ISO timestamp"},"periodEnd":{"type":"string","description":"Period end ISO timestamp"},"volume":{"type":"number","description":"Total traded volume (USD) within the bucket"},"openInterest":{"type":"number","description":"Open interest snapshot (USD). Uses current snapshot."},"winningTradesCount":{"type":"number","description":"Number of winning trades (net realized > 0) within the bucket"},"winningTradesUsd":{"type":"number","description":"Total USD from winning trades within the bucket (sum of positive net realized PnL)"},"losingTradesCount":{"type":"number","description":"Number of losing trades (net realized < 0) within the bucket"},"losingTradesUsd":{"type":"number","description":"Total USD from losing trades within the bucket (sum of absolute value of negative net realized PnL)"}},"required":["periodStart","periodEnd","volume","openInterest","winningTradesCount","winningTradesUsd","losingTradesCount","losingTradesUsd"]},"PortfolioOverallDto":{"type":"object","properties":{"totalWinningTradesCount":{"type":"number","description":"Total winning trades (net realized > 0) across the selected period"},"totalLosingTradesCount":{"type":"number","description":"Total losing trades (net realized < 0) across the selected period"},"totalWinningUsd":{"type":"number","description":"Total USD from winning trades across the selected period (sum of positive net realized PnL)"},"totalLosingUsd":{"type":"number","description":"Total USD from losing trades across the selected period (sum of absolute value of negative net realized PnL)"},"currentOpenInterest":{"type":"number","description":"Current total open interest (USD) across open positions"},"currentTotalVolume":{"type":"number","description":"Trading volume (USD) for the selected period filtered to PEAR fills"},"unrealizedPnl":{"type":"number","description":"Unrealized PnL (USD) from current open positions"},"totalTrades":{"type":"number","description":"Total trades for the selected period (open/close/reduce/increase counted as one trade each)"}},"required":["totalWinningTradesCount","totalLosingTradesCount","totalWinningUsd","totalLosingUsd","currentOpenInterest","currentTotalVolume","unrealizedPnl","totalTrades"]}}},"paths":{"/portfolio":{"get":{"description":"Returns bucketed volume, open interest snapshot, win/loss trade counts, and overall metrics derived from trade history, trade history assets, and current open positions. Records marked as FULLY_EXTERNAL are excluded. When startDate or endDate is provided, only period-scoped overall metrics are returned.","operationId":"PortfolioController_getPortfolio","parameters":[{"name":"startDate","required":false,"in":"query","description":"Start date (ISO string or ms timestamp)","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"End date (ISO string or ms timestamp)","schema":{"type":"string"}}],"responses":{"200":{"description":"Portfolio data for all intervals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioResponseDto"}}}}},"summary":"Get portfolio summary buckets and overall metrics","tags":["Portfolio"]}}}}
```

## Get portfolio analytics with risk-adjusted metrics

> Returns portfolio and per-asset performance analytics including risk-adjusted metrics, rolling windows, and both realized-only and realized+unrealized variants.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PortfolioAnalyticsResponseDto":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/PortfolioAnalyticsConfigDto"},"portfolio":{"$ref":"#/components/schemas/PortfolioMetricsDto"},"assets":{"type":"array","items":{"$ref":"#/components/schemas/AssetAnalyticsDto"}},"pairs":{"type":"array","items":{"$ref":"#/components/schemas/PairBreakdownDto"}},"series":{"type":"array","items":{"$ref":"#/components/schemas/SeriesPointDto"}}},"required":["config","portfolio","assets","pairs"]},"PortfolioAnalyticsConfigDto":{"type":"object","properties":{"rollingWindowDays":{"type":"number","description":"Rolling window size in days"},"startDate":{"type":"string","description":"Start date ISO string"},"endDate":{"type":"string","description":"End date ISO string"}},"required":["rollingWindowDays","startDate","endDate"]},"PortfolioMetricsDto":{"type":"object","properties":{"realizedOnly":{"description":"Metrics from closed trades only","allOf":[{"$ref":"#/components/schemas/MetricVariantDto"}]},"realizedPlusUnrealized":{"description":"Metrics including unrealized PnL from open positions","allOf":[{"$ref":"#/components/schemas/MetricVariantDto"}]},"realizedHitRate":{"type":"number","description":"Profitable closed trades / total closed trades","nullable":true},"profitFactor":{"type":"number","description":"Portfolio-level profit factor (gross profit / gross loss)","nullable":true},"avgWinSize":{"type":"number","description":"Portfolio-level average winning trade size in USD","nullable":true},"avgLossSize":{"type":"number","description":"Portfolio-level average losing trade size in USD","nullable":true},"breakevenHitRate":{"type":"number","description":"Required hit rate to break even from average win/loss sizes","nullable":true},"cushion":{"type":"number","description":"Realized hit rate minus breakeven hit rate","nullable":true}},"required":["realizedOnly","realizedPlusUnrealized","realizedHitRate","profitFactor","avgWinSize","avgLossSize","breakevenHitRate","cushion"]},"MetricVariantDto":{"type":"object","properties":{"pnlAbsolute":{"type":"number","description":"Absolute PnL in USD"},"pnlPercent":{"type":"number","description":"PnL as decimal fraction of capital base (0.12 = 12%)","nullable":true},"hitRate":{"type":"number","description":"Fraction of profitable events (0.6 = 60%)","nullable":true},"profitFactor":{"type":"number","description":"Gross profit / gross loss (absolute)","nullable":true},"avgWinSize":{"type":"number","description":"Mean positive PnL value in USD","nullable":true},"avgLossSize":{"type":"number","description":"Mean negative PnL value in USD","nullable":true},"avgReturnPerWin":{"type":"number","description":"Mean return of winning trades","nullable":true},"avgReturnPerLoss":{"type":"number","description":"Mean return of losing trades","nullable":true},"maxDrawdown":{"type":"number","description":"Maximum drawdown as decimal fraction","nullable":true},"sharpeRatio":{"type":"number","description":"Annualized Sharpe ratio (sqrt(365))","nullable":true},"sortinoRatio":{"type":"number","description":"Annualized Sortino ratio (sqrt(365))","nullable":true}},"required":["pnlAbsolute","pnlPercent","hitRate","profitFactor","avgWinSize","avgLossSize","avgReturnPerWin","avgReturnPerLoss","maxDrawdown","sharpeRatio","sortinoRatio"]},"AssetAnalyticsDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset symbol (e.g. BTC)"},"realizedOnly":{"$ref":"#/components/schemas/MetricVariantDto"},"realizedPlusUnrealized":{"$ref":"#/components/schemas/MetricVariantDto"},"unrealizedReturnPerDay":{"type":"number","description":"Unrealized PnL / max(1, days open)","nullable":true}},"required":["asset","realizedOnly","realizedPlusUnrealized","unrealizedReturnPerDay"]},"PairBreakdownDto":{"type":"object","properties":{"key":{"type":"string","description":"Stable basket key, formatted as L:BTC,ETH|S:SOL"},"longAssets":{"description":"Long-side assets in the basket","type":"array","items":{"type":"string"}},"shortAssets":{"description":"Short-side assets in the basket","type":"array","items":{"type":"string"}},"trades":{"type":"number","description":"Closed trade count for this basket"},"wins":{"type":"number","description":"Winning closed trade count for this basket"},"losses":{"type":"number","description":"Losing closed trade count for this basket"},"hitRate":{"type":"number","description":"Winning trades / total trades","nullable":true},"avgWinSize":{"type":"number","description":"Mean positive trade PnL in USD","nullable":true},"avgLossSize":{"type":"number","description":"Mean negative trade PnL in USD","nullable":true},"expectancy":{"type":"number","description":"Average PnL per trade in USD","nullable":true},"totalPnl":{"type":"number","description":"Total realized PnL in USD for this basket"},"bookPercent":{"type":"number","description":"Basket total PnL / portfolio total realized PnL","nullable":true}},"required":["key","longAssets","shortAssets","trades","wins","losses","hitRate","avgWinSize","avgLossSize","expectancy","totalPnl","bookPercent"]},"SeriesPointDto":{"type":"object","properties":{"date":{"type":"string","description":"UTC date string (YYYY-MM-DD)"},"trades":{"type":"number","description":"Closed trades on this day"},"wins":{"type":"number","description":"Winning closed trades on this day"},"losses":{"type":"number","description":"Losing closed trades on this day"},"dayPnl":{"type":"number","description":"Realized PnL on this day in USD"},"hitRate":{"type":"number","description":"Winning trades / total trades on this day","nullable":true},"winLossRatio":{"type":"number","description":"Average winning trade size / average losing trade size on this day","nullable":true},"rollingHitRate":{"type":"number","description":"Rolling winning trades / rolling total trades","nullable":true},"rollingWinLossRatio":{"type":"number","description":"Rolling average winning trade size / rolling average losing trade size","nullable":true},"dailyReturn":{"type":"number","description":"Daily portfolio return","nullable":true},"cumulativeReturn":{"type":"number","description":"Cumulative return from start"},"equity":{"type":"number","description":"Equity value"},"drawdown":{"type":"number","description":"Current drawdown from peak"},"rollingSharpe":{"type":"number","description":"Rolling Sharpe ratio","nullable":true},"rollingSortino":{"type":"number","description":"Rolling Sortino ratio","nullable":true},"rollingVolatility":{"type":"number","description":"Rolling annualized volatility","nullable":true},"rollingFunding":{"type":"number","description":"Rolling annualized net funding rate","nullable":true}},"required":["date","trades","wins","losses","dayPnl","hitRate","winLossRatio","rollingHitRate","rollingWinLossRatio","dailyReturn","cumulativeReturn","equity","drawdown","rollingSharpe","rollingSortino","rollingVolatility","rollingFunding"]}}},"paths":{"/portfolio/analytics":{"get":{"description":"Returns portfolio and per-asset performance analytics including risk-adjusted metrics, rolling windows, and both realized-only and realized+unrealized variants.","operationId":"PortfolioController_getAnalytics","parameters":[{"name":"startDate","required":false,"in":"query","description":"Start date (ISO string or ms timestamp)","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"End date (ISO string or ms timestamp)","schema":{"type":"string"}},{"name":"interval","required":false,"in":"query","description":"Display interval for date range","schema":{"enum":["1d","1w","1m","1y","all"],"type":"string"}},{"name":"rollingWindowDays","required":false,"in":"query","description":"Rolling window size in days (default 30, min 7, max 365)","schema":{"type":"number"}},{"name":"includeSeries","required":false,"in":"query","description":"Include daily/rolling time series (default true)","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Portfolio analytics data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioAnalyticsResponseDto"}}}}},"summary":"Get portfolio analytics with risk-adjusted metrics","tags":["Portfolio"]}}}}
```


# Markets

## Get markets data

> Retrieve market groups including active markets, top gainers, top losers, highlighted markets, and watchlist

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/markets":{"get":{"description":"Retrieve market groups including active markets, top gainers, top losers, highlighted markets, and watchlist","operationId":"MarketsController_getMarkets","parameters":[{"name":"offset","required":false,"in":"query","description":"Offset for pagination","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number for pagination (minimum 1)","schema":{"type":"string"}},{"name":"pageSize","required":false,"in":"query","description":"Page size (items per page, maximum 100)","schema":{"type":"string"}},{"name":"engine","required":false,"in":"query","description":"Filter by engine type","schema":{"type":"string"}},{"name":"minVolume","required":false,"in":"query","description":"Filter by minimum volume","schema":{"type":"string"}},{"name":"change24h","required":false,"in":"query","description":"Filter by price change","schema":{"type":"string"}},{"name":"netFunding","required":false,"in":"query","description":"Filter by either positive or negative funding rate","schema":{"type":"string"}},{"name":"searchText","required":false,"in":"query","description":"Search text to filter markets","schema":{"type":"string"}},{"name":"sort","required":false,"in":"query","description":"Sort field and direction (e.g., volume:desc)","schema":{"type":"string"}},{"name":"excludeText","required":false,"in":"query","description":"Text to exclude from results","schema":{"type":"string"}},{"name":"active","required":false,"in":"query","description":"Filter by active status","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved markets data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketsResponse"}}}},"400":{"description":"Bad request - Invalid query parameters"}},"summary":"Get markets data","tags":["Markets"]}}},"components":{"schemas":{"MarketsResponse":{"type":"object","properties":{"markets":{"description":"List of active order-asset groups","type":"array","items":{"$ref":"#/components/schemas/MarketsGroupItem"}},"total":{"type":"number","description":"Total number of markets (after filters)"},"page":{"type":"number","description":"Page number for pagination"},"pageSize":{"type":"number","description":"Page size (items per page)"},"totalPages":{"type":"number","description":"Total number of pages"}},"required":["markets","total","page","pageSize","totalPages"]},"MarketsGroupItem":{"type":"object","properties":{"longAssets":{"description":"Distinct long assets in the order group with weights","type":"array","items":{"$ref":"#/components/schemas/PairAssetDto"}},"shortAssets":{"description":"Distinct short assets in the order group with weights","type":"array","items":{"$ref":"#/components/schemas/PairAssetDto"}},"openInterest":{"type":"string","description":"Open interest in USD for all assets in this group"},"volume":{"type":"string","description":"24h traded volume in USD for this order group"},"ratio":{"type":"string","description":"Current long/short ratio for this group"},"prevRatio":{"type":"string","description":"Previous day long/short ratio for this group"},"change24h":{"type":"string","description":"24h change as decimal (e.g. 0.05 = +5%)"},"weightedRatio":{"type":"string","description":"Weighted (synthetic 50/50) current ratio for this group"},"weightedPrevRatio":{"type":"string","description":"Weighted (synthetic 50/50) previous day ratio for this group"},"weightedChange24h":{"type":"string","description":"Weighted (synthetic 50/50) 24h change as decimal"},"netFunding":{"type":"string","description":"Net funding for the basket, weighted by allocation (longs negative, shorts positive)"}},"required":["longAssets","shortAssets","openInterest","volume","netFunding"]},"PairAssetDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset symbol"},"weight":{"type":"number","description":"Weight allocation for this asset (0.0001 to 1.0). If not provided, weights will be evenly distributed.","minimum":0.0001,"maximum":1}},"required":["asset"]}}}}
```

## GET /markets/active

> Get active market assets and pairs

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/markets/active":{"get":{"operationId":"MarketsController_getActiveMarket","parameters":[],"responses":{"200":{"description":"Market data retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActiveAssetsResponse"}}}}},"summary":"Get active market assets and pairs","tags":["Markets"]}}},"components":{"schemas":{"ActiveAssetsResponse":{"type":"object","properties":{"active":{"description":"List of actively traded order-asset groups","type":"array","items":{"$ref":"#/components/schemas/ActiveAssetGroupItem"}},"topGainers":{"description":"Top gaining long/short pairs over 24h","type":"array","items":{"$ref":"#/components/schemas/ActiveAssetGroupItem"}},"topLosers":{"description":"Top losing long/short pairs over 24h","type":"array","items":{"$ref":"#/components/schemas/ActiveAssetGroupItem"}},"highlighted":{"description":"Highlighted long/short pairs","type":"array","items":{"$ref":"#/components/schemas/ActiveAssetGroupItem"}},"watchlist":{"description":"User watchlist long/short pairs","type":"array","items":{"$ref":"#/components/schemas/ActiveAssetGroupItem"}}},"required":["active","topGainers","topLosers","highlighted","watchlist"]},"ActiveAssetGroupItem":{"type":"object","properties":{"key":{"type":"string","description":"Unique identifier for the order group"},"longAssets":{"description":"Distinct long assets in the order group with weights","type":"array","items":{"$ref":"#/components/schemas/PairAssetDto"}},"shortAssets":{"description":"Distinct short assets in the order group with weights","type":"array","items":{"$ref":"#/components/schemas/PairAssetDto"}},"openInterest":{"type":"string","description":"Open interest in USD for all assets in this group"},"volume":{"type":"string","description":"24h traded volume in USD for this order group"},"ratio":{"type":"string","description":"Current long/short ratio for this group"},"prevRatio":{"type":"string","description":"Previous day long/short ratio for this group"},"change24h":{"type":"string","description":"24h change as decimal (e.g. 0.05 = +5%)"},"weightedRatio":{"type":"string","description":"Weighted (synthetic 50/50) current ratio for this group"},"weightedPrevRatio":{"type":"string","description":"Weighted (synthetic 50/50) previous day ratio for this group"},"weightedChange24h":{"type":"string","description":"Weighted (synthetic 50/50) 24h change as decimal"},"netFunding":{"type":"string","description":"Net funding for the basket, weighted by allocation (longs negative, shorts positive)"}},"required":["key","longAssets","shortAssets","openInterest","volume","netFunding"]},"PairAssetDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset symbol"},"weight":{"type":"number","description":"Weight allocation for this asset (0.0001 to 1.0). If not provided, weights will be evenly distributed.","minimum":0.0001,"maximum":1}},"required":["asset"]}}}}
```

## GET /markets/v2

> Get market data v2 (actives + watchlist baskets)

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/markets/v2":{"get":{"operationId":"MarketsController_getMarketDataV2","parameters":[],"responses":{"200":{"description":"Market data v2 retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketDataV2Response"}}}}},"summary":"Get market data v2 (actives + watchlist baskets)","tags":["Markets"]}}},"components":{"schemas":{"MarketDataV2Response":{"type":"object","properties":{"baskets":{"description":"List of baskets","type":"array","items":{"$ref":"#/components/schemas/MarketDataV2BasketDto"}}},"required":["baskets"]},"MarketDataV2BasketDto":{"type":"object","properties":{"longAssets":{"description":"Long assets with weights","type":"array","items":{"$ref":"#/components/schemas/MarketDataV2AssetDto"}},"shortAssets":{"description":"Short assets with weights","type":"array","items":{"$ref":"#/components/schemas/MarketDataV2AssetDto"}},"category":{"type":"string","description":"Basket category","enum":["active","watchlist","ai-picks"]},"name":{"type":"string","description":"Optional basket name"}},"required":["longAssets","shortAssets","category"]},"MarketDataV2AssetDto":{"type":"object","properties":{"asset":{"type":"string","description":"Asset symbol"},"weight":{"type":"number","description":"Weight allocation"}},"required":["asset","weight"]}}}}
```


# Vault Wallet

## Get vault wallet

> Retrieve a specific vault wallet by address (agent\_address or vault\_address)

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"GetVaultWalletResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the vault wallet"},"vaultAddress":{"type":"object","description":"Vault wallet address"},"leader_address":{"type":"string","description":"Vault wallet address"},"agentAddress":{"type":"string","description":"Public address"},"isApproved":{"type":"boolean","description":"Whether the vault wallet is approved for trading"},"createdAt":{"type":"string","description":"Timestamp when the vault wallet was created"},"updatedAt":{"type":"string","description":"Timestamp when the vault wallet was last updated"},"privyWalletId":{"type":"string","description":"Privy wallet ID for creating the signer"},"name":{"type":"object","description":"Vault wallet name","nullable":true},"about":{"type":"object","description":"Vault wallet description/about","nullable":true},"imageUrl":{"type":"object","description":"Image URL for the vault wallet","nullable":true},"transactionHash":{"type":"object","description":"Transaction hash from vault creation","nullable":true}},"required":["id","vaultAddress","leader_address","agentAddress","isApproved","createdAt","updatedAt","privyWalletId"]}}},"paths":{"/vault-wallet":{"get":{"description":"Retrieve a specific vault wallet by address (agent_address or vault_address)","operationId":"VaultWalletController_getVaultWallet","parameters":[{"name":"vaultAddress","required":true,"in":"query","description":"Vault address - can be agent_address (Privy wallet) or vault_address (contract)","schema":{"type":"string"}}],"responses":{"200":{"description":"Vault wallet retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVaultWalletResponseDto"}}}},"401":{"description":"Unauthorized - invalid or missing token"},"404":{"description":"Vault wallet not found"}},"summary":"Get vault wallet","tags":["Vault Wallet"]}}}}
```

## Create a new vault wallet with onchain deployment

> This API performs all vault creation steps in one call: 1) Creates a Privy wallet (agent), 2) Deploys vault contract via PearVaultFactory onchain, 3) Saves to database, 4) Creates backend agent wallet for trading. This replaces the old two-step process (createVaultWallet + registerVault).

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CreateVaultWalletRequestDto":{"type":"object","properties":{"leader_address":{"type":"string","description":"Leader/owner address of the vault"},"name":{"type":"string","description":"Name for the vault wallet"},"about":{"type":"string","description":"Description/about text for the vault wallet"},"imageUrl":{"type":"string","description":"Image URL for the vault wallet"},"configId":{"type":"number","description":"Configuration ID for the vault from frontend (0-based index)","minimum":0}},"required":["leader_address","name","imageUrl","configId"]},"CreateVaultWalletResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the vault wallet"},"leader_address":{"type":"string","description":"Leader/owner address"},"vaultAddress":{"type":"string","description":"Generated vault contract address from blockchain"},"agentAddress":{"type":"string","description":"Privy agent wallet address"},"isApproved":{"type":"boolean","description":"Whether the vault wallet is approved for trading"},"name":{"type":"string","description":"Vault wallet name"},"about":{"type":"string","description":"Vault wallet description/about"},"imageUrl":{"type":"string","description":"Image URL for the vault wallet"},"transactionHash":{"type":"string","description":"Transaction hash from vault creation"},"createdAt":{"type":"string","description":"Timestamp when the vault wallet was created"},"message":{"type":"string","description":"Success message"}},"required":["id","leader_address","vaultAddress","agentAddress","isApproved","name","about","imageUrl","transactionHash","createdAt","message"]}}},"paths":{"/vault-wallet":{"post":{"description":"This API performs all vault creation steps in one call: 1) Creates a Privy wallet (agent), 2) Deploys vault contract via PearVaultFactory onchain, 3) Saves to database, 4) Creates backend agent wallet for trading. This replaces the old two-step process (createVaultWallet + registerVault).","operationId":"VaultWalletController_createVaultWallet","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVaultWalletRequestDto"}}}},"responses":{"201":{"description":"Vault created successfully with onchain transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVaultWalletResponseDto"}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"Unauthorized - invalid or missing token"},"500":{"description":"Failed to create vault (Privy wallet creation or blockchain transaction failed)"}},"summary":"Create a new vault wallet with onchain deployment","tags":["Vault Wallet"]}}}}
```

## Delete vault wallet

> Delete a specific vault wallet by address. This action cannot be undone.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/vault-wallet":{"delete":{"description":"Delete a specific vault wallet by address. This action cannot be undone.","operationId":"VaultWalletController_deleteVaultWallet","parameters":[{"name":"vaultAddress","required":true,"in":"query","description":"Vault address - can be agent_address (Privy wallet) or vault_address (contract)","schema":{"type":"string"}}],"responses":{"204":{"description":"Vault wallet deleted successfully"},"401":{"description":"Unauthorized - invalid or missing token"},"404":{"description":"Vault wallet not found"}},"summary":"Delete vault wallet","tags":["Vault Wallet"]}}}}
```

## Get all vault wallets

> Retrieve all vault wallets for the authenticated user. Supports filtering by name and address.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"GetVaultWalletResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the vault wallet"},"vaultAddress":{"type":"object","description":"Vault wallet address"},"leader_address":{"type":"string","description":"Vault wallet address"},"agentAddress":{"type":"string","description":"Public address"},"isApproved":{"type":"boolean","description":"Whether the vault wallet is approved for trading"},"createdAt":{"type":"string","description":"Timestamp when the vault wallet was created"},"updatedAt":{"type":"string","description":"Timestamp when the vault wallet was last updated"},"privyWalletId":{"type":"string","description":"Privy wallet ID for creating the signer"},"name":{"type":"object","description":"Vault wallet name","nullable":true},"about":{"type":"object","description":"Vault wallet description/about","nullable":true},"imageUrl":{"type":"object","description":"Image URL for the vault wallet","nullable":true},"transactionHash":{"type":"object","description":"Transaction hash from vault creation","nullable":true}},"required":["id","vaultAddress","leader_address","agentAddress","isApproved","createdAt","updatedAt","privyWalletId"]}}},"paths":{"/vault-wallet/all":{"get":{"description":"Retrieve all vault wallets for the authenticated user. Supports filtering by name and address.","operationId":"VaultWalletController_getAllVaultWallets","parameters":[{"name":"name","required":false,"in":"query","description":"Filter vault wallets by name (case-insensitive partial match)","schema":{"type":"string"}},{"name":"address","required":false,"in":"query","description":"Filter vault wallets by address (matches agent_address or vault_address, case-insensitive partial match)","schema":{"type":"string"}}],"responses":{"200":{"description":"Vault wallets retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GetVaultWalletResponseDto"}}}}},"401":{"description":"Unauthorized - invalid or missing token"}},"summary":"Get all vault wallets","tags":["Vault Wallet"]}}}}
```

## Refresh agent wallet for vault

> Create a new agent wallet for a specific registered vault. This is useful when the current agent wallet needs to be refreshed or rotated.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"RefreshApiForVaultResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the vault wallet"},"leader_address":{"type":"string","description":"Owner wallet address"},"vaultAddress":{"type":"string","description":"Vault contract address"},"newAgentWalletAddress":{"type":"string","description":"New agent wallet address for backend trading"},"message":{"type":"string","description":"Success message"}},"required":["id","leader_address","vaultAddress","newAgentWalletAddress","message"]}}},"paths":{"/vault-wallet/refreshAPIforVault":{"post":{"description":"Create a new agent wallet for a specific registered vault. This is useful when the current agent wallet needs to be refreshed or rotated.","operationId":"VaultWalletController_refreshApiForVault","parameters":[{"name":"vaultAddress","required":true,"in":"query","description":"Vault address - can be agent_address (Privy wallet) or vault_address (contract)","schema":{"type":"string"}}],"responses":{"200":{"description":"Agent wallet refreshed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshApiForVaultResponseDto"}}}},"401":{"description":"Unauthorized - invalid or missing token"},"404":{"description":"Vault wallet not found or vault not registered"}},"summary":"Refresh agent wallet for vault","tags":["Vault Wallet"]}}}}
```

## Transfer USDC from spot to perp account

> Transfer USDC directly from spot account to perp account for trading

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TransferSpotToPerpRequestDto":{"type":"object","properties":{"amount":{"type":"string","description":"Amount of USDC to transfer from spot to perp account","minimum":0.01},"asset":{"type":"string","description":"Asset to transfer (default: USDC)","default":"USDC"}},"required":["amount"]},"TransferResponseDto":{"type":"object","properties":{"success":{"type":"boolean","description":"Transfer success status"},"amount":{"type":"string","description":"Amount transferred"},"asset":{"type":"string","description":"Asset transferred"},"direction":{"type":"string","description":"Transfer direction"},"message":{"type":"string","description":"Success message"}},"required":["success","amount","asset","direction","message"]}}},"paths":{"/vault-wallet/spot-to-perp":{"post":{"description":"Transfer USDC directly from spot account to perp account for trading","operationId":"VaultWalletController_transferSpotToPerp","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferSpotToPerpRequestDto"}}}},"responses":{"200":{"description":"Transfer completed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferResponseDto"}}}},"400":{"description":"Invalid transfer amount or insufficient balance"},"401":{"description":"Unauthorized - invalid or missing token"}},"summary":"Transfer USDC from spot to perp account","tags":["Vault Wallet"]}}}}
```

## Transfer USDC from perp to spot account

> Transfer USDC directly from perp account to spot account

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"TransferPerpToSpotRequestDto":{"type":"object","properties":{"amount":{"type":"string","description":"Amount of USDC to transfer from perp to spot account","minimum":0.01},"asset":{"type":"string","description":"Asset to transfer (default: USDC)","default":"USDC"}},"required":["amount"]},"TransferResponseDto":{"type":"object","properties":{"success":{"type":"boolean","description":"Transfer success status"},"amount":{"type":"string","description":"Amount transferred"},"asset":{"type":"string","description":"Asset transferred"},"direction":{"type":"string","description":"Transfer direction"},"message":{"type":"string","description":"Success message"}},"required":["success","amount","asset","direction","message"]}}},"paths":{"/vault-wallet/perp-to-spot":{"post":{"description":"Transfer USDC directly from perp account to spot account","operationId":"VaultWalletController_transferPerpToSpot","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferPerpToSpotRequestDto"}}}},"responses":{"200":{"description":"Transfer completed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferResponseDto"}}}},"400":{"description":"Invalid transfer amount or insufficient balance"},"401":{"description":"Unauthorized - invalid or missing token"}},"summary":"Transfer USDC from perp to spot account","tags":["Vault Wallet"]}}}}
```

## Swap spot token to USDC and transfer to perp

> Swap a spot token (ETH, SOL, etc.) to USDC and transfer the USDC to perp account for trading

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SwapAndTransferRequestDto":{"type":"object","properties":{"fromAsset":{"type":"string","description":"Asset to swap from (e.g., ETH, SOL, BTC)"},"amount":{"type":"string","description":"Amount of the source asset to swap","minimum":0.001},"toAsset":{"type":"string","description":"Asset to swap to (default: USDC)","default":"USDC"}},"required":["fromAsset","amount"]},"SwapAndTransferResponseDto":{"type":"object","properties":{"fromAmount":{"type":"string","description":"Amount of source asset swapped"},"toAmount":{"type":"string","description":"Amount of target asset received"},"exchangeRate":{"type":"number","description":"Exchange rate used"},"fromAsset":{"type":"string","description":"Source asset"},"toAsset":{"type":"string","description":"Target asset"},"message":{"type":"string","description":"Success message"}},"required":["fromAmount","toAmount","exchangeRate","fromAsset","toAsset","message"]}}},"paths":{"/vault-wallet/swap-and-transfer":{"post":{"description":"Swap a spot token (ETH, SOL, etc.) to USDC and transfer the USDC to perp account for trading","operationId":"VaultWalletController_swapAndTransferToPerp","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwapAndTransferRequestDto"}}}},"responses":{"200":{"description":"Swap and transfer completed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwapAndTransferResponseDto"}}}},"400":{"description":"Invalid swap parameters or insufficient balance"},"401":{"description":"Unauthorized - invalid or missing token"}},"summary":"Swap spot token to USDC and transfer to perp","tags":["Vault Wallet"]}}}}
```

## Get spot and perp account balances

> Retrieve balances for both spot and perp accounts

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"GetBalancesResponseDto":{"type":"object","properties":{"spotBalances":{"type":"object","description":"Spot account balances"},"perpBalances":{"type":"object","description":"Perp account balances"},"totalValue":{"type":"string","description":"Total account value in USD"}},"required":["spotBalances","perpBalances","totalValue"]}}},"paths":{"/vault-wallet/balances":{"get":{"description":"Retrieve balances for both spot and perp accounts","operationId":"VaultWalletController_getBalances","parameters":[],"responses":{"200":{"description":"Balances retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBalancesResponseDto"}}}},"401":{"description":"Unauthorized - invalid or missing token"}},"summary":"Get spot and perp account balances","tags":["Vault Wallet"]}}}}
```


# Public Stats

## Get fee and volume stats for addresses

> Returns total external\_fee\_paid, builder\_fee\_paid, and volume (size \* price) for PEAR fills, per address. Supports comma-separated addresses and optional startFrom filter.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/public-stats/address":{"get":{"description":"Returns total external_fee_paid, builder_fee_paid, and volume (size * price) for PEAR fills, per address. Supports comma-separated addresses and optional startFrom filter.","operationId":"PublicStatsController_getAddressStats","parameters":[{"name":"addresses","required":true,"in":"query","description":"Comma-separated list of addresses","schema":{"type":"string"}},{"name":"startFrom","required":false,"in":"query","description":"ISO timestamp to filter fills from (inclusive)","schema":{"type":"string"}}],"responses":{"200":{"description":"Address stats retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressStatsResponseDto"}}}}},"summary":"Get fee and volume stats for addresses","tags":["Public Stats"]}}},"components":{"schemas":{"AddressStatsResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AddressStatsItemDto"}}},"required":["data"]},"AddressStatsItemDto":{"type":"object","properties":{"address":{"type":"string","description":"Wallet address"},"totalExternalFeePaid":{"type":"number","description":"Total external fees paid (USD)"},"totalBuilderFeePaid":{"type":"number","description":"Total builder fees paid (USD)"},"totalVolume":{"type":"number","description":"Total volume (size * price) in USD"}},"required":["address","totalExternalFeePaid","totalBuilderFeePaid","totalVolume"]}}}}
```


# Fills

## Get fills

> Retrieve fills with optional filters for address, asset, client, Pear trade status, and time range.

```json
{"openapi":"3.0.0","info":{"title":"Pear Protocol Trading API","version":"1.0.0"},"servers":[{"url":"https://hl-v2.pearprotocol.io","description":"Production (Mainnet)"}],"paths":{"/fills":{"get":{"description":"Retrieve fills with optional filters for address, asset, client, Pear trade status, and time range.","operationId":"FillsController_getFills","parameters":[{"name":"address","required":false,"in":"query","description":"Filter by wallet address (case-insensitive)","schema":{"type":"string"}},{"name":"assetName","required":false,"in":"query","description":"Filter by asset name","schema":{"type":"string"}},{"name":"clientId","required":false,"in":"query","description":"Filter by client ID","schema":{"type":"string"}},{"name":"isPearTrade","required":false,"in":"query","description":"Filter by Pear trade (cloid prefix 0x50454152). Defaults to true.","schema":{"default":true,"type":"string"}},{"name":"startTime","required":false,"in":"query","description":"Filter fills with fillTime >= this value (unix ms)","schema":{"type":"string"}},{"name":"endTime","required":false,"in":"query","description":"Filter fills with fillTime <= this value (unix ms)","schema":{"type":"string"}}],"responses":{"200":{"description":"Fills retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FillItemDto"}}}}}},"summary":"Get fills","tags":["Fills"]}}},"components":{"schemas":{"FillItemDto":{"type":"object","properties":{"id":{"type":"string"},"clientId":{"type":"string","nullable":true},"orderId":{"type":"string"},"chunkId":{"type":"string","nullable":true},"externalOrderId":{"type":"string","nullable":true},"assetName":{"type":"string"},"address":{"type":"string"},"fillTime":{"type":"string","nullable":true},"side":{"type":"string","nullable":true},"dir":{"type":"string","nullable":true},"feeToken":{"type":"string","nullable":true},"cloid":{"type":"string","nullable":true},"tid":{"type":"string","nullable":true},"txHash":{"type":"string","nullable":true},"price":{"type":"number"},"size":{"type":"number"},"externalFeePaid":{"type":"number"},"builderFeePaid":{"type":"number"},"isPearTrade":{"type":"boolean"},"isLiquidation":{"type":"boolean"},"liqMarkPx":{"type":"number","nullable":true},"liqMethod":{"type":"string","nullable":true},"liquidatedUser":{"type":"string","nullable":true},"createdAt":{"type":"string"}},"required":["id","clientId","orderId","chunkId","externalOrderId","assetName","address","fillTime","side","dir","feeToken","cloid","tid","txHash","price","size","externalFeePaid","builderFeePaid","isPearTrade","isLiquidation","liqMarkPx","liqMethod","liquidatedUser","createdAt"]}}}}
```


# Trading Fees

Much like every single Centralised or Decentralised Exchange (CEX or DEX), Pear Protocol charges a fee when users trade on the platform. The fees are paid per transaction will have some fixed elements (open position fee) and some variable elements (funding rate, gas etc).

In this section we’ll break down some of the main fee’s that a user will incur.

Please note, Pear Protocol is a fully decentralised trading dApp, and as such over time intends to pass back as much of the fee generation as possible to either the Pear DAO or to tokenholders.

### **Open Fee**

When a user enters a pair trade, Pear will charge 0.06% on the position size as an trade open fee. This covers **both** the long leg and the short leg.

### **Close Fee**

When a user closes a pair trade, Pear will charge 0.06% on the position size as a close trade fee. Again, this covers **both** the long and the short leg, and is necessary to offset the costs that the protocol incurs.

### **Execution Costs**

Pear sources its liquidity from Hyperliquid, SYMM, Vertex and GMX. The onward execution costs of these platforms are borne by the user in addition to the platform fees they pay to Pear. Those fees are constantly evolving and as such we encourage the reader to read the documentation on [Hyperliquid](https://hyperliquid.gitbook.io/hyperliquid-docs/trading/fees) and the other engines respectively.&#x20;

For reference, Pear is a taker (not a maker), since all trades are currently opened as market orders and not limit orders.

However, we do represent the net exposure of every trade after these fees on the Pear front end. The values seen there include all the costs incurred to open the trade, but please do be mindful of the variable costs including the funding rate and borrowing costs as these can eat into the return.

{% hint style="info" %}
Many users significantly reduce the fee they pay by using a combination of referral, stPEAR based discounts and Volume based rebates. More details on those are in the next 3 sections.&#x20;

The effective cost can go down as low to 0.022% (a 63% reduction)
{% endhint %}


# Referrals

Pear is committed to fostering a community of active pair traders that can learn from one another and share their expertise when trading in a long-short manner.

To encourage more users and usage, Pear Protocol uses a generous referrals program, with the following mechanics.\
\
If User A invites User B and User B executes via their ref link, then 2 conditions are triggered:

\- 10% of all referee’s trading fees goes to the ***ref**errer* (in the form of claimable $ETH)

\- ***referee*** gets 10% discount on their own fee they pay

For example, if User A refers User B, and User B places trades that generate $100 of trading fees paid to Pear Protocol (net of their own -10% fee discount), then User A will see a claimable balance of $10 (10%) in $ETH.&#x20;

Link to referrals: <https://pear.garden/dashboard> => Referrals Tab

Here, traders can create a referral code that they can eventually share via link or directly into their X account.

Once a code has been created and shared, traders need to wait their referees to place trades. Eventually, they should be able to claim their rewards in ETH.

This applies across all 4 trading engines.

<figure><img src="/files/B5zqBryunMvv9HTwShys" alt=""><figcaption></figcaption></figure>


# stPEAR-based trading discounts

There are significant fee discounts available if the wallet holds a certain amount of staked Pear tokens (stPEAR)

<figure><img src="/files/rjIQ5hK3FRTezUILitvT" alt=""><figcaption></figcaption></figure>

These are automatically applied at point of execution on the Isolated and Cross (Orderbooks) mode.\
\
Say a user entered a trade for $10,000. The open fee by default would have been $13\
\
If this user held say 50,000 s$PEAR tokens, they would only pay 0.9\*$13, = $11.70 of fees (10% discount).  Of this $11.70:\
\
80% to Staking pool = $9.36

20% to Treasury = $2.34\
\
Thus, the 'net' amount of $9.36 (after considering discounts) is eligible for $PEAR stakers.&#x20;

However, for our intent-based engine, the fee discount based on your stPEAR balance is not captured at the point of execution, but instead it is claimable on the Dashboard>Rebates.&#x20;

{% hint style="info" %}
note: Our intent engine captures both Open and Close fees together at trade inception. Thus you'll be able to claim a larger amount than expected of $ETH once you open a trade, but once you close a position this $ETH amount won't change. The same logic also applies for your Monthly Volume. i.e. when you close a trade, you won't earn any more $ETH, since it has already been made available for you to claim.
{% endhint %}

<figure><img src="/files/DcXVms9fNgeOsGCc0EXR" alt=""><figcaption></figcaption></figure>

The above section of the Dashboard (Rebates Tab) is where you can claim your Fee Discounts from Staking (stPEAR). You can claim these at any time. The amount owed to you will be in 'Claimable Discount'. You can also see how much $ETH you have already claimed.\
\
$ETH will be sent directly to your wallet.


# Fee Rebates

Pear has implemented a Fee Rebate mechanism across both engines. This significantly reduces the cost to trade on the platform.

The more you trade in any given month, Pear Treasury will pay you **up to** 18% of your Pear fees incurred in rebates. The tiers are as follows:

<figure><img src="/files/0sc6P3wAtmHsMvUtax3X" alt=""><figcaption><p>We can only rebate fees captured by us. Execution fees captured by GMX, Vertex, SYMM or the underlying Market Makers are not eligible.</p></figcaption></figure>

{% hint style="info" %}
Pear collects 20% of your fee, and 80% goes to stakers. So in effect, Pear Treasury effectively will give up almost all it's internalised fee's to our largest users.&#x20;
{% endhint %}

It is important to know that fees for our intent engine are captured upfront (open and close fees). Thus every time you OPEN a new trade on Intents (and if you in Tier 3 or above) you will be able to claim your rebate. However, when you CLOSE a trade on Intents, even though your volume has increased, the fee was already captured and thus no new amounts will reflect on the dashboard for that month.

This amount is claimable in ETH on the Dashboard. **Claims begin from trades placed after 5pm UTC on 11 November 2024.**

<figure><img src="/files/Ez3MFEF2LkwPD6cFRUoV" alt=""><figcaption></figcaption></figure>

Essentially, the more you trade, the cheaper it will be to trade on Pear. Here is an example:\
\
Say you are Tier 2 (10% rebate). You place a trade for $100,000 on the intents engine and incur a 0.13% open fee and a 0.13% close fee (0.26% total, all captured upfront).\
\
The total fee captured by Pear is $260 on your $100,000 trade.\
\
You will be able to claim = $26 in ETH (10% of the $260). These are claimable at the end of each monthly epoch.<br>


# Token

&#x20;Token information

Token ticker: PEAR

Token type: ERC-20

Address: [0x3212dc0F8c834e4DE893532d27CC9B6001684DB0](https://arbiscan.io/txs?a=0x3212dc0f8c834e4de893532d27cc9b6001684db0)

Max supply: 1,000,000,000 tokens

**Utility**

The $PEAR token is a utility token with 3 major benefits:

**1/** 80% revenue share for $PEAR stakers - paid in ETH

**2/** Further fee reductions for traders based on amount of stPear held

**3/** Ownership and governance in the future of Pear Protocol including any plans for integrations with other Exchanges and other new products and features.

\
**stPEAR**

When users stake their PEAR token, they mint stPEAR, which is used to calculate staking rewards.

Ticker: stPEAR

Token type: ERC-20\
Address: [0xcE3be5204017BB1bD279937f92dF09Fd7F539B92](https://arbiscan.io/address/0xce3be5204017bb1bd279937f92df09fd7f539b92)

Max supply: 1,000,000,000 tokens&#x20;

{% hint style="info" %}
note: stPEAR is not transferable
{% endhint %}


# Tokenomics Update - July 2025

In July 2025, after securing [governance approval](https://snapshot.box/#/s:pearprotocol.eth/proposal/0x74e72571f2f13f578872b1c72743f36cbd95866e0f0b05bf0a1a415026db71c3), Pear completed a $4.1m strategic raise from institutional investors.&#x20;

#### 💸 Deal Structure

Total Raised: $4.1M\
Token Price: $0.0203 \
Total PEAR Allocated: 202,005,718\
Vesting: 12-month linear vest, starting 28 September 2025\
Accrual: Daily (1/365), claim-based, no auto-unlocks

Fairness to Prior Investors: These new tokens begin vesting after the 27 September 2025 unlock, where earlier investors receive their 50% cliff. This sequencing ensures transparency and opportunity for informed decision-making.

This means that on 28 September 2025, an investor in this round receiving say 10M tokens will only get (1/365)% of those = 0.274% of their allocation. There is no ‘cliff’ or upfront amount given unlike in previous rounds. This is to ensure a slow release of their supply and align them with the long-term vision of the team.

#### 🔥 Burn History & Adjusted Total Supply

We’ve consistently removed excess supply through token burns, with additional burns already pre-committed. Here is a breakdown of how that supply has evolved since TGE.

**Historical and future burns**

| 25 Dec 2024                                           | 10,000,000                                           |
| ----------------------------------------------------- | ---------------------------------------------------- |
| 31 Mar 2025                                           | 49,807,949                                           |
| 17 Jul 2025                                           | 10,000,000                                           |
| 27 Sep 2025 (planned)                                 | 77,972,523                                           |
| <mark style="color:$success;">**Total Burned**</mark> | <mark style="color:$success;">**147,780,472**</mark> |

* Original Max Supply: 1,000,000,000 PEAR
* Adjusted Max Supply: 852,219,528 PEAR

\~15% of supply permanently burned, this has come from previous Treasury supply and makes each token more scarce. This completes our commitment to burn an equivalent amount of supply at each major unlock in 2025.

📊 **Updated Ownership Breakdown**

This strategic round together with the previous burns introduces an updated token distribution pie. Below are the pie charts of the percentage allocation of the original 1bn tokens, and the subsequent percentage allocation of the final circulating supply (once burns have been accounted for.\
\
Here is the comparison relative to the original 1BN tokens:

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeBKMTp3uEWFFGLTgy5af4dRKkOgyg01P4oNyhHcCewiigGCw5TneKDZ62l10owZhVJIzMfOnbkckk9_xAGfvS0KZvoG7-xPtZLGI7wSY40hOz0Vgj8d7a_cOmCG99WWgE8FgjUbQ?key=pYTT-_2HJqdW7kPaA_Wzew" alt=""><figcaption></figcaption></figure>

Note that the Early Supporter figure is higher than in previous pie charts due to more people completing the Tide tasks before the deadline. The team and advisor allocation has come down since then to reduce supply overhang.\
\
And here relative to the final circulating supply:

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfJkibe0RWVdq00ybLmATgrjAQ54gttK9M-LjPfHBFPmZ_IvD7Oc83g8kH6Jlg-ucrf7I-8MhjApkfevngeC6dCQXr1kjntqMJ9-rzRQKjSrBka5vo-wNO6MtC7KC2bd1hVeMX-og?key=pYTT-_2HJqdW7kPaA_Wzew" alt=""><figcaption></figcaption></figure>

#### 🧩 TL;DR

* A $4.1M round brings in strategic partners aligned with the Pear ecosystem
* These investors paid $0.0203 (a 15% premium to the price over a 30 day lookback window), and vest linearly starting 28 Sept 2025
* Prior investors unlock before this round begins vesting
* PEAR supply has dropped from 1B → 852.2M via aggressive burns
* Emission schedule and ownership pie have been restructured transparently and fairly


# Staking&#x20;

The token will be at the heart of the Pear Protocol ecosystem, playing a valuable role in decentralizing the project and rewarding all participants in the ecosystem.

The token is where most of the protocol value will be accrued, in the form of ETH revenues. This level is currently set at 80% of all net fees\* accruing to $PEAR stakers. \
\
The below graphic outlines how this works.

<figure><img src="/files/V1K1rTBCDxrcasU50E40" alt=""><figcaption><p>*net of referral and other discounts.<br>** note that fees ultimately flow in ETH - the use of USDC here is to simplify the illustration</p></figcaption></figure>

The $PEAR token is one of two tokens in our ecosystem.\
\
When users come to our front end and stake it, they will receive $sPEAR (staked pear) in return (1:1 mint and redeem). By holding $sPEAR you qualify to receive a certain % of the revenue in the StakingPool.\
\
For example, lets say you own 1% of $PEAR supply (10,000,000 tokens), and you mint 10,000,000 $sPEAR (1% of supply).\
\
If the revenue pool was $100, you would be able to claim a maximum of $1.

In order to avoid the StakingPool being gamed, there will be a linear exit fee applied, slashing your $sPEAR:$PEAR redeem ratio based on how long you have been in the pool.

1 day: -20% exit fee

7 days: -5% exit fee

30 days: -1% exit fee

31 days: 0% exit fee<br>

For the above user with 10,000,000 s$PEAR, if they exited after 1 day, they would incur the -20% exit penalty, redeeming 8,000,000 s$PEAR to 8,000,000 $PEAR (1:1)\
\
The 2,000,000 $sPEAR they paid as an exit fee would automatically be distributed on a pro-rata basis between all the sPEAR holders, rewarding those who are more loyal as they can receive a higher % of the pool.

Thus, a user may wish to think about these 3 elements:\
\
1\) APR from staking\
2\) Gaining more sPEAR which can later be converted to PEAR (1:1) as people exit staking\
3\) Price appreciation of $PEAR as revenues and the protocol grows.<br>

{% hint style="info" %}
Note: As of 26 September 2024, 80% of the revenues from the Isolated and Cross-engine (Orderbooks) are automatically sent to the staking contract. Fees generated on our Intent Engine are distributed at 00:00 UTC
{% endhint %}


# Staking walkthrough

To stake your tokens head to the Dashboard, and click on the staking tab.

You'll see the following details:

<figure><img src="/files/8M0f1mVybpFcz8cvI2AX" alt=""><figcaption></figcaption></figure>

The Total PEAR is how many PEAR tokens are in your wallet.\
\
Click on "STAKE" and it will open this modal.

<figure><img src="/files/jGxHsO2XweR8ocVkrB2A" alt=""><figcaption></figcaption></figure>

Note: you'll have to sign two transactions - one to approve the use of your PEAR, and one to actually stake.&#x20;

<figure><img src="/files/0CHsjkwPbobeUOu3ieNS" alt=""><figcaption></figcaption></figure>

Once you've approved and staked, you will now hold a corresponding number of StPear. You can unstake those at any time, subject to the penalties.

<figure><img src="/files/KTrt3t4zdC1wR9QJZ5Bm" alt=""><figcaption></figcaption></figure>

As the protocol accrues trading fees from GMX, Vertex and SYMM - you can claim these in ETH. Additionally, as people leave the staking pool before 30 days, their foregone stPEAR in the form of penalties will be pro-rata available to you to claim. Both buttons are below:\ <br>

<figure><img src="/files/6CYhWbdsPzsMbFGXTUA0" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Note: the staking contract updates in real time with block times and as such you may have to wait a few minutes until the Claimable Rewards updates.
{% endhint %}


# Staking FAQs

**1. What is staking in Pear Protocol? What do users stake, and what do they receive?**&#x20;

Staking in Pear Protocol allows users to lock up their $PEAR tokens and receive $sPEAR (Staked PEAR) in a 1:1 ratio. By holding $sPEAR, users become eligible to receive a portion of the revenue generated in the StakingPool. The longer you hold $sPEAR, the more you benefit from both the rewards and loyalty bonuses within the ecosystem.

**2. How are staking rewards calculated?**&#x20;

The rewards are calculated based on your share of the $sPEAR supply. For instance, if you hold 1% of the total $sPEAR supply, you are entitled to claim 1% of the StakingPool’s revenue. If the total pool revenue is $100, you would be able to claim $1 as your reward.

#### 3. How **does the exit process work? Is it FIFO (First-In, First-Out)?**&#x20;

Yes, the exit process follows a queue-based system, effectively making it FIFO (First-In, First-Out). When you exit (unstake) your $sPEAR, the protocol applies exit fees based on the duration of each individual stake, starting with the oldest staked amounts first.

For example, if you staked tokens across multiple days, the protocol will redeem the earliest staked amounts first, applying the corresponding exit fee (20%, 5%, or 1%) depending on how long each portion has been staked. This ensures that exit penalties are fairly applied based on the time each stake has been in the pool.

Day 1: Staked 10,000 PEAR Day 9: Staked 5,000 PEAR Day 11: Staked 2,000 PEAR

On Day 17, the user decides to exit 11,000 tokens. Here's how it would work:

First, it processes the 10,000 PEAR from Day 1 (16 days ago):

This is beyond 7 days but less than 30 days, so it incurs a 5% fee. 10,000 \* 0.95 = 9,500 PEAR returned

Then, it processes 1,000 PEAR from the Day 9 stake (8 days ago):

This is beyond 7 days but less than 30 days, so it also incurs a 5% fee. 1,000 \* 0.95 = 950 PEAR returned

Total PEAR returned: 9,500 + 950 = 10,450 PEAR Total fee paid: 500 + 50 = 550 PEAR The remaining 4,000 PEAR from Day 9 and 2,000 PEAR from Day 11 would remain staked. This FIFO system ensures that users benefit from reduced fees on their older stakes while maintaining newer stakes if they perform a partial exit.

**4. Can users claim rewards at any time?**&#x20;

Yes, users can claim their portion of the StakingPool revenue at any time without any penalties. However, in certain cases, exiting (unstaking) your $sPEAR back to $PEAR could be subject to an exit fee, which decreases over time depending on how long you have staked.

**5. How does the exit penalty work?**&#x20;

When users redeem their $sPEAR back into $PEAR, a slashing exit fee is applied based on the duration of their staking period:

Exiting after 1 day results in a 20% exit fee. Exiting after 7 days results in a 5% exit fee. Exiting after 30 days results in a 1% exit fee. For example, if a user stakes 10,000,000 $PEAR and exits after 1 day, they would incur a 20% penalty, meaning they would redeem 8,000,000 $PEAR instead of the full 10,000,000. The remaining 2,000,000 $sPEAR is distributed proportionally to other $sPEAR holders, rewarding long-term stakers.

**6. How are exit penalties distributed?**&#x20;

The $sPEAR tokens paid as exit fees are automatically distributed among the remaining $sPEAR holders. This mechanism rewards users who stay staked for longer, as they receive a greater share of the pool over time.

**7. Can I add to my stake at any time?**&#x20;

Yes, you can add to your stake at any time by converting more $PEAR to $sPEAR. Each new stake is treated as a separate entry in the staking queue, with its own timestamp for calculating exit fees.

**8. How often are staking rewards distributed?**&#x20;

Staking rewards are continuously accrued in real-time from every trade that occurs on the Pear Protocol platform. For each trade, 80% of the generated fees are allocated to the staking rewards pool, while the remaining 20% goes to the Pear treasury. This means that as a staker, your potential rewards grow with each transaction on the platform, providing a dynamic and ongoing benefit for participating in the staking program.

**9. Is there a minimum staking amount?**&#x20;

No, there is no minimum staking amount in the Pear Protocol. You have the flexibility to stake any amount of $PEAR tokens that you're comfortable with, whether it's a small amount to test the waters or a larger sum for potentially greater rewards. This allows all users, regardless of their holdings, to participate in the staking program and earn rewards proportional to their stake.

**10. Can I partially unstake my $sPEAR?**&#x20;

Yes, you can unstake any amount of $sPEAR. The FIFO system will apply to partial unstaking, processing your oldest stakes first and applying the appropriate exit fees based on the staking duration of each portion.

**11. What happens to my staking rewards if I unstake?**&#x20;

When you unstake, you'll receive any accrued rewards up to that point. Future rewards will be proportional to your remaining staked amount, if any.

**12. Are there any risks associated with staking?**&#x20;

While staking is designed to be beneficial, it's important to understand that:

* There may be opportunity costs of locking up your tokens.
* The value of rewards can fluctuate based on the protocol's performance.
* Smart contract risks, while minimized through audits and security measures, cannot be entirely eliminated. Always do your own research and invest responsibly.

{% hint style="info" %}
note: Staking is prohibited in certain Restricted Territories. To ensure compliance we have geo-blocked users from Restricted Territories from the Dashboard and other parts of the app. There is also an opt-in confirmation required at the point of staking. Furthermore, the Terms of Use clearly state that Staking is not prohibited if you are from a Restricted Territory. Users should seek their own independent advice if they are unsure of their legal and tax obligations.
{% endhint %}


# DAO & Governance

Pear Protocol has been designed to run in a truly decentralised manner. The intention is that the front end (”The Protocol”) will ultimately be governed by tokenholders, who become contributors to the project and oversee how it runs.

To see and vote on proposals visit: <https://snapshot.box/#/s:pearprotocol.eth>


# Smart Contract addresses

Pear Protocol works with various internal and external smart contracts on Arbitrum Mainnet.

### Pear Protocol Contracts

* Comptroller: [0xb9800E10E83fbF9F7513Bb284e23a0145dCc2CFb ](https://arbiscan.io/address/0xb9800e10e83fbf9f7513bb284e23a0145dcc2cfb)
* ArbRewardsClaimer: [0xedD408902e47aa155E49ca8585E05c33A6C95B95 ](https://arbiscan.io/address/0xedD408902e47aa155E49ca8585E05c33A6C95B95)
* CallbackReceiver: [0xb1391e0ed6a72c1efb11d624b8f418efc3a2c69e](https://arbiscan.io/address/0xb1391e0ed6a72c1efb11d624b8f418efc3a2c69e)
* GmxAdapterV2: [0x3cECe4F99de32bb6332Ab40D6560EFB2b838352c](https://arbiscan.io/address/0x3cECe4F99de32bb6332Ab40D6560EFB2b838352c)
* GmxFactoryV2: [0xddba98640ba9c19fb3838d7982de798c1ed301df ](https://arbiscan.io/address/0xddba98640ba9c19fb3838d7982de798c1ed301df)
* PlatformLogicV2: [0x61126e4dcecbc7a43ac9fd783ccf66c62d9622fe](https://arbiscan.io/address/0x61126e4dcecbc7a43ac9fd783ccf66c62d9622fe)&#x20;
* VertexFactory: [0x05aE9d0575d1B2D5A3169DC5afE4C2b8b4B6571a](https://arbiscan.io/address/0x05aE9d0575d1B2D5A3169DC5afE4C2b8b4B6571a)
* Pear Staker: [0xcE3be5204017BB1bD279937f92dF09Fd7F539B92](https://arbiscan.io/address/0xce3be5204017bb1bd279937f92df09fd7f539b92)
* FeeRebateManager: [0x80D9790EA5CacA7Dea4A70FD94c3c365bB2af717](https://arbiscan.io/address/0x80D9790EA5CacA7Dea4A70FD94c3c365bB2af717)
* Vesting Contract: [0x11F0Fd0AAc620F7cB7521b116E413f97d1425C28](https://arbiscan.io/address/0x11f0fd0aac620f7cb7521b116e413f97d1425c28)

#### GMX Contracts:

* GMX: [0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a](https://arbiscan.io/address/0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a)
* Vault: [0x489ee077994B6658eAfA855C308275EAd8097C4A](https://arbiscan.io/address/0x489ee077994B6658eAfA855C308275EAd8097C4A)
* Router: [0xaBBc5F99639c9B6bCb58544ddf04EFA6802F4064](https://arbiscan.io/address/0xaBBc5F99639c9B6bCb58544ddf04EFA6802F4064)
* PositionRouter: [0xb87a436B93fFE9D75c5cFA7bAcFff96430b09868](https://arbiscan.io/address/0xb87a436B93fFE9D75c5cFA7bAcFff96430b09868)
* OrderBook: [0x09f77e8a13de9a35a7231028187e9fd5db8a2acb](https://arbiscan.io/address/0x09f77e8a13de9a35a7231028187e9fd5db8a2acb)
* Reader: [0x22199a49A999c351eF7927602CFB187ec3cae489](https://arbiscan.io/address/0x22199a49A999c351eF7927602CFB187ec3cae489)
* RewardReader: [0x8BFb8e82Ee4569aee78D03235ff465Bd436D40E0](https://arbiscan.io/address/0x8BFb8e82Ee4569aee78D03235ff465Bd436D40E0)
* OrderBookReader: [0xa27C20A7CF0e1C68C0460706bB674f98F362Bc21](https://arbiscan.io/address/0xa27C20A7CF0e1C68C0460706bB674f98F362Bc21)

#### **Vertex SDK smart contracts:**

* Clearinghouse: [0xAE1ec28d6225dCE2ff787dcb8CE11cF6D3AE064f](https://arbiscan.io/address/0xAE1ec28d6225dCE2ff787dcb8CE11cF6D3AE064f)
* Endpoint: [0xbbEE07B3e8121227AfCFe1E2B82772246226128e](https://arbiscan.io/address/0xbbEE07B3e8121227AfCFe1E2B82772246226128e)
* PerpEngine: [0xb74C78cca0FADAFBeE52B2f48A67eE8c834b5fd1](https://arbiscan.io/address/0xb74C78cca0FADAFBeE52B2f48A67eE8c834b5fd1)
* FeeCalculator: [0x2259440579447D0625a5E28dfF3E743d207e8890](https://arbiscan.io/address/0x2259440579447D0625a5E28dfF3E743d207e8890)
* Querier: [0x1693273B443699bee277eCbc60e2C8027E91995d](https://arbiscan.io/address/0x1693273B443699bee277eCbc60e2C8027E91995d)

#### &#x20;**SYMMIO Contracts:**

* Pear Account: [0x6273242a7E88b3De90822b31648C212215caaFE4](https://arbiscan.io/address/0x6273242a7E88b3De90822b31648C212215caaFE4)
* SymmFactory: [0x5262f53ceD23a198963Dd6B3625c01E5a98266Ed](https://arbiscan.io/address/0x5262f53ceD23a198963Dd6B3625c01E5a98266Ed)


# Audits and Security

We have completed 2 comprehensive and phased audits with Shieldify, and have implemented all the suggestions. \
\
The results of both can be found here:

v0.9: <https://github.com/shieldify-security/audits-portfolio/blob/main/reports/PearLabs-V0.9-Security-Review.pdf>

v1: <https://github.com/shieldify-security/audits-portfolio/blob/main/reports/PearLabs-V1-Security-Review.pdf>

&#x20;


# Restricted Territories

Elements of page the trading app, Vaults and the Staking page are geo-blocked from certain regions.

* Belarus
* Central African Republic
* Crimea (Region of Ukraine)
* Cuba
* Democratic People's Republic of Korea (North Korea)
* Democratic Republic of the Congo
* Donetsk (Region of Ukraine)
* Eritrea
* Haiti
* Iran
* Iraq
* Lebanon
* Libya
* Luhansk (Region of Ukraine)
* Mali
* Myanmar
* Nicaragua
* Russia
* Somalia
* South Sudan
* Sudan
* Syria
* United Arab Emirates
* United Kingdom
* United States of America
* Venezuela
* Yemen *(particularly Houthi-controlled areas)*
* Zimbabwe


# Brand Assets

For our media kit see: [pear.garden/brand](https://pear.garden/brand)

\
For all media enquiries please contact <dev@pearprotocol.io>


# Agent Pear Statistics

Users of the Pear Protocol front-end will see a collapsible "Agent Pear" section that houses some advanced statistics.&#x20;

{% hint style="info" %}
You do not need to understand these terms to be a profitable pair trader. Most users will not need to reference these values, but we include them for users who may find them a helpful reference point.
{% endhint %}

Here is a wider definition of each of these terms.

## 1. Correlation

Correlation measures the strength and direction of the relationship between the hourly price movements of the two assets. We use **Pearson’s correlation coefficient**, which ranges from **-1** to **+1**.

* **+1** → perfect positive correlation (assets move together).
* **-1** → perfect negative correlation (assets move in opposite directions).
* **0** → no linear relationship.

Correlation helps you analyse if the pairs selected have a directional relationship and the magnitude of that relationship.

## 2. Cointegration

While correlation captures short-term co-movements, **cointegration** tests for a *long-term, mean-reverting relationship* between two asset prices.

* Assets may be highly correlated but still drift apart (non-stationary spread).
* Cointegration ensures that, despite short-term deviations, the spread between the assets tends to revert to a stable mean.

This property underpins the profitability of statistical arbitrage: if the spread diverges, it has a statistical tendency to revert. Again, cointegration is not a necessity for most pair traders unless you are doing statistical arbitrage.

## 3. Rolling Z-score

The **rolling Z-score** measures how far the current spread is from its rolling mean, in units of standard deviations:

$$
Z = \frac{\text{Spread} - \text{Mean(Spread)}}{\text{StdDev(Spread)}}
$$

* **High positive Z-score** → spread is wider than usual (potentially short this pair).
* **Low negative Z-score** → spread is tighter than usual (potentially long this pair).
* **Z-score near 0** → spread is at equilibrium.

Traders typically use thresholds (e.g., enter at ±2, exit at 0) to systematize when to enter and exit mean reverting pair trades.

## 4. Beta

In trading, **beta (β)** measures how much one asset moves relative to another. In our case, beta represents the **rolling hedge ratio**, which determines how to size the long and short legs of a trade to maintain a **beta-neutral position**.

* Beta measures how much one asset moves relative to the other.
* Example: if Asset A has a **beta of 1.26** versus Asset B, this means that for every 1% move in B, Asset A tends to move 1.26%.

**Practical example:**\
\
Constructing a **long A / short B** pair with $100,000 capital:

**Practical example:**

Constructing a **long A / short B** pair with $100,000 capital:

$$
1.26 \times (\text{Long A}) = \text{Short B}
$$

$$
\text{Long A} \approx $44,248, \quad \text{Short B} \approx $55,752
$$

This weighting ensures the portfolio is **beta-neutral**, so P\&L is driven primarily by the convergence of the spread rather than market direction. In an ideal scenario a trader is rebalancing their trades as the beta evolves over-time.

## 5. Volatility&#x20;

Volatility measures the **standard deviation of log returns** for the pair. It reflects the typical magnitude of price swings in the spread.

σ = √( 1 ÷ (N–1) × Σ ( rᵢ – r̄ )² )

where rᵢ are the log returns of the spread and r̄ is their mean.

* Higher volatility → larger and more frequent price swings (more opportunity, more risk)
* Lower volatility → smaller price fluctuations (steadier spreads, fewer signals)

Volatility helps traders calibrate position sizing and risk management for each pair.

⚡ **Together:**

* **Correlation** → validates short-term co-movement.
* **Cointegration** → confirms long-term mean reversion.
* **Rolling Z-score** → provides entry/exit signals.
* **Beta** → ensures correct hedge sizing and risk balance.
* **Volatility** → quantifies the riskiness of the spread and informs overall position sizing


# Portfolio Margin and Liquidations

Hyperliquid, SYMM and Vertex work off the concept of portfolio margin.

All your positions are in portfolio margin, meaning they share unified collateral and thus you must monitor the overall account health to avoid liquidations.&#x20;

There is no single 'liquidation' price on a pair, users must ensure that their 'Balance' is > 'Maintenance Margin'.

<figure><img src="/files/rnAHWohUoSFG8qYruPdX" alt=""><figcaption></figcaption></figure>

**Liquidation logic**

Liquidations ensue when your Cross Margin Ratio % reaches certain thresholds. The risk engine is complex but essentially you want to ensure this number stays **less than 90%**. To mitigate liquidation risk, deposit more to your account and/or close existing trades.

Note, we do not show an ‘estimated’ liquidation price for each trade  given the path dependence of each leg it’s very inaccurate for the following reasons.&#x20;

When you pair trade there are multiple different ‘paths’ to get from say a level of 100 to 90 (-10%)

Eg. Asset A could stay flat and asset B could go up 10%

or Asset A could go up 20% and asset B could go up 30%&#x20;

Etc etc. So the concept of a single liquidation level for a pair is not possible as the margin requirements for each leg are different.

The most important thing is to monitor your overall account health and manage risk at a portfolio level.<br>


# FAQs

Frequently Asked Questions

### What is Pear Protocol?

Pear is a **non-custodial trading front-end** for executing **pair trades** on integrated decentralized venues like Hyperliquid, Vertex, SYMMIO, and GMX.\
It lets you take simultaneous long and short positions on perps — with capital efficiency and risk transparency — all from one UI.

***

### Why trade pairs instead of just going long or short?

Most traders lose money trying to time the market directionally.\
**Pair trading focuses on relative performance**, letting you express views like:

* “SOL will outperform ETH”
* “BTC will underperform ETH”
* “Layer 2 tokens will outperform majors”

It works in any market — bull, bear, or chop — and helps avoid getting chopped up by broad market swings.

***

### How does execution work?

Pear is a **front-end interface** — not an exchange or custodian.

* It splits your trade into **long** and **short** legs
* It routes each leg to your selected venue
* Both legs are timestamp-synced for execution efficiency
* You always control your funds (they sit in your wallet or in the trading engine)

***

### Where are my funds held?

It depends on the venue:

* **GMX** → Trades directly from your wallet (Arbitrum)
* **Hyperliquid, Vertex, SYMMIO** → You deposit collateral into the protocol’s trading engine. Pear manages positions but never holds custody.

***

### What assets can I trade?

You can pair trade **any supported perp markets** on:

* Hyperliquid
* Vertex
* SYMMIO
* GMX

The exact pairs depend on what each protocol offers. Pear auto-surfaces supported markets.

***

### How do fees work?

When you trade via Pear:

* You pay the normal trading fees of the underlying venue
* You may receive **rebates** or **discounts** via staking PEAR or through referral rewards
* On Hyperliquid, trades are routed with Pear’s **builder code**, and fees are transparently split per Hyperliquid’s public builder model

***

### Is Pear Protocol a DEX?

No. Pear is a **trading layer and routing engine** — we don’t custody funds or match trades.\
We route orders to supported venues (DEXs or on-chain perps) using smart contracts or APIs.

***

### How do I hedge impermanent loss as an LP?

Pear enables **pair trading limit orders**, which can be used to hedge concentrated liquidity positions.\
For example:

If you LP in PEPE/ETH, you can set a pair trade (short PEPE, long ETH) to activate if price moves out of your LP range — mitigating impermanent loss.

***

### Do I need to hold $PEAR to use Pear?

No — anyone can use Pear without holding $PEAR.\
However, holding and staking PEAR may unlock:

* Trading fee discounts up to 50%
* Volume based rebates
* Governance participation

***

### Is Pear available on mobile?

Currently, Pear is optimized for desktop.\
Mobile web is possible and a PWA is on the roadmap.

***

### Is there an API?

Yes — Pear offers an **API** for strategy automation and execution.\
See the Architecture and Integration section for docs and examples.


# Terms of Service

{% file src="/files/ybUkW2omHULEThn9kR6z" %}


# Privacy Policy

{% file src="/files/y4jzzjtk0ohIB0dK1ccv" %}


