# GET Contract Symbols

## /contract-symbols

```json
/contract-symbols
```

**Example Query:**

```
https://base-hedger82.rasa.capital/contract-symbols
```

**Example Response:**

```json
   {
      "price_precision": 1,
      "quantity_precision": 3,
      "name": "BTCUSDT",
      "symbol": "BTC",
      "asset": "USDT",
      "symbol_id": 1,
      "is_valid": true,
      "min_acceptable_quote_value": 120,
      "min_acceptable_portion_lf": "0.003000000000000000",
      "trading_fee": "0.000600000000000000",
      "max_leverage": 60,
      "max_notional_value": 2100000,
      "rfq_allowed": true,
      "hedger_fee_open": "0.0006",
      "hedger_fee_close": "0.0006",
      "max_funding_rate": "200",
      "min_notional_value": "100",
      "max_quantity": "1000",
      "lot_size": "0"
    },
    {
      "price_precision": 3,
      "quantity_precision": 1,
      "name": "FILUSDT",
      "symbol": "FIL",
      "asset": "USDT",
      "symbol_id": 55,
      "is_valid": true,
      "min_acceptable_quote_value": 10,
      "min_acceptable_portion_lf": "0.004000000000000000",
      "trading_fee": "0.000800000000000000",
      "max_leverage": 50,
      "max_notional_value": 1750000,
      "rfq_allowed": true,
      "hedger_fee_open": "0.0006",
      "hedger_fee_close": "0.0006",
      "max_funding_rate": "200",
      "min_notional_value": "5",
      "max_quantity": "10000000",
      "lot_size": "0"
    }, //...
```

#### **Data Sources**

Values are derived from two sources:

1. **On-Chain Contract Data**: Immutable parameters fetched directly from the blockchain (via `getSymbol(symbolId)` or`getSymbols(start, size)`).
2. **Hedger-Defined Parameters**: Configurable values set by the market maker/hedger, subject to on-chain constraints.

**Contract-Sourced Values**

* **`symbol_id`**: Unique identifier for the trading pair (e.g., `1` for BTCUSDT). Mapped directly from the contract’s `symbolId`.
* **`name`**: Trading pair name (e.g., `BTCUSDT`).&#x20;
* **`is_valid`**: Indicates if the symbol is active for trading. Mapped from the contract’s `isValid`.
* **`min_acceptable_quote_value`**: Minimum quote value (e.g., $120) required to open a position. Converted from the contract’s fixed-point value (e.g., `120000000000000000000` → `120`).
* **`min_acceptable_portion_lf`**: Minimum portion of the liquidity fee (e.g., `0.003`). Converted from the contract’s fixed-point value (e.g., `3000000000000000` → `0.003`).
* **`trading_fee`**: Fee charged per trade (e.g., `0.0006` or 0.06%). Derived from the contract’s `tradingFee` (e.g., `600000000000000` → `0.0006`).

**Hedger-Defined Values**

* **`max_leverage`**: Maximum leverage allowed (e.g., `60x`). Must be **≤** the contract’s `Leverage` (e.g., `60` ≤ `100`).
* **`max_notional_value`**: Maximum position size (e.g., $2,100,000). Must be **≥** the contract’s `minAcceptableQuoteValue` (e.g., `2100000` ≥ `120`).
* **`max_quantity`**: Maximum tradable quantity (e.g., `1000` BTC). No on-chain constraints.
* **`max_funding_rate`**: Upper limit for funding rate (e.g., `200` ). Set by the hedger.
* **`min_notional_value`**: Minimum position size (e.g., $100). Configured by the hedger.
* **`hedger_fee_open`/`hedger_fee_close`**: Additional fees charged by the hedger (e.g., `0.0006`).
* **`rfq_allowed`**: Whether Request for Quote (RFQ) is enabled for the symbol.

**Derived Values**

* **`symbol`/`asset`**: Base and quote assets (e.g., `BTC` and `USDT`). Parsed from the `name` field (e.g., `BTCUSDT` → `symbol: BTC`, `asset: USDT`).
* **`price_precision`**: Number of decimal places for price (e.g., `1` → $100.1). Determined by the hedger based on market conventions.
* **`quantity_precision`**: Number of decimal places for quantity (e.g., `3` → 0.001 BTC). Derived from `min_acceptable_portion_lf` (e.g., `0.003` implies 3 decimals).
* **`lot_size`**: Always `0` (no minimum lot size enforced).

## Contract Symbols Implementation (Rasa)

### Router

```python
@common_router.get(
    '/contract-symbols', responses={status.HTTP_200_OK: {"model": SymbolsContractResponseSchema}},
    response_model=SymbolsContractResponseSchema
)
async def get_contract_symbols():
    symbols = await get_contract_all_symbols()
    return dict(count=len(symbols), symbols=symbols)
```

### Controller Logic

**Caching**

Uses `@redis_ttl_cache(ttl=300)`, so the *entire* symbol list is stored in Redis for 5 minutes. Subsequent calls within that window skip on-chain and DB work.

**On-Chain Fetching**

```python
symbols = await symmio_contract.functions
                         .getSymbols(start=0, size=500)
                         .call_async()
```

Calls the SYMMIO “diamond” contract’s `getSymbols` method to retrieve up to 500 entries and returns a list of tuples matching the on-chain `Symbol` struct fields.

{% hint style="info" %}
*A size of 500 may be insufficient for future symbols added to the SYMM contracts.*
{% endhint %}

**Filters & Whitelists**

```python
if not symbol[2]:                     # on-chain `isValid == false`
    continue
if symbol[1].upper() not in whitelist:
    continue
```

Drops any symbol with `isValid == false` or if the symbol is not in your hedger’s own whitelist (normalized to uppercase).

**Price Precision and Quantity Precision**

```python
price_precision    = Symbol.get_price_precision(symbol[1])
quantity_precision = Symbol.get_quantity_precision(symbol[1])
```

These methods query the **Postgres** `Symbol` table for the precision values you configured.

**USDT-Pair Restriction**

```python
if symbol[1].endswith("USDT"):
    … include in result …
```

Only includes symbols quoted in USDT.

### **Composing the Response Object**

**The response dict consists of:**

* **On-chain fields**: `symbolId`, `name`, `isValid`, `minAcceptableQuoteValue`, etc.
* **DB/config fields**: `price_precision`, `quantity_precision`, plus hedger parameters (max leverage, fees, notional caps) via `HedgerParameters`.
* Returns a list of dicts, one per symbol.&#x20;

**Full Controller Snippet**

```python
@redis_ttl_cache(ttl=300)
async def get_contract_all_symbols():
    symbols: List[Tuple] = await symmio_contract.functions.getSymbols(start=0, size=500).call_async()
    symbols_list = []
    symbol_whitelist = get_symbol_whitelist()
    for symbol in symbols:
        if not symbol[2]:
            continue
        if symbol[1].upper() not in symbol_whitelist:
            continue
        try:
            price_precision = Symbol.get_price_precision(symbol[1])
            quantity_precision = Symbol.get_quantity_precision(symbol[1])
        except PreConditionException:
            price_precision = None
            quantity_precision = None
        if 'USDT' == symbol[1][-4:]:
            symbols_list.append({
                'name': symbol[1].upper(), 'symbol': symbol[1][:-4], 'asset': 'USDT', 'symbol_id': symbol[0],
                'price_precision': price_precision,
                'quantity_precision': quantity_precision,
                'is_valid': symbol[2],
                'min_acceptable_quote_value': (Decimal(symbol[3]) / Scale) * MinQuoteValueMultiplier,
                'min_acceptable_portion_lf': Decimal(symbol[4]) / Scale,
                'trading_fee': Decimal(symbol[5]) / Scale,
                'max_leverage': int(
                    HedgerParameters.get_by_key(f"quote_boundaries::dynamic::{symbol[1]}::leverage::max")),
                'max_notional_value': HedgerParameters.get_by_key_convert_decimal(
                    f'quote_boundaries::{symbol[1]}::notionalValue::max'),
                'rfq_allowed': symbol[1].upper() not in OpenPositionSymbolBlackList,
                'max_funding_rate': HedgerParameters.get_by_key_convert_decimal('quote::max-funding-rate'),
                'hedger_fee_open': HedgerParameters.get_by_key(
                    f'{HedgerParameterPrefixes.open_order_gap}{symbol[1].upper()}'),
                'hedger_fee_close': HedgerParameters.get_by_key(
                    f'{HedgerParameterPrefixes.close_order_gap}{symbol[1].upper()}')
            })
    return symbols_list
```

For reference, the structure of an on-chain `Symbol` is here:

```solidity
struct Symbol {
    uint256 symbolId;                   // tuple index [0]
    string  name;                       // index [1]
    bool    isValid;                    // index [2]
    uint256 minAcceptableQuoteValue;    // index [3]
    uint256 minAcceptablePortionLF;     // index [4]
    uint256 tradingFee;                 // index [5]
    uint256 maxLeverage;                // index [6]
    uint256 fundingRateEpochDuration;   // index [7]
    uint256 fundingRateWindowTime;      // index [8]
}
```


---

# Agent Instructions: Querying This Documentation

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

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

```
GET https://docs.symm.io/liquidity-provider-documentation/building-a-solver-on-symmio/5.-creating-the-apis/get-contract-symbols.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

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