PythonとDockerで簡単に始める！仮想通貨自動売買の全手順：②

## 前回の記事
https://qiita.com/todotodo/items/f608a2024ff05d78afa1

## 背景
`Docker`や`Python`といった技術を単体で勉強してるけど実際に動くシステムを作ったことはない、という方もいるのではないでしょうか。自分もその一人です。
というわけで実際に動くシステムを作りつつ記事としてアウトプットしていきます。
とりあえず何かシステムを作ってみたい方の助けになれば幸いです。

:::note warn
+ 本記事は素人が趣味で作成しているものです
+ 何か間違いがありましたらやさしく教えてくださると嬉しいです
+ 特にセキュリティ面は一切考慮されていません
+ 本記事を参考にして何か不利益を被っても一切責任を取れません
:::

## この記事で何をするのか？
+ `Docker`を使用してシステムのインフラを作成します
+ `Python`による仮想通貨自動売買プログラムを構築します
+ 3部構成のうちの第2弾です
    1\. Dockerによるインフラ構築
    https://qiita.com/todotodo/items/f608a2024ff05d78afa1
    2\. `APIによる仮想通貨価格取得とDBへの格納`
    3\. 売買判断プログラム作成

## 作成するシステムの概要
Host OS上にPythonコンテナとMysqlコンテナで構成します。
Pythonコンテナで仮想通貨データの取得し、MysqlコンテナのDBへ格納します。定期的に売買判断を行い、実際にAPIによって自動注文します。
![システム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2087704/878f6f9c-0cae-6266-c03c-0edd5e655a5f.png)


## `GMO コイン` から仮想通貨価格を取得する
`GMOコイン`はサービスの`API`を提供しています。下記の公式ドキュメントにAPIキーの作成方法からサンプルコードまで丁寧にまとめられています。

https://api.coin.z.com/docs/#restrictions

Host OS の`./app`以下に`GMO_API.py`を作成します。
この`GMO_API.py`ではGMOコイン関係の関数を記述します。
将来的にはapp.pyから呼び出して使用されます。
```terminal
todotodo@vm:~/BTC_Trading$ tree app
app
├── app.py
└── GMO_API.py
```

第1回で作成した`docker-compose.yml`によってHost OS の`./app`はPythonコンテナの`/app`にマウントされているので、Host OS側で作成した`GMO_API.py`がコンテナ内からも見えることが確認できます。
```terminal
todotodo@vm:~/BTC_Trading$ docker compose exec python bash
root@9b0fe47aa47a:/app# ls
GMO_API.py  app.py
```

`GMO_API.py`でBTC価格を取得する関数を定義しています。
```python
import requests
import json

def Get_price(symbol):
    symbol = symbol
    path = '/v1/ticker?symbol=' + symbol
    r = requests.get(url_pub+path)
    price_json = r.json()["data"]
    return price_json

if __name__ == '__main__': 
    print(Get_price('BTC'))
```

実際に実行してみると`BTC`の価格を取得できていることがわかります。
```terminal
root@9b0fe47aa47a:/app# python GMO_API.py 
[{'ask': '14619998', 'bid': '14619550', 'high': '14705851', 'last': '14619998', 'low': '14520000', 'symbol': 'BTC', 'timestamp': '2025-02-08T13:42:45.226Z', 'volume': '177.12065'}]
```

## DBに格納する
Host OS の`./app`以下に`Insert_DB.py`を作成します。
この`Insert_DB.py`では仮想通貨価格(今回は`BTC`)を取得し、Mysqlコンテナ内のDBへ挿入します。

```python
import mysql.connector
import GMO_API

cnx = mysql.connector.connect(
    user='root',
    password='root',
    host='10.10.10.2',
    database='BTC'
)

cursor = cnx.cursor()

insert_query=(
    '''
    INSERT INTO btc_table
        (timestamp, ask, bid, high, low, volume)
    VALUES
        (%s, %s, %s, %s, %s, %s)
    '''
)

json_data = GMO_API.Get_price("BTC")[0]
timestamp = json_data["timestamp"].translate(str.maketrans({'T': ' ', 'Z': ' '}))
ask = json_data["ask"]
bid = json_data["bid"]
high = json_data["high"]
low = json_data["low"]
volume = json_data["volume"]

data = (timestamp, ask, bid, high, low, volume)
cursor.execute(insert_query, data)
cnx.commit()

cnx.close()
cursor.close()
```

Pythonコンテナから`Insert_DB.py`を実行し、Dockerコンテナ内のDBを確認します。
```terminal
todotodo@vm:~/BTC_Trading$ docker compose exec python bash
WARN[0000] /home/stodo/BTC_Trading/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion 
root@814a99804ce9:/app# python Insert_DB.py 

root@814a99804ce9:/app# mysql -u root -h 10.10.10.2 -p
Enter password:
```

仮想通貨価格をDBに格納できていることが確認できました。
```sql
MySQL [(none)]> SELECT * FROM BTC.btc_table;
+---------------------+----------+----------+----------+----------+---------+
| timestamp           | ask      | bid      | high     | low      | volume  |
+---------------------+----------+----------+----------+----------+---------+
| 2025-02-08 14:47:11 | 14583700 | 14583700 | 14705900 | 14520000 | 142.759 |
+---------------------+----------+----------+----------+----------+---------+
1 row in set (0.006 sec)

MySQL [(none)]> 
```

## 定期的に仮想通貨価格を取得する
Linuxでコマンドを定期実行したい際には`cron`を使用します。
今回使用するPythonコンテナには`cron`が入っていないので`Dockerfile`を編集してinstallします。
仮想通貨価格を定期的に取得するため`/etc/crontab`に`Insert_DB.py`を定期実行するようにという命令を書き込みます。今回の場合は3分刻みの取得とします。
`cron`については下記資料で詳しく説明させています。
https://qiita.com/rerofumi/items/fc0126c4e985b78f769b

```Dockerfile
FROM python:latest
RUN apt-get update && \
    apt-get install -y \
    build-essential \
    cmake \
    git \
    sudo \
    wget \
    vim \
    mariadb-client \
    iputils-ping \
    cron
RUN pip install --upgrade pip
COPY ./requirements.txt /requirements.txt    
RUN pip install -r /requirements.txt

WORKDIR /app
RUN echo '*/3 * * * * root python /app/Insert_DB.py' >> /etc/crontab
CMD ["cron", "-f"]
```
変更をコンテナに反映するためコンテナを止めて再度ビルドします。
```terminal
todotodo@vm:~/BTC_Trading$ docker-compose down --rmi all --volumes --remove-orphans
todotodo@vm:~/BTC_Trading$ docker compose build
todotodo@vm:~/BTC_Trading$ docker compose up -d
```
`Insert_DB.py`が定期的に実行されDBにデータが書き込まれています。
```sql
MySQL [(none)]> SELECT * FROM BTC.btc_table;
+---------------------+----------+----------+----------+----------+---------+
| timestamp           | ask      | bid      | high     | low      | volume  |
+---------------------+----------+----------+----------+----------+---------+
| 2025-02-08 14:47:11 | 14583700 | 14583700 | 14705900 | 14520000 | 142.759 |
| 2025-02-09 05:57:01 | 14735000 | 14735000 | 14760000 | 14620000 | 68.5515 |
| 2025-02-09 06:00:01 | 14735000 | 14735000 | 14760000 | 14620000 |  68.508 |
+---------------------+----------+----------+----------+----------+---------+
```

## まとめ
今回は仮想通貨自動売買システムの仮想通貨価格を取得して保存する部分を作成しました。
次回は売買判断をする部分を作成して完成となります！

### 参考資料
https://qiita.com/yokra9/items/f527a7892434d2464886

https://qiita.com/rerofumi/items/fc0126c4e985b78f769b