diff --git a/examples/01_create_limit_order.py b/examples/01_create_limit_order.py index 1f72e64..4a3a196 100644 --- a/examples/01_create_limit_order.py +++ b/examples/01_create_limit_order.py @@ -11,6 +11,7 @@ from x10.perpetual.trading_client import PerpetualTradingClient LOGGER = logging.getLogger() +MARKET_NAME = ETH_USD_MARKET ENDPOINT_CONFIG = MAINNET_CONFIG @@ -25,7 +26,7 @@ async def run_example(): trading_client = PerpetualTradingClient(ENDPOINT_CONFIG, stark_account) markets_dict = await trading_client.markets_info.get_markets_dict() - market = markets_dict[ETH_USD_MARKET] + market = markets_dict[MARKET_NAME] adjust_price_by_pct = get_adjust_price_by_pct(market.trading_config) order_size = market.trading_config.min_order_size diff --git a/examples/02_create_limit_order_with_partial_tpsl.py b/examples/02_create_limit_order_with_partial_tpsl.py index 4cfb2b5..a8ef98a 100644 --- a/examples/02_create_limit_order_with_partial_tpsl.py +++ b/examples/02_create_limit_order_with_partial_tpsl.py @@ -17,6 +17,7 @@ from x10.perpetual.trading_client import PerpetualTradingClient LOGGER = logging.getLogger() +MARKET_NAME = ETH_USD_MARKET ENDPOINT_CONFIG = MAINNET_CONFIG @@ -31,7 +32,7 @@ async def run_example(): trading_client = PerpetualTradingClient(ENDPOINT_CONFIG, stark_account) markets_dict = await trading_client.markets_info.get_markets_dict() - market = markets_dict[ETH_USD_MARKET] + market = markets_dict[MARKET_NAME] adjust_price_by_pct = get_adjust_price_by_pct(market.trading_config) order_size = market.trading_config.min_order_size diff --git a/examples/03_subscribe_to_stream.py b/examples/03_subscribe_to_stream.py index a60c69e..4c6f00c 100644 --- a/examples/03_subscribe_to_stream.py +++ b/examples/03_subscribe_to_stream.py @@ -4,10 +4,12 @@ from signal import SIGINT, SIGTERM from examples.init_env import init_env +from x10.config import ETH_USD_MARKET from x10.perpetual.configuration import MAINNET_CONFIG from x10.perpetual.stream_client import PerpetualStreamClient LOGGER = logging.getLogger() +MARKET_NAME = ETH_USD_MARKET ENDPOINT_CONFIG = MAINNET_CONFIG @@ -16,7 +18,7 @@ async def subscribe_to_streams(stop_event: asyncio.Event): stream_client = PerpetualStreamClient(api_url=ENDPOINT_CONFIG.stream_url) async def subscribe_to_orderbook(): - async with stream_client.subscribe_to_orderbooks("BTC-USD") as orderbook_stream: + async with stream_client.subscribe_to_orderbooks(MARKET_NAME) as orderbook_stream: while not stop_event.is_set(): try: msg = await asyncio.wait_for(orderbook_stream.recv(), timeout=1) diff --git a/examples/04_create_limit_order_with_builder.py b/examples/04_create_limit_order_with_builder.py new file mode 100644 index 0000000..97ba2b4 --- /dev/null +++ b/examples/04_create_limit_order_with_builder.py @@ -0,0 +1,67 @@ +import logging.handlers +from asyncio import run + +from examples.init_env import init_env +from examples.utils import find_order_and_cancel, get_adjust_price_by_pct +from x10.config import ETH_USD_MARKET +from x10.perpetual.accounts import StarkPerpetualAccount +from x10.perpetual.configuration import MAINNET_CONFIG +from x10.perpetual.order_object import create_order_object +from x10.perpetual.orders import OrderSide, TimeInForce +from x10.perpetual.trading_client import PerpetualTradingClient + +LOGGER = logging.getLogger() +MARKET_NAME = ETH_USD_MARKET +ENDPOINT_CONFIG = MAINNET_CONFIG + + +async def run_example(): + env_config = init_env() + + assert env_config.builder_id, "X10_BUILDER_ID is not set" + + stark_account = StarkPerpetualAccount( + api_key=env_config.api_key, + public_key=env_config.public_key, + private_key=env_config.private_key, + vault=env_config.vault_id, + ) + trading_client = PerpetualTradingClient(ENDPOINT_CONFIG, stark_account) + markets_dict = await trading_client.markets_info.get_markets_dict() + fees = await trading_client.account.get_fees(market_names=[MARKET_NAME], builder_id=env_config.builder_id) + builder_fee = fees.data[0].builder_fee_rate + + market = markets_dict[ETH_USD_MARKET] + adjust_price_by_pct = get_adjust_price_by_pct(market.trading_config) + + order_size = market.trading_config.min_order_size + order_price = adjust_price_by_pct(market.market_stats.bid_price, -10.0) + + LOGGER.info("Builder: id=%s, fee=%s", env_config.builder_id, builder_fee) + LOGGER.info("Creating LIMIT order object for market: %s", market.name) + + new_order = create_order_object( + account=stark_account, + starknet_domain=ENDPOINT_CONFIG.starknet_domain, + market=market, + side=OrderSide.BUY, + amount_of_synthetic=order_size, + price=market.trading_config.round_price(order_price), + time_in_force=TimeInForce.GTT, + reduce_only=False, + post_only=True, + builder_id=env_config.builder_id, + builder_fee=builder_fee, + ) + + LOGGER.info("Placing order...") + + placed_order = await trading_client.orders.place_order(order=new_order) + + LOGGER.info("Order is placed: %s", placed_order.to_pretty_json()) + + await find_order_and_cancel(trading_client=trading_client, logger=LOGGER, order_id=placed_order.data.id) + + +if __name__ == "__main__": + run(main=run_example()) diff --git a/examples/builder_order_example_simple.py b/examples/builder_order_example_simple.py deleted file mode 100644 index 035a856..0000000 --- a/examples/builder_order_example_simple.py +++ /dev/null @@ -1,78 +0,0 @@ -import logging -import logging.config -import logging.handlers -import os -from asyncio import run -from decimal import Decimal - -from dotenv import load_dotenv - -from x10.perpetual.accounts import StarkPerpetualAccount -from x10.perpetual.configuration import TESTNET_CONFIG -from x10.perpetual.orders import OrderSide -from x10.perpetual.simple_client.simple_trading_client import BlockingTradingClient -from x10.perpetual.trading_client import PerpetualTradingClient - -NUM_PRICE_LEVELS = 1 - -load_dotenv() - -API_KEY = os.getenv("X10_API_KEY") -PUBLIC_KEY = os.getenv("X10_PUBLIC_KEY") -PRIVATE_KEY = os.getenv("X10_PRIVATE_KEY") -VAULT_ID = int(os.environ["X10_VAULT_ID"]) - - -async def clean_it(trading_client: PerpetualTradingClient): - logger = logging.getLogger("placed_order_example") - positions = await trading_client.account.get_positions() - logger.info("Positions: %s", positions.to_pretty_json()) - balance = await trading_client.account.get_balance() - logger.info("Balance: %s", balance.to_pretty_json()) - open_orders = await trading_client.account.get_open_orders() - await trading_client.orders.mass_cancel(order_ids=[order.id for order in open_orders.data]) - - -async def setup_and_run(): - stark_account = StarkPerpetualAccount( - vault=VAULT_ID, - private_key="" if PRIVATE_KEY is None else PRIVATE_KEY, - public_key="" if PUBLIC_KEY is None else PUBLIC_KEY, - api_key="" if API_KEY is None else API_KEY, - ) - trading_client = PerpetualTradingClient( - endpoint_config=TESTNET_CONFIG, - stark_account=stark_account, - ) - builder_id = 2001 - builder_fee = ( - (await trading_client.account.get_fees(market_names=["BTC-USD"], builder_id=builder_id)) - .data[0] - .builder_fee_rate - ) - - positions = await trading_client.account.get_positions() - for position in positions.data: - print(f"consumed im: ${round((position.size * position.mark_price) / position.leverage, 2)}") - - await clean_it(trading_client) - - blocking_client = BlockingTradingClient( - endpoint_config=TESTNET_CONFIG, - account=stark_account, - ) - - await blocking_client.create_and_place_order( - amount_of_synthetic=Decimal("0.1"), - price=Decimal("122001"), - market_name="BTC-USD", - side=OrderSide.BUY, - post_only=False, - external_id="0x123", - builder_id=builder_id, - builder_fee=builder_fee, - ) - - -if __name__ == "__main__": - run(main=setup_and_run()) diff --git a/examples/init_env.py b/examples/init_env.py index abf6b8d..2e3f76a 100644 --- a/examples/init_env.py +++ b/examples/init_env.py @@ -15,6 +15,7 @@ class EnvConfig: public_key: str | None = None private_key: str | None = None vault_id: int | None = None + builder_id: int | None = None def init_env(require_private_api: bool = True): @@ -28,6 +29,7 @@ def init_env(require_private_api: bool = True): public_key = os.getenv("X10_PUBLIC_KEY") private_key = os.getenv("X10_PRIVATE_KEY") vault_id = os.getenv("X10_VAULT_ID") + builder_id = os.getenv("X10_BUILDER_ID") if require_private_api: assert api_key, "X10_API_KEY is not set" @@ -43,4 +45,5 @@ def init_env(require_private_api: bool = True): public_key=public_key, private_key=private_key, vault_id=int(vault_id) if vault_id else None, + builder_id=int(builder_id) if builder_id else None, ) diff --git a/pyproject.toml b/pyproject.toml index 1567655..c80b80a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "x10-python-trading-starknet" -version = "0.0.16" +version = "0.0.17" description = "Python client for X10 API" authors = ["X10 "] repository = "https://github.com/x10xchange/python_sdk"