-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
30 changed files
with
3,450 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
.git | ||
.gitignore | ||
.node-version | ||
*.iml | ||
LICENSE | ||
VERSION | ||
README.md | ||
Changelog.md | ||
Makefile | ||
docker-compose.yml | ||
node_modules | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 2 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,3 +57,6 @@ typings/ | |
# dotenv environment variables file | ||
.env | ||
|
||
*.iml | ||
.node-version | ||
.credential.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
FROM node:boron-slim | ||
|
||
# install nc for sync-request | ||
ENV DEBIAN_FRONTEND noninteractive | ||
RUN apt-get update && apt-get install -y --no-install-recommends \ | ||
netcat | ||
|
||
ADD . /blac/ | ||
RUN cd /blac && npm install |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<p align="center"> | ||
<img alt="BLAC" src="https://raw.githubusercontent.com/yamorijp/blac/master/capture.jpg" width="600"/> | ||
</p> | ||
|
||
|
||
BLAC (Bitflyer Lightning API Console) は ビットコイン取引所 [bitFlyer](https://bitflyer.jp) が提供する | ||
[bitFlyer Lightning API](https://bitflyer.jp/docs) を使用した非公式のCLIツールパッケージです。 | ||
|
||
Lightning APIクライアントを統合したjavascriptの対話型コンソールプログラム、 | ||
リアルタイム更新の板表示プログラムと約定履歴表示プログラムを含みます。 | ||
|
||
当プログラムは"experimental"です。 | ||
十分なテストが行われていません。オーダー発行を行う場合は最初に少額でお試しください。 | ||
|
||
※U.S.リージョンには対応していません | ||
|
||
|
||
## 導入手順 | ||
|
||
当プログラムはNode.jsで動作するjsスクリプトです。 | ||
実行には[Node.js](https://nodejs.org) が必要です。バージョン6.10.0以上を導入してください。 | ||
|
||
また、サードパーティ製のnpmモジュールに依存しています。 | ||
[npm](https://www.npmjs.com/) か [yarn](https://yarnpkg.com/) を使用してインストールを行ってください。 | ||
|
||
$ npm install | ||
|
||
|
||
|
||
## プログラムの実行方法 | ||
|
||
nodeコマンドでスクリプトを実行します。 | ||
|
||
$ node console.js | ||
|
||
いくつかコマンドラインオプションがあります。`-h`オプションで確認してください。 | ||
|
||
$ node console.js -h | ||
|
||
|
||
## 対話型コンソール (console.js) | ||
|
||
Lightning APIクライアントを統合したREPLコンソールプログラムです。 | ||
対話型シェルでjavascriptを使用した注文発注や取消等、Lightning APIの呼び出しが行えます。 | ||
|
||
残高の確認やオーダー発行などPrivate APIに属する機能の呼び出しにはAPI keyとAPI secretが必要になります。 | ||
[bitFlyer Lightning](https://lightning.bitflyer.jp)にログイン後、[開発者ページ](https://lightning.bitflyer.jp/developer)から取得してください。 | ||
|
||
PI keyとAPI secretは`.bc_set_key`コマンドで設定します。設定した認証情報はプログラム終了時まで有効です。 | ||
|
||
> .bf_set_key YOUR_API_KEY YOUR_API_SECRET | ||
|
||
`.bf_store_key`コマンドで書き出しを行っておくと起動時に自動で読み込みます。(※平文で保存されます。セキュリティに注意) | ||
|
||
|
||
APIの詳細は、bitFlyerによる[API Documentation](https://lightning.bitflyer.jp/docs)を参照してください。 | ||
|
||
|
||
オプション: | ||
|
||
-n, --no-banner スタートアップバナーを表示しない | ||
|
||
例: | ||
|
||
$ node console.js -n | ||
|
||
|
||
|
||
## 板表示プログラム (board.js) | ||
|
||
リアルタイム更新の板表示プログラムです。 | ||
値段範囲で注文をまとめるグルーピング表示に対応しています。(`-g`オプション) | ||
|
||
|
||
オプション: | ||
-p, --product <code> プロダクトコード (BTC_JPY|ETH_BTC|BCH_BTC|FX_BTC_JPY) | ||
-r, --row <n> 買いと売り注文の表示行数 (デフォルト: 24) | ||
-g, --group <n> 指定範囲の注文をまとめて表示 (デフォルト: 無効) | ||
例: | ||
$ node board.js -p BTC_JPY -r 32 -g 1000 | ||
|
||
## 約定履歴表示プログラム (executions.js) | ||
|
||
リアルタイム更新の約定履歴表示プログラムです。 | ||
|
||
|
||
オプション: | ||
|
||
-p, --product <code> プロダクトコード (BTC_JPY|ETH_BTC|BCH_BTC|FX_BTC_JPY) | ||
-r, --row <n> 履歴の表示行数 (デフォルト: 48) | ||
|
||
例: | ||
|
||
$ node executions.js -p ETH_BTC -r 20 | ||
|
||
|
||
## ライセンス | ||
|
||
MIT | ||
|
||
|
||
bitcoin: `1BpLZm4JEFiDqAnaexuYMhGJZKdRQJKixP` | ||
monacoin: `MEaJSzymtvpB7AtrryVzn9LeZYhCrustpJ` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
#!/usr/bin/env node | ||
|
||
"use strict"; | ||
|
||
require('./core/polyfill'); | ||
|
||
const throttle = require('lodash.throttle'); | ||
|
||
const term = require('./core/terminal'); | ||
const api = require('./lightning/api'); | ||
const model = require('./core/model'); | ||
const products = require('./core/product'); | ||
|
||
const render_wait = 200; | ||
|
||
let product = products.BtcJpy; | ||
let health = new model.Health(); | ||
let ticker = new model.Ticker(); | ||
let board = new model.Board(); | ||
|
||
|
||
const _render = () => { | ||
let out = process.stdout; | ||
|
||
out.write(term.clear); | ||
out.write(term.nl); | ||
|
||
out.write(" Product:".padEnd(20)); | ||
out.write(product.name.padStart(26)); | ||
out.write(term.nl); | ||
|
||
out.write(" Last Price:".padEnd(20)); | ||
out.write(term.colorful( | ||
ticker.price >= ticker.price_old ? term.green : term.red, | ||
product.format_price(ticker.price).padStart(26))); | ||
out.write(term.nl); | ||
|
||
out.write(" Bid/Ask Ratio:".padEnd(20)); | ||
out.write(term.colorful( | ||
ticker.ratio >= 1.0 ? term.green : term.red, | ||
ticker.ratio.toFixed(2).padStart(26))); | ||
out.write(term.nl); | ||
|
||
out.write(" 24H Volume:".padEnd(20)); | ||
out.write(product.format_volume(ticker.volume).padStart(26)); | ||
out.write(term.nl); | ||
|
||
out.write(term.separator + term.nl); | ||
|
||
board.getAsks().forEach(row => { | ||
out.write(product.format_volume(row[1]).padStart(16)); | ||
out.write(" " + term.colorful(term.red, product.format_price(row[0]).padStart(12)) + " "); | ||
out.write("".padEnd(16)); | ||
out.write(term.nl); | ||
}); | ||
board.getBids().forEach(row => { | ||
out.write("".padEnd(16)); | ||
out.write(" " + term.colorful(term.green, product.format_price(row[0]).padStart(12)) + " "); | ||
out.write(product.format_volume(row[1]).padStart(16)); | ||
out.write(term.nl); | ||
}); | ||
|
||
out.write(term.separator + term.nl); | ||
|
||
out.write(` Service) ${health.health} Market) ${health.state}`); | ||
out.write(term.nl); | ||
}; | ||
const render = throttle(_render, render_wait); | ||
|
||
|
||
const main = (program) => { | ||
product = products.get_product(program.product); | ||
board.lock() | ||
.setRowCount(program.row) | ||
.setGroupingFactor(program.group); | ||
|
||
let check_health = function () { | ||
new api.PublicAPI().call('GET', '/v1/getboardstate', {product_code: product.code}) | ||
.then(data => { | ||
health.update(data); | ||
render(); | ||
}); | ||
}; | ||
check_health(); | ||
setInterval(check_health, 60000); | ||
|
||
let board_channel = 'lightning_board_' + product.code; | ||
let ticker_channel = 'lightning_ticker_' + product.code; | ||
new api.RealtimeAPI() | ||
.attach((channel, message) => { | ||
switch (channel) { | ||
case board_channel: | ||
board.update(message); | ||
break; | ||
case ticker_channel: | ||
ticker.update(message); | ||
break; | ||
} | ||
render(); | ||
}) | ||
.subscribe([board_channel, ticker_channel]); | ||
|
||
new api.PublicAPI() | ||
.call('GET', '/v1/board', {product_code: product.code}) | ||
.then(data => { | ||
board.setData(data); | ||
board.unlock(); | ||
render(); | ||
}); | ||
}; | ||
|
||
|
||
const program = require('commander'); | ||
program | ||
.version(require("./package.json").version) | ||
.description("Display BitFlyer Lightning's order book") | ||
.option("-p, --product <code>", "Product code (BTC_JPY|ETH_BTC|BCH_BTC|FX_BTC_JPY)", s => s.toUpperCase(), "BTC_JPY") | ||
.option("-r, --row <n>", "Number of display rows (default: 24)", v => parseInt(v), 24) | ||
.option("-g, --group <n>", "Order grouping unit (default: 0.0)", v => parseFloat(v), 0.0) | ||
.on("--help", () => { | ||
console.log(""); | ||
console.log(" Examples:"); | ||
console.log(""); | ||
console.log(" $ node board.js -p BTC_JPY -r 32 -g 1000"); | ||
console.log(""); | ||
}) | ||
.parse(process.argv); | ||
|
||
main(program); | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#!/usr/bin/env node | ||
|
||
"use strict"; | ||
|
||
require('./core/polyfill'); | ||
|
||
const repl = require('repl'); | ||
|
||
const term = require('./core/terminal'); | ||
const command = require('./core/command'); | ||
|
||
const api = require('./lightning/api'); | ||
const pub = require('./lightning/builder/pub'); | ||
const pri = require('./lightning/builder/pri'); | ||
|
||
const version = require('./package.json').version; | ||
|
||
const banner = `${term.yellow}${term.bold} | ||
_ _ | ||
| | | | | ||
| |__ | | __ _ ___ | ||
| '_ \\| |/ _\` |/ __| | ||
| |_) | | (_| | (__ | ||
|_.__/|_|\\__,_|\\___| | ||
${term.reset}${term.yellow} | ||
bitflyer - lightning - api - console | ||
${term.reset} | ||
コンテキスト変数: | ||
api -> APIクライアント | ||
pub -> パブリックAPI | ||
pri -> プライベートAPIと認証 | ||
コマンド: | ||
.help または .bf_* help を参照 | ||
> .bf_buy help | ||
APIドキュメント: | ||
bitFlyer Lightning API - https://lightning.bitflyer.jp/docs | ||
例: | ||
> pri.set_credential(YOUR_API_KEY, YOUR_API_SECRET) | ||
> pri.getchildorders.create() | ||
> _.product_code("BTC_JPY").child_order_state("ACTIVE") | ||
> _.executeSync() | ||
`; | ||
|
||
const loadCredential = () => { | ||
try { | ||
const config = require('./.credential.json'); | ||
if (config.api_key && config.api_secret) { | ||
pri.set_credential(config.api_key, config.api_secret); | ||
console.log(term.colorful(term.green, " (.credential.json loaded)\n\n")); | ||
} | ||
} catch (e) { | ||
// not found | ||
} | ||
}; | ||
|
||
const initContext = (context) => { | ||
context.api = api; | ||
context.pub = pub; | ||
context.pri = pri; | ||
}; | ||
|
||
|
||
const main = (program) => { | ||
|
||
if (!program.nobanner) { | ||
process.stdout.write(term.clear); | ||
process.stdout.write(term.nl); | ||
process.stdout.write(banner); | ||
} | ||
|
||
loadCredential(); | ||
|
||
let server = repl.start('> '); | ||
|
||
initContext(server.context); | ||
server.on('reset', initContext); | ||
|
||
Object.values(command.commands) | ||
.forEach(cmd => server.defineCommand(cmd.getName(), { | ||
help: cmd.getHelp(), | ||
action(arg) { | ||
cmd.doAction(server, arg); | ||
} | ||
})); | ||
}; | ||
|
||
|
||
const program = require('commander'); | ||
program | ||
.version(require("./package.json").version) | ||
.description("bitflyer - lightning - api - console") | ||
.option("-n, --no-banner", "Don't show ugly startup banner", false) | ||
.on("--help", () => { | ||
console.log(""); | ||
console.log(" Examples:"); | ||
console.log(""); | ||
console.log(" $ node console.js -n"); | ||
console.log(""); | ||
}) | ||
.parse(process.argv); | ||
|
||
main(program); |
Oops, something went wrong.