
Python调用Google Bard API 完整指南
Deribit 是一家在线加密货币衍生品交易所,专注于加密货币期货和期权交易。
Derbit API 是一种允许我们通过代码在 Deribit 上自动交易加密货币期货和期权的方法。
在 Deribit 上开户完全免费,但交易所会向客户收取交易费。交易所的收费模式基于做市商-接受者原则。
挂单是指从订单簿中移除流动性的订单,而吃单则相反。Deribit 费用因产品而异,按合约标的资产的百分比计算。
就合同而言,费用结构如下:
请记住,期权费用不能超过期权价格的 12.5%。此外,期货和期权合约有交割费,如下图所示:
至于清算费用,则如下:
Deribit 不收取任何存款费用,而 BTC 的提款费用可能取决于比特币网络的当前状态。
在为您的账户注资时,您只有一个选择,那就是比特币。这意味着 Deribit 不支持任何法定货币存款方式。
自2020年11月9日起,Deribit 要求所有新客户获得验证身份才能进行交易。这意味着需要提供居住证明和身份证件。
自 2021 年起,Deribit 已无法访问
如果您位于、注册或以其他方式设立于下列国家/地区,或者是下列国家/地区的公民或居民:
Deribit 可以用其他更适合您需求的应用程序替代。以下是列表:
Deribit 拥有以下客户:
请务必访问以下 GitHub 来访问这些客户端:
https://github.com/deribit/deribit-api-clients
为了充分了解 Deribit API 的功能,我们首先需要开设一个帐户以获取 API 密钥。我将向您展示几个交易场景,我们需要的帐户是此链接上的测试帐户:
测试版和正式版 Deribit 账户的注册流程基本相同。以下是正式版网站的链接:
到达那里后,你会看到一个帐户创建框。请务必点击绿色的“创建帐户”按钮,然后填写你的电子邮件地址、昵称、创建密码并选择你的国家/地区。
之后,您将收到来自 Deribit 的验证电子邮件。请务必仔细检查并确认。完成后,您将进入以下屏幕:
现在,我们需要的是 API 密钥。为此,请转到右上角的个人资料图标,然后单击“设置”。之后,导航到 API 部分并单击“添加新密钥”按钮。
会出现一个弹出屏幕,提示您分配新 API 密钥的主要功能。选项范围从帐户到托管权限。在本文中,我将为它们全部赋予读取 + 写入权限。
批准后,将创建 API 密钥,您将清楚地看到您的客户端 ID 和客户端密钥。您还可以执行多种操作,例如二维码、重置密钥、删除密钥等。
由于我们需要的一切都已设置好,以下标题将从主要公共端点开始探索 API,并以两个交易场景中的私有 API 顺序结束。
为了获取 Deribit 提供的所有货币,您可以使用 get_currencies 端点。我们将导入所需的库并以以下方式调用其 API:
import asyncio
import websockets
import json
import pandas as pd
import pprint
import nest_asyncio
nest_asyncio.apply()
msg = \
{
"jsonrpc" : "2.0",
"id" : 7538,
"method" : "public/get_currencies",
"params" : {
}
}
async def call_api(msg):
async with websockets.connect('wss://test.deribit.com/ws/api/v2') as websocket:
await websocket.send(msg)
while websocket.open:
response = await websocket.recv()
json_par = json.loads(response)
print(json_par)
return(json_par)
response = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
由于响应看起来不太好,我们将使用 pprint 库来漂亮地打印它。
pprint.pprint(response)
更好的是,让我们在函数中添加 pprint 作为我们的主要打印方式,并调用下一个将获取价格数据的端点。
有多个 Deribit 端点包含价格数据,但最“精确”的是公共行情端点。让我们更新该函数以获得更漂亮的打印效果。
msg = {
"jsonrpc" : "2.0",
"id" : 8106,
"method" : "public/ticker",
"params" : {
"instrument_name" : "BTC-PERPETUAL"
}
}
async def call_api(msg):
async with websockets.connect('wss://test.deribit.com/ws/api/v2') as websocket:
await websocket.send(msg)
while websocket.open:
response = await websocket.recv()
json_par = json.loads(response)
pprint.pprint(json_par)
return(json_par)
response = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
如果您想获取指数价格,您可以使用“get_index_price”端点。
msg = {"jsonrpc": "2.0",
"method": "public/get_index_price",
"id": 42,
"params": {
"index_name": "btc_usd"}
}
response = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
{'id': 42,
'jsonrpc': '2.0',
'result': {'estimated_delivery_price': 57848.15, 'index price': 57848.15},
'testnet': True,
'usDiff': 177,
'usIn': 1616071078267979,
'usOut': 16160710782681561}
Deribit 提供了一些历史数据端点,例如资金利率历史和历史波动率。让我们从后者开始,获取这两个数据:
msg = {
"jsonrpc" : "2.0",
"id" : 8387,
"method" : "public/get_historical_volatility",
"params" : {
"currency" : "BTC"
}
}
response = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
我们要做的下一步是将响应放入 pandas 数据框中,以便以后使用。
volatility = pd.DataFrame(response['result'])
volatility.head()
为了获取有关数据框的一些基本统计数据,您可以使用 pd.describe 函数:
pd.set_option('precision', 3)
volatility.describe()
现在来看看融资利率的历史:
msg = {
"jsonrpc" : "2.0",
"id" : 7617,
"method" : "public/get_funding_rate_history",
"params" : {
"instrument_name" : "BTC-PERPETUAL",
"start_timestamp" : 1569888000000,
"end_timestamp" : 1569902400000
}
}
response = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
订单簿数据可以通过使用公共 get_order_book 端点获取。交易所未指定订单簿的最大层级深度。我们将使用层级 25 作为请求:
msg = {
"jsonrpc" : "2.0",
"id" : 8772,
"method" : "public/get_order_book",
"params" : {
"instrument_name" : "BTC-PERPETUAL",
"depth" : 25
}
}
response = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
我们现在应该通过提取其中的重要部分来清理响应。为此,我将为买入价和卖出价创建单独的数据框,然后将两者合并在一起。
bids = pd.DataFrame(response['result']['bids'])
asks = pd.DataFrame(response['result']['asks'])
book = pd.merge(bids, asks, left_index=True, right_index=True)
book.head()
如果您想重命名列,您可以传递以下命令:
book = df.rename({"0_x":"Bid Price","1_x":"Bid Amount",
"0_y":"Ask Price","1_y":"Ask Amount"}, axis='columns')
交易(又称交易)可通过使用按货币或按工具获取交易端点从 Deribit 获取。对于结算,您只需在请求消息中将“交易”更改为“结算”。
让我们从前者开始,按货币获取交易和结算:
msg = {
"jsonrpc" : "2.0",
"id" : 9290,
"method" : "public/get_last_trades_by_currency",
"params" : {
"currency" : "BTC",
"count" : 2
}
}
response = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
现在谈谈定居点:
msg = {
"jsonrpc" : "2.0",
"id" : 4497,
"method" : "public/get_last_settlements_by_currency",
"params" : {
"currency" : "BTC",
"type" : "delivery",
"count" : 2
}
}
response = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
Deribit 提供多种可通过其端点启动的订单类型。但在我们逐一介绍每种订单类型并编写两个交易方案之前,我们应该先了解一下订单由哪些参数组成。
基本订单参数如下:
instrument_name
– 您的资产名称(必填)amount
– 要求的订单大小(必填)type
– 默认为“limit”,但可以是stop_limit,market,stop_marketlabel
– 用户定义的订单标签price
– 基础货币的订单价格仅适用于限价订单和止损限价订单。time_in_force
– 指定订单持续多长时间。可以是“good_til_cancelled”、“fill_or_kill”、“immediate_or_cancel”。max_show
– 订单中向其他客户显示的最大金额(例如,0 表示订单不可见)post_only
– “如果为真,则订单被视为仅后送订单。如果新价格会导致订单立即成交(作为接受者),则价格将更改为略低于价差。仅与 time_in_force = 结合使用才有效good_til_cancelled
”reject_post_only
– “如果订单被视为仅发布订单,并且此字段设置为 true,则订单将不经修改地放入订单簿,或者请求被拒绝并且订单被取消。”reduce_only
– 如果为真,则降低当前位置stop_price
– 止损限价单的止损价trigger
– 它定义了 stop_limit 和 stop_market 订单的触发类型。advanced
– 高级期权订单类型(仅适用于期权)mmp
– 订购 MMP 标志现在我们已经了解了主要的订单构建模块,接下来让我们探索一些特殊的订单构建模块以及如何启动它们。
Deribit 中的所有订单都具有类似的结构,如最后一个标题所示。这意味着,为了触发永续合约的订单,我们只需指定正确的工具名称(例如 BTC-PERPETUAL)。
订单信息的示例如下:
msg = {
"jsonrpc" : "2.0",
"id" : 4122,
"method" : "private/cancel_all_by_instrument",
"params" : {
"instrument_name" : "BTC-PERPETUAL",
"type" : "all"
}
}
如果您跳过此部分,这是我们用来发送请求的函数:
async def call_api(msg):
async with websockets.connect('wss://test.deribit.com/ws/api/v2') as websocket:
###############
# Before sending a message, make sure that your connection
# is authenticated (use public/auth call before)
###############
await websocket.send(msg)
while websocket.open:
response = await websocket.recv()
json_par = json.loads(response)
print(json_par)
return(json_par)
Deribit 永续合约的特点是持续测量合约标记价格与 Deribit BTC 指数之间的差额。
这两个价格水平之间的百分比差异是适用于所有未平仓永续合约的 8 小时融资利率的基础。有关更多信息,请访问以下链接:
https://www.deribit.com/pages/docs/perpetual
Deribit 中的所有订单都具有类似的结构。这意味着,为了触发期货合约的订单,我们只需指定正确的工具名称(例如 BTC-24SEP21)。
订单信息的示例如下:
msg = {
"jsonrpc" : "2.0",
"id" : 4122,
"method" : "private/cancel_all_by_instrument",
"params" : {
"instrument_name" : "BTC-24SEP21",
"type" : "all"
}
}
Deribit 上的比特币期货以现金结算,而非通过“实物”交割 BTC 进行结算。这意味着在结算时,BTC 期货的买家不会购买实际的 BTC,卖家也不会出售 BTC。
只有在合约结算时才会根据到期价格(以 BTC 价格指数的最近 30 分钟平均值计算)转移损失/收益。有关更多信息,请访问以下链接:
https://www.deribit.com/pages/docs/futures
Deribit 中的所有订单都具有类似的结构。这意味着,为了触发期货合约的订单,我们只需指定正确的工具名称(例如 ETH-19MAR21)。
订单信息的示例如下:
msg = {
"jsonrpc" : "2.0",
"id" : 4122,
"method" : "private/cancel_all_by_instrument",
"params" : {
"instrument_name" : "ETH-19MAR21",
"type" : "all"
}
}
Deribit 遵循欧式现金结算期权,这意味着期权仅在到期时行使,不能提前行使。在 Deribit 上,这将自动发生。
更多信息请访问以下链接:
https://www.deribit.com/pages/docs/options
在此示例中,我将向您展示如何正确安全地启动具有指定要求的订单。我们想要做的是当 BTC 达到特定价格时启动 ETH 交易。
为了实现这一点,我们需要设置订单基础,然后创建一个循环来检查价格水平是否被触及。如果价格被触及,我们将执行市价订单。否则,我们将继续循环。
当价格执行后,我们会等待几秒钟,然后检查订单是否已完成。这一额外步骤对于您的交易策略非常重要,因为交易所服务器可能会遇到一些问题。
让我们继续导入相关库并设置主交易循环。
#Order Foundation
import asyncio
import websockets
import json
import pandas as pd
from time import sleep
import pprint
import hmac
import hashlib
from datetime import datetime
import nest_asyncio
nest_asyncio.apply()
async def call_api(msg):
async with websockets.connect('wss://test.deribit.com/ws/api/v2') as websocket:
await websocket.send(msg)
while websocket.open:
response = await websocket.recv()
json_par = json.loads(response)
#print(json_par)
return(json_par)
clientId = "TzxHdA_N"
clientSecret = "3LsbOcO7Fqzv_oT9-RDy1JwvYG7uR3NnF5HXDnvn6AA"
timestamp = round(datetime.now().timestamp() * 1000)
nonce = "123"
data = ""
signature = hmac.new(
bytes(clientSecret, "latin-1"),
msg=bytes('{}\n{}\n{}'.format(timestamp, nonce, data), "latin-1"),
digestmod=hashlib.sha256).hexdigest().lower()
auth_msg = {
"jsonrpc" : "2.0",
"id" : 42,
"method" : "public/auth",
"params" : {
"grant_type" : "client_signature",
"client_id" : clientId,
"timestamp" : timestamp,
"signature" : signature,
"nonce" : nonce,
"data" : data
}
}
price_msg = {
"jsonrpc" : "2.0",
"id" : 42,
"method" : "public/ticker",
"params" : {
"instrument_name" : "BTC-PERPETUAL"
}
}
order_msg = {
"jsonrpc" : "2.0",
"id" : 42,
"method" : "private/buy",
"params" : {
"instrument_name" : "ETH-PERPETUAL",
"amount" : 5,
"type" : "market",
"label" : "algoorder"
}
}
check_order = {
"jsonrpc" : "2.0",
"id" : 42,
"method" : "private/get_order_state",
"params" : {
"order_id" : "ETH-331562"
}
}
#Main order loop
while True:
try:
btc = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(price_msg)))
except exception as e:
print("Unable to obtain BTC price")
if btc['result']['best_ask_price'] < 58800.0:
print("The price mark was not reached.")
sleep(60)
continue
elif btc['result']['best_ask_price'] >= 58800.0:
try:
auth = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(auth_msg)))
pprint.pprint(auth)
except exception as e:
print('There was an authentication error')
try:
order = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(order_msg)))
#print(order)
except exception as e:
print("Error occurred while placing order")
sleep(2)
try:
order_check = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(check_order)))
pprint.pprint(order_check)
except excpetion as e:
print("Error checking order")
if order_check['result']['order_state'] == 'filled' or order_check['result']['order_state'] == "open":
print ('Order placed at {}'.format(pd.Timestamp.now()))
break
else:
print('Order was canceled {}'.format(pd.Timestamp.now()))
break
如果我们想计算两种货币之间的百分比变动,然后下订单,该怎么办?好吧,这个例子将解决这个问题!
主要任务是当 BTC 在过去 5 分钟内波动 5% 时执行 ETH 交易。这意味着我们需要创建一个循环来获取两种加密货币的价格并计算两者之间的百分比变化。
如果百分比变化小于 5%,算法将休眠 5 分钟并再次计算百分比变化。如果百分比变化等于或大于 5%,则交易将执行。
交易执行后,我们将休眠几秒钟,然后检查交易是否已完成。现在逻辑已经设置好,是时候编写代码了:
clientId = "ID_HERE"
clientSecret = "SECRET_HERE"
timestamp = round(datetime.now().timestamp() * 1000)
nonce = "123"
data = ""
signature = hmac.new(
bytes(clientSecret, "latin-1"),
msg=bytes('{}\n{}\n{}'.format(timestamp, nonce, data), "latin-1"),
digestmod=hashlib.sha256).hexdigest().lower()
auth_msg = {
"jsonrpc" : "2.0",
"id" : 42,
"method" : "public/auth",
"params" : {
"grant_type" : "client_signature",
"client_id" : clientId,
"timestamp" : timestamp,
"signature" : signature,
"nonce" : nonce,
"data" : data
}
}
btc_price_msg = {
"jsonrpc" : "2.0",
"id" : 42,
"method" : "public/ticker",
"params" : {
"instrument_name" : "BTC-PERPETUAL"
}
}
order_msg = {
"jsonrpc" : "2.0",
"id" : 42,
"method" : "private/buy",
"params" : {
"instrument_name" : "ETH-PERPETUAL",
"amount" : 5,
"type" : "market",
"label" : "algoorder"
}
}
check_order = {
"jsonrpc" : "2.0",
"id" : 42,
"method" : "private/get_order_state",
"params" : {
"order_id" : "ETH-331562"
}
}
while True:
try:
btc_old = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(btc_price_msg)))
except exception as e:
print("Unable to obtain BTC price")
sleep(300)
try:
btc_new = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(btc_price_msg)))
except exception as e:
print("Unable to obtain BTC price")
percent = (btc_new['result']['best_ask_price'] - btc_old['result']['best_ask_price'] * 100) / btc_old['result']['best_ask_price']
if percent < 5:
print("The requirement was not fulfilled.")
sleep(0.1)
continue
elif percent >= 5:
try:
auth = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(auth_msg)))
pprint.pprint(auth)
except exception as e:
print('There was an authentication error')
try:
order = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(order_msg)))
#print(order)
except exception as e:
print("Error occurred while placing order")
sleep(2)
try:
order_check = asyncio.get_event_loop().run_until_complete(call_api(json.dumps(check_order)))
pprint.pprint(order_check)
except excpetion as e:
print("Error checking order")
if order_check['result']['order_state'] == 'filled' or order_check['result']['order_state'] == "open":
print ('Order placed at {}'.format(pd.Timestamp.now()))
break
else:
print('Order was canceled {}'.format(pd.Timestamp.now()))
break
如果您想取消并使用 Deribit 下订单,您可以传递类似以下请求:
msg = \
{
"jsonrpc" : "2.0",
"id" : 4214,
"method" : "private/cancel",
"params" : {
"order_id" : "ETH-SLIS-12"
}
}
async def call_api(msg):
async with websockets.connect('wss://test.deribit.com/ws/api/v2') as websocket:
###############
# Before sending the message, make sure that your connection
# is authenticated (use public/auth call before)
###############
await websocket.send(msg)
while websocket.open:
response = await websocket.recv()
# do something with the response...
print(response)
asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))