node.jsでbitcoin自動取引する話

本記事は以下に引っ越しました。
今後Qiita上での更新はありません。

https://zenn.dev/ririli47/articles/6d9e0635c120eed2f49f

# 注意
本記事はあくまで技術的な内容であり、実際のbitcoinの運用に関して一切の責任を負いません。
取引を行う際はご自分の責任のもとでお試しいただくことをご了承ください。

# この記事のターゲット
- node.js触ってみたい
- bitcoinでちょっとお小遣い稼ぎしてみたい
- プログラムを一定間隔で常に動かすにはどうしたらいいの？
- （Mac環境）

# ゴール
node.jsで一定間隔ごとにbitflyerの板情報を監視して自動で注文を出すプログラムをEC2のインスタンス上で動かす。

# 本題

## bitflyer
本記事ではbitcoinの取引所に[bitflyer](https://bitflyer.com/ja-jp)を利用します。
アカウントの取得はサイトの指示に従ってください。
取引はLightning FX で行いますので板が見れる状態にしてください。

## node.js
入っていない場合はinstallします。
以下参照。
https://qiita.com/Alex_mht_code/items/422f5ce10d9c9d5729b7

## プロジェクト作成
新規nodeプロジェクトを用意します。

```
mkdir my-project
cd my-project
npm init
touch main.js
```

### apiキーの取得
bitflyerで自分のAPIキーを取得します。
重要なパラメータなのでgithubにあげたりしないように注意してください。
別ファイルに切り分けて読み込みます。

```
touch config.js
```

```config.js
module.exports = {
  apiKey: __apiKey__,
  secret: __secret__,
}
```

```main.js
const config = require ('./config')
```

### cctxの導入
bitflyerのAPIにリクエストするため、[cctx](https://github.com/ccxt/ccxt)というライブラリを利用します。

```
npm install cctx
```

```main.js
const ccxt = require ('ccxt')
const bitflyer = new ccxt.bitflyer (config)

//bitflyerの板情報を取得するメソッドを実行（板はFX_BTC_JPYを指定）
const ticker = await bitflyer.fetchTicker ('FX_BTC_JPY')
```


### 一定間隔で実行
async awaitを利用します。

```main.js
const ccxt = require ('ccxt')
const config = require ('./config')

//10秒
const interval = 10000

const sleep = (timer) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, timer)
    })
}

(async function () {
  while(true) {
    //bitflyerの板情報を取得するメソッドを実行（板はFX_BTC_JPYを指定）
    const ticker = await bitflyer.fetchTicker ('FX_BTC_JPY')
    await sleep(interval)
  }
}) ();

```

### いつ買っていつ売るの
本来ならじっくり考えてそれなりに複雑アルゴリズムが必要なところですが、今回はクソザコなめくじアルゴリズムをとりあえず実装します。

方針としては
- 10秒毎に板情報を取得
- 3回連続で値上がりしていたら買う
- 3回連続値下がりしたら売る
とします。

```main.js
const ccxt = require ('ccxt')
const config = require ('./config')

//過去3回文のデータを保持するところ
const records = []
//注文情報
let order = null
//注文単位 0.01BitCoin
const orderSize = 0.01;

//10秒
const interval = 10000

const sleep = (timer) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, timer)
    })
}

(async function () {
  while(true) {
    //bitflyerの板情報を取得するメソッドを実行（板はFX_BTC_JPYを指定）
    const ticker = await bitflyer.fetchTicker ('FX_BTC_JPY')
    //最終取引価格
    records.push(ticker.last)
    if (records.length > 3) {
      //4つめがきたら古いものを消す
      records.shift()
    }

    if(order) {
      //注文情報がある
      if (records[2] < records[1] && records[1] < records[0]) {
        //売る
        order = await bitflyer.createMarketSellOrder("FX_BTC_JPY", orderSize);
        console.log(order)

        order = null
      }
    }
    else {
      //注文情報がない
      if (records[0] < records[1] && records[1] < records[2]) {
        //購入
        order = await bitflyer.createMarketBuyOrder("FX_BTC_JPY", orderSize);
        console.log(order)
      }
    } 
    
    await sleep(interval)
  }
}) ()
```

### ずっと実行するには？
foreverというツールがあります。
Node.jsを動かし続けるためのツールです。

以下参照
[foreverコマンドでNodeJSアプリを起動したままにする](https://qiita.com/h1y0r1n/items/a2cf8f2e8d3d31ccba49)

### EC2インスタンス
AWSアカウントを取得して適当に立てましょう。
ここはきっとたくさん記事があるのでスキップ。
処理的には全く重くないのでt2.nanoとかでもいいと思います。

## まとめ
人事を尽くして天命を待つ。
もちろんこのアルゴリズムで勝てる時もあれば負ける時もあります。
手を変え品を変えいろんなアルゴリズムを試してますがうまくいかないものですね。
まぁ自分が板にへばりつくよりもはっきりした基準で売買してくれるのでストレスみたいなものはないかも。

よりよいアルゴリズムを考えるゲームだと思うと結構楽しいですよ。