ArkeBot market maker
OpenDAX v4 opens the ability to boost liquidity provisioning via market-making bots and connecting to the Yellow Network.
Every trading pair comprises a market with its own liquidity.
Liquidity determines how easily and fast any trader can buy or sell an asset without substantially impacting the price. In other words, the more orders and order volumes in the order book, the higher liquidity, and a trader can trade instantly at a fair price.
High liquidity for traders results in:
- fair price (thanks to supply/demand balance)
- low slippage (the change in price after the order is met - emerges in markets when a large demand or supply impacts the price. In a highly liquid market, even a large order is unlikely to impact the price much)
- rise of order book depth - more orders in the order book are more informative and appealing for traders
- price swing mitigation - as with slippage, higher liquidity makes drastic price change less probable
There are other benefits, but from the exchange business point of view, the crucial one is the overall attractiveness of the market and the exchange.
Market making is a dedicated activity aimed to boost liquidity and improve market indicators: depth, bid-ask spread, volume, and others.
Openware maintains ArkeBot, an open-source solution for automated market-making and liquidity provisioning.
Also, connecting to the Yellow Network and aggregating liquidity will dramatically improve the market indicators on the exchange. But the reasonable step would be to implement market-making solutions first so that the exchange had better liquidity and thus better fees level in peer-to-peer agreements with other brokerages.
OpenDAX v4 will be able to connect to the Yellow Network after its production release.
Arke is an open-source trading bot, developed and maintained by Openware.
Alongside other automation functions, it can perform local market-making operations as well as import liquidity from a source exchange to yours.
Here we suggest a low-risk strategy for Arke to provide liquidity to your exchange: Orderback.
Note, you need to have funds in your wallet on Binance (how much funds depends on your liquidity expectations).
To launch the Orderback market-making strategy on your exchange:
Create a Binance account, complete KYB, and top-up an entity account on Binance (or other exchange you like - see Arke configs below).
Go to the account API Management, create, and save an API key with Secret.
With this account, Arke will be able to copy orders to your target exchange and orderback to Binance when orders are met.
1.2.1 Take Gotrue API key and JWT from request (browser dev tools):
- Dev tools → Application tab → Storage/LocalStorage/https://… → Key
app_config
Here copy thegoTrueAnon
parameter value.

- Dev tools → Application tab → Storage/LocalStorage/https://… → Key
session
Here copy the JWT from theaccess_token
parameter value.

1.2.2 Using
curl 'https://odax-master.v4.uat.opendax.app/api/v1/auth/user' -X PUT -H 'apikey: goTrueAnon' -H "Content-Type: application/json" -H "Authorization: Bearer access_token" -d '{"password":"your_password"}'
you can set password for the user.Make sure you’ve replaced the exchange URL before
/api/v1/auth/user
, then goTrueAnon
, access_token
, and entered your password instead of your_password
.The account email and this password will be used to configure Arke.
Put it on the desired cloud or another server.
Configure your trading strategies in the file config/strategies.yml :
You need to configure at least two accounts: for Binance and for your OpenDAX v4 exchange (see the example below).
Field | Description |
id | ID identifying the account (must be unique) |
driver | Name of exchange driver (supported values are: opendax_v4 , finex , binance , bitfinex , kraken , and others) |
debug | Flag to extend logs verbosity, valid values are: true or false |
host | Base URL of the exchange API |
ws | WebSocket URL of the exchange. You can omit this parameter in an OpenDAX v4 account configs - Arke will fetch it automatically. See the example below |
key | API key. For the v4 account configs, this is the market-maker account email. This account will post orders on the exchange |
secret | Secret key is the password set by the command in 1.2.2 (see above) |
delay | Minimum delay to respect between requests to this exchange (in second) |
To save your resources, we suggest setting the
debug
field to false
. But before doing this, you definitely want to make a test run, where you should use true
and examine detailed logs.log_level: INFO # Level of Arke log info
accounts:
#---------------------------{source}-----------------------------------
- id: binance_source # Unique account id of the source
driver: binance # One of supported sources drivers
delay: 1 # Delay of balance information update
host: "https://binance.com/api" # Your source URL. Ommitable for binance
ws: "wss://binance.com/ws" # Your source WebSocet URL. Ommitable for binance
key: "" # API key from source (not required for copy strategy)
secret: "" # Secret from API key from source (not required for copy strategy)
#---------------------------{target}-----------------------------------
- id: example-account1 # Unique account id of the target
driver: opendax_v4 # Only supported target driver
key: "[email protected]" # market-maker account email, required
secret: "123456" # password, required
host: "https://opendax.instance" # Your target URL
Arke already has configured
host
and ws
parameters for Binance, so you can omit them. As well as the debug
field, which you've already set in the target exchange account.Configure a strategy for each market: BTCUSDT, ETHUSDT, and so on.
Here we talk about the Orderback strategy, but ArkeBot suggests other ones too. Also, you can run multiple strategies.
Field | Description |
id | ID of the strategy (arbitrary string, must be unique) |
type | Strategy type (valid: orderback , fixedprice , microtrades , copy ) |
debug | Flag to extend logs verbosity, valid values are: true or false |
enabled | Flag to enable the strategy, could be: true or false (if you have multiple strategies, you can turn some of them off) |
period | Orderbook update period (in seconds), must be sufficient: remember about delay in accounts and rate limit in Finex |
period_random_delay | (optional) Random delay which will be added to the static period |
fx | (optional) Forex conversion rate configuration to apply to price (see below) |
strategies:
#---------------------------{strategy}-----------------------------------
- id: BTCUSDT-orderback # Name of a strategy
type: orderback # Type of the strategy
debug: false # true to see extra Arke logs
enabled: true # true to run this strategy after Arke (re)startgit
period: 90 # Period of order book refresh
The orderback strategy uses a source exchange market to create an orderbook on a target market, and has the ability to order back the liquidity from the source exchange market.
Some preset behaviors of ArkeBot:
- The depth of the created orderbook is defined by the number of orders on each side with the
levels_count
parameter and the price difference between orders with thelevels_size
parameter. - The
levels_size
parameter defines the price range between levels. Arke creates an order for each level, aggregating the volume of all source orders within the range. Thelevels_count
parameter defines how many times Arke has to repeat this operation for each side and create an order on the target exchange. - If in the source orderbook there are no orders on a required level (your
levels_price_step
is less than the actual price steps), Arke will create in the target orderbook on this level one order with a minimal amount. - As soon as an order on a target exchange is matched, the strategy creates an order on the source exchange with the matched amount and the same price without the spread (and you will lose the fee). If the
spread
configured is higher than the exchange's fee, the P&L will be positive.
Field | Description |
spread_bids | Spread for bids side (in percentage) |
spread_asks | Spread for asks side (in percentage) |
limit_asks_base | Sum of amounts of orders on ask side |
limit_bids_base | Sum of amounts of orders on bid side |
limit_by_source_balance | Limit bids and asks amount according to the source account balances (default: false ) |
balance_base_perc | Ratio for sum of amounts of orders on ask side based on base currency balance |
balance_quote_perc | Ratio for sum of amounts of orders on bid side based on quote currency balance |
levels_size | Minimum price difference between orders |
levels_count | Number of orders for each side |
levels_price_step | Minimum price difference between levels |
levels_price_func | Function to use to calculate levels size: constant , linear , exp (default: constant ) |
max_amount_per_order | Maximum size for one order. If more liquidity is needed for one level, several orders of this size will be created |
side | Side where orders will be created (valid: asks , bids , both ) |
enable_orderback | Flag for enabling orderback. Can be: true or false |
min_order_back_amount | The amount of the trade must be higher than this value for the order back to be created, otherwise the trade will be ignored (since Binance will reject the orderback less than, for example, $10 in base currency) |
orderback_grace_time | The time to wait incoming trades before triggering the order back, default 1 sec |
orderback_type | The order back type it will be created, could be: limit or market , default is market |
You can omit minor parameters.
Please, remember that in order not to lose on fees, you should include the fees in the price (
spread
parameters).params:
spread_bids: 0.02 # Percentage difference from the best price on buy side
spread_asks: 0.02 # Percentage difference from the best price on sell side
limit_asks_base: 10 # The amount of base currency that will be placed for sale in the order book, if have enough balance
limit_bids_base: 10 # The amount of base currency that will be placed for buy in the order book, if have enough balance in quote currency equivalent
levels_size: 0.5 # Minimum price difference between price points
levels_count: 5 # Maximum amount of price points that may be created
side: both # Side, ask, bid or both to apply the strategy on
enable_orderback: true # True to perform order back on the source, if on target exchange orders was matched with this strategy
min_order_back_amount: 0.0002 # The minimum amount of tokens bought or sold on target exchange at the same price point in a period of a second to perform an order back (made to ignore microtrade strategy)
The
target
and source
configurations need to be defined for each strategy.Field | Description |
account_id | ID of account which will place order on target exchange |
market_id | ID of the market as it is on the target exchange |
Field | Description |
account_id | ID of account which will place order on target exchange |
market_id | ID of the market as it is on the source exchange |
target:
account_id: example-account1 # Unique account id, from the account section, that will be used as a target (your exchange)
market_id: btcusdt # Market pair code in lowercase, from your target exchange
sources:
- account_id: binance_account # Unique account id, from the account section, that will be used as a source
market_id: BTCUSDT # Market pair code in uppercase, from you source exchange
Note that target
market_id
may differ from the source one. In this case, you should set up fx
parameters to define the conversion rate.See the next chapter.
Set up a forex parameter if you need to convert currencies' for market-making. For example, you want to fetch BTCUSDT orderbook from Binance, but create from it MATICUSDT orderbook on your exchange. You need to convert BTCs to Matics.
There are two options:
- fixed forex rate (“static”
type
) you define yourself
To set up the “fixer”
type
parameter, you need a license to fetch dynamic conversion rates from fixer.io.Detail of the
fx
section to configure for a strategy:Field | Description |
type | The type of the forex class to use: “static“ for a fixed conversion rate, “fixer” for dynamic rate fetched from fixer.io |
rate | Static value of the rate to apply to prices of the strategy (this parameter is used for the “static” type, the parameters below are for the fixer type) |
api_key | Fixer API key |
currency_from | Currency code |
currency_to | Currency code |
period | Refresh period in seconds, default: 3600 |
https | Enable HTTPS communication (default true ) |
fx:
type: fixer # Set Fixer for dynamic conversion rate take from forex
api_key: # Your key (without brackets) from https://fixer.io/ to request conversion rate
currency_from: USD # Source exchange currency you are converting from
currency_to: KRW # Target exchange currency you are converting to
period: 3600 # Period of converting rate refresh
target:
account_id: example-account1 # Unique account id, from the account section, that will be used as a target (your exchange)
market_id: btckrw # Market pair code in lowercase, from your target exchange
sources:
- account_id: binance_source # Unique account id, from the account section, that will be used as a source
market_id: BTCUSDT # Market pair code in uppercase, from you source exchange
Run the command:
bundle install
Run the command:
bundle exec ./bin/arke start
Note that in the example, we configure one strategy, for one market, via Binance exchange.
log_level: INFO
accounts:
- id: example-account1
driver: opendax_v4
debug: false
host: "https://some.opendax.instance/api/"
key: "71e3c1bc4b635f2abe068b5e21d5aa60874687677523d904abd2e05179fad222"
delay: 0.01
- id: binance-account
driver: binance
#host and ws are omitted since the driver has these parameters already
key: ""
secret: ""
delay: 0.015
strategies:
- id: BTCUSDT-orderback
type: orderback
debug: false
enabled: true
period: 90
params:
spread_bids: 0.005
spread_asks: 0.005
limit_asks_base: 10
limit_bids_base: 10
levels_size: 0.5
levels_count: 5
side: both
enable_orderback: true
min_order_back_amount: 0.0002
target:
account_id: example-account1
market_id: btcusdt
sources:
- account_id: binance-account
market_id: BTCUSDT
Please, consider the following cautions:
- You should monitor your Binance (or whatever source) and OpenDAX v4 accounts balances. Obviously, Arke will be able to create orders copied from Binance on v4 only if you have sufficient balance. And similarly, it has to be enough tokens on your Binance balance to post orderback's orders on Binance.
When testing Arke on Goerli testnet v4 instance, you can update your testnet v4 balance via the Supabase admin panel.
- You should better test the strategy configurations first. For testing Orderback, you can use another your exchange (if you have one).
- You can easily start testing with a Copy strategy (without orderbacks): use your Binance account and your OpenDAX v4 instance on the Goerli testnet. Arke will copy orders from Binance to your exchange. Orderback in this case is impossible.
You can also use Binance Testnet with the
driver: binance
parameter, but you need to specify host
and ws
parameters. Still, as binance.testnet doesn’t allow you to directly top-up it’s account, you can’t test Orderback strategy with this source.delay
value affects Arke’s busyness and resource demand. For example, if you have many markets and a shortdelay
, the number of calls will rise spectacularly.period
value must be sufficient, otherwise, Arke will start a new strategy run before finishing the previous one. This will lead to undesired orderbook twists.- Testing parameters may differ: for example, you should use
debug: true
on testings. - Setting
spread
allows you to avoid losses on fees and define your profit on market-making. - You need to monitor your balance on your target exchange, and your Binance balance. Arke doesn’t transfer funds between exchanges, but copies orders from Binance to your exchange, and then makes orderback (copies back) for orders that are executed on your exchange. This approach helps to keep your balance but doesn’t give a guarantee since trading may exceed it.
Last modified 7mo ago