2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

さくらのVPS for Windows Server と ngrokを活用したTradingView bot の構築

Last updated at Posted at 2024-03-02

さくらのVPS for WindowsServer と ngrokを活用したTradingView bot の構築方法

以前はCloud Functionsを利用してBYBITなどの海外取引所で自動売買botを容易に作成できました。しかし、最近BYBITをはじめとする海外取引所では、アメリカのIPアドレスからのAPIアクセスを制限するようになりました。この変更により、自動売買botの作成が困難になっています。他の方法で実現可能かもしれませんが、インターネット上での情報は見つかりません。

TradingViewの魅力は、仮想通貨だけでなく、指数、商品、株価など様々なマーケットを比較しやすく、簡単にバックテストができる点にあります。この便利さを活かして、TradingView botの構築に取り組み始めました。

上記のリンクは、参考にしたウェブサイトです。今回は、Bybitで使用できるように修正、またさくらのVPS for Windows Serverで動かす所までをやっていきます。

今回作成したmain.pyは最初にポジションを持っている前提のプログラムです。
初期実行時は手動でポジションを持って下さい。ヘッジモードでは正常に動作しません。

・環境構築確認用プログラム post_requests.pyを作成、実行
・TradingViewでストラテジーの設定、Webhook経由のアラート通知を設定する

上記2項目以外は全て、さくらのVPS for Windows Server上で操作を行い、ngrok.exeとmain.pyを常時起動する必要があります。

必要な手順

1. TradingViewのEssentialプランの契約
月額14.95$ (年次契約12.95
2. さくらのVPS for Windows Server の契約
月額1,210円 CPU 仮想2Core メモリ 1GB SSD 50GB リージョン 大阪、石狩
3. ngrokのアカウント作成とインストール
4. ngrokを起動してWebhook用のURLを取得する
5.Webhook経由のアラートを受信したら売買するプログラムを準備
6.TradingViewでストラテジーの設定、Webhook経由のアラート通知を設定する

1. TradingViewのEssentialプランの契約

TradingViewに契約してない方は、月額で契約した方が良いと思います。毎年ブラックフライデー前後で格安になる時期があるので、それまで待った方が得策です。

2. さくらのVPS for Windows Server の契約

VPSにはサーバータイプとWindows環境の2つあります。
サーバータイプはOSがCentOS、AlmaLinux、Rocky Linux 、Ubuntu 、KUSANAGI、Debianと普段見かけないOSばかりです。初学者はWindows Serverがオススメです。環境設定等、余計な所でハマる事が多いのでお金で時間を買う感覚です。
スクリーンショット 2024-03-02 162257.png

自分は1Gの契約ですが、
TradingView bot と 他のbotの合計2つbotを動かしても割と余裕あります

3. ngrokのアカウント作成とインストール

高頻度に取引を行う以外、フリープランで大丈夫です。
ここからはさくらのVPS for Windows Serverの画面上で行います。

登録が終わると画面左側のGetting Started項目の中
Setup&installationに進みます
スクリーンショット 2024-03-02 163841.png

さくらのVPS for Windows Serverにインストールしていきます。
スクリーンショット 2024-03-02 162539.png
インストールの仕方はサイトに分かりやすく記載されていますが、

インストールするコマンド
choco install ngrok

上記コマンドはさくらのVPS for Windows Serverの初期状態では使えないので、DLしてインストールしましょう。
インストールしたら、DLしたファイルをダブルクリックしてngrok.exeを開きます

4. ngrokを起動してWebhook用のURLを取得する

次にアカウントの認証を行います。
スクリーンショット 2024-03-02 162802.png

ngrokの管理画面からYour Aauthtokenを確認することができます。

こちらを利用して認証作業を行います。

Command Lineのコマンドを、ngrok.exe画面に入力。
ここでngrokの準備は完了です

次にWebhook用のURLを取得します。

Webhook用のURLを取得
ngrok http 40

上記コマンドを入力すると次のような画面が表示されます。

スクリーンショット 2024-03-02 165658.png

Forwardingのhttps:~~~~~ngrok-free.appまでがTradingViewでwebhookに入力するURLです。freeプランだと起動する毎に~~~部分が変更になるので注意して下さい。

次にポートの開放をやっていきます

スクリーンショット 2024-03-02 170310.png
Windows Defender ファイヤーウォールを開きます
詳細設定から
受信の規則 から 新しい規則を作成します。画像と同じ様に設定してください。
プロトコルの種類を”TCP"
ローカルポートを”特定のポート”
ポート番号を”4040”にして下さい。

ローカルPCだとngrok http 80 で作成して、ローカルポート80を開放で良かったんですが、何故かVPSだと上記設定じゃないとダメでした。良く分かりません。詳しい人教えてください

ここまでで、webhookを受信する設定は完了です。
これからテストプログラムを使って動作確認していきます。

次はpost_requests.pyを作成して正しく受信できるか確認します
下記プログラムをローカルPCで作成実行してください。

post_requests.py
#ローカルPCで作成、実行
import requests
import time

url = "https:~~~~~ngrok-free.appまで入力/webhook"

requests.post(url=url, json={"contents": "test message"})

さくらのVPS for Windows Serverのngrok.exeで正しく受信できたら、画面上に出力されます
スクリーンショット 2024-03-02 165658.png
200 OK!!
スクリーンショット 2024-03-02 172111.png

5. Webhook経由のアラートを受信したら売買するプログラムを準備

main.py
import http.server
import socketserver
import json
import time
from pybit.unified_trading import HTTP
import os
from os.path import join, dirname
from dotenv import load_dotenv

# .env ファイルのパスを設定
dotenv_path = join(dirname(__file__), '.env_bybit_key')
load_dotenv(dotenv_path, verbose=True)

api_key = os.getenv("BYBIT_API_KEY")
api_secret = os.getenv("BYBIT_API_SECRET")

# セッションの初期化
session = HTTP(
    testnet=False,  # 実際の環境での使用の場合
    api_key=api_key,
    api_secret=api_secret,
)



def position_entry(side):
    try:
        print(session.place_order(
            category="linear",
            symbol="BTCUSDT",
            side=side,
            orderType="Market",
            qty=0.01,
            positionIdx = 0
        ))
    except Exception as e:
        print(e)
def position_close(side):
    try:
        print(session.place_order(
            category="linear",
            symbol="BTCUSDT",
            side=side,
            orderType="Market",
            qty=0.01,
            positionIdx = 0,
            reduceOnly = True
        ))
    except Exception as e:
        print(e)
        

class WebhookHandler(http.server.BaseHTTPRequestHandler):
    def do_POST(self):
        
        # データの抽出
        content_length = int(self.headers['Content-Length'])
        req_body = self.rfile.read(content_length).decode("utf-8")
        
        try:
            # JSONとしてデータを解析
            data = json.loads(req_body)
            
            # 'side'キーの値に基づいて処理を分岐
            if 'side' in data:
                if data['side'] == 'buy':
                    print("side_buy")  # 買い注文の場合
                    position_close("Buy")#決済
                    time.sleep(0.1)#0.1秒待機
                    position_entry("Buy")#新規注文
                    
                if data['side'] == "sell":
                    print("side_seLL")  # 売り注文の場合
                    position_close("Sell")#決済
                    time.sleep(0.1)#0.1秒待機
                    position_entry("Sell")#新規注文
                    
        except json.JSONDecodeError:
            print("受信したデータは有効なJSON形式ではありません。")

        # ステータスコード200を返す
        self.send_response(200)
        self.end_headers()
        
with socketserver.TCPServer(("", 40), WebhookHandler) as httpd:
    print("サーバー起動中...")
    httpd.serve_forever()

.env_bybit_key
BYBIT_API_KEY=************
BYBIT_API_SECRET=************

main.pyと.env_bybit_keyをさくらのVPS for Windows Serverに用意します
main.pyの
with socketserver.TCPServer(("", 40), WebhookHandler) as httpd:
上記部分は自分の開いたポートに変更してください

6. TradingViewでストラテジーの設定、Webhook経由のアラート通知を設定する

スクリーンショット 2024-03-02 175017.png

設定のメッセージ欄に設定します

{"side":"{{strategy.order.action}}"}

webhook URLを設定したら完了です。

全てが完了したら実際にポジションを持つか確認してみましょう

動作確認.py

import requests

# WebhookのURL (ngrokなどでローカルサーバーを外部に公開)
url = "https://12c-12.121212.ngrok-free.app"

# 送信するデータ
data = {"side":"sell"} 
# POSTリクエストを送信
response = requests.post(url=url, json=data)

# レスポンスのステータスコードを出力
print(f"Status Code: {response.status_code}")

# レスポンスの内容を出力
print(f"Response: {response.text}")

まとめ

初期ポジションは手動で持つ前提を忘れないでください。
今回説明にセキュリティ面は省いたので、各自で設定を忘れずに行って下さい。

webhook発動からポジションを持つまで5秒ほどかかります。

良いbotterライフを!!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?