R2 Bitcoin Arbitrager is an automatic arbitrage trading system powered by Node.js + TypeScript.
R2 Bitcoin Arbitrager is an automatic arbitrage trading application targeting Bitcoin exchanges.
Web UI mode is for browser clients.
Console mode is for CUI-only environment like Linux boxes with no GUI.
git clone https://github.com/bitrinjani/r2.git
npm install
. (or yarn
)cd r2
npm install
config_default.json
in the folder to config.json
key
and secret
fields with your API keys (tokens) and secrets. Set enabled
to false
for exchanges you do not use.webGateway.enabled
to true. By default, R2 starts in Console mode.npm start
or yarn start
.npm start
or
git clone https://github.com/bitrinjani/r2.git
docker build
and docker run
.cd r2
docker build -t r2:latest .
docker run --rm -it r2:latest
R2 works on any OS that supports Node.js, such as:
Web UI works on the latest version of Google Chrome.
R2 supports the following exchanges.
Exchange | Cash | Margin |
---|---|---|
bitFlyer | ✔️ | ✔️* |
Quoine | ✔️ | ✔️ |
Coincheck | ✔️ | ✔️ |
bitbank.cc | ️️️✔️ | |
BTCBox | ✔️ |
*bitFlyer margin trading (BTC-FX/JPY) is available as a broker plugin.
maxShortPosition
config is 0 and the current position is 0 for a broker, the ask quotes for the broker will be filtered out.minTargetProfitPercent
. If there is no arbitrage opportunity, R2 waits for the next iteration.onSingleLeg
config.After the spread has became smaller than the configured value, exitNetProfitRatio
, R2 tries to close the pair.
minTargetProfitPercent
to μ + σ every few seconds.All configurations are stored in config.json
.
Name | Values | Description |
---|---|---|
language | "ja" or "en" | UI language. Japanese or English. |
demoMode | true or false | If it's true, the arbitrager analyzes spreads but doesn't send any real trade. |
priceMergeSize | number | Merges small quotes into the specified price ladder before analyzing arbitrage opportunity. |
maxSize | number | Maximum BTC size to be sent to brokers. |
minSize | number | Minimum BTC size to be sent to brokers. |
minTargetProfitPercent | number | Minimum target profit in percent against notional (= inverted spread %). Profit percentage against notional is calculated by 100 * expected profit / (MID price * volume) . |
maxTargetProfit | number | [Optional] Max target profit. This is a safe-guard for abnormal quotes. If the expected profit is larger than this, R2 won't attempt arbitrage. |
maxTargetProfitPercent | number | [Optional] Max target profit in percent. |
exitNetProfitRatio | number | R2 attempts to close open pairs when the spread has decreased by this percentage. For example, when the open profit of an open pair is 200 JPY and exitNetProfitRatio is 20(%), R2 closes the pair once the closing cost has became 160. |
maxTargetVolumePercent | number | [Optional] In order to execute orders as fast as possible and avoid slippage, R2 checks the volume of the quotes from the exchanges and makes sure the target volume consumes less than this percentage of the volume of the target quote before executing the order |
acceptablePriceRange | number | [Optional] Allows execution with price that is disadvantageous by the set value(%) from target price. (Like a market order.) |
iterationInterval | Millisecond | Time lapse in milliseconds of an iteration. When it's set to 3000, the quotes fetch and the spreads analysis for all the brokers are done every 3 seconds |
positionRefreshInterval | Millisecond | Time lapse in milliseconds of position data refresh. Position data is used to check max exposure and long/short availability for each broker. |
sleepAfterSend | Millisecond | Time lapse in milliseconds after one arbitrage is done. |
maxNetExposure | number | Maximum total net exposure. If net exposure qty is larger than this value, Arbitrager stops. |
maxRetryCount | number | Maximum retry count to check if arbitrage orders are filled or not. If the orders are not filled after the retries, Arbitrager tries to cancel the orders and continues. |
orderStatusCheckInterval | Millisecond | Time lapse in milliseconds to check if arbitrage orders are filled or not. |
stabilityTracker | - | See stabilityTracker config below |
onSingleLeg | - | See onSingleLeg config below |
analytics | - | See ANALYTICS_PLUGIN.md |
webGateway | - | See webGateway config details below |
Default config:
"webGateway": {
"enabled": false,
"host": "127.0.0.1",
"openBrowser": true
},
Web UI URL is http://127.0.0.1:8720 by default. TCP port 8720 and 8721 need to be opened.
R2 automatically disables trading activities on unstable brokers.
recoveryInterval
milliseconds has passed.threshold
value.By default, a broker which has failed three API calls within 5 minutes would be disabled for trading for at most 5 minutes.
Default configuration:
...
"stabilityTracker": {
"threshold": 8,
"recoveryInterval": 300000
},
...
The onSingleLeg config specifies what action should be taken when only one leg is filled.
...
"onSingleLeg": {
"action": "Reverse",
"actionOnExit": "Proceed",
"options": {
"limitMovePercent": 5,
"ttl": 3000
}
},
...
Name | Values | Description |
---|---|---|
broker | Bitflyer, Quoine or Coincheck | Broker name |
npmPath | string | npm package name for the broker plugin. |
enabled | true or false | Enable the broker for arbitrage |
key | string | Broker API Key |
secret | string | BrokerAPI Secret |
maxLongPosition | number | Maximum long position allowed for the broker. R2 won't send orders to the broker if current long position is larger than this value. |
maxShortPosition | number | Maximum short position allowed for the broker. R2 won't send orders to the broker if current short position is larger than this value. |
cashMarginType | Cash, MarginOpen, NetOut | Arbitrage order type. Not all options are supported for each exchange. See the table below. |
commissionPercent | number | Comission percentage for each trade. Commission JPY amount is calculated by target price * target volume * (commissionPercent / 100) . Arbitrager calculates expected profit by inversed spread * volume - commission JPY amount . |
noTradePeriods | list of ["starttime", "endtime"] | See noTradePeriods section below |
Exchange | Supported option |
---|---|
Bitflyer | Cash |
Quoine | Cash, NetOut |
Coincheck | Cash, MarginOpen, NetOut |
Bitbankcc | Cash |
Btcbox | Cash |
Quoine's NetOut is natively handled by Exchange API. Quoine can close multiple positions by one order. Coincheck's NetOut is artificially handled by R2 because the exchange doesn't support netout operation. Coincheck's NetOut works as below.
Please note this implementation doesn't close multiple positions by one order.
The noTradePeriods config specifies the periods when the quotes from the exchange must be ignored. The config is useful for scheduled maintenance periods, e.g. 4:00-4:15 in bitFlyer.
{
"broker": "Bitflyer",
...
"noTradePeriods": [["04:00", "04:15"]]
},
{
"broker": "Bitflyer",
...
"noTradePeriods": [["04:00", "04:15"], ["9:00", "9:30"]]
},
R2 can send notification messages to Slack and LINE when it detects the configured keywords in the output logs.
// config.json
{
...
"logging": {
"slack": {
"enabled": false,
"url": "https://hooks.slack.com/services/xxxxxx",
"channel": "#ch1",
"username": "abc",
"keywords": ["error", "profit"]
},
"line": {
"enabled": false,
"token": "TOKEN",
"keywords": ["error", "profit"]
}
}
}
Name | Values | Description |
---|---|---|
enabled | true or false | Enable notification |
url | string | Slack Incoming Webhook URL |
channel | string | Slack channel name |
username | string | Slack user name |
keywords | string[] | Keyword list |
Name | Values | Description |
---|---|---|
enabled | true or false | Enable notification |
token | string | LINE Notify token |
keywords | string[] | Keyword list |
All log files are saved under logs
directory.
File name | Description |
---|---|
info.log | Standard log file |
debug.log | Verbose logging, including all REST HTTP requests and responses in JSON format |
Several utility scripts are available to close positions, show balances and clear cache.
See TOOLS.md
test
script runs ts-jest.
npm test
This project is licensed under the MIT License - see the LICENSE file for details
USE THE SOFTWARE AT YOUR OWN RISK. YOU ARE RESPONSIBLE FOR YOUR OWN MONEY. THE AUTHOR HAS NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
Blackbird, which targets US exchanges.