[PYTHON] Ich war vergebens, weil ich mit pybitflyer keine Bestellung für Eltern erhalten konnte

Einführung

Es wird gesagt, dass mit der Bitflyer-API vier Sonderbestellungen aufgegeben werden können.

order_method:Wie man bestellt. Geben Sie einen der folgenden Werte an. Wenn weggelassen, ist der Wert"SIMPLE"ist.
"SIMPLE":Dies ist eine spezielle Bestellung, die eine Bestellung aufgibt.
"IFD":Geben Sie eine IFD-Bestellung auf. Eine Bestellmethode, bei der zwei Bestellungen gleichzeitig aufgegeben werden und die zweite Bestellung automatisch aufgegeben wird, wenn die erste Bestellung ausgeführt wird.
"OCO":Geben Sie eine OCO-Bestellung auf. Dies ist eine Bestellmethode, bei der zwei Bestellungen gleichzeitig aufgegeben werden. Wenn eine Bestellung abgeschlossen ist, wird die andere Bestellung automatisch storniert.
"IFDOCO": IFD-Geben Sie eine OCO-Bestellung auf. Eine Bestellmethode, bei der eine OCO-Bestellung automatisch aufgegeben wird, nachdem die erste Bestellung ausgeführt wurde.

Von unten zitiert https://lightning.bitflyer.com/docs

Es gibt ein Paket namens pybitflyer, mit dem Sie die Bitflyer-API mit Python aufrufen können. (Sie können es mit pip installieren.) Ich spreche davon, die oben genannte Sonderbestellung mit diesem Paket aufgeben zu wollen. https://github.com/yagays/pybitflyer

Vorbereitung

Importieren Sie die erforderlichen Pakete. Bereiten Sie API_KEY und API_SECRET in separaten Dateien vor.

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)

※Vorsichtsmaßnahmen

Wenn API_KEY und API_SECRET korrekt eingestellt sind, kann die Bestellung unten akzeptiert werden. Bitte beachten Sie, dass wir nicht für Verluste verantwortlich sind.

Fehlerbeispiel

Die Funktion, die eine spezielle Bestellung aufgibt, ist "Elternbestellung senden". Verwenden Sie für die Parameter das folgende Beispiel. https://lightning.bitflyer.com/docs Die Art der Sonderbestellung ist "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

→ Wütend werden, wenn das Argument falsch ist

Erfolgsgeschichte

Ich fand heraus, dass die Ursache darin bestand, dass es aus den obigen Parametern in das Wörterbuch aufgenommen wurde. Die Beispieldokumentation zu Bitflyer ist ein Beispiel für das direkte Aufrufen der API ohne Verwendung von Pybitflyer. Als Beweis dafür wird die Bestellung übergeben, wenn Sie die API direkt mit dem Beispiel des Bitflyer-Dokuments aufrufen.

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'}

Wenn es sich um eine API-Direktbestellung handelt, können Sie das Beispiel unverändert einfügen (obwohl ich es in FX_BTC_JPY geändert habe, weil ich nicht über die Mittel verfüge).

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'}

Außerdem ungelöste Sache

Die Sonderbestellung "EINFACH" hat das gleiche Verständnis wie die Bestellung "Kind senden", aber ich werde wütend, wenn ich versuche, "EINFACH" mit der Bestellung "Eltern senden" zu machen. Ich benutze sendchild order, weil es gut gelaunt ist.

api.sendparentorder(
    order_method = "SIMPLE",
    minute_to_expire = 10000,
    time_in_force =  "GTC",
    parameters = [
        {
            #IFD: Bestellung zum Grenzpreis kaufen, OCO-Bestellung bei Ausführung
            "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}

Impressionen

Wenn ich ruhig darüber nachdenke, kann ich es nicht weitergeben, da ich den Beispiel-BODY direkt von der API in den Wrapper eingebe, wie er ist. Ich habe es jedoch in der Hoffnung gepostet, dass es Menschen helfen würde, die in Schwierigkeiten sind, weil sie nicht in der gleichen Weise übergeordnete Bestellungen senden können.

Zukunftsaussichten

Wir haben einen BOT erstellt, der die REST-API für den Bestellungsteil und WEBSOCKET verwendet, um den Vertragsstatus zu überprüfen und den Preis zu erhalten, und testen ihn auf AWS. Ob Sie einen Kauf- oder Verkaufseintrag tätigen, wird durch eine Zufallszahl entschieden. Jetzt, da ich weiß, wie man bestellt und wie man weiter bestellt, werde ich mich darauf konzentrieren, über die Logik nachzudenken, um den Eintrag zu entscheiden. Ich denke auch, dass ich die Anzahl der REST-APIs reduzieren kann, weil ich übergeordnete Bestellungen senden kann. Ich bin der Meinung, dass die REST-API als Engpass langsam ist.

Recommended Posts

Ich war vergebens, weil ich mit pybitflyer keine Bestellung für Eltern erhalten konnte
Ich bekomme einen UnicodeDecodeError mit mecab-python3
Ich erhalte einen KeyError in pyclustering.xmeans
Eine Geschichte, die ich süchtig danach war, eine Video-URL mit Tweepy zu bekommen
[Python] Holen Sie sich die Dateien mit Python in den Ordner
Wenn ich einen Chrom-Treiberfehler in Selenium bekomme
Ich erhalte einen UnicodeDecodeError, wenn ich mit mod_wsgi laufe
[PyTorch] Ich war ein wenig verloren in torch.max ()
Ich möchte mit einem Knopf am Kolben übergehen
Ich erhalte eine java.util.regex.PatternSyntaxException, wenn ich einen String in PySpark teile
Ich war süchtig danach, 2020 mit Selen (+ Python) zu kratzen
Ich möchte mit einem Roboter in Python arbeiten.
Iframe in Seite mit Selenium kann nicht bearbeitet werden
Ich habe eine Klasse erstellt, um das Analyseergebnis von MeCab in ndarray mit Python zu erhalten
Wovon ich süchtig war, als ich mit riesigen Dateien in einer Linux 32-Bit-Umgebung umging
Lambda in VPC kann keine E-Mails mit Boto3 senden, selbst wenn der VPC-Endpunkt für SES verwendet wird
Ich habe ein einfaches Tippspiel mit tkinter of Python gemacht
Ich hatte Probleme, weil die Zeichenfolge im PDF seltsam war
Wörter, die mich als Programmieranfänger interessiert haben
Ich habe versucht "Wie man eine Methode in Python dekoriert"
Verarbeiten Sie die Dateien im Ordner in der Reihenfolge mit dem Shell-Skript
Ich habe versucht, mit Hy ・ Define a class zu beginnen
Bis Django etwas mit einem Linienbot zurückgibt!
Ich habe ein Skript geschrieben, um eine beliebte Seite in Japan zu bekommen
Ich habe mit Tkinter of Python ein Puzzlespiel (wie) gemacht