richmanbtc先生式のMLBOTを作りたい。
前回の記事ではrichmanbtc先生のチュートリアルを入門して一通りなぞってみました。
MLBOTチュートリアル部分では
過去データの読み込み~バックテストまでで、
肝心なBOTの作り方と設置方法がのってなかったので自分で調べて作ってみます。
今回はBOTの実装とBOTの設置までやりたいです。
Table of Contents
BOTの作り方
今回0から自分で調べて作ります。手順としては、こんな感じでやっていきます。
①こういうの出来たらいいなぁ(ゴール設定)
②ネットでググる
③(*’ω’)ひらめく
④メモる
⑤書き出す
⑥実装する
最初はなんとなく「こういうの作りたいなぁ」というのを決めます。そして周辺知識を調べてメモるを繰り返します。先にゴールを設定して必要なものを割り出します。
richmanbtc方式のBOTを作ってサーバー設置までしたい(ゴール設定)
以下、調べたことと閃いたこと覚えたこことです。
- Dockerをそのままサーバーに置ける方法が楽みたい。
- GCPに無料枠あるらしい
- ConohaVPSがおすすめらしい
- AWS使った方がいいよ派もいるみたい
- Pythonの無限ループ式のBOTで良さそう
- Pandasでローソク足作れる
- Pybottersというライブラリが良さそう
- ローソク足15分足作ればいけそう
- SSHなどの設定めんどくさそう
- Dockerでいい
- テクニカル指標ライブラリのTa-lib付きのDockerイメージがあるみたい
- エディタはVScodeが良さそう
- GCPは使った分だけ課金なので良さそう
決定事項
- Docker
- pandas
- Pybotters
- GCPでDocker動かす
- VScode
ここまで調べたので、スモールステップでちょっとづつ手を動かします。
手始めに最小限のDockerイメージを作ってGCPに設置、Pythonを動かすまでしてみます。
DockerはYoutubeの動画を観て少し理解しました。
まずはDockerにPython入れてイメージにしてGCPに入れます。一行のファイル作ってUP。ログが表示されれば設置完了になります。
1 |
print("Hello World") |
また調べてみると、Dockerファイルの保管するサービスとコードを保管するサービスとPythonを実行するサーバーサービスと3つ使う必要があるそうです。
Pythonコード、Dockerファイルの保管、バージョン管理 | GitHub |
Python実行するサーバー | Cloud Run |
GitHub新規リポジトリ作成
GitHubにコードを保存していきます。


Privateで非公開リポジトリです。

これ使う。
1 2 3 4 5 6 7 |
echo "# mlbot-hosono-style" >> README.md git init git add README.md git commit -m "first commit" git branch -M main git remote add origin https://github.com/harukihosono/mlbot-hosono-style.git git push -u origin main |






ここにコードを順次アップロードします。
Visual Studio Codeをインストール
VSCodeをインストールします。
使い方はしまぶーさんに動画がわかりやすい。
VSCodeでGitHubに接続します。
コードの保存→GitHubのリポジトリにプッシュでコード管理できます。
設置するサーバーを悩む
サーバーってどこ使えばいいんだろ。
GCPには仮想PCサービスがあってメモリから選べたりします。
でもメモリ・ディスク・CPU・GPU・ネットワーク・DNS・固定IP・ネットワークとインフラ周りの知識が必須になるのでちょっと難しい。
サーバーレスという選択
昨日は仮想PCで作ろうと思ったけどかなり工程が難しかったのでサーバーレスサービスであるCloud Runでいいなと思いました。
ネットに転がっているのがWhileループ型のBOTなので一回落ちたらメモリのデータが消滅してしまいます。
そこで、データベースに価格を保存するBOTとデータベースから価格を取得するBOTをつくる方法を考えました。
このほうがシンプルですしね。
Dockerで一番簡単なファイルをつくってGitHubにプッシュ

フォルダ構成
bot/
├ Dockerfile
├ sample.py
1 2 3 |
FROM python:3.9-slim-buster COPY sample.py sample.py CMD python sample.py |
1 |
print("Hello World") |
これでGitHubにプッシュします。

Cloud Runにデプロイ







ちょっと待つとGitHubのコードを読み取りCloudRunへ自動でデプロイ(設置)されます。

エラーでました。公式チュートリアル読むとWebアプリである必要があるみたいです。

でもログにHelloWorldが表示されているのでデプロイは問題なくできたようです。
公式チュートリアルのコードを参考にして元のコードを改変します。
PythonライブラリFlaskでWebアプリ化させます。
sample.py →main.py
フォルダ構成
bot/
├ Dockerfile
├ main.py
1 2 3 4 5 6 7 |
FROM python:3.9-slim-buster ENV PYTHONUNBUFFERED True ENV APP_HOME /app WORKDIR $APP_HOME COPY . ./ RUN pip install Flask gunicorn CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app |
1 2 3 4 5 6 7 |
from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return "Hello World" if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=8080) |
改変したのをGitHubにプッシュして、コンソールから未承認のURLを許可してアクセスしてみると、


Hello Worldがブラウザに表示されました。これで、OK。

認証をいれて非公開にします。
ここまでを振り返ると、PythonをGCPへ設置が完了まで出来ました。
次は価格保存用のデータベースを用意します。
データベースの準備
色々と調べたのですが、従来からあるSQLはGCPで使おうとすると月額料金が3000円ぐらいかかるみたいだったので、格安で使える「FIrestore」を使います。
詳しい人はコメントで教えてください
データベースの準備




ここに価格情報をいれていきます。
まずはデータベースのテストします。
Dockerファイル更新 ー RUN pip install google-cloud-firestore を 追加。
ライブラリgoogle-cloud-firestore を追加、データベースへ書き込むコードを追加
bot/
├ Dockerfile
├ main.py
1 2 3 4 5 6 7 8 |
FROM python:3.9-slim-buster ENV PYTHONUNBUFFERED True ENV APP_HOME /app WORKDIR $APP_HOME COPY . ./ RUN pip install Flask gunicorn RUN pip install google-cloud-firestore CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#--------------------------------------------------- # DB #--------------------------------------------------- from google.cloud import firestore def setDB(): db = firestore.Client() doc_ref = db.collection("test").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'name': 'Test' }) #--------------------------------------------------- # Webアプリ化 #--------------------------------------------------- from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): setDB() #データベース書き込み return "Hello World" if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=8080) |
GitHubにプッシュしたのでこれでデータベースへ書き込みテストします。
ブラウザでHelloWorldを更新するとデータベースへ書き込みされると思います。


コレクションは”test”
ドキュメントは空白なのでユニークなIDが付与されるみたいです。
フィールドの作成日時はUTC+9なので日本時間です。
書き込みできたのでデータベースの読み込みしてみましょう。
データベース書き込みから読み込みに変更します。
bot/
├ Dockerfile
├ main.py
1 2 3 4 5 6 7 8 |
FROM python:3.9-slim-buster ENV PYTHONUNBUFFERED True ENV APP_HOME /app WORKDIR $APP_HOME COPY . ./ RUN pip install Flask gunicorn RUN pip install google-cloud-firestore CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#--------------------------------------------------- # DB #--------------------------------------------------- from google.cloud import firestore def setDB(price): db = firestore.Client() doc_ref = db.collection("test").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'price': price }) def getDB(): db = firestore.Client() docs = db.collection("test").stream() #データベース読み込み data = docs[0].to_dict() #データを辞書型に変換 return data #--------------------------------------------------- # Webアプリ化 #--------------------------------------------------- from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): data = getDB() #データベース読み込み return data if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=8080) |

よーし次はリアルタイムティックでリアルタイムに価格を取得してデータベースへ書き込むプログラムですね。
GMOコインから価格を取得してデータベースへ書き込む
richmanbtc式のBOTは15分足があればOK
GMOコインでKline(始値、高値、安値、終値、取引高)情報を取得できるみたいです。
しかし、前日の価格しか取得できません。
今回は、何秒おきに価格を取得してデータベースへ書き込むスクリプトを作成します。
GMOコインから価格取得してみます。

コピペで動きましたのでこれ使います。
実行結果はこちら

1 2 3 4 5 6 |
import requests import json endPoint = 'https://api.coin.z.com/public' path = '/v1/ticker?symbol=BTC' response = requests.get(endPoint + path) print(json.dumps(response.json(), indent=2)) |
現在価格がリアルタイムティックで取得出来ています。
データベースへ書き込むコードを変更します。
変更前
1 2 3 4 5 6 7 |
def setDB(): db = firestore.Client() doc_ref = db.collection("test").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'name': 'Test' }) |
変更後
1 2 3 4 5 6 7 |
def setDB(prices): db = firestore.Client() doc_ref = db.collection("price").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'prices': prices }) |
コレクション名を”price”へ変更
引数priceを受け取りpriceをデータベースへ書き込みます。
GMOのコードを価格を返す関数に変更します。
変更前
1 2 3 4 5 6 |
import requests import json endPoint = 'https://api.coin.z.com/public' path = '/v1/ticker?symbol=BTC' response = requests.get(endPoint + path) print(json.dumps(response.json(), indent=2)) |
変更後
1 2 3 4 5 6 7 8 9 10 |
import requests def get_gmo_price(symbol): endPoint = 'https://api.coin.z.com/public' path = '/v1/ticker?symbol='+symbol response = requests.get(endPoint + path) data = response.json() price = data["data"][0] return price symbol="BTC" get_gmo_price(symbol) |
現在のファイル構成です。
bot/
├ Dockerfile
├ main.py
1 2 3 4 5 6 7 8 9 |
FROM python:3.9-slim-buster ENV PYTHONUNBUFFERED True ENV APP_HOME /app WORKDIR $APP_HOME COPY . ./ RUN pip install Flask gunicorn RUN pip install google-cloud-firestore RUN pip install requests CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#--------------------------------------------------- # GMOから価格を取得 #--------------------------------------------------- import requests def get_gmo_price(symbol): endPoint = 'https://api.coin.z.com/public' path = '/v1/ticker?symbol='+symbol response = requests.get(endPoint + path) data = response.json() price = data["data"][0] return price #--------------------------------------------------- # DB #--------------------------------------------------- from google.cloud import firestore def setDB(price): db = firestore.Client() doc_ref = db.collection("price").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'price': price }) def getDB(): db = firestore.Client() docs = db.collection("price").stream() #データベース読み込み data = docs[0].to_dict() #最新データを辞書型に変換 return data #--------------------------------------------------- # Webアプリ化 #--------------------------------------------------- from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): symbol="BTC" #symbolを指定 price = get_gmo_price(symbol) #GMOに価格を取得 setDB(price) #priceをデータベースに書き込む data = getDB() #データベースの最新データを読み込み return data if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=8080) |

起動すれば最新価格をデータベースに保存します。
Cloud Schedulerで定期実行させる
アプリを定期的に起動させれば価格がデータベースに入る。
Cloud Schedulerで1分間おきに実行させてみます。





これでデータベースに定期的に価格が保存されます。

あとはアプリを1分間価格取得するように変更します。
アプリを1分間価格取得するように変更
bot/
├ Dockerfile
├ main.py
1 2 3 4 5 6 7 8 9 |
FROM python:3.9-slim-buster ENV PYTHONUNBUFFERED True ENV APP_HOME /app WORKDIR $APP_HOME COPY . ./ RUN pip install Flask gunicorn RUN pip install google-cloud-firestore RUN pip install requests CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#--------------------------------------------------- # 1分間起動させる #--------------------------------------------------- def for_1_minute(): prices=[] for i in range(20): symbol="BTC" #symbolを指定 price = get_gmo_price(symbol) #GMOに価格を取得 prices.append(price) time.sleep(3) setDB(prices) #priceをデータベースに書き込む return "価格取得とDB書き込み完了" #--------------------------------------------------- # GMOから価格を取得 #--------------------------------------------------- import requests def get_gmo_price(symbol): endPoint = 'https://api.coin.z.com/public' path = '/v1/ticker?symbol='+symbol response = requests.get(endPoint + path) data = response.json() price = data["data"][0] return price #--------------------------------------------------- # DB #--------------------------------------------------- from google.cloud import firestore def setDB(prices): db = firestore.Client() doc_ref = db.collection("price").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'prices': prices }) def getDB(): db = firestore.Client() docs = db.collection("price").stream() #データベース読み込み data = docs[0].to_dict() #最新データを辞書型に変換 return data #--------------------------------------------------- # Webアプリ化 #--------------------------------------------------- from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): data = for_1_minute() return data if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=8080) |

単数だと無料枠を超えるのでリストで一度にデータベースに書き込みして書き込み回数を減らす。読み込みも課金防止のため出来るだけ少なくするとよさそう。
変更前
1 2 3 4 5 6 7 |
def setDB(price): db = firestore.Client() doc_ref = db.collection("price").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'price': price }) |
変更後
1 2 3 4 5 6 7 |
def setDB(prices): db = firestore.Client() doc_ref = db.collection("price").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'prices': prices }) |
これで1個目の価格情報を取得してデータベースに保存するBOTが完成。
次はデータベースから価格情報を取得して過去のデータベース削除するやつ作りたい
今日はここまで、気が向いたら更新します。
データベースから価格情報を取得して過去のデータは削除して綺麗にたもつ
データベースから価格情報を取得して過去のデータベース削除するやつ作りたい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#--------------------------------------------------- # Webアプリ化 #--------------------------------------------------- from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): data = for_1_minute() return data #追加 @app.route("/trade") def trade(): data = for_1_minute() return data if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=8080) |
エンドポイントを増やして機能を拡大させてみます。
ごちゃごちゃしてきたのでClass化させてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
import time import requests from google.cloud import firestore class Get_price: #--------------------------------------------------- # 1分間起動させる #--------------------------------------------------- def for_1_minute(self): prices=[] for i in range(20): symbol="BTC" #symbolを指定 price = self.get_gmo_price(symbol) #GMOに価格を取得 prices.append(price) time.sleep(3) self.setDB(prices) #priceをデータベースに書き込む return "価格取得とDB書き込み完了" #--------------------------------------------------- # GMOから価格を取得 #--------------------------------------------------- def get_gmo_price(self,symbol): endPoint = 'https://api.coin.z.com/public' path = '/v1/ticker?symbol='+symbol response = requests.get(endPoint + path) data = response.json() price = data["data"][0] return price #--------------------------------------------------- # DB #--------------------------------------------------- def setDB(self,prices): db = firestore.Client() doc_ref = db.collection("price").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'price': prices }) def getDB(self): db = firestore.Client() docs = db.collection("price").stream() #データベース読み込み data = docs[0].to_dict() #最新データを辞書型に変換 return data class Create_Candle: #--------------------------------------------------- # DB #--------------------------------------------------- def deleteDB(self): db = firestore.Client() docs = db.collection("price").stream() #データベース読み込み for doc in docs: db.collection("price").document(doc.id).delete() #--------------------------------------------------- # Webアプリ化 #--------------------------------------------------- from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): get_price=Get_price() data = get_price.for_1_minute() return data @app.route("/trade") def trade(): create_Candle=Create_Candle() create_Candle.deleteDB() return "データベース削除" if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=8080) |
Class2個作ってエンドポイントでBOT機能分けました。

とりあえず、データベース削除機能つけたのでこれも定期実行させます。

今日はここまでで。
思ってたよりも料金がかさむ
ごめんなさい。
Cloud Runで24時間稼働させて価格を取得するように設定したけど、思ったよりも料金がかさんでしまいました。

価格を取得する機能をCloud Functionに移植します。
急遽Cloud RunをCloud Functionsへ変更









1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import time import requests from google.cloud import firestore class Get_price: #--------------------------------------------------- # 1分間起動させる #--------------------------------------------------- def for_1_minute(self): prices=[] for i in range(20): symbol="BTC" #symbolを指定 price = self.get_gmo_price(symbol) #GMOに価格を取得 prices.append(price) time.sleep(3) self.setDB(prices) #priceをデータベースに書き込む return "価格取得とDB書き込み完了" #--------------------------------------------------- # GMOから価格を取得 #--------------------------------------------------- def get_gmo_price(self,symbol): endPoint = 'https://api.coin.z.com/public' path = '/v1/ticker?symbol='+symbol response = requests.get(endPoint + path) data = response.json() price = data["data"][0] return price #--------------------------------------------------- # DB #--------------------------------------------------- def setDB(self,prices): db = firestore.Client() doc_ref = db.collection("price").document() doc_ref.set({ 'created': firestore.SERVER_TIMESTAMP, 'price': prices }) def getDB(self): db = firestore.Client() docs = db.collection("price").stream() #データベース読み込み data = docs[0].to_dict() #最新データを辞書型に変換 return data #--------------------------------------------------- # Webアプリ化 #--------------------------------------------------- #不要な部分削除 #引数request追加 def hello_world(request): get_price=Get_price() data = get_price.for_1_minute() return data #不要な部分削除 |
1 2 |
requests google-cloud-firestore |
①Cloud RunのコードをコピペでCloud Functions へ貼り付けします。
②hello_world() → hello_world(request)
③Webアプリ化の不要な部分を削ります。
④外部ライブラリの
・requests
・google-cloud-firestore
はrequirements.txtに記載すると pip install してくれます。
Cloud Functions では「価格取得の取得」と「データベースへの価格保存」までの役割を持たせます。
ローソク足15分足4本値(OHLC)を作る
ここからはPythonの表計算ライブラリのpandasを使っていきます。
pandasのohlc()という関数を使うと価格情報をohlcに変換してくれます。
自分のパソコンからGCPのデータベースにアクセスするには?
こっからちょっと難しい。
GCPのアプリからデータベースへは自動的に認証されてアクセスが出来ますがローカルPC(自分のPC)からGCPのDBにアクセスする方法ってどうやるんでしょうか?
そこで登場するのがGCPの認証システムです。
秘密鍵という”権限の許可証”を発行します。
やってみたほうが理解しやすいと思うのでとりあえずやってみましょう。
























お疲れ様でした。
以上でデータベースの許可証の発行と鍵の保存まで完了です。
データベースへの許可証である秘密鍵は公開しないように気をつけてください。
Firestoreに自分のパソコンから接続してみる
自分のPCからGCPのFirestoreデータベースへ接続します。





1 2 3 4 5 6 7 8 9 |
import firebase_admin from firebase_admin import credentials from firebase_admin import firestore # Use a service account cred = credentials.Certificate('key.json') firebase_admin.initialize_app(cred) db = firestore.client() docs = db.collection("price").get() print(docs[0].id) |
ドキュメントのフィールドを取得してみよう
変更前
1 2 |
docs = db.collection("price").get() print(docs[0].id) |
変更後
1 2 |
docs = db.collection("price").get() print(docs[0].to_dict()) |

改行されてないから読みづらいですね。
今度はライブラリpprintを使ってデータを読みやすくしてみましょう。
1 2 3 |
docs = db.collection("price").get() from pprint import pprint pprint(docs[0].to_dict()) |

BOT開発、この作業死ぬほどやりますw
必要な情報が”現在価格”と”時刻”ですね。
1 2 3 4 |
docs = db.collection("price").get() from pprint import pprint pprint(docs[0].to_dict()["price"][0]["last"]) pprint(docs[0].to_dict()["price"][0]["timestamp"]) |
priceの0番目の”last”
priceの0番目の”timestamp”
を表示させてみます。

おさらいするとデータベースの価格情報までアクセスできました。
次は表計算ライブラリのpandasにデータを読み込ませる。
表計算ライブラリのpandasを使う
まずはインストールします。

1 |
pip install pandas |
テスト用にpandas-test.pyファイルを作る

まずは適当にテスト
1 2 3 |
import pandas as pd df = pd.DataFrame( [[30000,20220601],[30100,20220602]], columns=['価格','時刻'] ) print(df) |

df.set_index(‘時刻’, inplace = True)でindexを指定します。
1 2 3 4 |
import pandas as pd df = pd.DataFrame( [[30000,20220601],[30100,20220602]], columns=['価格','時刻'] ) df.set_index('時刻', inplace = True) #追加 print(df) |

datetime型でサンプルつくる
1 2 3 4 |
import pandas as pd dates = pd.date_range('2022-06-01', '2022-06-30', freq='B') df = pd.DataFrame({'price': 30000 + dates.day}, index=dates) print(df) |

1 2 3 4 5 6 7 |
Highlighing Code Block のインストール HTML として保持 import pandas as pd dates = pd.date_range('2022-06-01', '2022-06-30', freq='B') df = pd.DataFrame({'price': 30000 + dates.day}, index=dates) ohlc = df['price'].resample('W').ohlc() print(ohlc) |

あとはかくかくしかじかで
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#--------------------------------------------------- # データベースへのアクセス #--------------------------------------------------- import firebase_admin from firebase_admin import credentials from firebase_admin import firestore # Use a service account cred = credentials.Certificate('key.json') firebase_admin.initialize_app(cred) db = firestore.client() docs = db.collection("price").get() #--------------------------------------------------- # データベースの値を配列に変換 #--------------------------------------------------- import datetime date=[] price=[] datas = docs[0].to_dict()["price"] for data in datas: str = data["timestamp"] str = str.replace("T"," ") str = str[:-5] str = datetime.datetime.strptime(str, '%Y-%m-%d %H:%M:%S') date.append(str) price.append(float(data["last"])) #--------------------------------------------------- # pandas #--------------------------------------------------- import pandas as pd ser1 = pd.Series(data = price, index = date ,name="pirce") df = pd.DataFrame ({"price":price}, index=date) ohlc = df["price"].resample('10S').ohlc() print(ohlc) |

今日はここまでで
BybitがGoogleのIPアドレス規制をしているためです。国内のVPSなら使…
自分のbotで使ってるAPIキーを使用しているんですが、 You have br…
pybit 最新版にコードを変更しました。コードとrequirements.tx…
お返事ありがとうございます。はい。pybit==2.3.0になっております。
コードはあっていると思います。rewuirements.txtは「pybit==…