diff options
author | CoprDistGit <infra@openeuler.org> | 2023-05-18 05:43:40 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-05-18 05:43:40 +0000 |
commit | d2dcf0f1014ddc7ff481a0780d4e06f68179c6dc (patch) | |
tree | d1d0b54809540c28787ffb3823640dc0325333a9 | |
parent | 17394b4d1f8d3c954b1a6370fa6010e350e8278e (diff) |
automatic import of python-dydx-python
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-dydx-python.spec | 2127 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 2129 insertions, 0 deletions
@@ -0,0 +1 @@ +/dydx-python-0.11.3.tar.gz diff --git a/python-dydx-python.spec b/python-dydx-python.spec new file mode 100644 index 0000000..0fd7f9a --- /dev/null +++ b/python-dydx-python.spec @@ -0,0 +1,2127 @@ +%global _empty_manifest_terminate_build 0 +Name: python-dydx-python +Version: 0.11.3 +Release: 1 +Summary: dYdX Python REST API for Limit Orders +License: Apache 2.0 +URL: https://github.com/dydxprotocol/dydx-python +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/85/ed/a8a5ca26cb181d7ec89cad6cb21a95483a27db44ce604d9ce7773a7e6b9d/dydx-python-0.11.3.tar.gz +BuildArch: noarch + +Requires: python3-requests +Requires: python3-requests-mock +Requires: python3-six +Requires: python3-web3 +Requires: python3-eth-account +Requires: python3-pytest +Requires: python3-tox +Requires: python3-setuptools +Requires: python3-eth-keys + +%description +<p align="center"><img src="https://s3.amazonaws.com/dydx-assets/dydx_logo_black.svg" width="256" /></p> + +<div align="center"> + <a href="https://circleci.com/gh/dydxprotocol/workflows/dydx-python/tree/master"> + <img src="https://img.shields.io/circleci/project/github/dydxprotocol/dydx-python.svg" alt='CI' /> + </a> + <a href='https://pypi.org/project/dydx-python'> + <img src='https://img.shields.io/pypi/v/dydx-python.svg' alt='PyPi'/> + </a> + <a href='https://github.com/dydxprotocol/dydx-python/blob/master/LICENSE'> + <img src='https://img.shields.io/github/license/dydxprotocol/dydx-python.svg?longCache=true' alt='License' /> + </a> +</div> + +dYdX Python API for Limit Orders + +The library is currently tested against Python versions 2.7, 3.4, 3.5, and 3.6 + +## Installation +`dydx-python` is available on [PyPI](https://pypi.org/project/dydx-python). Install with `pip`: +``` +pip install dydx-python +``` + +## Documentation + +Check the [dYdX developer docs](https://docs.dydx.exchange/#/api?id=orderbook) for the API endpoint. + +## Example Usage + +### Initializing the client + +```python +from dydx.client import Client +import dydx.constants as consts +import dydx.util as utils + +# create a new client with a private key (string or bytearray) +client = Client( + private_key='0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d', + node='https://mainnet.infura.io/v3/00000000000000000000000000000000' +) +``` + +### HTTP API Calls + +#### Trading Pairs + +```python +# Get all trading pairs for dydx +pairs = client.get_pairs() +``` + +#### Account Balances + +```python +# Get my account balances of margin-trading accounts +my_balances = client.get_my_balances() + +# Get my account balances of perpetual accounts +balances = client.get_my_perpetual_balances() +``` + +#### Open Orders + +```python +# Get orders created by my account for both sides of the book +my_orders = client.get_my_orders( + market=['WETH-DAI', 'DAI-WETH'], + limit=None, + startingBefore=None +) + +# Get all orders for both sides of the book +ten_days_ago = datetime.datetime.now() - datetime.timedelta(days=10) +all_orders = client.get_orders( + market=['WETH-DAI', 'DAI-WETH'], + makerAccountOwner=None, # optional + makerAccountNumber=None, # optional + limit=2, # optional + startingBefore=ten_days_ago # optional +) +``` + +#### Historical Fills + +```python +# Get fills created by my account for both sides of the orderbook +my_fills = client.get_my_fills( + market=['WETH-DAI', 'DAI-WETH'], + limit=None, # optional + startingBefore=None # optional +) + +# Get all fills from one side of the book +all_fills = client.get_fills( + market=['WETH-DAI'], # 'DAI-WETH' side of the book is not included + makerAccountOwner='0x5F5A46a8471F60b1E9F2eD0b8fc21Ba8b48887D8', # optional + makerAccountNumber=0, # optional + limit=2, # optional + startingBefore=None # optional +) +''' +fills = { + "fills": [ + { + uuid: "b53ab8c4-465f-4950-add2-dd807c048d68", + createdAt: "2020-03-08T17:42:36.037Z", + transactionHash: "0x39576745c2f030ba04bf4df7bcc64ffaa97421243c53e714bca4161163be9d51", + status: "PENDING", + market: "WETH-DAI", + side: "BUY", + feeAmount: "0", + orderClientId: null, + price: "217.019", + amount: "15000000000000000000", + orderId: "0x8924cdc0d18899d250bfa27d5929967e26e7e676745a28b6ee5b3a8f182ceb9f", + accountOwner: "0x8a9d46d28003673cd4fe7a56ecfcfa2be6372e64", + accountNumber: "63397253610709255086306580859198088914565604507660670583302927962305720029570", + liquidity: "TAKER" + }, + ... + ] +} +''' + +# Get one order by id +order = client.get_order( + orderId, +) +''' +order = { + "order" = { + "uuid": "c95c386a-307d-4fbf-bcac-a7ff965a7207", + "id": "0x812f2e71081daa820d08fa25c76c06332cd39282433679a413c03c5d4591bc35", + "clientId": "d046f4db-12a9-48fb-b413-6916a9f0cfff", + "status": "CANCELED", + "accountOwner": "0x862821badb9c5800654015ba9a2d9d7894c83a7a", + "accountNumber": "0", + "orderType": "LIMIT", + "fillOrKill": false, + "postOnly": false, + "triggerPrice": null, + "market": "WETH-DAI", + "side": "BUY", + "baseAmount": "186056800000000000000", + "quoteAmount": "39808712928000001179648", + "filledAmount": "0", + "price": "213.96", + "cancelReason": "USER_CANCELED", + "createdAt": "2020-03-08T17:35:24.694Z", + "updatedAt": "2020-03-08T17:35:25.474Z", + "expiresAt": "2020-03-08T17:55:29.000Z" + } +} +''' +``` + +#### Historical Trades + +```python +# Get trades created by my account for both sides of the orderbook +my_trades = client.get_my_trades( + market=['WETH-DAI', 'DAI-WETH'], + limit=None, # optional + startingBefore=None # optional +) + +# Get all trades from one side of the book +all_trades = client.get_trades( + market=['WETH-DAI'], # 'DAI-WETH' side of the book is not included + makerAccountOwner='0x5F5A46a8471F60b1E9F2eD0b8fc21Ba8b48887D8', # optional + makerAccountNumber=0, # optional + limit=2, # optional + startingBefore=None # optional +) +''' +trades = { + "trades": [ + { + "uuid": "7b00efba-5002-4562-b777-0122ede33fec", + "createdAt": "2020-03-08T17:32:35.413Z", + "transactionHash": "0xfd6fe9605114a5d44000b51d126751eee1f38866ebd4d4be7eacf89d8bf264d9", + "status": "CONFIRMED", + "market": "WETH-DAI", + "side": "SELL", + "price": "214.90", + "amount": "2447332508052454104", + "makerOrderId": "0x9e5cf0e5091566651ad33c56fb4e24ce96341b561d31180f0d471163709b098d", + "makerAccountOwner": "0x862821badb9c5800654015ba9a2d9d7894c83a7a", + "makerAccountNumber": "0", + "takerOrderId": "0xc1a71851c62fc132ece0060c46a076cb082741ef6b80f894b20c4351b824dfb7", + "takerAccountOwner": "0xd3069c9e486a8b77add55ae3ceb3a4b138fb76c7", + "takerAccountNumber": "48394678789855236190833155557217125360276244141304950018155758748772338730587" + }, + ... + ] +} +''' +``` + +#### Create an Order (Perp) + +```python +# Create order to LONG ETH with an order quantity of 2,500 ETH-USD contracts +# at a price of 250 USD per ETH. +created_order = client.place_order( + market=consts.PAIR_WETH_PUSD, + side=consts.SIDE_SELL, + amount=utils.usd_to_order_amount(25000), + price=Decimal('250e-12'), + fillOrKill=False, + postOnly=False +) + +# Create order to BUY 10 PBTC for 723,400.00 USDC (a price of 7234.00 PBTC/USDC) +created_order = client.place_order( + market=consts.PAIR_PBTC_USDC, + side=consts.SIDE_BUY, + amount=utils.btc_to_sats(10), + price=Decimal('72.34'), + fillOrKill=False, + postOnly=False +) + +# Create order to BUY 100 PLINK for 1,500.00 USDC (a price of 15.00 PLINK/USDC) +created_order = client.place_order( + market=consts.PAIR_PLINK_USDC, + side=consts.SIDE_BUY, + amount=utils.link_to_order_amount(100), + price=Decimal('15.00'), + fillOrKill=False, + postOnly=False +) +``` + +#### Create an Order (Solo) + +```python +# Create order to BUY 10 ETH for 2504.90 DAI (a price of 250.49 DAI/ETH) +created_order = client.place_order( + market=consts.PAIR_WETH_DAI, + side=consts.SIDE_BUY, + amount=utils.token_to_wei(10, consts.MARKET_WETH), + price=Decimal('250.49'), + fillOrKill=False, + postOnly=False +) + +# Create order to SELL 10 ETH for 1500.10 USDC (a price of 150.01 USDC/ETH) +# 'e-12' is in the price since USDC has 6 decimal places (ETH and DAI have 18) +created_order = client.place_order( + market=consts.PAIR_WETH_USDC, + side=consts.SIDE_SELL, + amount=utils.token_to_wei(10, consts.MARKET_WETH), + price=Decimal('150.01e-12'), + fillOrKill=False, + postOnly=False +) +``` + +#### Cancel an Order + +```python +# Cancel the previously created solo order +order_hash = created_order['order']['id'] +canceled_order = client.cancel_order( + hash=order_hash +) + +# Cancel the previously created perpetual order +order_hash = created_order['order']['id'] +canceled_order = client.cancel_perpetual_order( + hash=order_hash +) +``` + +#### Get Orderbook + +```python +orderbook = client.get_orderbook( + market='WETH-DAI' +) +''' +orderbook = { + "bids": [ + { + "id": "0xefa4562c0747a8f2a9aa69abb817474ee9e98c8505a71de6054a610ac744b0cd", + "uuid": "c58be890-6e76-4e98-95d4-27977a91af19", + "amount": "17459277053478281216", + "price": "160.08" + }, + { + "id": "0xa2ab9f653106fefef5b1264a509b02eab021ffea442307e995908e5360f3cd4d", + "uuid": "d2dba4c6-6442-46bc-b097-1f37312cf279", + "amount": "149610989871929360384", + "price": "160.07" + }, + { + "id": "0xec35d60dd1c5eab86cd7881fcbc1239193ceda695df2815d521a46f54bd90580", + "uuid": "24d5a4e1-195b-43fa-a7d8-1d794619e97e", + "amount": "54494000000000000000", + "price": "160.06" + }, + ], + "asks": [ + { + "id": "0xb242e2006a0d99c390fc7256d10558844a719d580e80eaa5a4f99dd14bd9ce5e", + "uuid": "6fdff2f3-0175-4297-bf23-89526eb9aa36", + "amount": "12074182754430260637", + "price": "160.30" + }, + { + "id": "0xe32a00e11b91b6f8daa70fbe03ad0100fa458c0d87e5c59f2e629ce9d5d32921", + "uuid": "3f9b35a8-d843-4ae6-bc8b-b534b07e8093", + "amount": "50000000000000000000", + "price": "160.40" + }, + { + "id": "0xcad0c2e92094bd1dd17a694bd25933a8825c6014aaf4ae2925512f62c15ae968", + "uuid": "5aefdfd2-4e4d-4b37-9c99-35e8eec0ed9a", + "amount": "50000000000000000000", + "price": "160.50" + }, + ] +} +''' +``` + +#### Get Solo Market + +```python +market = client.get_market( + market='WETH-DAI' +) +''' +market = { + "market": { + "WETH-DAI": { + "name": "WETH-DAI", + "baseCurrency": { + "currency": "WETH", + "decimals": 18, + "soloMarketId": 0, + }, + "quoteCurrency": { + "currency": "DAI", + "decimals": 18, + "soloMarketId": 3, + }, + "minimumTickSize": "0.01", + "minimumOrderSize": "100000000000000000", + "smallOrderThreshold": "500000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0015", + }, + } +} +''' +``` + +#### Get Solo Markets + +```python +markets = client.get_markets() +''' +markets = { + "markets": { + "WETH-DAI": { + "name": "WETH-DAI", + "baseCurrency": { + "currency": "WETH", + "decimals": 18, + "soloMarketId": 0, + }, + "quoteCurrency": { + "currency": "DAI", + "decimals": 18, + "soloMarketId": 3, + }, + "minimumTickSize": "0.01", + "minimumOrderSize": "100000000000000000", + "smallOrderThreshold": "500000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0015", + }, + "WETH-USDC": { + "name": "WETH-USDC", + "baseCurrency": { + "currency": "WETH", + "decimals": 18, + "soloMarketId": 0, + }, + "quoteCurrency": { + "currency": "USDC", + "decimals": 6, + "soloMarketId": 2, + }, + "minimumTickSize": "0.00000000000001", + "minimumOrderSize": "100000000000000000", + "smallOrderThreshold": "500000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0015", + }, + "DAI-USDC": { + "name": "DAI-USDC", + "baseCurrency": { + "currency": "DAI", + "decimals": 18, + "soloMarketId": 3, + }, + "quoteCurrency": { + "currency": "USDC", + "decimals": 6, + "soloMarketId": 1, + }, + "minimumTickSize": "0.0000000000000001", + "minimumOrderSize": "20000000000000000000", + "smallOrderThreshold": "100000000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0005", + }, + } +} +''' +``` + +#### Get Perpetual Market + +```python +market = client.get_perpetual_market( + market='PBTC-USDC' +) +''' +market = { + "market": { + "uuid": "f6d20698-32ac-4f3a-a9c4-b6b7528b7b94", + "market": "PBTC-USDC", + "oraclePrice": "68.9615", + "fundingRate": "0", + "minCollateral": "0.1075", + "globalIndexValue": "0", + "globalIndexTimestamp": "1587407069", + "createdAt": "2020-04-09T22:42:35.696Z", + "updatedAt": "2020-04-20T18:48:06.334Z" + } +} +''' +``` + +#### Get Perpetual Markets + +```python +markets = client.get_perpetual_markets() +''' +markets = { + "markets": [ + { + "uuid": "f6d20698-32ac-4f3a-a9c4-b6b7528b7b94", + "market": "PBTC-USDC", + "oraclePrice": "68.9615", + "fundingRate": "0", + "minCollateral": "0.1075", + "globalIndexValue": "0", + "globalIndexTimestamp": "1587407069", + "createdAt": "2020-04-09T22:42:35.696Z", + "updatedAt": "2020-04-20T18:47:06.197Z" + } + ] +} +''' +``` + +### Perpetuals + +#### Deposit / Withdraw + +```python +# deposit 2 ETH into the ETH-USD Perpetual +tx_hash = client.eth.perp.deposit( + market=consts.PAIR_WETH_PUSD, + amount=utils.token_to_wei(2, consts.MARKET_WETH) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 1 ETH from the ETH-USD Perpetual +tx_hash = client.eth.perp.withdraw( + market=consts.PAIR_WETH_PUSD, + amount=utils.token_to_wei(1, consts.MARKET_WETH) +) +receipt = client.eth.get_receipt(tx_hash) +``` + +```python +# deposit 100 USDC into the BTC-USD Perpetual +tx_hash = client.eth.perp.set_allowance(consts.PAIR_PBTC_USDC) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.perp.deposit( + market=consts.PAIR_PBTC_USDC, + amount=utils.token_to_wei(100, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 50 USDC from the BTC-USD Perpetual +tx_hash = client.eth.perp.withdraw( + market=consts.PAIR_PBTC_USDC, + amount=utils.token_to_wei(50, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) +``` + +```python +# deposit 100 USDC into the LINK-USD Perpetual +tx_hash = client.eth.perp.set_allowance(consts.PAIR_PLINK_USDC) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.perp.deposit( + market=consts.PAIR_PLINK_USDC, + amount=utils.token_to_wei(100, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 50 USDC from the LINK-USD Perpetual +tx_hash = client.eth.perp.withdraw( + market=consts.PAIR_PLINK_USDC, + amount=utils.token_to_wei(50, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) +``` + +#### Getters + +```python +# get the USD value of PBTC +# Since PBTC is measured in Satoshis (1e-8 of one BTC) and USDC has 6 decimal places, +# a normal price of $7200 per BTC would return a result of 72. +btc_price = client.eth.perp.get_oracle_price( + market=consts.PAIR_PBTC_USDC +) + +# get the USD value of PLINK +# Since PLINK and USDC both have 6 decimal places, +# a normal price of $15 per LINK would return a result of 15. +btc_price = client.eth.perp.get_oracle_price( + market=consts.PAIR_PLINK_USDC +) + +# get the ETH value of USD +# Since USD is considered to have 6 decimal places, and ETH has 18 decimals places, +# a normal price of $250 per ETH would have a price of 1 / (250e-12). +eth_price = client.eth.perp.get_oracle_price( + market=consts.PAIR_WETH_PUSD +) +``` + +### Solo (ETH trading) + +#### Deposit / Withdraw + +```python +# deposit 10 ETH +# does not require set_allowance +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_WETH, + wei=utils.token_to_wei(10, consts.MARKET_WETH) +) +receipt = client.eth.get_receipt(tx_hash) + + +# deposit 10 WETH ERC20 tokens without using the WETH payable proxy address +# requires set_allowance +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_WETH, + wei=utils.token_to_wei(10, consts.MARKET_WETH), + asEth=False +) +receipt = client.eth.get_receipt(tx_hash) + + +# deposit 100 DAI +tx_hash = client.eth.solo.set_allowance(market=consts.MARKET_DAI) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_DAI, + wei=utils.token_to_wei(100, consts.MARKET_DAI) +) +receipt = client.eth.get_receipt(tx_hash) + + +# deposit 100 USDC +tx_hash = client.eth.solo.set_allowance(market=consts.MARKET_USDC) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_USDC, + wei=utils.token_to_wei(100, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 10 WETH ERC20 tokens without using the WETH payable proxy address +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_WETH, + wei=utils.token_to_wei(10, consts.MARKET_WETH), + asEth=False +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 50 USDC +tx_hash = client.eth.solo.withdraw( + market=consts.MARKET_USDC, + wei=utils.token_to_wei(50, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw all DAI (including interest) +tx_hash = client.eth.solo.withdraw_to_zero(market=consts.MARKET_DAI) +receipt = client.eth.get_receipt(tx_hash) +``` + +#### Getters + +```python +# get the USD value of one atomic unit of DAI +dai_price = client.eth.solo.get_oracle_price(consts.MARKET_DAI) + +# get dYdX balances +balances = client.eth.solo.get_my_balances() +''' +balances = [ + -91971743707894, + 3741715702031854553560, + 2613206278 +] +''' + +# get dYdX account collateralization +collateralization = client.eth.get_my_collateralization() +''' +collateralization = 2.5 or float('inf') +''' + +# collateralization must remain above the minimum to prevent liquidation +assert(collateralization > consts.MINIMUM_COLLATERALIZATION) +''' +consts.MINIMUM_COLLATERALIZATION = 1.15 +''' +``` + +### General Ethereum Getters + +Getting information directly from the blockchain by querying a node + +```python +# get Wallet balances +balance = client.eth.get_my_wallet_balance(consts.MARKET_DAI) +''' +balance = 1000000000000000000 +''' + +## Testing +``` +# Install the requirements +pip install -r requirements.txt + +# Run the tests +docker-compose up +tox +``` + + + + +%package -n python3-dydx-python +Summary: dYdX Python REST API for Limit Orders +Provides: python-dydx-python +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-dydx-python +<p align="center"><img src="https://s3.amazonaws.com/dydx-assets/dydx_logo_black.svg" width="256" /></p> + +<div align="center"> + <a href="https://circleci.com/gh/dydxprotocol/workflows/dydx-python/tree/master"> + <img src="https://img.shields.io/circleci/project/github/dydxprotocol/dydx-python.svg" alt='CI' /> + </a> + <a href='https://pypi.org/project/dydx-python'> + <img src='https://img.shields.io/pypi/v/dydx-python.svg' alt='PyPi'/> + </a> + <a href='https://github.com/dydxprotocol/dydx-python/blob/master/LICENSE'> + <img src='https://img.shields.io/github/license/dydxprotocol/dydx-python.svg?longCache=true' alt='License' /> + </a> +</div> + +dYdX Python API for Limit Orders + +The library is currently tested against Python versions 2.7, 3.4, 3.5, and 3.6 + +## Installation +`dydx-python` is available on [PyPI](https://pypi.org/project/dydx-python). Install with `pip`: +``` +pip install dydx-python +``` + +## Documentation + +Check the [dYdX developer docs](https://docs.dydx.exchange/#/api?id=orderbook) for the API endpoint. + +## Example Usage + +### Initializing the client + +```python +from dydx.client import Client +import dydx.constants as consts +import dydx.util as utils + +# create a new client with a private key (string or bytearray) +client = Client( + private_key='0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d', + node='https://mainnet.infura.io/v3/00000000000000000000000000000000' +) +``` + +### HTTP API Calls + +#### Trading Pairs + +```python +# Get all trading pairs for dydx +pairs = client.get_pairs() +``` + +#### Account Balances + +```python +# Get my account balances of margin-trading accounts +my_balances = client.get_my_balances() + +# Get my account balances of perpetual accounts +balances = client.get_my_perpetual_balances() +``` + +#### Open Orders + +```python +# Get orders created by my account for both sides of the book +my_orders = client.get_my_orders( + market=['WETH-DAI', 'DAI-WETH'], + limit=None, + startingBefore=None +) + +# Get all orders for both sides of the book +ten_days_ago = datetime.datetime.now() - datetime.timedelta(days=10) +all_orders = client.get_orders( + market=['WETH-DAI', 'DAI-WETH'], + makerAccountOwner=None, # optional + makerAccountNumber=None, # optional + limit=2, # optional + startingBefore=ten_days_ago # optional +) +``` + +#### Historical Fills + +```python +# Get fills created by my account for both sides of the orderbook +my_fills = client.get_my_fills( + market=['WETH-DAI', 'DAI-WETH'], + limit=None, # optional + startingBefore=None # optional +) + +# Get all fills from one side of the book +all_fills = client.get_fills( + market=['WETH-DAI'], # 'DAI-WETH' side of the book is not included + makerAccountOwner='0x5F5A46a8471F60b1E9F2eD0b8fc21Ba8b48887D8', # optional + makerAccountNumber=0, # optional + limit=2, # optional + startingBefore=None # optional +) +''' +fills = { + "fills": [ + { + uuid: "b53ab8c4-465f-4950-add2-dd807c048d68", + createdAt: "2020-03-08T17:42:36.037Z", + transactionHash: "0x39576745c2f030ba04bf4df7bcc64ffaa97421243c53e714bca4161163be9d51", + status: "PENDING", + market: "WETH-DAI", + side: "BUY", + feeAmount: "0", + orderClientId: null, + price: "217.019", + amount: "15000000000000000000", + orderId: "0x8924cdc0d18899d250bfa27d5929967e26e7e676745a28b6ee5b3a8f182ceb9f", + accountOwner: "0x8a9d46d28003673cd4fe7a56ecfcfa2be6372e64", + accountNumber: "63397253610709255086306580859198088914565604507660670583302927962305720029570", + liquidity: "TAKER" + }, + ... + ] +} +''' + +# Get one order by id +order = client.get_order( + orderId, +) +''' +order = { + "order" = { + "uuid": "c95c386a-307d-4fbf-bcac-a7ff965a7207", + "id": "0x812f2e71081daa820d08fa25c76c06332cd39282433679a413c03c5d4591bc35", + "clientId": "d046f4db-12a9-48fb-b413-6916a9f0cfff", + "status": "CANCELED", + "accountOwner": "0x862821badb9c5800654015ba9a2d9d7894c83a7a", + "accountNumber": "0", + "orderType": "LIMIT", + "fillOrKill": false, + "postOnly": false, + "triggerPrice": null, + "market": "WETH-DAI", + "side": "BUY", + "baseAmount": "186056800000000000000", + "quoteAmount": "39808712928000001179648", + "filledAmount": "0", + "price": "213.96", + "cancelReason": "USER_CANCELED", + "createdAt": "2020-03-08T17:35:24.694Z", + "updatedAt": "2020-03-08T17:35:25.474Z", + "expiresAt": "2020-03-08T17:55:29.000Z" + } +} +''' +``` + +#### Historical Trades + +```python +# Get trades created by my account for both sides of the orderbook +my_trades = client.get_my_trades( + market=['WETH-DAI', 'DAI-WETH'], + limit=None, # optional + startingBefore=None # optional +) + +# Get all trades from one side of the book +all_trades = client.get_trades( + market=['WETH-DAI'], # 'DAI-WETH' side of the book is not included + makerAccountOwner='0x5F5A46a8471F60b1E9F2eD0b8fc21Ba8b48887D8', # optional + makerAccountNumber=0, # optional + limit=2, # optional + startingBefore=None # optional +) +''' +trades = { + "trades": [ + { + "uuid": "7b00efba-5002-4562-b777-0122ede33fec", + "createdAt": "2020-03-08T17:32:35.413Z", + "transactionHash": "0xfd6fe9605114a5d44000b51d126751eee1f38866ebd4d4be7eacf89d8bf264d9", + "status": "CONFIRMED", + "market": "WETH-DAI", + "side": "SELL", + "price": "214.90", + "amount": "2447332508052454104", + "makerOrderId": "0x9e5cf0e5091566651ad33c56fb4e24ce96341b561d31180f0d471163709b098d", + "makerAccountOwner": "0x862821badb9c5800654015ba9a2d9d7894c83a7a", + "makerAccountNumber": "0", + "takerOrderId": "0xc1a71851c62fc132ece0060c46a076cb082741ef6b80f894b20c4351b824dfb7", + "takerAccountOwner": "0xd3069c9e486a8b77add55ae3ceb3a4b138fb76c7", + "takerAccountNumber": "48394678789855236190833155557217125360276244141304950018155758748772338730587" + }, + ... + ] +} +''' +``` + +#### Create an Order (Perp) + +```python +# Create order to LONG ETH with an order quantity of 2,500 ETH-USD contracts +# at a price of 250 USD per ETH. +created_order = client.place_order( + market=consts.PAIR_WETH_PUSD, + side=consts.SIDE_SELL, + amount=utils.usd_to_order_amount(25000), + price=Decimal('250e-12'), + fillOrKill=False, + postOnly=False +) + +# Create order to BUY 10 PBTC for 723,400.00 USDC (a price of 7234.00 PBTC/USDC) +created_order = client.place_order( + market=consts.PAIR_PBTC_USDC, + side=consts.SIDE_BUY, + amount=utils.btc_to_sats(10), + price=Decimal('72.34'), + fillOrKill=False, + postOnly=False +) + +# Create order to BUY 100 PLINK for 1,500.00 USDC (a price of 15.00 PLINK/USDC) +created_order = client.place_order( + market=consts.PAIR_PLINK_USDC, + side=consts.SIDE_BUY, + amount=utils.link_to_order_amount(100), + price=Decimal('15.00'), + fillOrKill=False, + postOnly=False +) +``` + +#### Create an Order (Solo) + +```python +# Create order to BUY 10 ETH for 2504.90 DAI (a price of 250.49 DAI/ETH) +created_order = client.place_order( + market=consts.PAIR_WETH_DAI, + side=consts.SIDE_BUY, + amount=utils.token_to_wei(10, consts.MARKET_WETH), + price=Decimal('250.49'), + fillOrKill=False, + postOnly=False +) + +# Create order to SELL 10 ETH for 1500.10 USDC (a price of 150.01 USDC/ETH) +# 'e-12' is in the price since USDC has 6 decimal places (ETH and DAI have 18) +created_order = client.place_order( + market=consts.PAIR_WETH_USDC, + side=consts.SIDE_SELL, + amount=utils.token_to_wei(10, consts.MARKET_WETH), + price=Decimal('150.01e-12'), + fillOrKill=False, + postOnly=False +) +``` + +#### Cancel an Order + +```python +# Cancel the previously created solo order +order_hash = created_order['order']['id'] +canceled_order = client.cancel_order( + hash=order_hash +) + +# Cancel the previously created perpetual order +order_hash = created_order['order']['id'] +canceled_order = client.cancel_perpetual_order( + hash=order_hash +) +``` + +#### Get Orderbook + +```python +orderbook = client.get_orderbook( + market='WETH-DAI' +) +''' +orderbook = { + "bids": [ + { + "id": "0xefa4562c0747a8f2a9aa69abb817474ee9e98c8505a71de6054a610ac744b0cd", + "uuid": "c58be890-6e76-4e98-95d4-27977a91af19", + "amount": "17459277053478281216", + "price": "160.08" + }, + { + "id": "0xa2ab9f653106fefef5b1264a509b02eab021ffea442307e995908e5360f3cd4d", + "uuid": "d2dba4c6-6442-46bc-b097-1f37312cf279", + "amount": "149610989871929360384", + "price": "160.07" + }, + { + "id": "0xec35d60dd1c5eab86cd7881fcbc1239193ceda695df2815d521a46f54bd90580", + "uuid": "24d5a4e1-195b-43fa-a7d8-1d794619e97e", + "amount": "54494000000000000000", + "price": "160.06" + }, + ], + "asks": [ + { + "id": "0xb242e2006a0d99c390fc7256d10558844a719d580e80eaa5a4f99dd14bd9ce5e", + "uuid": "6fdff2f3-0175-4297-bf23-89526eb9aa36", + "amount": "12074182754430260637", + "price": "160.30" + }, + { + "id": "0xe32a00e11b91b6f8daa70fbe03ad0100fa458c0d87e5c59f2e629ce9d5d32921", + "uuid": "3f9b35a8-d843-4ae6-bc8b-b534b07e8093", + "amount": "50000000000000000000", + "price": "160.40" + }, + { + "id": "0xcad0c2e92094bd1dd17a694bd25933a8825c6014aaf4ae2925512f62c15ae968", + "uuid": "5aefdfd2-4e4d-4b37-9c99-35e8eec0ed9a", + "amount": "50000000000000000000", + "price": "160.50" + }, + ] +} +''' +``` + +#### Get Solo Market + +```python +market = client.get_market( + market='WETH-DAI' +) +''' +market = { + "market": { + "WETH-DAI": { + "name": "WETH-DAI", + "baseCurrency": { + "currency": "WETH", + "decimals": 18, + "soloMarketId": 0, + }, + "quoteCurrency": { + "currency": "DAI", + "decimals": 18, + "soloMarketId": 3, + }, + "minimumTickSize": "0.01", + "minimumOrderSize": "100000000000000000", + "smallOrderThreshold": "500000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0015", + }, + } +} +''' +``` + +#### Get Solo Markets + +```python +markets = client.get_markets() +''' +markets = { + "markets": { + "WETH-DAI": { + "name": "WETH-DAI", + "baseCurrency": { + "currency": "WETH", + "decimals": 18, + "soloMarketId": 0, + }, + "quoteCurrency": { + "currency": "DAI", + "decimals": 18, + "soloMarketId": 3, + }, + "minimumTickSize": "0.01", + "minimumOrderSize": "100000000000000000", + "smallOrderThreshold": "500000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0015", + }, + "WETH-USDC": { + "name": "WETH-USDC", + "baseCurrency": { + "currency": "WETH", + "decimals": 18, + "soloMarketId": 0, + }, + "quoteCurrency": { + "currency": "USDC", + "decimals": 6, + "soloMarketId": 2, + }, + "minimumTickSize": "0.00000000000001", + "minimumOrderSize": "100000000000000000", + "smallOrderThreshold": "500000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0015", + }, + "DAI-USDC": { + "name": "DAI-USDC", + "baseCurrency": { + "currency": "DAI", + "decimals": 18, + "soloMarketId": 3, + }, + "quoteCurrency": { + "currency": "USDC", + "decimals": 6, + "soloMarketId": 1, + }, + "minimumTickSize": "0.0000000000000001", + "minimumOrderSize": "20000000000000000000", + "smallOrderThreshold": "100000000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0005", + }, + } +} +''' +``` + +#### Get Perpetual Market + +```python +market = client.get_perpetual_market( + market='PBTC-USDC' +) +''' +market = { + "market": { + "uuid": "f6d20698-32ac-4f3a-a9c4-b6b7528b7b94", + "market": "PBTC-USDC", + "oraclePrice": "68.9615", + "fundingRate": "0", + "minCollateral": "0.1075", + "globalIndexValue": "0", + "globalIndexTimestamp": "1587407069", + "createdAt": "2020-04-09T22:42:35.696Z", + "updatedAt": "2020-04-20T18:48:06.334Z" + } +} +''' +``` + +#### Get Perpetual Markets + +```python +markets = client.get_perpetual_markets() +''' +markets = { + "markets": [ + { + "uuid": "f6d20698-32ac-4f3a-a9c4-b6b7528b7b94", + "market": "PBTC-USDC", + "oraclePrice": "68.9615", + "fundingRate": "0", + "minCollateral": "0.1075", + "globalIndexValue": "0", + "globalIndexTimestamp": "1587407069", + "createdAt": "2020-04-09T22:42:35.696Z", + "updatedAt": "2020-04-20T18:47:06.197Z" + } + ] +} +''' +``` + +### Perpetuals + +#### Deposit / Withdraw + +```python +# deposit 2 ETH into the ETH-USD Perpetual +tx_hash = client.eth.perp.deposit( + market=consts.PAIR_WETH_PUSD, + amount=utils.token_to_wei(2, consts.MARKET_WETH) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 1 ETH from the ETH-USD Perpetual +tx_hash = client.eth.perp.withdraw( + market=consts.PAIR_WETH_PUSD, + amount=utils.token_to_wei(1, consts.MARKET_WETH) +) +receipt = client.eth.get_receipt(tx_hash) +``` + +```python +# deposit 100 USDC into the BTC-USD Perpetual +tx_hash = client.eth.perp.set_allowance(consts.PAIR_PBTC_USDC) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.perp.deposit( + market=consts.PAIR_PBTC_USDC, + amount=utils.token_to_wei(100, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 50 USDC from the BTC-USD Perpetual +tx_hash = client.eth.perp.withdraw( + market=consts.PAIR_PBTC_USDC, + amount=utils.token_to_wei(50, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) +``` + +```python +# deposit 100 USDC into the LINK-USD Perpetual +tx_hash = client.eth.perp.set_allowance(consts.PAIR_PLINK_USDC) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.perp.deposit( + market=consts.PAIR_PLINK_USDC, + amount=utils.token_to_wei(100, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 50 USDC from the LINK-USD Perpetual +tx_hash = client.eth.perp.withdraw( + market=consts.PAIR_PLINK_USDC, + amount=utils.token_to_wei(50, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) +``` + +#### Getters + +```python +# get the USD value of PBTC +# Since PBTC is measured in Satoshis (1e-8 of one BTC) and USDC has 6 decimal places, +# a normal price of $7200 per BTC would return a result of 72. +btc_price = client.eth.perp.get_oracle_price( + market=consts.PAIR_PBTC_USDC +) + +# get the USD value of PLINK +# Since PLINK and USDC both have 6 decimal places, +# a normal price of $15 per LINK would return a result of 15. +btc_price = client.eth.perp.get_oracle_price( + market=consts.PAIR_PLINK_USDC +) + +# get the ETH value of USD +# Since USD is considered to have 6 decimal places, and ETH has 18 decimals places, +# a normal price of $250 per ETH would have a price of 1 / (250e-12). +eth_price = client.eth.perp.get_oracle_price( + market=consts.PAIR_WETH_PUSD +) +``` + +### Solo (ETH trading) + +#### Deposit / Withdraw + +```python +# deposit 10 ETH +# does not require set_allowance +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_WETH, + wei=utils.token_to_wei(10, consts.MARKET_WETH) +) +receipt = client.eth.get_receipt(tx_hash) + + +# deposit 10 WETH ERC20 tokens without using the WETH payable proxy address +# requires set_allowance +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_WETH, + wei=utils.token_to_wei(10, consts.MARKET_WETH), + asEth=False +) +receipt = client.eth.get_receipt(tx_hash) + + +# deposit 100 DAI +tx_hash = client.eth.solo.set_allowance(market=consts.MARKET_DAI) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_DAI, + wei=utils.token_to_wei(100, consts.MARKET_DAI) +) +receipt = client.eth.get_receipt(tx_hash) + + +# deposit 100 USDC +tx_hash = client.eth.solo.set_allowance(market=consts.MARKET_USDC) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_USDC, + wei=utils.token_to_wei(100, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 10 WETH ERC20 tokens without using the WETH payable proxy address +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_WETH, + wei=utils.token_to_wei(10, consts.MARKET_WETH), + asEth=False +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 50 USDC +tx_hash = client.eth.solo.withdraw( + market=consts.MARKET_USDC, + wei=utils.token_to_wei(50, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw all DAI (including interest) +tx_hash = client.eth.solo.withdraw_to_zero(market=consts.MARKET_DAI) +receipt = client.eth.get_receipt(tx_hash) +``` + +#### Getters + +```python +# get the USD value of one atomic unit of DAI +dai_price = client.eth.solo.get_oracle_price(consts.MARKET_DAI) + +# get dYdX balances +balances = client.eth.solo.get_my_balances() +''' +balances = [ + -91971743707894, + 3741715702031854553560, + 2613206278 +] +''' + +# get dYdX account collateralization +collateralization = client.eth.get_my_collateralization() +''' +collateralization = 2.5 or float('inf') +''' + +# collateralization must remain above the minimum to prevent liquidation +assert(collateralization > consts.MINIMUM_COLLATERALIZATION) +''' +consts.MINIMUM_COLLATERALIZATION = 1.15 +''' +``` + +### General Ethereum Getters + +Getting information directly from the blockchain by querying a node + +```python +# get Wallet balances +balance = client.eth.get_my_wallet_balance(consts.MARKET_DAI) +''' +balance = 1000000000000000000 +''' + +## Testing +``` +# Install the requirements +pip install -r requirements.txt + +# Run the tests +docker-compose up +tox +``` + + + + +%package help +Summary: Development documents and examples for dydx-python +Provides: python3-dydx-python-doc +%description help +<p align="center"><img src="https://s3.amazonaws.com/dydx-assets/dydx_logo_black.svg" width="256" /></p> + +<div align="center"> + <a href="https://circleci.com/gh/dydxprotocol/workflows/dydx-python/tree/master"> + <img src="https://img.shields.io/circleci/project/github/dydxprotocol/dydx-python.svg" alt='CI' /> + </a> + <a href='https://pypi.org/project/dydx-python'> + <img src='https://img.shields.io/pypi/v/dydx-python.svg' alt='PyPi'/> + </a> + <a href='https://github.com/dydxprotocol/dydx-python/blob/master/LICENSE'> + <img src='https://img.shields.io/github/license/dydxprotocol/dydx-python.svg?longCache=true' alt='License' /> + </a> +</div> + +dYdX Python API for Limit Orders + +The library is currently tested against Python versions 2.7, 3.4, 3.5, and 3.6 + +## Installation +`dydx-python` is available on [PyPI](https://pypi.org/project/dydx-python). Install with `pip`: +``` +pip install dydx-python +``` + +## Documentation + +Check the [dYdX developer docs](https://docs.dydx.exchange/#/api?id=orderbook) for the API endpoint. + +## Example Usage + +### Initializing the client + +```python +from dydx.client import Client +import dydx.constants as consts +import dydx.util as utils + +# create a new client with a private key (string or bytearray) +client = Client( + private_key='0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d', + node='https://mainnet.infura.io/v3/00000000000000000000000000000000' +) +``` + +### HTTP API Calls + +#### Trading Pairs + +```python +# Get all trading pairs for dydx +pairs = client.get_pairs() +``` + +#### Account Balances + +```python +# Get my account balances of margin-trading accounts +my_balances = client.get_my_balances() + +# Get my account balances of perpetual accounts +balances = client.get_my_perpetual_balances() +``` + +#### Open Orders + +```python +# Get orders created by my account for both sides of the book +my_orders = client.get_my_orders( + market=['WETH-DAI', 'DAI-WETH'], + limit=None, + startingBefore=None +) + +# Get all orders for both sides of the book +ten_days_ago = datetime.datetime.now() - datetime.timedelta(days=10) +all_orders = client.get_orders( + market=['WETH-DAI', 'DAI-WETH'], + makerAccountOwner=None, # optional + makerAccountNumber=None, # optional + limit=2, # optional + startingBefore=ten_days_ago # optional +) +``` + +#### Historical Fills + +```python +# Get fills created by my account for both sides of the orderbook +my_fills = client.get_my_fills( + market=['WETH-DAI', 'DAI-WETH'], + limit=None, # optional + startingBefore=None # optional +) + +# Get all fills from one side of the book +all_fills = client.get_fills( + market=['WETH-DAI'], # 'DAI-WETH' side of the book is not included + makerAccountOwner='0x5F5A46a8471F60b1E9F2eD0b8fc21Ba8b48887D8', # optional + makerAccountNumber=0, # optional + limit=2, # optional + startingBefore=None # optional +) +''' +fills = { + "fills": [ + { + uuid: "b53ab8c4-465f-4950-add2-dd807c048d68", + createdAt: "2020-03-08T17:42:36.037Z", + transactionHash: "0x39576745c2f030ba04bf4df7bcc64ffaa97421243c53e714bca4161163be9d51", + status: "PENDING", + market: "WETH-DAI", + side: "BUY", + feeAmount: "0", + orderClientId: null, + price: "217.019", + amount: "15000000000000000000", + orderId: "0x8924cdc0d18899d250bfa27d5929967e26e7e676745a28b6ee5b3a8f182ceb9f", + accountOwner: "0x8a9d46d28003673cd4fe7a56ecfcfa2be6372e64", + accountNumber: "63397253610709255086306580859198088914565604507660670583302927962305720029570", + liquidity: "TAKER" + }, + ... + ] +} +''' + +# Get one order by id +order = client.get_order( + orderId, +) +''' +order = { + "order" = { + "uuid": "c95c386a-307d-4fbf-bcac-a7ff965a7207", + "id": "0x812f2e71081daa820d08fa25c76c06332cd39282433679a413c03c5d4591bc35", + "clientId": "d046f4db-12a9-48fb-b413-6916a9f0cfff", + "status": "CANCELED", + "accountOwner": "0x862821badb9c5800654015ba9a2d9d7894c83a7a", + "accountNumber": "0", + "orderType": "LIMIT", + "fillOrKill": false, + "postOnly": false, + "triggerPrice": null, + "market": "WETH-DAI", + "side": "BUY", + "baseAmount": "186056800000000000000", + "quoteAmount": "39808712928000001179648", + "filledAmount": "0", + "price": "213.96", + "cancelReason": "USER_CANCELED", + "createdAt": "2020-03-08T17:35:24.694Z", + "updatedAt": "2020-03-08T17:35:25.474Z", + "expiresAt": "2020-03-08T17:55:29.000Z" + } +} +''' +``` + +#### Historical Trades + +```python +# Get trades created by my account for both sides of the orderbook +my_trades = client.get_my_trades( + market=['WETH-DAI', 'DAI-WETH'], + limit=None, # optional + startingBefore=None # optional +) + +# Get all trades from one side of the book +all_trades = client.get_trades( + market=['WETH-DAI'], # 'DAI-WETH' side of the book is not included + makerAccountOwner='0x5F5A46a8471F60b1E9F2eD0b8fc21Ba8b48887D8', # optional + makerAccountNumber=0, # optional + limit=2, # optional + startingBefore=None # optional +) +''' +trades = { + "trades": [ + { + "uuid": "7b00efba-5002-4562-b777-0122ede33fec", + "createdAt": "2020-03-08T17:32:35.413Z", + "transactionHash": "0xfd6fe9605114a5d44000b51d126751eee1f38866ebd4d4be7eacf89d8bf264d9", + "status": "CONFIRMED", + "market": "WETH-DAI", + "side": "SELL", + "price": "214.90", + "amount": "2447332508052454104", + "makerOrderId": "0x9e5cf0e5091566651ad33c56fb4e24ce96341b561d31180f0d471163709b098d", + "makerAccountOwner": "0x862821badb9c5800654015ba9a2d9d7894c83a7a", + "makerAccountNumber": "0", + "takerOrderId": "0xc1a71851c62fc132ece0060c46a076cb082741ef6b80f894b20c4351b824dfb7", + "takerAccountOwner": "0xd3069c9e486a8b77add55ae3ceb3a4b138fb76c7", + "takerAccountNumber": "48394678789855236190833155557217125360276244141304950018155758748772338730587" + }, + ... + ] +} +''' +``` + +#### Create an Order (Perp) + +```python +# Create order to LONG ETH with an order quantity of 2,500 ETH-USD contracts +# at a price of 250 USD per ETH. +created_order = client.place_order( + market=consts.PAIR_WETH_PUSD, + side=consts.SIDE_SELL, + amount=utils.usd_to_order_amount(25000), + price=Decimal('250e-12'), + fillOrKill=False, + postOnly=False +) + +# Create order to BUY 10 PBTC for 723,400.00 USDC (a price of 7234.00 PBTC/USDC) +created_order = client.place_order( + market=consts.PAIR_PBTC_USDC, + side=consts.SIDE_BUY, + amount=utils.btc_to_sats(10), + price=Decimal('72.34'), + fillOrKill=False, + postOnly=False +) + +# Create order to BUY 100 PLINK for 1,500.00 USDC (a price of 15.00 PLINK/USDC) +created_order = client.place_order( + market=consts.PAIR_PLINK_USDC, + side=consts.SIDE_BUY, + amount=utils.link_to_order_amount(100), + price=Decimal('15.00'), + fillOrKill=False, + postOnly=False +) +``` + +#### Create an Order (Solo) + +```python +# Create order to BUY 10 ETH for 2504.90 DAI (a price of 250.49 DAI/ETH) +created_order = client.place_order( + market=consts.PAIR_WETH_DAI, + side=consts.SIDE_BUY, + amount=utils.token_to_wei(10, consts.MARKET_WETH), + price=Decimal('250.49'), + fillOrKill=False, + postOnly=False +) + +# Create order to SELL 10 ETH for 1500.10 USDC (a price of 150.01 USDC/ETH) +# 'e-12' is in the price since USDC has 6 decimal places (ETH and DAI have 18) +created_order = client.place_order( + market=consts.PAIR_WETH_USDC, + side=consts.SIDE_SELL, + amount=utils.token_to_wei(10, consts.MARKET_WETH), + price=Decimal('150.01e-12'), + fillOrKill=False, + postOnly=False +) +``` + +#### Cancel an Order + +```python +# Cancel the previously created solo order +order_hash = created_order['order']['id'] +canceled_order = client.cancel_order( + hash=order_hash +) + +# Cancel the previously created perpetual order +order_hash = created_order['order']['id'] +canceled_order = client.cancel_perpetual_order( + hash=order_hash +) +``` + +#### Get Orderbook + +```python +orderbook = client.get_orderbook( + market='WETH-DAI' +) +''' +orderbook = { + "bids": [ + { + "id": "0xefa4562c0747a8f2a9aa69abb817474ee9e98c8505a71de6054a610ac744b0cd", + "uuid": "c58be890-6e76-4e98-95d4-27977a91af19", + "amount": "17459277053478281216", + "price": "160.08" + }, + { + "id": "0xa2ab9f653106fefef5b1264a509b02eab021ffea442307e995908e5360f3cd4d", + "uuid": "d2dba4c6-6442-46bc-b097-1f37312cf279", + "amount": "149610989871929360384", + "price": "160.07" + }, + { + "id": "0xec35d60dd1c5eab86cd7881fcbc1239193ceda695df2815d521a46f54bd90580", + "uuid": "24d5a4e1-195b-43fa-a7d8-1d794619e97e", + "amount": "54494000000000000000", + "price": "160.06" + }, + ], + "asks": [ + { + "id": "0xb242e2006a0d99c390fc7256d10558844a719d580e80eaa5a4f99dd14bd9ce5e", + "uuid": "6fdff2f3-0175-4297-bf23-89526eb9aa36", + "amount": "12074182754430260637", + "price": "160.30" + }, + { + "id": "0xe32a00e11b91b6f8daa70fbe03ad0100fa458c0d87e5c59f2e629ce9d5d32921", + "uuid": "3f9b35a8-d843-4ae6-bc8b-b534b07e8093", + "amount": "50000000000000000000", + "price": "160.40" + }, + { + "id": "0xcad0c2e92094bd1dd17a694bd25933a8825c6014aaf4ae2925512f62c15ae968", + "uuid": "5aefdfd2-4e4d-4b37-9c99-35e8eec0ed9a", + "amount": "50000000000000000000", + "price": "160.50" + }, + ] +} +''' +``` + +#### Get Solo Market + +```python +market = client.get_market( + market='WETH-DAI' +) +''' +market = { + "market": { + "WETH-DAI": { + "name": "WETH-DAI", + "baseCurrency": { + "currency": "WETH", + "decimals": 18, + "soloMarketId": 0, + }, + "quoteCurrency": { + "currency": "DAI", + "decimals": 18, + "soloMarketId": 3, + }, + "minimumTickSize": "0.01", + "minimumOrderSize": "100000000000000000", + "smallOrderThreshold": "500000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0015", + }, + } +} +''' +``` + +#### Get Solo Markets + +```python +markets = client.get_markets() +''' +markets = { + "markets": { + "WETH-DAI": { + "name": "WETH-DAI", + "baseCurrency": { + "currency": "WETH", + "decimals": 18, + "soloMarketId": 0, + }, + "quoteCurrency": { + "currency": "DAI", + "decimals": 18, + "soloMarketId": 3, + }, + "minimumTickSize": "0.01", + "minimumOrderSize": "100000000000000000", + "smallOrderThreshold": "500000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0015", + }, + "WETH-USDC": { + "name": "WETH-USDC", + "baseCurrency": { + "currency": "WETH", + "decimals": 18, + "soloMarketId": 0, + }, + "quoteCurrency": { + "currency": "USDC", + "decimals": 6, + "soloMarketId": 2, + }, + "minimumTickSize": "0.00000000000001", + "minimumOrderSize": "100000000000000000", + "smallOrderThreshold": "500000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0015", + }, + "DAI-USDC": { + "name": "DAI-USDC", + "baseCurrency": { + "currency": "DAI", + "decimals": 18, + "soloMarketId": 3, + }, + "quoteCurrency": { + "currency": "USDC", + "decimals": 6, + "soloMarketId": 1, + }, + "minimumTickSize": "0.0000000000000001", + "minimumOrderSize": "20000000000000000000", + "smallOrderThreshold": "100000000000000000000", + "makerFee": "0", + "largeTakerFee": "0.005", + "smallTakerFee": "0.0005", + }, + } +} +''' +``` + +#### Get Perpetual Market + +```python +market = client.get_perpetual_market( + market='PBTC-USDC' +) +''' +market = { + "market": { + "uuid": "f6d20698-32ac-4f3a-a9c4-b6b7528b7b94", + "market": "PBTC-USDC", + "oraclePrice": "68.9615", + "fundingRate": "0", + "minCollateral": "0.1075", + "globalIndexValue": "0", + "globalIndexTimestamp": "1587407069", + "createdAt": "2020-04-09T22:42:35.696Z", + "updatedAt": "2020-04-20T18:48:06.334Z" + } +} +''' +``` + +#### Get Perpetual Markets + +```python +markets = client.get_perpetual_markets() +''' +markets = { + "markets": [ + { + "uuid": "f6d20698-32ac-4f3a-a9c4-b6b7528b7b94", + "market": "PBTC-USDC", + "oraclePrice": "68.9615", + "fundingRate": "0", + "minCollateral": "0.1075", + "globalIndexValue": "0", + "globalIndexTimestamp": "1587407069", + "createdAt": "2020-04-09T22:42:35.696Z", + "updatedAt": "2020-04-20T18:47:06.197Z" + } + ] +} +''' +``` + +### Perpetuals + +#### Deposit / Withdraw + +```python +# deposit 2 ETH into the ETH-USD Perpetual +tx_hash = client.eth.perp.deposit( + market=consts.PAIR_WETH_PUSD, + amount=utils.token_to_wei(2, consts.MARKET_WETH) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 1 ETH from the ETH-USD Perpetual +tx_hash = client.eth.perp.withdraw( + market=consts.PAIR_WETH_PUSD, + amount=utils.token_to_wei(1, consts.MARKET_WETH) +) +receipt = client.eth.get_receipt(tx_hash) +``` + +```python +# deposit 100 USDC into the BTC-USD Perpetual +tx_hash = client.eth.perp.set_allowance(consts.PAIR_PBTC_USDC) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.perp.deposit( + market=consts.PAIR_PBTC_USDC, + amount=utils.token_to_wei(100, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 50 USDC from the BTC-USD Perpetual +tx_hash = client.eth.perp.withdraw( + market=consts.PAIR_PBTC_USDC, + amount=utils.token_to_wei(50, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) +``` + +```python +# deposit 100 USDC into the LINK-USD Perpetual +tx_hash = client.eth.perp.set_allowance(consts.PAIR_PLINK_USDC) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.perp.deposit( + market=consts.PAIR_PLINK_USDC, + amount=utils.token_to_wei(100, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 50 USDC from the LINK-USD Perpetual +tx_hash = client.eth.perp.withdraw( + market=consts.PAIR_PLINK_USDC, + amount=utils.token_to_wei(50, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) +``` + +#### Getters + +```python +# get the USD value of PBTC +# Since PBTC is measured in Satoshis (1e-8 of one BTC) and USDC has 6 decimal places, +# a normal price of $7200 per BTC would return a result of 72. +btc_price = client.eth.perp.get_oracle_price( + market=consts.PAIR_PBTC_USDC +) + +# get the USD value of PLINK +# Since PLINK and USDC both have 6 decimal places, +# a normal price of $15 per LINK would return a result of 15. +btc_price = client.eth.perp.get_oracle_price( + market=consts.PAIR_PLINK_USDC +) + +# get the ETH value of USD +# Since USD is considered to have 6 decimal places, and ETH has 18 decimals places, +# a normal price of $250 per ETH would have a price of 1 / (250e-12). +eth_price = client.eth.perp.get_oracle_price( + market=consts.PAIR_WETH_PUSD +) +``` + +### Solo (ETH trading) + +#### Deposit / Withdraw + +```python +# deposit 10 ETH +# does not require set_allowance +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_WETH, + wei=utils.token_to_wei(10, consts.MARKET_WETH) +) +receipt = client.eth.get_receipt(tx_hash) + + +# deposit 10 WETH ERC20 tokens without using the WETH payable proxy address +# requires set_allowance +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_WETH, + wei=utils.token_to_wei(10, consts.MARKET_WETH), + asEth=False +) +receipt = client.eth.get_receipt(tx_hash) + + +# deposit 100 DAI +tx_hash = client.eth.solo.set_allowance(market=consts.MARKET_DAI) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_DAI, + wei=utils.token_to_wei(100, consts.MARKET_DAI) +) +receipt = client.eth.get_receipt(tx_hash) + + +# deposit 100 USDC +tx_hash = client.eth.solo.set_allowance(market=consts.MARKET_USDC) # must only be called once, ever +receipt = client.eth.get_receipt(tx_hash) + +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_USDC, + wei=utils.token_to_wei(100, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 10 WETH ERC20 tokens without using the WETH payable proxy address +tx_hash = client.eth.solo.deposit( + market=consts.MARKET_WETH, + wei=utils.token_to_wei(10, consts.MARKET_WETH), + asEth=False +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw 50 USDC +tx_hash = client.eth.solo.withdraw( + market=consts.MARKET_USDC, + wei=utils.token_to_wei(50, consts.MARKET_USDC) +) +receipt = client.eth.get_receipt(tx_hash) + + +# withdraw all DAI (including interest) +tx_hash = client.eth.solo.withdraw_to_zero(market=consts.MARKET_DAI) +receipt = client.eth.get_receipt(tx_hash) +``` + +#### Getters + +```python +# get the USD value of one atomic unit of DAI +dai_price = client.eth.solo.get_oracle_price(consts.MARKET_DAI) + +# get dYdX balances +balances = client.eth.solo.get_my_balances() +''' +balances = [ + -91971743707894, + 3741715702031854553560, + 2613206278 +] +''' + +# get dYdX account collateralization +collateralization = client.eth.get_my_collateralization() +''' +collateralization = 2.5 or float('inf') +''' + +# collateralization must remain above the minimum to prevent liquidation +assert(collateralization > consts.MINIMUM_COLLATERALIZATION) +''' +consts.MINIMUM_COLLATERALIZATION = 1.15 +''' +``` + +### General Ethereum Getters + +Getting information directly from the blockchain by querying a node + +```python +# get Wallet balances +balance = client.eth.get_my_wallet_balance(consts.MARKET_DAI) +''' +balance = 1000000000000000000 +''' + +## Testing +``` +# Install the requirements +pip install -r requirements.txt + +# Run the tests +docker-compose up +tox +``` + + + + +%prep +%autosetup -n dydx-python-0.11.3 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-dydx-python -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Thu May 18 2023 Python_Bot <Python_Bot@openeuler.org> - 0.11.3-1 +- Package Spec generated @@ -0,0 +1 @@ +76477a5fbc6ce4ef8e8000f87c82cd9d dydx-python-0.11.3.tar.gz |