From 5206fcd1bc81494d4034d69142f88540af9dc289 Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Tue, 23 Apr 2024 03:35:22 +1000 Subject: [PATCH 1/9] docs: make it more clear that a MNEMONIC is required to run the script --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ab18c7b..88a1ef9 100644 --- a/README.md +++ b/README.md @@ -12,18 +12,24 @@ locally this should be a single dockerized neutron node - `make build-neutron` To run the default setup of a single neutron-node chain and a single trading bot: -- `make start-trade-bot` +- `make start-trade-bot MNEMONIC=...` +- at least a single mnenomic must be specified from the mnenomics listed in the options section below + - `MNEMONIC` + - `MNEMONICS` + - `BOT_MNEMONIC` + - `BOT_MNEMONICS` + - `FAUCET_MNEMONIC` This composed neutron chain and trading bot network will persist until you call: - `make stop-trade-bot` ### Test runs (start+stop) You can test a chain and bot(s) configuration and exit with cleanup in one step using: -- `make test-trade-bot` +- `make test-trade-bot MNEMONIC=...` However the default settings are quite conservative, and won't product many txs. A larger test which should generate approximately ~1000-2000 txs in ~6 minutes with 30 bots could be done with: -- `make test-trade-bot BOTS=30 BOT_RAMPING_DELAY=5 TRADE_FREQUENCY_SECONDS=0 TRADE_DURATION_SECONDS=180` +- `make test-trade-bot BOTS=30 BOT_RAMPING_DELAY=5 TRADE_FREQUENCY_SECONDS=0 TRADE_DURATION_SECONDS=180 MNEMONIC=...` This can be ideal for CI type testing of a service that depends on Dex transactions on a Neutron chain. But if you want the chain to persist after the trades are completed (with a finite `TRADE_DURATION_SECONDS`), From 02262a45c495cf07432b77e6e93570b9db4bed5f Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Tue, 23 Apr 2024 03:48:37 +1000 Subject: [PATCH 2/9] docs: explain the local demo mnemonics source twice --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 88a1ef9..5873806 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ To run the default setup of a single neutron-node chain and a single trading bot - `BOT_MNEMONIC` - `BOT_MNEMONICS` - `FAUCET_MNEMONIC` + - if running a local chain you can use DEMO_MNEMONICs from the neutron repo [networks/init.sh](https://github.com/neutron-org/neutron/blob/v3.0.0/network/init.sh#L19-L21) file This composed neutron chain and trading bot network will persist until you call: - `make stop-trade-bot` @@ -55,11 +56,6 @@ All docker-compose env vars are able to be set in both `make start-trade-bot` an - `GAS_PRICES`: calculate how many fees to pay from this fraction of gas - `TOKEN_CONFIG`: a token pairs configuration (JSON) object for eg. token amounts to trade - see [helpers.sh](https://github.com/neutron-org/dex-trading-bot/blob/131a5f1590483840305cb475f8a867996509333e/scripts/helpers.sh#L41-L63) for more setting details - - mnemonics: - - `FAUCET_MNEMONIC` (optional): the mnemonic of the account that will fund generated bots - - `BOT_MNEMONIC/S` or `MNEMONIC/S` (optional): the mnemonics for self-funded bot account(s) - - at least one of `FAUCET_MNEMONIC` or `BOT_/MNEMONIC/S` should be provided - - with a local chain you can use `DEMO_MNEMONIC`s from the neutron networks/init.sh file - `COINGECKO_API_TOKEN`: a Coingecko API token used for live prices fetching. Only used with respective token pair price setting. The token should be a [demo API token](https://www.coingecko.com/en/api/pricing). Pro tokens aren't supported because they use different endpoints. Keep in mind the very limited request rate the demo tokens provide when configuring the bots number and trading intensity. eg. `make start-trade-bot BOTS=30 BOT_RAMPING_DELAY=5 TRADE_FREQUENCY_SECONDS=0 TRADE_DURATION_SECONDS=450 MNEMONIC=...` From 1c464bdfbbaa1f983ed32a93630108a9e8d2ad78 Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Thu, 25 Apr 2024 22:08:59 +1000 Subject: [PATCH 3/9] docs: move mnenomic option documentation to one section --- README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5873806..d2d5795 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,9 @@ To run the bot, you will first need a chain to run the bot against, locally this should be a single dockerized neutron node - `make build-neutron` -To run the default setup of a single neutron-node chain and a single trading bot: +To run the default setup of a single neutron-node chain and a single trading bot with a single wallet: - `make start-trade-bot MNEMONIC=...` -- at least a single mnenomic must be specified from the mnenomics listed in the options section below - - `MNEMONIC` - - `MNEMONICS` - - `BOT_MNEMONIC` - - `BOT_MNEMONICS` - - `FAUCET_MNEMONIC` - - if running a local chain you can use DEMO_MNEMONICs from the neutron repo [networks/init.sh](https://github.com/neutron-org/neutron/blob/v3.0.0/network/init.sh#L19-L21) file +- the available `MNENOMIC` options are explained in the [Options section](#mnemonic-options) This composed neutron chain and trading bot network will persist until you call: - `make stop-trade-bot` @@ -38,6 +32,19 @@ then `make start-trade-bot` should be used instead. ## Available options +### Mnemonic options +A single mnenomic option must be specified to run `make start-trade-bot` or `make test-trade-bot` this may be in the form of: +- a list of mnemonics to be used (delimited with any `\r\n,;` characters) where one mnemonic is given to each bot (in series). An error will be thrown if not enough mnemonics are provided for the number of `BOTS` requested. + - `MNEMONIC` + - `MNEMONICS` + - `BOT_MNEMONIC` + - `BOT_MNEMONICS` +- a single mnenomic which will be used to like a faucet to fund a separate randomly generated wallet for each bot requested (so you may easily run more than one bot with one wallet). + - `FAUCET_MNEMONIC` +- if you are running a local chain you can use the DEMO_MNEMONICs from the neutron repo [networks/init.sh](https://github.com/neutron-org/neutron/blob/v3.0.0/network/init.sh#L19-L21) file for these settings. + +### Optional options + All docker-compose env vars are able to be set in both `make start-trade-bot` and `make test-trade-bot` - Chain variables - `CHAIN_ID`: the chain ID From 935c7008f2bdfd6cfcfa3fb87f5e451187cdfd1b Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Thu, 25 Apr 2024 22:15:56 +1000 Subject: [PATCH 4/9] docs: explain the behavior of using FAUCET_MNEMONIC at simulation end --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d2d5795..6c13797 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ A single mnenomic option must be specified to run `make start-trade-bot` or `mak - `BOT_MNEMONICS` - a single mnenomic which will be used to like a faucet to fund a separate randomly generated wallet for each bot requested (so you may easily run more than one bot with one wallet). - `FAUCET_MNEMONIC` + - on simulation end: the remaining token balance will be refunded to the faucet wallet. + - you should strongly consider using `ON_EXIT_WITHDRAW_POOLS=1` when using this option on a testnet. If the pools are not withdrawn after the simulation and you have not recorded the randomly generated mnenomics for each bot: then ***you will lose access to these deposited tokens***. - if you are running a local chain you can use the DEMO_MNEMONICs from the neutron repo [networks/init.sh](https://github.com/neutron-org/neutron/blob/v3.0.0/network/init.sh#L19-L21) file for these settings. ### Optional options From e9aa7360fcf09d6ffbb10a0bc95c86904d22e4cf Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Thu, 25 Apr 2024 22:22:57 +1000 Subject: [PATCH 5/9] docs: shorten line lengths to under 120 characters --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6c13797..75c57dd 100644 --- a/README.md +++ b/README.md @@ -33,17 +33,22 @@ then `make start-trade-bot` should be used instead. ## Available options ### Mnemonic options -A single mnenomic option must be specified to run `make start-trade-bot` or `make test-trade-bot` this may be in the form of: -- a list of mnemonics to be used (delimited with any `\r\n,;` characters) where one mnemonic is given to each bot (in series). An error will be thrown if not enough mnemonics are provided for the number of `BOTS` requested. +A single mnenomic option must be used to run `make start-trade-bot` or `make test-trade-bot` this may be in the form of: +- a list of mnemonics to be used (delimited with any `\r\n,;` characters) where one mnemonic is given to each bot. +An error will be thrown if not enough mnemonics are provided for the number of `BOTS` requested. - `MNEMONIC` - `MNEMONICS` - `BOT_MNEMONIC` - `BOT_MNEMONICS` -- a single mnenomic which will be used to like a faucet to fund a separate randomly generated wallet for each bot requested (so you may easily run more than one bot with one wallet). +- a single mnenomic which will be used to like a faucet to fund a separate randomly generated wallet for each bot +(so you may easily run more than one bot with one wallet). - `FAUCET_MNEMONIC` - on simulation end: the remaining token balance will be refunded to the faucet wallet. - - you should strongly consider using `ON_EXIT_WITHDRAW_POOLS=1` when using this option on a testnet. If the pools are not withdrawn after the simulation and you have not recorded the randomly generated mnenomics for each bot: then ***you will lose access to these deposited tokens***. -- if you are running a local chain you can use the DEMO_MNEMONICs from the neutron repo [networks/init.sh](https://github.com/neutron-org/neutron/blob/v3.0.0/network/init.sh#L19-L21) file for these settings. + - you should strongly consider using `ON_EXIT_WITHDRAW_POOLS=1` when using this option on a testnet. + If the pools are not withdrawn and you have not saved the randomly generated mnenomics for each bot + then ***you will lose access to these deposited tokens***. +- if you are running a local chain you can use the DEMO_MNEMONICs from the neutron repo +[networks/init.sh](https://github.com/neutron-org/neutron/blob/v3.0.0/network/init.sh#L19-L21) file for these settings. ### Optional options From 15d9165ab10e7510ae8e1a80b02c853af4d7307b Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Thu, 25 Apr 2024 22:53:17 +1000 Subject: [PATCH 6/9] docs: move TOKEN_CONFIG and PAIR_CONFIG docs to README file --- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++-- scripts/helpers.sh | 29 ++++------------------- 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 75c57dd..040b9a9 100644 --- a/README.md +++ b/README.md @@ -68,13 +68,66 @@ All docker-compose env vars are able to be set in both `make start-trade-bot` an - `ON_EXIT_WITHDRAW_POOLS`: if set, withdraw all user's Dex pools after TRADE_DURATION_SECONDS - `GAS_ADJUSTMENT`: how much more than the base estimated gas price to pay for each tx - `GAS_PRICES`: calculate how many fees to pay from this fraction of gas - - `TOKEN_CONFIG`: a token pairs configuration (JSON) object for eg. token amounts to trade - - see [helpers.sh](https://github.com/neutron-org/dex-trading-bot/blob/131a5f1590483840305cb475f8a867996509333e/scripts/helpers.sh#L41-L63) for more setting details + - `TOKEN_CONFIG`: a token pairs configuration (JSON) object to specify trading behavior to use for each token pair + - see the [TOKEN_CONFIG option section](#token_config-option) for more details - `COINGECKO_API_TOKEN`: a Coingecko API token used for live prices fetching. Only used with respective token pair price setting. The token should be a [demo API token](https://www.coingecko.com/en/api/pricing). Pro tokens aren't supported because they use different endpoints. Keep in mind the very limited request rate the demo tokens provide when configuring the bots number and trading intensity. eg. `make start-trade-bot BOTS=30 BOT_RAMPING_DELAY=5 TRADE_FREQUENCY_SECONDS=0 TRADE_DURATION_SECONDS=450 MNEMONIC=...` will start a persistent chain that for the first ~10min (7min+ramping) will generate ~5000txs using 30 bots. +#### TOKEN_CONFIG option + +format for TOKEN_CONFIG is: +``` +TOKEN_CONFIG = { + "amountAtokenA<>amountBtokenB": numeric_price_or_PAIR_CONFIG_object, + "defaults": PAIR_CONFIG +} +``` +the object keys are the usable tokens for each pair (to be shared across all bots), +the object values are the price ratio of tokenB/tokenA, a coingecko pair or a config object: (default values are listed) +``` +PAIR_CONFIG = { + "price": 1, # price ratio is of tokenB/tokenA (how many tokenA is required to buy 1 tokenB?), OR + "price": "coingecko:api_idA<>api_idB", # for live price retrieval, use the coingecko API IDs of the tokens (e.g. "coingecko:cosmos<>neutron-3" for atom<>ntrn pair) + "ticks": 100, # number of ticks for each bot to deposit + "fees": [1, 5, 20, 100] # each LP deposit fee may be (randomly) one of the whitelisted fees here + "gas": "0untrn" # additional gas tokens that bots can use to cover gas fees + "rebalance_factor": 0.5, # fraction of excessive deposits on either pair side to rebalance on each trade + "deposit_factor": 0.5, # fraction of the recommended maximum reserves to use on a single tick deposit + "swap_factor": 0.5, # max fraction of a bot's token reserves to use on a single swap trade (max: 1) + "swap_accuracy": 100, # ~1% of price: swaps will target within ~1% of current price + "deposit_accuracy": 1000, # ~10% of price: deposits will target within ~10% of current price + "amplitude1": 5000, # ~50% of price: current price will vary by ~50% of set price ratio + "period1": 36000, # ten hours: current price will cycle min->max->min every ten hours + "amplitude2": 1000, # ~10% of price: current price will vary by an additional ~10% of price ratio + "period2": 600, # ten minutes: current price will cycle amplitude2 offset every ten minutes +} +``` + +For example the following `TOKEN_CONFIG` option sets each bot to trade on 3 pools +- the first `uibcusdc<>uibcatom` with all default options except price of `1uibcatom = 10uibcusdc` +- the second `untrn<>uibcusdc` with custom GoinGecko pricing and specified 50 deposited ticks +- the third `untrn<>uibcatom` with custom sinusoidal pricing around a price of `1uibcatom = 5untrn` +- all pools will operate with the specified `defaults` values of `fees` and `gas` +```js +TOKEN_CONFIG = { + "10000000000000uibcusdc<>10000000000000uibcatom": 10, + "100000000000untrn<>100000000000uibcusdc":{ + "price": "coingecko:neutron-3<>usd-coin", + "ticks": 50 + }, + "1000000000uibcatom<>1000000000untrn":{ + "price": 5, + "amplitude2": 100 + }, + "defaults":{ + "fees": [0,1,2,3,4,5,10,20,50,100,150,200], + "gas": "1000000000untrn" + } +} +``` + # Troubleshooting The chain should be visible at http://localhost:26657 and REST at http://localhost:1317. diff --git a/scripts/helpers.sh b/scripts/helpers.sh index 1e8cc1d..723bcc7 100644 --- a/scripts/helpers.sh +++ b/scripts/helpers.sh @@ -38,30 +38,11 @@ getBotNumber() { fi } -# format for TOKEN_CONFIG is: -# TOKEN_CONFIG = { -# "amountAtokenA<>amountBtokenB": numeric_price_or_PAIR_CONFIG_object, -# "defaults": PAIR_CONFIG -# } -# the object keys are the usable tokens for each pair (to be shared across all bots), -# the object values are the price ratio of tokenB/tokenA, a coingecko pair or a config object: (default values are listed) -# PAIR_CONFIG = { -# "price": 1, # price ratio is of tokenB/tokenA (how many tokenA is required to buy 1 tokenB?), OR -# "price": "coingecko:api_idA<>api_idB", # for live price retrieval, use the coingecko API IDs of the tokens (e.g. "coingecko:cosmos<>neutron-3" for atom<>ntrn pair) -# "ticks": 100, # number of ticks for each bot to deposit -# "fees": [1, 5, 20, 100] # each LP deposit fee may be (randomly) one of the whitelisted fees here -# "gas": "0untrn" # additional gas tokens that bots can use to cover gas fees -# "rebalance_factor": 0.5, # fraction of excessive deposits on either pair side to rebalance on each trade -# "deposit_factor": 0.5, # fraction of the recommended maximum reserves to use on a single tick deposit -# "swap_factor": 0.5, # max fraction of a bot's token reserves to use on a single swap trade (max: 1) -# "swap_accuracy": 100, # ~1% of price: swaps will target within ~1% of current price -# "deposit_accuracy": 1000, # ~10% of price: deposits will target within ~10% of current price -# "amplitude1": 5000, # ~50% of price: current price will vary by ~50% of set price ratio -# "period1": 36000, # ten hours: current price will cycle min->max->min every ten hours -# "amplitude2": 1000, # ~10% of price: current price will vary by an additional ~10% of price ratio -# "period2": 600, # ten minutes: current price will cycle amplitude2 offset every ten minutes -# } -# which is transformed to format for token_config_array = [ +# getTokenConfigArray transforms a given TOKEN_CONFIG (or TOKEN_CONFIG_DEFAULT) object +# into a new format that is easier to query through `jq`. +# the TOKEN_CONFIG and PAIR_CONFIG object format is listed in the README file +# +# token_config_array = [ # { # "pair": [ # { From 40a1fa035f40d053b7e10545739720b181a73e75 Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Thu, 25 Apr 2024 22:55:43 +1000 Subject: [PATCH 7/9] docs: make TOKEN_CONFIG option header larger --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 040b9a9..43aac67 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ All docker-compose env vars are able to be set in both `make start-trade-bot` an eg. `make start-trade-bot BOTS=30 BOT_RAMPING_DELAY=5 TRADE_FREQUENCY_SECONDS=0 TRADE_DURATION_SECONDS=450 MNEMONIC=...` will start a persistent chain that for the first ~10min (7min+ramping) will generate ~5000txs using 30 bots. -#### TOKEN_CONFIG option +### TOKEN_CONFIG option format for TOKEN_CONFIG is: ``` From 414fe0c8104dc72a7a56a700dcbc0a2a0c3010c1 Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Thu, 25 Apr 2024 22:57:51 +1000 Subject: [PATCH 8/9] style: make whitespace more consistent --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 43aac67..939da47 100644 --- a/README.md +++ b/README.md @@ -88,20 +88,20 @@ the object keys are the usable tokens for each pair (to be shared across all bot the object values are the price ratio of tokenB/tokenA, a coingecko pair or a config object: (default values are listed) ``` PAIR_CONFIG = { - "price": 1, # price ratio is of tokenB/tokenA (how many tokenA is required to buy 1 tokenB?), OR - "price": "coingecko:api_idA<>api_idB", # for live price retrieval, use the coingecko API IDs of the tokens (e.g. "coingecko:cosmos<>neutron-3" for atom<>ntrn pair) - "ticks": 100, # number of ticks for each bot to deposit - "fees": [1, 5, 20, 100] # each LP deposit fee may be (randomly) one of the whitelisted fees here - "gas": "0untrn" # additional gas tokens that bots can use to cover gas fees - "rebalance_factor": 0.5, # fraction of excessive deposits on either pair side to rebalance on each trade - "deposit_factor": 0.5, # fraction of the recommended maximum reserves to use on a single tick deposit - "swap_factor": 0.5, # max fraction of a bot's token reserves to use on a single swap trade (max: 1) - "swap_accuracy": 100, # ~1% of price: swaps will target within ~1% of current price - "deposit_accuracy": 1000, # ~10% of price: deposits will target within ~10% of current price - "amplitude1": 5000, # ~50% of price: current price will vary by ~50% of set price ratio - "period1": 36000, # ten hours: current price will cycle min->max->min every ten hours - "amplitude2": 1000, # ~10% of price: current price will vary by an additional ~10% of price ratio - "period2": 600, # ten minutes: current price will cycle amplitude2 offset every ten minutes + "price": 1, # price ratio is of tokenB/tokenA (how many tokenA is required to buy 1 tokenB?), OR + "price": "coingecko:api_idA<>api_idB", # for live price retrieval, use the coingecko API IDs of the tokens (e.g. "coingecko:cosmos<>neutron-3" for atom<>ntrn pair) + "ticks": 100, # number of ticks for each bot to deposit + "fees": [1, 5, 20, 100] # each LP deposit fee may be (randomly) one of the whitelisted fees here + "gas": "0untrn" # additional gas tokens that bots can use to cover gas fees + "rebalance_factor": 0.5, # fraction of excessive deposits on either pair side to rebalance on each trade + "deposit_factor": 0.5, # fraction of the recommended maximum reserves to use on a single tick deposit + "swap_factor": 0.5, # max fraction of a bot's token reserves to use on a single swap trade (max: 1) + "swap_accuracy": 100, # ~1% of price: swaps will target within ~1% of current price + "deposit_accuracy": 1000, # ~10% of price: deposits will target within ~10% of current price + "amplitude1": 5000, # ~50% of price: current price will vary by ~50% of set price ratio + "period1": 36000, # ten hours: current price will cycle min->max->min every ten hours + "amplitude2": 1000, # ~10% of price: current price will vary by an additional ~10% of price ratio + "period2": 600, # ten minutes: current price will cycle amplitude2 offset every ten minutes } ``` From 4aa35c80fa01696346cd9643440e9eb8317703d2 Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Fri, 26 Apr 2024 23:40:04 +1000 Subject: [PATCH 9/9] docs: remove leftover word Co-authored-by: sotnikov-s <34917380+sotnikov-s@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 939da47..ab332cc 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ An error will be thrown if not enough mnemonics are provided for the number of ` - `MNEMONICS` - `BOT_MNEMONIC` - `BOT_MNEMONICS` -- a single mnenomic which will be used to like a faucet to fund a separate randomly generated wallet for each bot +- a single mnenomic which will be used like a faucet to fund a separate randomly generated wallet for each bot (so you may easily run more than one bot with one wallet). - `FAUCET_MNEMONIC` - on simulation end: the remaining token balance will be refunded to the faucet wallet.