{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "6c70a8c3", "metadata": {}, "outputs": [], "source": [ "\n", "import asyncio\n", "import requests\n", "from x10.config import MAINNET_CONFIG, TESTNET_CONFIG\n", "from x10.core.stark_account import StarkPerpetualAccount\n", "from x10.perpetual.trading_client import PerpetualTradingClient\n", "from x10.models.order import OrderSide, OrderType\n", "import time\n", "from dotenv import load_dotenv\n", "import os\n", "import uuid\n", "import asyncio\n", "import logging\n", "from decimal import Decimal\n", "import modules.extended_auth as extend_auth\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ff971ca9", "metadata": {}, "outputs": [], "source": [ "load_dotenv()\n", "\n", "API_KEY = os.getenv('EXTENDED_API_KEY')\n", "PUBLIC_KEY = os.getenv('EXTENDED_STARK_KEY_PUBLIC') # public Stark key (l2Key from account info)\n", "PRIVATE_KEY = os.getenv('EXTENDED_STARK_KEY_PRIVATE') # private Stark key (hex)\n", "VAULT = int(os.getenv('EXTENDED_VAULT_NUMBER')) # l2Vault from account info (integer)\n", "\n", "CONFIG = MAINNET_CONFIG\n", "\n", "ORDER_MARKET = \"ETH-USD\"\n", "ORDER_SIDE = OrderSide.BUY\n", "ORDER_QTY = Decimal(\"0.01\")\n", "ORDER_PRICE = Decimal(\"2200.1\")" ] }, { "cell_type": "code", "execution_count": 3, "id": "fc2c6d2b", "metadata": {}, "outputs": [], "source": [ "client, trading_client = await extend_auth.create_auth_account_and_trading_client()" ] }, { "cell_type": "code", "execution_count": 4, "id": "c366706f", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Error response from https://api.starknet.extended.exchange/api/v1/user/order: {\"status\":\"ERROR\",\"error\":{\"code\":1125,\"message\":\"Invalid price precision\"}}\n" ] }, { "ename": "ValueError", "evalue": "Error response from https://api.starknet.extended.exchange/api/v1/user/order: code 400 - {\"status\":\"ERROR\",\"error\":{\"code\":1125,\"message\":\"Invalid price precision\"}}", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mValueError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m placed_order = await trading_client.place_order(\n\u001b[32m 2\u001b[39m market_name=ORDER_MARKET,\n\u001b[32m 3\u001b[39m amount_of_synthetic=ORDER_QTY,\n\u001b[32m 4\u001b[39m price=ORDER_PRICE,\n", "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py_313/lib/python3.13/site-packages/x10/perpetual/trading_client/trading_client.py:101\u001b[39m, in \u001b[36mPerpetualTradingClient.place_order\u001b[39m\u001b[34m(self, market_name, amount_of_synthetic, price, side, taker_fee, post_only, previous_order_id, expire_time, time_in_force, self_trade_protection_level, external_id, builder_fee, builder_id, reduce_only, tp_sl_type, take_profit, stop_loss)\u001b[39m\n\u001b[32m 78\u001b[39m expire_time = utc_now() + timedelta(hours=\u001b[32m1\u001b[39m)\n\u001b[32m 80\u001b[39m order = create_order_object(\n\u001b[32m 81\u001b[39m account=\u001b[38;5;28mself\u001b[39m.__stark_account,\n\u001b[32m 82\u001b[39m market=market,\n\u001b[32m (...)\u001b[39m\u001b[32m 99\u001b[39m stop_loss=stop_loss,\n\u001b[32m 100\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m101\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mawait\u001b[39;00m \u001b[38;5;28mself\u001b[39m.__order_management_module.place_order(order)\n", "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py_313/lib/python3.13/site-packages/x10/perpetual/trading_client/order_management_module.py:31\u001b[39m, in \u001b[36mOrderManagementModule.place_order\u001b[39m\u001b[34m(self, order)\u001b[39m\n\u001b[32m 28\u001b[39m LOGGER.debug(\u001b[33m\"\u001b[39m\u001b[33mPlacing an order: id=\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, order.id)\n\u001b[32m 30\u001b[39m url = \u001b[38;5;28mself\u001b[39m._get_url(\u001b[33m\"\u001b[39m\u001b[33m/user/order\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m---> \u001b[39m\u001b[32m31\u001b[39m response = \u001b[38;5;28;01mawait\u001b[39;00m send_post_request(\n\u001b[32m 32\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m \u001b[38;5;28mself\u001b[39m.get_session(),\n\u001b[32m 33\u001b[39m url,\n\u001b[32m 34\u001b[39m PlacedOrderModel,\n\u001b[32m 35\u001b[39m json=order.to_api_request_json(exclude_none=\u001b[38;5;28;01mTrue\u001b[39;00m),\n\u001b[32m 36\u001b[39m api_key=\u001b[38;5;28mself\u001b[39m._get_api_key(),\n\u001b[32m 37\u001b[39m )\n\u001b[32m 38\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m response\n", "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py_313/lib/python3.13/site-packages/x10/utils/http.py:173\u001b[39m, in \u001b[36msend_post_request\u001b[39m\u001b[34m(session, url, model_class, json, api_key, request_headers, response_code_to_exception)\u001b[39m\n\u001b[32m 171\u001b[39m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mwith\u001b[39;00m session.post(url, json=json, headers=headers) \u001b[38;5;28;01mas\u001b[39;00m response:\n\u001b[32m 172\u001b[39m response_text = \u001b[38;5;28;01mawait\u001b[39;00m response.text()\n\u001b[32m--> \u001b[39m\u001b[32m173\u001b[39m \u001b[30;43mhandle_known_errors\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43murl\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mresponse_code_to_exception\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mresponse\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mresponse_text\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 174\u001b[39m response_model = parse_response_to_model(response_text, model_class)\n\u001b[32m 176\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m (response_model.status != ResponseStatus.OK) \u001b[38;5;129;01mor\u001b[39;00m (response_model.error \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m):\n", "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py_313/lib/python3.13/site-packages/x10/utils/http.py:243\u001b[39m, in \u001b[36mhandle_known_errors\u001b[39m\u001b[34m(url, response_code_handler, response, response_text)\u001b[39m\n\u001b[32m 241\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m response.status > \u001b[32m299\u001b[39m:\n\u001b[32m 242\u001b[39m LOGGER.error(\u001b[33m\"\u001b[39m\u001b[33mError response from \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, url, response_text)\n\u001b[32m--> \u001b[39m\u001b[32m243\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mError response from \u001b[39m\u001b[38;5;132;01m{\u001b[39;00murl\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m: code \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mresponse.status\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m - \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mresponse_text\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n", "\u001b[31mValueError\u001b[39m: Error response from https://api.starknet.extended.exchange/api/v1/user/order: code 400 - {\"status\":\"ERROR\",\"error\":{\"code\":1125,\"message\":\"Invalid price precision\"}}" ] } ], "source": [ "placed_order = await trading_client.place_order(\n", " market_name=ORDER_MARKET,\n", " amount_of_synthetic=ORDER_QTY,\n", " price=ORDER_PRICE,\n", " side=ORDER_SIDE,\n", " taker_fee=Decimal(\"0.00025\"),\n", " # previous_order_id='1295034892466447624365619416628580523728221205816494340545831832663414858661'\n", ")" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "WrappedApiResponse[EmptyModel](status='OK', data=EmptyModel(), error=None, pagination=None)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = await trading_client.orders.mass_cancel(markets=['ETH-USD'])\n", "c" ] }, { "cell_type": "code", "execution_count": null, "id": "03913674", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 6, "id": "8dd8aa73", "metadata": {}, "outputs": [], "source": [ "d = await trading_client.account.get_positions_history()" ] }, { "cell_type": "code", "execution_count": 12, "id": "5f74f7cc", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
| \n", " | 0 | \n", "1 | \n", "2 | \n", "3 | \n", "4 | \n", "5 | \n", "6 | \n", "7 | \n", "8 | \n", "9 | \n", "10 | \n", "11 | \n", "12 | \n", "13 | \n", "
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | \n", "(id, 2047947640758337536) | \n", "(account_id, 270571) | \n", "(market, ETH-USD) | \n", "(side, SHORT) | \n", "(size, 0.2160000000000000) | \n", "(max_position_size, 0.2160000000000000) | \n", "(leverage, 50.0000000000000000) | \n", "(open_price, 2315.5000000000000000) | \n", "(exit_price, 2308.6000000000000000) | \n", "(realised_pnl, 1.4249250000000000) | \n", "(realised_pnl_breakdown, trade_pnl=Decimal('1.... | \n", "(created_time, 1777103741241) | \n", "(exit_type, TRADE) | \n", "(closed_time, 1777133049026) | \n", "
| 1 | \n", "(id, 2047512381621272576) | \n", "(account_id, 270571) | \n", "(market, ETH-USD) | \n", "(side, LONG) | \n", "(size, 0.2150000000000000) | \n", "(max_position_size, 0.2150000000000000) | \n", "(leverage, 50.0000000000000000) | \n", "(open_price, 2316.6000000000000000) | \n", "(exit_price, 2315.5000000000000000) | \n", "(realised_pnl, 0.0720660000000000) | \n", "(realised_pnl_breakdown, trade_pnl=Decimal('-0... | \n", "(created_time, 1776999967376) | \n", "(exit_type, TRADE) | \n", "(closed_time, 1777103741241) | \n", "
| 2 | \n", "(id, 2047419314696355840) | \n", "(account_id, 270571) | \n", "(market, ETH-USD) | \n", "(side, LONG) | \n", "(size, 0.2150000000000000) | \n", "(max_position_size, 0.2150000000000000) | \n", "(leverage, 50.0000000000000000) | \n", "(open_price, 2321.7000000000000000) | \n", "(exit_price, 2327.3000000000000000) | \n", "(realised_pnl, 1.3196460000000000) | \n", "(realised_pnl_breakdown, trade_pnl=Decimal('1.... | \n", "(created_time, 1776977778492) | \n", "(exit_type, TRADE) | \n", "(closed_time, 1776996621824) | \n", "