It is said that four special orders can be placed with the bitflyer API.
order_method:How to order. Specify one of the following values. If omitted, the value is"SIMPLE"is.
"SIMPLE":This is a special order that places one order.
"IFD":Place an IFD order. An ordering method in which two orders are placed at a time and the second order is automatically placed when the first order is filled.
"OCO":Place an OCO order. This is an ordering method in which two orders are placed at the same time, and when one order is completed, the other order is automatically canceled.
"IFDOCO": IFD-Place an OCO order. An ordering method in which an OCO order is automatically placed after the first order is filled.
Quoted from below https://lightning.bitflyer.com/docs
There is a package called pybitflyer that is convenient for calling the bitflyer API with python. (You can install it with pip.) I'm talking about wanting to place the above special order using this package. https://github.com/yagays/pybitflyer
Import the required packages. Prepare API_KEY and API_SECRET in separate files.
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)
Below, if API_KEY and API_SECRET are set correctly, the order may be accepted. Please note that we are not responsible for any loss.
The function that places a special order is "send parent order". For the parameters, use the following sample as it is. https://lightning.bitflyer.com/docs The type of special order is "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
→ I get angry when the argument is wrong
I found that the cause was that it was included in the dictionary from the part above parameters. The sample of the bitflyer document is a sample when you hit the API directly without using pybitflyer. As a proof of that, if you hit the API directly with the sample of the bitflyer document as it is, the order will pass.
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'}
If it is an API direct order, you can paste the sample as it is (although I changed it to FX_BTC_JPY because I do not have the funds)
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'}
The special order "SIMPLE" is the same understanding as the send child order, but I get angry when I try to do "SIMPLE" with the send parent order. I'm using sendchild order because it passes in a good mood.
api.sendparentorder(
order_method = "SIMPLE",
minute_to_expire = 10000,
time_in_force = "GTC",
parameters = [
{
#IFD: Buy order at limit price, OCO order when executed
"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}
When I think about it calmly, I can't pass it because I input the sample BODY directly from the API into the wrapper as it is. However, I posted it with the hope that it would help people who are in trouble because they cannot issue send parent orders in the same way.
We have created a BOT that uses REST API for the order part and WEBSOCKET for contract status confirmation and price acquisition, and are testing it on AWS. Random numbers determine whether to buy or sell entries. Now that I know how to order and how to keep ordering, I will concentrate on thinking about the logic to decide the entry. I also think that I can reduce the number of REST APIs because I can issue send parent orders. I feel that the REST API is slow as a bottleneck.
Recommended Posts