dydX v4 clientの使い方

# 趣旨
コネクターを使わずに直接dydXをAPIでコールしたの初めてだったので記録に残しておきます。v4-client-pyを使えばウォレットの生成やトレードやその他手動での作業の全てをbot化できると思います。今後も自分のスキルを磨く練習だと思って色々いじって記録に残そうと思います。

# IndexerのDocs
使い方は以下のDocsの該当ページに全て記載されています。Githubを見るのもよいと思います。

https://docs.dydx.exchange/api_integration-clients/indexer_client

ライブラリをインストールします。
```bash
pip install v4-client-py
```

# 実践コード
NETWORKとClientは一度きりで良いのですが、初心者のためにあえて何度も記載します。コピペすれば動くように。

:::note alert 
validator_configについてはよくわかっていないのでまだ解説できません。
そのうち学びます。
:::

### BTCマーケットデータ

```python fetch_btc_makretdata.py
from v4_client_py import IndexerClient
from v4_client_py.clients.constants import ValidatorConfig, IndexerConfig, Network
import json

# Using placeholder values for url_prefix and aerial_url
NETWORK = Network(
    env='testnet',
    validator_config=ValidatorConfig(
        grpc_endpoint='https://dydx-ops-rpc.kingnodes.com', # or other node URL
        chain_id='dydx-mainnet-1',
        ssl_enabled=True,
        url_prefix='https://example.com/prefix',
        aerial_url='https://example.com/aerial'
    ),
    indexer_config=IndexerConfig(
        rest_endpoint='https://indexer.dydx.trade',
        websocket_endpoint='wss://indexer.dydx.trade',
    ),
    faucet_endpoint='',
)

client = IndexerClient(
    config=NETWORK.indexer_config,
)

markets_response = client.markets.get_perpetual_markets()

# Extract BTC data
if hasattr(markets_response, 'data'):
    data = markets_response.data
    btc_data = data.get('markets', {}).get('BTC-USD', {})
    if btc_data:
        pretty_btc_data = json.dumps(btc_data, indent=4)
        print(pretty_btc_data)
    else:
        print("BTC data not found in the response.")
else:
    print("The response object does not have a 'data' attribute.")
```
実行結果

```bash
{
    "clobPairId": "0",
    "ticker": "BTC-USD",
    "status": "ACTIVE",
    "oraclePrice": "67480.36196",
    "priceChange24H": "-2264.65254",
    "volume24H": "450104114.3081",
    "trades24H": 104933,
    "nextFundingRate": "0.00001396",
    "initialMarginFraction": "0.05",
    "maintenanceMarginFraction": "0.03",
    "openInterest": "718.8128",
    "atomicResolution": -10,
    "quantumConversionExponent": -9,
    "tickSize": "1",
    "stepSize": "0.0001",
    "stepBaseQuantums": 1000000,
    "subticksPerTick": 100000,
    "marketType": "CROSS",
    "openInterestLowerCap": "0",
    "openInterestUpperCap": "0",
    "baseOpenInterest": "718.7128"
}
```




### オーダーブック
BTCのオーダーブックを取得します。

```python fetch_orderbook.py
from v4_client_py import IndexerClient
from v4_client_py.clients.constants import ValidatorConfig, IndexerConfig, Network
import json

# Using placeholder values for url_prefix and aerial_url
NETWORK = Network(
    env='testnet',
    validator_config=ValidatorConfig(
        grpc_endpoint='https://dydx-ops-rpc.kingnodes.com', # or other node URL
        chain_id='dydx-mainnet-1',
        ssl_enabled=True,
        url_prefix='https://example.com/prefix',
        aerial_url='https://example.com/aerial'
    ),
    indexer_config=IndexerConfig(
        rest_endpoint='https://indexer.dydx.trade',
        websocket_endpoint='wss://indexer.dydx.trade',
    ),
    faucet_endpoint='',
)

client = IndexerClient(
    config=NETWORK.indexer_config,
)

# ticker is the market ticket, such as "BTC-USD"
market_orderbook_response = client.markets.get_perpetual_market_orderbook('BTC-USD')
market_orderbook = market_orderbook_response.data

market_orderbook_asks = market_orderbook['asks']
market_orderbook_bids = market_orderbook['bids']

# Pretty print the orderbook data
print("Asks:")
print(json.dumps(market_orderbook_asks, indent=4))
print("Bids:")
print(json.dumps(market_orderbook_bids, indent=4))
```
実行結果
```bash
Asks:
[
    {
        "price": "67307",
        "size": "0.003"
    },
    {
        "price": "67308",
        "size": "0.5161"
    },
    {
        "price": "67309",
        "size": "0.453"
    },
    {
        "price": "67312",
        "size": "0.1"
    },
    {
        "price": "67313",
        "size": "0.297"
    },
    {
        "price": "67314",
        "size": "0.0001"
    },
    {
        "price": "67319",
        "size": "0.0448"
    },
    {
        "price": "67321",
        "size": "0.2"
    },
    {
        "price": "67323",
        "size": "0.1267"
    },
    {
        "price": "67324",
        "size": "0.33"
    },
    {
        "price": "67325",
        "size": "0.8909"
    },
    {
        "price": "67326",
        "size": "0.0288"
    },
    {
        "price": "67332",
        "size": "0.1"
    },
    {
        "price": "67333",
        "size": "0.0295"
    },
    {
        "price": "67349",
        "size": "0.8153"
    },
    {
        "price": "67362",
        "size": "0.0234"
    },
    {
        "price": "67371",
        "size": "0.0011"
    },
    {
        "price": "67379",
        "size": "0.0582"
    },
    {
        "price": "67389",
        "size": "0.363"
    },
    {
        "price": "67390",
        "size": "0.1122"
    },
    {
        "price": "67395",
        "size": "0.0027"
    },
    {
        "price": "67413",
        "size": "0.2239"
    },
    {
        "price": "67416",
        "size": "0.8153"
    },
    {
        "price": "67477",
        "size": "2.5447"
    },
    {
        "price": "67481",
        "size": "0.033"
    },
    {
        "price": "67484",
        "size": "0.8153"
    },
    {
        "price": "67524",
        "size": "4.514"
    },
    {
        "price": "67551",
        "size": "0.8153"
    },
    {
        "price": "67613",
        "size": "0.5662"
    },
    {
        "price": "67619",
        "size": "0.8153"
    },
    {
        "price": "67686",
        "size": "0.8153"
    },
    {
        "price": "67699",
        "size": "0.0639"
    },
    {
        "price": "67700",
        "size": "0.025"
    },
    {
        "price": "67754",
        "size": "0.8153"
    },
    {
        "price": "67798",
        "size": "0.049"
    },
    {
        "price": "67799",
        "size": "0.1"
    },
    {
        "price": "67822",
        "size": "0.8153"
    },
    {
        "price": "67859",
        "size": "0.5662"
    },
    {
        "price": "67942",
        "size": "0.3493"
    },
    {
        "price": "68014",
        "size": "0.2973"
    },
    {
        "price": "68015",
        "size": "0.0032"
    },
    {
        "price": "68300",
        "size": "1"
    },
    {
        "price": "68337",
        "size": "0.002"
    },
    {
        "price": "68346",
        "size": "0.2239"
    },
    {
        "price": "68400",
        "size": "0.03"
    },
    {
        "price": "68524",
        "size": "0.03"
    },
    {
        "price": "68538",
        "size": "0.1122"
    },
    {
        "price": "68550",
        "size": "0.1"
    },
    {
        "price": "68600",
        "size": "0.03"
    },
    {
        "price": "68620",
        "size": "0.012"
    },
    {
        "price": "68700",
        "size": "0.1"
    },
    {
        "price": "68742",
        "size": "0.013"
    },
    {
        "price": "68880",
        "size": "1"
    },
    {
        "price": "68891",
        "size": "0.026"
    },
    {
        "price": "68900",
        "size": "0.05"
    },
    {
        "price": "68960",
        "size": "1"
    },
    {
        "price": "68980",
        "size": "1"
    },
    {
        "price": "69000",
        "size": "1.1"
    },
    {
        "price": "69191",
        "size": "1"
    },
    {
        "price": "69259",
        "size": "1"
    },
    {
        "price": "69311",
        "size": "0.008"
    },
    {
        "price": "69349",
        "size": "1"
    },
    {
        "price": "69362",
        "size": "5"
    },
    {
        "price": "69400",
        "size": "0.05"
    },
    {
        "price": "69480",
        "size": "1"
    },
    {
        "price": "69536",
        "size": "0.1122"
    },
    {
        "price": "69562",
        "size": "5"
    },
    {
        "price": "69580",
        "size": "1"
    },
    {
        "price": "69680",
        "size": "1"
    },
    {
        "price": "69700",
        "size": "0.01"
    },
    {
        "price": "69780",
        "size": "1"
    },
    {
        "price": "69800",
        "size": "0.1052"
    },
    {
        "price": "69820",
        "size": "1"
    },
    {
        "price": "69860",
        "size": "1"
    },
    {
        "price": "69880",
        "size": "2"
    },
    {
        "price": "69889",
        "size": "0.0012"
    },
    {
        "price": "69900",
        "size": "2.1293"
    },
    {
        "price": "69950",
        "size": "0.19"
    },
    {
        "price": "69980",
        "size": "2.05"
    },
    {
        "price": "69981",
        "size": "0.0071"
    },
    {
        "price": "69990",
        "size": "2"
    },
    {
        "price": "70060",
        "size": "1"
    },
    {
        "price": "70100",
        "size": "0.06"
    },
    {
        "price": "70152",
        "size": "0.0008"
    },
    {
        "price": "70177",
        "size": "0.1"
    },
    {
        "price": "70200",
        "size": "0.02"
    },
    {
        "price": "70260",
        "size": "0.1423"
    },
    {
        "price": "70350",
        "size": "2"
    },
    {
        "price": "70450",
        "size": "0.05"
    },
    {
        "price": "70490",
        "size": "3"
    },
    {
        "price": "70500",
        "size": "0.1283"
    },
    {
        "price": "70763",
        "size": "0.008"
    },
    {
        "price": "70807",
        "size": "0.008"
    },
    {
        "price": "70987",
        "size": "0.1"
    },
    {
        "price": "71000",
        "size": "0.15"
    },
    {
        "price": "71111",
        "size": "1"
    },
    {
        "price": "71200",
        "size": "1.6"
    },
    {
        "price": "71380",
        "size": "0.01"
    },
    {
        "price": "71400",
        "size": "1"
    },
    {
        "price": "71500",
        "size": "0.01"
    }
]
Bids:
[
    {
        "price": "67306",
        "size": "0.05"
    },
    {
        "price": "67305",
        "size": "0.05"
    },
    {
        "price": "67303",
        "size": "0.1001"
    },
    {
        "price": "67301",
        "size": "0.4181"
    },
    {
        "price": "67299",
        "size": "0.45"
    },
    {
        "price": "67298",
        "size": "0.0583"
    },
    {
        "price": "67297",
        "size": "1.2709"
    },
    {
        "price": "67295",
        "size": "0.8909"
    },
    {
        "price": "67294",
        "size": "0.0295"
    },
    {
        "price": "67290",
        "size": "0.1689"
    },
    {
        "price": "67287",
        "size": "0.0334"
    },
    {
        "price": "67285",
        "size": "0.0295"
    },
    {
        "price": "67282",
        "size": "0.0305"
    },
    {
        "price": "67281",
        "size": "0.2972"
    },
    {
        "price": "67260",
        "size": "0.0234"
    },
    {
        "price": "67249",
        "size": "0.3355"
    },
    {
        "price": "67248",
        "size": "0.005"
    },
    {
        "price": "67220",
        "size": "0.0582"
    },
    {
        "price": "67215",
        "size": "0.8153"
    },
    {
        "price": "67187",
        "size": "0.1122"
    },
    {
        "price": "67165",
        "size": "0.1"
    },
    {
        "price": "67159",
        "size": "2.2896"
    },
    {
        "price": "67150",
        "size": "0.331"
    },
    {
        "price": "67149",
        "size": "0.0591"
    },
    {
        "price": "67148",
        "size": "0.8153"
    },
    {
        "price": "67133",
        "size": "0.2239"
    },
    {
        "price": "67113",
        "size": "0.008"
    },
    {
        "price": "67104",
        "size": "0.01"
    },
    {
        "price": "67081",
        "size": "0.8153"
    },
    {
        "price": "67074",
        "size": "0.03"
    },
    {
        "price": "67057",
        "size": "4.6631"
    },
    {
        "price": "67055",
        "size": "0.1"
    },
    {
        "price": "67050",
        "size": "2.3272"
    },
    {
        "price": "67014",
        "size": "0.8153"
    },
    {
        "price": "67011",
        "size": "1"
    },
    {
        "price": "67000",
        "size": "1.3453"
    },
    {
        "price": "66999",
        "size": "0.5662"
    },
    {
        "price": "66990",
        "size": "0.0373"
    },
    {
        "price": "66951",
        "size": "0.0639"
    },
    {
        "price": "66950",
        "size": "0.425"
    },
    {
        "price": "66947",
        "size": "0.8153"
    },
    {
        "price": "66944",
        "size": "0.1"
    },
    {
        "price": "66905",
        "size": "0.5662"
    },
    {
        "price": "66900",
        "size": "1.05"
    },
    {
        "price": "66893",
        "size": "0.1497"
    },
    {
        "price": "66880",
        "size": "0.8153"
    },
    {
        "price": "66859",
        "size": "1.25"
    },
    {
        "price": "66815",
        "size": "0.049"
    },
    {
        "price": "66814",
        "size": "0.8153"
    },
    {
        "price": "66808",
        "size": "0.075"
    },
    {
        "price": "66800",
        "size": "1"
    },
    {
        "price": "66786",
        "size": "0.3493"
    },
    {
        "price": "66766",
        "size": "0.05"
    },
    {
        "price": "66747",
        "size": "0.8153"
    },
    {
        "price": "66709",
        "size": "0.0032"
    },
    {
        "price": "66700",
        "size": "0.2"
    },
    {
        "price": "66601",
        "size": "0.2973"
    },
    {
        "price": "66600",
        "size": "1"
    },
    {
        "price": "66550",
        "size": "1"
    },
    {
        "price": "66500",
        "size": "1.512"
    },
    {
        "price": "66480",
        "size": "0.2239"
    },
    {
        "price": "66447",
        "size": "1"
    },
    {
        "price": "66425",
        "size": "0.1"
    },
    {
        "price": "66415",
        "size": "0.1505"
    },
    {
        "price": "66400",
        "size": "1"
    },
    {
        "price": "66300",
        "size": "1.3791"
    },
    {
        "price": "66200",
        "size": "1.08"
    },
    {
        "price": "66190",
        "size": "0.1"
    },
    {
        "price": "66142",
        "size": "0.1122"
    },
    {
        "price": "66102",
        "size": "1"
    },
    {
        "price": "66101",
        "size": "1"
    },
    {
        "price": "66100",
        "size": "2.1"
    },
    {
        "price": "66050",
        "size": "1"
    },
    {
        "price": "66003",
        "size": "0.25"
    },
    {
        "price": "66000",
        "size": "7.1511"
    },
    {
        "price": "65965",
        "size": "0.0047"
    },
    {
        "price": "65900",
        "size": "0.01"
    },
    {
        "price": "65884",
        "size": "0.1122"
    },
    {
        "price": "65777",
        "size": "2"
    },
    {
        "price": "65666",
        "size": "1"
    },
    {
        "price": "65656",
        "size": "0.35"
    },
    {
        "price": "65600",
        "size": "1.4324"
    },
    {
        "price": "65555",
        "size": "0.0005"
    },
    {
        "price": "65551",
        "size": "1"
    },
    {
        "price": "65550",
        "size": "2.5"
    },
    {
        "price": "65500",
        "size": "0.511"
    },
    {
        "price": "65444",
        "size": "2"
    },
    {
        "price": "65432",
        "size": "1"
    },
    {
        "price": "65430",
        "size": "0.7"
    },
    {
        "price": "65388",
        "size": "0.5699"
    },
    {
        "price": "65365",
        "size": "0.0509"
    },
    {
        "price": "65288",
        "size": "1"
    },
    {
        "price": "65266",
        "size": "0.5"
    },
    {
        "price": "65256",
        "size": "0.0007"
    },
    {
        "price": "65200",
        "size": "7"
    },
    {
        "price": "65189",
        "size": "0.0007"
    },
    {
        "price": "65173",
        "size": "0.0383"
    },
    {
        "price": "65128",
        "size": "2"
    },
    {
        "price": "65111",
        "size": "1"
    },
    {
        "price": "65100",
        "size": "0.25"
    }
]
```