botにDBが最適かどうかはわからないけど、とりあえず勉強がてらやってみた

# 趣旨
DBについての知識が欲しくなったので勉強目的でとりあえず動くものを作ってみました。
忘れないうちにここにまとめて記録しておきます。

# MySQLサーバーのインストール方法

私はボタン一つでサーバーが立ち上がるサービスを利用しているので、この作業はやっていません。不具合が出ても責任は取れませんのでご了承ください。

## 必要な Linux コマンド
ターミナルを開き、以下のコマンドを実行してMySQLサーバーをインストールします。
```
sudo apt update
sudo apt install mysql-server
```

インストールが完了したら、MySQLサービスが正常に動作していることを確認します。
```
sudo systemctl status mysql
```

インストール後、以下のコマンドを実行してセキュリティを強化します。
```
sudo mysql_secure_installation
```

以下のコマンドを使用してMySQLにログインします。

データベースを作成します。
```
CREATE DATABASE `username$default`;
```
データベースが作成できたか確認します。
```
SHOW DATABASES;
```
使用するデータベースとして指定します。
```
USE `username$default`;
```

スキマを設定します。
```
CREATE TABLE btc_price_data (
    id INT AUTO_INCREMENT PRIMARY KEY,
    date DATETIME NOT NULL,
    open FLOAT NOT NULL,
    high FLOAT NOT NULL,
    low FLOAT NOT NULL,
    close FLOAT NOT NULL,
    volume BIGINT NOT NULL,
    UNIQUE(date)
);
```
```
sudo mysql -u root -p
```
新しいユーザーを登録します。
```
CREATE USER 'username$default' IDENTIFIED BY 'password';
```

ユーザーに権限を付与します。
```
GRANT ALL PRIVILEGES ON *.* TO 'username$default';
```

権限のリロードをします。
```
FLUSH PRIVILEGES;
```
新しいユーザーでログインします。
```
mysql -u username -p
```

# テクニカル分析して注文まで行うコードサンプル

TA-LibをLinux環境にインストールする必要があります。
やり方がわからない場合は以下の記事が参考になります。

https://qiita.com/danieltanaka/items/2eceb81d303e2634bb87

```python: database.py
import yfinance as yf
import pandas as pd
import numpy as np
import talib
import mysql.connector

def place_order(buy_signal):
    # 注文を行う関数。buy_signalを引数として受け取り、その情報に基づいて注文を行います。
    print(f"Placing order based on signal: {buy_signal}")
    # ここに注文するための関数を設定

def fetch_btc_data():
    # yfinanceライブラリを使用して、BTC-USDの価格データを取得する関数。
    btc = yf.Ticker("BTC-USD")
    hist = btc.history(period="1mo", interval="1h")
    hist.reset_index(inplace=True)
    # 取得したデータから特定のカラム（日時、開始価格、最高価格、最低価格、終了価格、取引量）を選択し、返します。
    return hist[['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume']]

# データベースと接続
def connect_to_database():
    # mysql.connectorを使用してMySQLデータベースに接続する関数。
    return mysql.connector.connect(host='host', 
                                   database='username$default', 
                                   user='username', 
                                   password='password')

# データベースにデータを保存
def store_data_in_mysql(data):
    # 引数で受け取ったデータ（Pandas DataFrame）をMySQLデータベースに保存する関数。
    connection = connect_to_database()
    cursor = connection.cursor()
    insert_query = """
    INSERT INTO btc_price_data (date, open, high, low, close, volume)
    VALUES (%s, %s, %s, %s, %s, %s)
    ON DUPLICATE KEY UPDATE open=VALUES(open), high=VALUES(high), low=VALUES(low), close=VALUES(close), volume=VALUES(volume);
    """
    for row in data.itertuples(index=False, name=None):
        # データフレームの各行をタプルとして取得し、データベースに挿入します。
        datetime_val = row[0]  # 'Datetime'は最初の要素です。
        open_val = row[1]
        high_val = row[2]
        low_val = row[3]
        close_val = row[4]
        volume_val = row[5]
        
        # データベースの日時形式に合わせて、日時を文字列に変換する必要がある場合があります。
        datetime_str = datetime_val.strftime('%Y-%m-%d %H:%M:%S')

        cursor.execute(insert_query, (datetime_str, open_val, high_val, low_val, close_val, volume_val))
    connection.commit()
    cursor.close()
    connection.close()

# データベースからデータを取得・分析
def fetch_and_analyze_data():
    # データベースからBTC価格データを取得し、RSI指標を計算して分析する関数。
    connection = connect_to_database()
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM btc_price_data ORDER BY date ASC")
    rows = cursor.fetchall()
    cursor.close()
    connection.close()

    dates = [row[1] for row in rows]
    close_prices = np.array([row[5] for row in rows], dtype=float)
    rsi = talib.RSI(close_prices)

    if len(rsi) > 0 and rsi[-1] < 30:
        # RSI指標が30未満の場合、購入シグナルとして検出し、その情報を表示します。
        buy_signal = (dates[-1], close_prices[-1], rsi[-1])
        print(f"Buy Signal on {buy_signal[0]} - Close Price: {buy_signal[1]}, RSI: {buy_signal[2]}")
        place_order(buy_signal)
    else:
        # 購入シグナルが検出されなかった場合、その旨を表示します。
        print("No buy signal detected.")

# メイン関数。データを取得し、データベースに保存後、データを分析します
def main():
    data = fetch_btc_data()
    store_data_in_mysql(data)
    fetch_and_analyze_data() 

```