かーぶ(仮)

主に日本株やってます。長期ではなく短期取引メインです。TradeStation等株取引ツールも紹介します。

pybotterを用いたひげとりbot

寄り道

MLとの接続を作ったりしないといけないんだけど、とりあえずbotっぽいものを作りたかった。

全ては流用

Pybotterの使い方を学ぶために、以下で紹介されているひげとりbotを流用して作成。 (ありがとうございます)

note.com

開示に際して

恥ずかしいコメントは削除するけど、勉強用のprint文はそのままで汚くてすいません。 colabで使う際は適当に分けて貼り付けてください。

GoogleColabでのコード byテストネット環境

!pip install pybotters

# 重要!
# colabでasyncioを使うときに以下2行を実行。
import nest_asyncio
nest_asyncio.apply()

import asyncio
import pybotters

BYBIT_API_KEY = "---"
BYBIT_API_SECRET = "---"

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

#importとか
import time
import pandas as pd
import numpy as np
import random
import requests
import datetime

#Main loop

async def main():
    async with pybotters.Client(apis=apis, base_url='https://api-testnet.bybit.com') as client:
       
        TICKER = 'BTCUSD'
        LOT = 10
        MIN_LOT = 1
        TICK = 0.5
        MARGIN = 0.0025

        cond = True

        # メインループ
        while True:
          # REST APIデータ並列リクエスト
          resps = await asyncio.gather(
              client.get('/v2/public/kline/list', params={
                  'symbol': TICKER, 'interval': 1, 'from': int(time.time()) - 3600
                  }),
              client.get("/v2/public/tickers",params={"symbol": TICKER}),
              client.get('/v2/private/order', params={'symbol': TICKER}),
              client.get('/v2/private/position/list', params={'symbol': TICKER}),
              client.get("/v2/private/wallet/balance",params={"coin": 'BTC'}),
          )
            
          kline,tickers, order, position,balance = await asyncio.gather(*[r.json() for r in resps])
          
          print(datetime.datetime.now())
          print("<<kline>>",kline)
          print("<<tickers>>",tickers)
          print("<<order>>",order)
          print("<<position>>",position)
          print("<<balance>>",balance)

          
          # デリバティブの保有資産
          # 現在のポジションを取得する。WR追加
          BTC_posi = balance['result']["BTC"]['equity']
          print("BTC_posi  :",BTC_posi)

          # 現在の注文状況を取得する。


          # 古いオーダーをキャンセル
          if True:
              await client.post('/v2/private/order/cancelAll', data={
                  'symbol': 'BTCUSD'
              })
              print("注文ALLキャンセル 動作確認完了")

          best_bid = float(tickers["result"][0]['bid_price'])
          best_ask = float(tickers["result"][0]['ask_price'])
          
          fair_mid = ((best_ask+best_bid)/2)
        
          print("【使用する値】")
          print("bid_price  ",tickers["result"][0]['bid_price'])
          print("ask_price  ",tickers["result"][0]['ask_price'])

          
          # ポジションをすべて取得
          posi=float(position["result"]["size"])
          print("ポジション: ",posi)

          # 新規買い
          try: 
            side_temp = "Buy"
            qty_temp = LOT - posi if posi>0 else LOT
            price_temp = int(min(fair_mid * (1-MARGIN), best_ask-TICK*5))
        
            new_buy=await client.post('/v2/private/order/create', data={
                'symbol': TICKER,  #'BTCUSD',
                'side': side_temp,
                'order_type': 'Limit',#market:成り行き、limit:指値
                'qty': qty_temp,
                'price': price_temp,
                'time_in_force': "PostOnly",   # 'GoodTillCancel',
            })
            print("買い注文", side_temp ,"  ", qty_temp,"  ", price_temp)
            print(await new_buy.json())
          except Exception as e: print(e); pass    

          # 新規売り
          try:
            side_temp = "Sell"
            qty_temp = LOT - posi if posi>0 else LOT
            price_temp = int(max(fair_mid * (1+MARGIN), best_bid+TICK*5))

            new_sell = await client.post('/v2/private/order/create', data={
                'symbol': TICKER,  #'BTCUSD',
                'side': side_temp,
                'order_type': 'Limit',#market:成り行き、limit:指値
                'qty': qty_temp,
                'price': price_temp,
                'time_in_force': "PostOnly",   # 'GoodTillCancel',
            })
            print("売り注文", side_temp ,"  ", qty_temp,"  ", price_temp)
            print(await new_sell.json())
          except Exception as e: print(e); pass   

          # アンワインド 反対売買を行う。min_LOTより大きい場合はポジションと逆方向に注文をだす。
          if abs(posi)>MIN_LOT:
              try:
                side_temp = 'Sell' if posi>0 else 'Buy'
                qty_temp = int(abs(posi))
                price_temp = int(max(fair_mid, best_bid+TICK) if posi>0 else min(fair_mid, best_ask-TICK))
                

                unwind = await client.post('/v2/private/order/create', data={
                    'symbol': TICKER,  #'BTCUSD',
                    'side': side_temp,
                    'order_type': 'Limit',#Market:成り行き、limit:指値
                    'qty': qty_temp,
                    'price': price_temp,
                    'time_in_force': 'GoodTillCancel'#"PostOnly",   # 
                })
                print("アンワイド注文", side_temp ,"  ", qty_temp,"  ", price_temp)
                print(await unwind.json())
              except Exception as e: print(e); pass    
          
          # 待機(10秒) 
          await asyncio.sleep(10)


# 非同期メイン関数を実行
if __name__ == '__main__':
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        pass
/*コード内行数*/ /*コード内全選択*/