見出し画像

初心者用のBOTサンプルです

どうもです。みなさん本当にお久しぶりです。初めての方はこんにちはmac_botterです。

かなり久しぶりの投稿になりますが、今回投稿する内容はタイトルにあります通り、弄って良し、そもまま使って挙動を確認するも良しの「初心者用のBOTサンプル」になります。本文で軽く解説をしています。気になる方はぜひ読んでみてください。

ちなみにロジックにつきましてはシグナルの王道にして滅多に活躍しないゴールデンクロスとデットクロスです。

最近はBTCの氷河期とも巷では言われたりしていて、手持ち無沙汰な感じなので新しいことでも始めてみようって方もそこそこいるのではないでしょうか。

そういう方たちの参考になれば嬉しいです。私も今回は新しいライブラリを使ってBOTを作ってみました。

使用したライブラリ
・pybotters(まちゅけん様)
ライブラリのURLはこちらになります。

ではBOTの方を見ていきましょう。

Bybitです。また、今回はテストネットを利用しています。皆さんも実際のお金を動かすのが躊躇われる方は利用してみてはいかがでしょうか。

実行環境
・macOS
・Python 3.8
・pybotters

ロジック
ロジックは先ほども記述した通り。ゴールデンクロスとデットクロスをシグナルとして売買していきます。

この記事を見ている方でゴールデンクロス、デットクロスを知らない方はおそらくいないでしょうが一応改めて簡単に説明していきます。

ゴールデンクロス
短期移動平均線が中期(長期)移動平均を下から上に突き抜ける現象

デットクロス
短期移動平均線が中期(長期)移動平均を上から下に抜く現象

これらがゴールデンクロス、デットクロスになります。このBOTでは現在の状況をフラットな状態としてそこからゴールデンクロスに転じればBuy 、デットクロスに転じればSellを成り行きで執行します。

この場合、最初だけ自分が設定したロットで売買を行い、次の売買からは自分が設定したロットの2倍のロットで売買を行うことで現在のポジションの決済と新規の注文を同時に行うことになります。

例)10ドル買い->20ドル売り->20ドル買い->20ドル売り

この場合保有しているポジションはずっと10ドル分となります。

ではコードです。pybotterの詳しい使い方は上記のサイトをご覧ください。

import asyncio
import time
import numpy as np
import pybotters


# apis
apis = {
   'bybit_testnet': ['', '']
}

#移動平均を計算する関数
def moving_average(data, w):
   return np.convolve(data, np.ones(w), 'valid') / w

async def main():
   async with pybotters.Client(apis=apis, base_url='https://api-testnet.bybit.com') as client:
       #現在のorderを全部キャンセル
       await client.post('/v2/private/order/cancelAll')
       #現在positionを持っていたら待機
       while True:
           P = await client.get('/v2/private/position/list', params={'symbol': 'BTCUSD'})
           P = await P.json()
           if P['result']['side'] == 'None':
               break
           await asyncio.sleep(5.0)
       
       situation  = ''
       # メインループ
       while True:
           # REST APIデータ並列リクエスト
           resps = await asyncio.gather(
               client.get('/v2/public/kline/list', params={
                   'symbol': 'BTCUSD', 'interval': 1, 'from': int(time.time()) - 7200
               }),
               client.get('/v2/private/order', params={'symbol': 'BTCUSD'}),
               client.get('/v2/private/position/list', params={'symbol': 'BTCUSD'}),
           )
           kline, order, position = await asyncio.gather(*[r.json() for r in resps])

           # シグナル計算
           close = []
           close = [float(kline['result'][i]['close']) for i in range(len(kline['result']))]
           close = np.array(close)
           #短期,中期の移動平均を計算
           st = moving_average(close, 25)
           st = st[-1]
           mt = moving_average(close, 75)
           mt = mt[-1]
           if situation == '':
               if max(st,mt) == st:
                   situation = 'GC'
               else:
                   situation = 'DC'
                   
           cond = False
           side = ''
           #ドル
           qty = 10
           if situation == 'GC':
               if max(st,mt) == mt:
                   cond = True
                   side = 'Sell'
                   situation = 'DC'
                   print(side)
           elif situation == 'DC':
               if max(st,mt) == st:
                   cond = True
                   side = 'Buy'
                   situation = 'GC'
                   print(side)
           print(st,mt,situation)

           # オーダー執行
           if cond:
               P = await client.get('/v2/private/position/list', params={'symbol': 'BTCUSD'})
               P = await P.json()
               if P['result']['side'] != 'None':
                   qty*=2
               await client.post('/v2/private/order/create', data={
                   'symbol': 'BTCUSD',
                   'side': side,
                   'order_type': 'Market',
                   'qty': qty,
                   'time_in_force': 'GoodTillCancel',
               })

           # 待機(30秒)
           await asyncio.sleep(30.0)


# 非同期メイン関数を実行(Ctrl+Cで終了)
if __name__ == '__main__':
   try:
       asyncio.run(main())
   except KeyboardInterrupt:
       pass


もしこの記事が気に入っていただけたなら「いいね」をお願いいたします。また、他の記事の方もご一読してくだされば幸いです。

この記事が気に入ったらサポートをしてみませんか?