[PYTHON] J'ai été en vain parce que je n'ai pas pu obtenir de commande parent avec pybitflyer

introduction

Il est dit que quatre commandes spéciales peuvent être passées avec l'API bitflyer.

order_method:Comment commander. Spécifiez l'une des valeurs suivantes. Si omis, la valeur est"SIMPLE"est.
"SIMPLE":Ceci est une commande spéciale qui passe une commande.
"IFD":Passez une commande IFD. Une méthode de commande dans laquelle deux commandes sont passées à la fois et la deuxième commande est automatiquement passée lorsque la première commande est exécutée.
"OCO":Passez une commande OCO. Il s'agit d'une méthode de commande dans laquelle deux commandes sont passées en même temps, et lorsqu'une commande est terminée, l'autre commande est automatiquement annulée.
"IFDOCO": IFD-Passez une commande OCO. Une méthode de commande dans laquelle une commande OCO est automatiquement passée après l'exécution de la première commande.

Cité ci-dessous https://lightning.bitflyer.com/docs

Il existe un package appelé pybitflyer qui est pratique pour appeler l'API bitflyer avec python. (Vous pouvez l'installer avec pip.) Je parle de vouloir passer la commande spéciale ci-dessus en utilisant ce package. https://github.com/yagays/pybitflyer

Préparation

Importez les packages requis. Préparez API_KEY et API_SECRET dans des fichiers séparés.

import time 
import pybitflyer
import configparser
import json 
import requests

config = configparser.ConfigParser()
config.read('./config.txt')
API_KEY = config['bf']['api_key']
API_SECRET = config['bf']['api_secret']

api = pybitflyer.API(api_key=API_KEY,api_secret=API_SECRET)

※Remarques

Ci-dessous, si API_KEY et API_SECRET sont correctement définis, la commande peut être acceptée. Veuillez noter que nous ne sommes pas responsables de toute perte.

Exemple d'échec

La fonction qui passe une commande spéciale est "envoyer la commande parent". Pour les paramètres, utilisez l'exemple suivant tel quel. https://lightning.bitflyer.com/docs Le type de commande spéciale est "IFDOCO".

api.sendparentorder(
    {
  "order_method": "IFDOCO",
  "minute_to_expire": 10000,
  "time_in_force": "GTC",
  "parameters": [{
    "product_code": "BTC_JPY",
    "condition_type": "LIMIT",
    "side": "BUY",
    "price": 30000,
    "size": 0.1
  },
  {
    "product_code": "BTC_JPY",
    "condition_type": "LIMIT",
    "side": "SELL",
    "price": 32000,
    "size": 0.1
  },
  {
    "product_code": "BTC_JPY",
    "condition_type": "STOP_LIMIT",
    "side": "SELL",
    "price": 28800,
    "trigger_price": 29000,
    "size": 0.1
  }]
})
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-19-2b96f6a935f1> in <module>
     24     "price": 28800,
     25     "trigger_price": 29000,
---> 26     "size": 0.1
     27   }]
     28 })

TypeError: sendparentorder() takes 1 positional argument but 2 were given

→ Mettez-vous en colère lorsque l'argument est faux

Succès

J'ai trouvé que la cause était qu'il était inclus dans le dictionnaire à partir de la partie ci-dessus paramètres. L'exemple de documentation de bitflyer est un exemple pour accéder directement à l'API sans utiliser pybitflyer. Pour preuve de cela, si vous frappez directement l'API avec l'échantillon du document bitflyer tel quel, la commande passera.

api.sendparentorder(
  order_method =  "IFDOCO",
  minute_to_expire = 10000,
  time_in_force = "GTC",
  parameters = [{
    "product_code": "FX_BTC_JPY",
    "condition_type": "LIMIT",
    "side": "BUY",
    "price": 900000,
    "size": 0.01
  },
  {
    "product_code": "FX_BTC_JPY",
    "condition_type": "LIMIT",
    "side": "SELL",
    "price": 950000,
    "size": 0.01
  },
  {
    "product_code": "FX_BTC_JPY",
    "condition_type": "STOP_LIMIT",
    "side": "SELL",
    "price": 800000,
    "trigger_price": 810000,
    "size": 0.01
  }]
)
{'parent_order_acceptance_id': 'JRF20200114-110537-710593'}

S'il s'agit d'une commande directe d'API, vous pouvez coller l'échantillon tel quel (même si je l'ai changé en FX_BTC_JPY car je n'ai pas les fonds)

def order(side,price,size):
    base_url = "https://api.bitflyer.jp"
    path_url = "/v1/me/sendparentorder"
    method = "POST"
    api_key = API_KEY
    api_secret = API_SECRET

    timestamp = str(datetime.datetime.today())
    
    params = {
      "order_method": "IFDOCO",
      "minute_to_expire": 10000,
      "time_in_force": "GTC",
      "parameters": [{
        "product_code": "FX_BTC_JPY",
        "condition_type": "LIMIT",
        "side": "BUY",
        "price": 920000,
        "size": 0.1
      },
      {
        "product_code": "FX_BTC_JPY",
        "condition_type": "LIMIT",
        "side": "SELL",
        "price": 1000000,
        "size": 0.1
      },
      {
        "product_code": "FX_BTC_JPY",
        "condition_type": "STOP_LIMIT",
        "side": "SELL",
        "price": 900000,
        "trigger_price": 890000,
        "size": 0.1
      }]
    }
    
    body = json.dumps(params)

    message = timestamp + method + path_url + body
    signature = hmac.new(bytearray(api_secret.encode('utf-8')), message.encode('utf-8') , digestmod = hashlib.sha256 ).hexdigest()

    headers = {
        'ACCESS-KEY' : api_key,
        'ACCESS-TIMESTAMP' : timestamp,
        'ACCESS-SIGN' : signature,
        'Content-Type' : 'application/json'
    }

    response = requests.post( base_url + path_url , data = body , headers = headers)
    print( response.status_code )
    print( response.json() )

orderprice = decideOrderPrice("BUY")
order("BUY",orderprice,0.01)
{'parent_order_acceptance_id': 'JRF20200114-110537-710593'}

De plus, chose non résolue

La commande spéciale "SIMPLE" est la même compréhension que la commande d'envoi d'enfant, mais je me fâche lorsque j'essaye de faire "SIMPLE" avec la commande d'envoi parent. J'utilise la commande sendchild car elle passe de bonne humeur.

api.sendparentorder(
    order_method = "SIMPLE",
    minute_to_expire = 10000,
    time_in_force =  "GTC",
    parameters = [
        {
            #IFD: ordre d'achat au prix limite, ordre OCO lorsqu'il est exécuté
            "product_code": "FX_BTC_JPY",
            "condition_type": "LIMIT",
            "side": "BUY",
            "price": 900000,
            "size": 0.1
        }]
)
{'status': -101, 'error_message': 'Invalid type of order', 'data': None}

Impressions

Quand j'y pense calmement, je ne peux pas le passer car je saisis l'échantillon BODY directement depuis l'API dans le wrapper tel quel. Cependant, je l'ai posté dans l'espoir que cela aiderait les gens qui ont des problèmes parce qu'ils ne peuvent pas envoyer des ordres aux parents de la même manière.

Perspectives d'avenir

Nous avons créé un BOT qui utilise l'API REST pour la partie commande et WEBSOCKET pour vérifier l'état du contrat et obtenir le prix, et nous le testons sur AWS. Le choix de faire une entrée d'achat ou de vente est décidé par un nombre aléatoire. Maintenant que je sais comment commander et comment continuer à commander, je vais me concentrer sur la réflexion sur la logique pour décider de l'entrée. Je pense également que je peux réduire le nombre d'API REST car je peux envoyer des commandes parentales. Je pense que l'API REST est lente comme un goulot d'étranglement.

Recommended Posts

J'ai été en vain parce que je n'ai pas pu obtenir de commande parent avec pybitflyer
J'obtiens un UnicodeDecodeError avec mecab-python3
J'obtiens une KeyError dans pyclustering.xmeans
Une histoire à laquelle j'étais accro à essayer d'obtenir une URL de vidéo avec tweepy
[Python] Récupérez les fichiers dans le dossier avec Python
Quand j'obtiens une erreur de pilote chrome dans Selenium
J'obtiens une UnicodeDecodeError lors de l'exécution avec mod_wsgi
[PyTorch] J'étais un peu perdu dans torch.max ()
Je veux faire la transition avec un bouton sur le ballon
J'obtiens une exception java.util.regex.PatternSyntaxException lors du fractionnement d'une chaîne dans PySpark
J'étais accro au grattage avec Selenium (+ Python) en 2020
Je veux travailler avec un robot en python.
Impossible de manipuler l'iframe dans la page avec Selenium
J'ai créé une classe pour obtenir le résultat de l'analyse par MeCab dans ndarray avec python
Ce à quoi j'étais accro en traitant d'énormes fichiers dans un environnement Linux 32 bits
Lambda dans VPC ne peut pas envoyer de courrier avec Boto3 même si vous utilisez le point de terminaison VPC pour SES
J'ai fait un jeu de frappe simple avec tkinter de Python
J'avais des problèmes car la chaîne de caractères dans le PDF était étrange
Des mots qui m'intéressaient en tant que débutant en programmation
J'ai essayé "Comment obtenir une méthode décorée en Python"
Traitez les fichiers du dossier dans l'ordre avec le script shell
J'ai essayé de commencer avec Hy ・ Définir une classe
Jusqu'à ce que Django retourne quelque chose avec un robot de ligne!
J'ai écrit un script pour obtenir un site populaire au Japon
J'ai fait un jeu de puzzle (comme) avec Tkinter of Python