GMOコイン FX API ラッパー
GMOコインにFX取引が追加され、APIも使えるようになりました。 GMOコインが扱うFXの特徴は、なんといっても1通貨単位から取引できることでしょう。(APIを利用する場合の最小取引単位は1000通貨でしたが…)既に、Selenium での自動取引は運転していますが、APIが使えるようになったのでUpdateしていこうと思います。まずはAPIラッパーを準備します。
参考にした仮想通貨のAPIラッパー
GMOコインの仮想通貨取引は以前からAPIが使えてラッパーもいくつか紹介されていますが、FX用のものが見当たらないのでドースーさんの仮想通貨用のラッパーを参考にしてFX用のラッパーを作成しました。
note(ノート)
【GMOコイン】APIラッパー【python】|ドースー
こんにちは。ドースー(@dosu0217)です。
自分のBotでも利用しているGMOコインで自動売買などをするためのAPIラッパーを公開します。
GMOコインのAPIドキュメントはこちら APIドキュメント| GMOコイン
GMOコインが提供するAPIのドキュメントページです。認証不要のPublic
APIと、APIキーによる認証が必要なPri api.coin.z.com
なお、このソースコードはこちらのニッケルメッキ先生が公開しているbitFlyer
APIのラッパークラスの記事をとても参考にしています。
とても勉強になるソースですのでよかったら見
dummy
注意点
API経由だと、残念ながら1通貨単位の発注ができないです。最小単位が1000になってます。あと、API経由での発注ですと手数料がかかります。これらのことから、発注は元々やっていたSeleniumでの発注のままにしたいと思っています。
ということで、発注関係はテストしてないので、ミスがあるかもしれません。バグがあったら教えてくださると嬉しいです。
ソースコード
GMOCoinFX_API_Wrapper.py
# gmocoinfx_api_wrapper.py
import aiohttp
import asyncio
import async_timeout
import json
from aiohttp import WSMsgType
import traceback
import time
from datetime import datetime
import hmac
import hashlib
import urllib
from secrets import token_hex
class GMOCoinFX():
# 定数
TIMEOUT = 3600 # タイムアウト
EXTEND_TOKEN_TIME = 3000 # アクセストークン延長までの時間
URLS = {'public': 'https://forex-api.coin.z.com/public',
'private': 'https://forex-api.coin.z.com/private',
'publicWS': 'wss://forex-api.coin.z.com/ws/public/v1',
'privateWS': 'wss://forex-api.coin.z.com/ws/private/v1',
}
# 変数
api_key = ''
api_secret = ''
session = None # セッション保持
requests = [] # リクエストパラメータ
token = '' # Private Websocket API用トークン
# ------------------------------------------------ #
# init
# ------------------------------------------------ #
def __init__(self, api_key, api_secret):
# APIキー・SECRETをセット
self.api_key = api_key
self.api_secret = api_secret
# ------------------------------------------------ #
# async request for rest api
# ------------------------------------------------ #
def set_request(self, method, access_modifiers, target_path, params):
if access_modifiers == 'public':
url = ''.join([self.URLS['public'], target_path])
if method == 'GET':
headers = ''
self.requests.append({'method': method,
'access_modifiers': access_modifiers,
'target_path': target_path, 'url': url,
'params': params, 'headers':{}})
if method == 'POST':
headers = {'Content-Type': 'application/json'}
self.requests.append({'method': method,
'access_modifiers': access_modifiers,
'target_path': target_path, 'url': url,
'params': params, 'headers':headers})
if access_modifiers == 'private':
url = ''.join([self.URLS['private'], target_path])
path = target_path
timestamp = '{0}000'.format(int(time.mktime(datetime.now().timetuple())))
if method == 'GET':
text = ''.join([timestamp, method, path,])
sign = self.get_sign(text)
headers = self.set_headers_for_private(timestamp=timestamp,
sign=sign)
self.requests.append({'url': url,
'method': method,
'headers': headers,
'params': params,
})
if method == 'POST':
post_data = json.dumps(params)
text = ''.join([timestamp, method, path, post_data])
sign = self.get_sign(text)
headers = self.set_headers_for_private(timestamp=timestamp,
sign=sign)
self.requests.append({'url': url,
'method': method,
'headers': headers,
'params': post_data,
})
if method == 'PUT':
post_data = json.dumps(params)
text = ''.join([timestamp, method, path])
sign = self.get_sign(text)
headers = self.set_headers_for_private(timestamp=timestamp,
sign=sign)
self.requests.append({'url': url,
'method': method,
'headers': headers,
'params': post_data,
})
def set_headers_for_private(self, timestamp, sign):
headers = {'API-KEY': self.api_key,
'API-TIMESTAMP': timestamp,
'API-SIGN': sign}
return headers
def get_sign(self, text):
sign = hmac.new(bytes(self.api_secret.encode('ascii')),
bytes(text.encode('ascii')), hashlib.sha256).hexdigest()
return sign
async def fetch(self, request):
status = 0
content = []
async with async_timeout.timeout(self.TIMEOUT):
try:
if self.session is None:
self.session = await aiohttp.ClientSession().__aenter__()
if request['method'] == 'GET':
async with self.session.get(url=request['url'],
params=request['params'],
headers=request['headers']) as response:
status = response.status
content = await response.read()
if status != 200:
# エラーのログ出力など必要な場合
pass
elif request['method'] == 'POST':
async with self.session.post(url=request['url'],
data=request['params'],
headers=request['headers']) as response:
status = response.status
content = await response.read()
if status != 200:
# エラーのログ出力など必要な場合
pass
elif request['method'] == 'PUT':
async with self.session.put(url=request['url'],
data=request['params'],
headers=request['headers']) as response:
status = response.status
content = await response.read()
if status != 200:
# エラーのログ出力など必要な場合
pass
if len(content) == 0:
result = []
else:
try:
result = json.loads(content.decode('utf-8'))
except Exception as e:
traceback.print_exc()
return result
except Exception as e:
# セッション終了
if self.session is not None:
await self.session.__aexit__(None, None, None)
await asyncio.sleep(0)
self.session = None
traceback.print_exc()
async def send(self):
promises = [self.fetch(req) for req in self.requests]
self.requests.clear()
return await asyncio.gather(*promises)
# ------------------------------------------------ #
# public api
# ------------------------------------------------ #
# 取引所ステータス
# 取引所の稼動状態を取得します。
def status(self):
params = {}
self.set_request(method='GET', access_modifiers='public',
target_path='/v1/status', params=params)
# 最新レート
# 全銘柄の最新レートを取得します。
def ticker(self):
params = {}
self.set_request(method='GET', access_modifiers='public',
target_path='/v1/ticker', params=params)
# KLine情報の取得
# 指定した銘柄の四本値を取得します。
def klines(self,symbol,date,priceType='BID',interval='1min'):
params = {'symbol': symbol,
'date' : date,
'priceType' : priceType,
'interval' : interval
}
self.set_request(method='GET', access_modifiers='public',
target_path='/v1/klines', params=params)
# 取引ルール
# 取引ルールを取得します。
def symbols(self):
params = {}
self.set_request(method='GET', access_modifiers='public',
target_path='/v1/symbols', params=params)
# ------------------------------------------------ #
# private api
# ------------------------------------------------ #
# 資産残高を取得
# 資産残高を取得します。
def assets(self):
params = {}
self.set_request(method='GET', access_modifiers='private',
target_path='/v1/account/assets', params=params)
# 注文情報取得
# 指定した注文IDの注文情報を取得します。
# rootOrderId orderId いずれか1つが必須です。2つ同時には設定できません。
def orders(self, rootOrderId='',orderId=''):
params = {}
if len(rootOrderId) > 0:
params['rootOrderId'] = rootOrderId
elif len(orderId) > 0:
params['orderId'] = orderId
self.set_request(method='GET', access_modifiers='private',
target_path='/v1/orders', params=params)
# 有効注文一覧
# 有効注文一覧を取得します。
# prevID,count は指定しない(銘柄別、100件以上の注文する場合に要修正)
def activeOrders(self, symbol=''):
params = {}
if len(symbol) > 0:
params['symbol'] = symbol
self.set_request(method='GET', access_modifiers='private',
target_path='/v1/activeOrders', params=params)
# 約定情報取得
# 約定情報を取得します。
# orderId executionId いずれか1つが必須です。2つ同時には設定できません。
def executions(self, orderId='', executionId=''):
params = {}
if len(orderId) > 0:
params['orderId'] = orderId
elif len(executionId) > 0:
params['executionId'] = executionId
self.set_request(method='GET', access_modifiers='private',
target_path='/v1/executions', params=params)
# 最新の約定一覧
# 最新約定一覧を取得します。
# 直近1日分から最新100件の約定情報を返します。
# count は指定せず。100(最大値)
def latestExecutions(self, symbol, count=''):
params = {'symbol': symbol}
if len(count) > 0:
params['count'] = count
self.set_request(method='GET', access_modifiers='private',
target_path='/v1/latestExecutions', params=params)
# 建玉一覧を取得
# 有効建玉一覧を取得します。
# countは100が最大で101以上だとエラー
# positionID順で取得できるので、最後のPositionIdをprevIdに入れて
# 続きを呼びなおせる。全建玉の一覧取得には、分けて呼び出す必要あり
def openPositions(self, symbol='',prevId='',count=''):
params = {}
if len(symbol) > 0:
params['symbol'] = symbol
if len(prevId) > 0:
params['prevId'] = prevId
if len(count) > 0:
params['count'] = count
self.set_request(method='GET', access_modifiers='private',
target_path='/v1/openPositions', params=params)
# 建玉サマリーを取得
# 建玉サマリーを取得します。
# 指定した銘柄の建玉サマリーを売買区分(買/売)ごとに取得できます。
# symbolパラメータ指定無しの場合は、保有している全銘柄の建玉サマリーを
# 売買区分(買/売)ごとに取得します。
def positionSummary(self, symbol=''):
params = {}
if len(symbol) > 0:
params['symbol'] = symbol
self.set_request(method='GET', access_modifiers='private',
target_path='/v1/positionSummary', params=params)
# Speed注文を出す
# lowerBound: 成立下限価格、SELLの場合指定可能
# upperBound: 成立上限価格、BUY の場合指定可能
# isHedgeable: 両建てなし(default) True で両建てあり
def speedOrder(self, symbol, side, size,
clientOrderId ='', lowerBound ='', upperBound='',
isHedgeable = False):
params = {'symbol': symbol,
'side': side,
'size': size
}
if len(clientOrderId) > 0:
params['clientOrderId'] = clientOrderId
if len(lowerBound) > 0:
params['lowerBound'] = lowerBound
if len(upperBound) > 0:
params['upperBound'] = upperBound
if isHedgeable:
params['isHedgeable'] = True
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/speedOrder', params=params)
# 新規注文を出す
# executionType: MARKET LIMIT STOP OCO
# LIMIT/OCO: limitPrice 必須 STOP/OCO: stopPrice 必須
# lowerBound: 成立下限価格、MARKET,SELLの場合指定可能
# upperBound: 成立上限価格、MARKET,BUY の場合指定可能
def order(self, symbol, side, size, executionType,
clientOrderId ='', limitPrice ='', stopPrice ='',
lowerBound ='', upperBound=''):
params = {'symbol': symbol,
'side': side,
'size': size,
'executionType': executionType,
}
if len(clientOrderId) > 0:
params['clientOrderId'] = clientOrderId
if len(limitPrice) > 0:
params['limitPrice'] = limitPrice
if len(stopPrice) > 0:
params['stopPrice'] = stopPrice
if len(lowerBound) > 0:
params['lowerBound'] = lowerBound
if len(upperBound) > 0:
params['upperBound'] = upperBound
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/order', params=params)
# IFD注文を出す
# firstSide : BUY/SELL 2次注文はこれの逆
# firstExecutionType: LIMIT/STOP
# secondExecutionType: LIMIT/STOP
def ifdOrder(self, symbol,
firstSide,
firstExecutionType, firstSize, firstPrice,
secondExecutionType, secondSize, secondPrice,
clientOrderId =''):
params = {'symbol': symbol,
'firstSide': firstSide,
'firstExecutionType': firstExecutionType,
'firstSize': firstSize,
'firstPrice': firstPrice,
'secondExecutionType': secondExecutionType,
'secondSize': secondSize,
'secondPrice': secondPrice
}
if len(clientOrderId) > 0:
params['clientOrderId'] = clientOrderId
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/ifdOrder', params=params)
# IFDOCO注文を出す
# firstSide : BUY/SELL 2次注文はこれの逆
# firstExecutionType: LIMIT/STOP
# secondExecutionType: LIMIT/STOP
def ifoOrder(self, symbol,
firstSide,
firstExecutionType, firstSize, firstPrice,
secondSize, secondLimitPrice, secondStopPrice,
clientOrderId =''):
params = {'symbol': symbol,
'firstSide': firstSide,
'firstExecutionType': firstExecutionType,
'firstSize': firstSize,
'firstPrice': firstPrice,
'secondSize': secondSize,
'secondLimitPrice': secondLimitPrice,
'secondStopPrice': secondStopPrice
}
if len(clientOrderId) > 0:
params['clientOrderId'] = clientOrderId
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/ifoOrder', params=params)
# 注文変更
# 注文変更をします。
# orderId clientOrderIdいずれか1つが必須です。2つ同時には設定できません。
def changeOrder(self, price, orderId='', clientOrderId=''):
params = {'price': price}
if len(orderId) > 0:
params['orderId'] = orderId
if len(clientOrderId) > 0:
params['clientOrderId'] = clientOrderId
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/changeOrder', params=params)
# OCO注文変更
# OCO注文変更をします。
# rootOrderId clientOrderIdいずれか1つが必須です。2つ同時には設定できません。
# limitPrice stopPrice 両方もしくはどちらか1つが必須です。
def changeOcoOrder(self, price, rootOrderId='', clientOrderId='',
limitPrice = '', stopPrice =''):
params = {'price': price}
if len(rootOrderId) > 0:
params['rootOrderId'] = rootOrderId
if len(clientOrderId) > 0:
params['clientOrderId'] = clientOrderId
if len(limitPrice) > 0:
params['limitPrice'] = limitPrice
if len(stopPrice) > 0:
params['stopPrice'] = stopPrice
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/changeOcoOrder', params=params)
# IFD注文変更
# IFD注文変更をします。
# rootOrderId clientOrderIdいずれか1つが必須です。2つ同時には設定できません。
# firstPrice secondPrice 両方もしくはどちらか1つが必須です。
def changeIfdOrder(self, rootOrderId='', clientOrderId='',
firstPrice = '', secondPrice =''):
params = {}
if len(rootOrderId) > 0:
params['rootOrderId'] = rootOrderId
if len(clientOrderId) > 0:
params['clientOrderId'] = clientOrderId
if len(firstPrice) > 0:
params['firstPrice'] = firstPrice
if len(secondPrice) > 0:
params['secondPrice'] = secondPrice
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/changeIfdOrder', params=params)
# IFDOCO注文変更
# IFDOCO注文変更をします。
# rootOrderId clientOrderIdいずれか1つが必須です。2つ同時には設定できません。
# firstPrice secondLimitPrice secondStopPrice のうち全てもしくはいずれか1つが必須です。
def changeIfoOrder(self, rootOrderId='', clientOrderId='',
firstPrice = '', secondLimitPrice ='', secondStopPrice =''):
params = {}
if len(rootOrderId) > 0:
params['rootOrderId'] = rootOrderId
if len(clientOrderId) > 0:
params['clientOrderId'] = clientOrderId
if len(firstPrice) > 0:
params['firstPrice'] = firstPrice
if len(secondLimitPrice) > 0:
params['secondLimitPrice'] = secondLimitPrice
if len(secondStopPrice) > 0:
params['secondStopPrice'] = secondStopPrice
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/changeIfoOrder', params=params)
# 注文の複数キャンセル
# 複数の注文を取消をします。
# rootOrderId clientOrderIdいずれか1つが必須です。2つ同時には設定できません。
# 最大10件まで注文を取消することができます。
def cancelOrders(self, rootOrderIds='', clientOrderIds=''):
params = {}
if len(rootOrderIds) > 0:
params['rootOrderIds'] = rootOrderIds
if len(clientOrderIds) > 0:
params['clientOrderIds'] = clientOrderIds
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/cancelOrders', params=params)
# 注文の一括キャンセル
# 一括で注文(通常注文、特殊注文いずれも)を取消します。
# 取消対象検索後に、対象注文を全て取消します。
# 1次注文が約定していないIFD、IFDOCOケースでは1次注文もしくは
# 2次注文にsideとsettleTypeの両方が一致するものが1つでもあれば注文全体を取消します。
# 1次注文が約定しているIFD、IFDOCOケースでは
# 2次注文にsideとsettleTypeの両方が一致するものがあれば2次注文を取消します。
def cancelBulkOrder(self, symbols, side='', settleType=''):
params = {'symbols':symbols}
if len(side) > 0:
params['side'] = side
if len(settleType) > 0:
params['settleType'] = settleType
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/cancelBulkOrder', params=params)
# 決済注文
# 決済注文をします。
# size settlePositionいずれか1つが必須です。2つ同時には設定できません。
# Side: BUY/SELL executionType: MARKET LIMIT STOP OCO
# size: 注文数量 建玉指定なし※size settlePositionいずれかのみ指定可能
# limitPrice: LIMIT OCO の場合は必須
# stopPrice: STOP OCO の場合は必須
# lowerBound:成立下限価格※executionType:MARKET side: SELLの場合に指定可能
# upperBound:成立上限価格※executionType:MARKET side: BUYの場合に指定可能
# settlePosition: 複数建玉 複数指定可能 ※size settlePositionいずれかのみ指定可能
# ※最大10件まで指定可能
# "settlePosition": [
# {
# "positionId": 1000342, 建玉ID
# "size": "10000" 注文数量
# }
# ]
def closeOrder(self, symbol, side, executionType,
clientOrderId='',size ='',
limitPrice='', stopPrice='',
lowerBound='', upperBound='',
settlePosition=''):
params = {'symbol': symbol,
'side': side,
'executionType': executionType
}
if len(clientOrderId) > 0:
params['clientOrderId'] = clientOrderId
if len(size) > 0:
params['size'] = size
if len(limitPrice) > 0:
params['limitPrice'] = limitPrice
if len(stopPrice) > 0:
params['stopPrice'] = stopPrice
if len(lowerBound) > 0:
params['lowerBound'] = lowerBound
if len(upperBound) > 0:
params['upperBound'] = upperBound
if len(settlePosition) > 0:
params['settlePosition'] = settlePosition
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/closeOrder', params=params)
# ---------------------------------------- #
# Private WebSocket API
# ---------------------------------------- #
# アクセストークンを取得
# Private WebSocket API用のアクセストークンを取得します。
def post_ws_auth(self):
params = {}
self.set_request(method='POST', access_modifiers='private',
target_path='/v1/ws-auth', params=params)
# アクセストークンを延長
# Private WebSocket API用のアクセストークンを延長します。
def put_ws_auth(self, token):
params = {'token': token}
self.set_request(method='PUT', access_modifiers='private',
target_path='/v1/ws-auth', params=params)
# アクセストークンを削除
# Private WebSocket API用のアクセストークンを削除します。
def delete_ws_auth(self, token):
params = {'token': token}
self.set_request(method='DELETE', access_modifiers='private',
target_path='/v1/ws-auth', params=params)
# ------------------------------------------------ #
# WebSocket
# ------------------------------------------------ #
# Public WebSocket
async def public_ws_run(self, callback, channels):
# 変数
end_point_public = self.URLS['publicWS']
while True:
try:
async with aiohttp.ClientSession() as session:
# Public WebSocket
async with session.ws_connect(end_point_public,
receive_timeout=self.TIMEOUT) as client:
if len(channels) > 0:
await self.subscribe(client, channels)
async for response in client:
if response.type != WSMsgType.TEXT:
print('response:' + str(response))
break
elif 'error' in response[1]:
print(response[1])
break
else:
data = json.loads(response[1])
await self.handler(callback, data)
except Exception as e:
print(e)
print(traceback.format_exc().strip())
await asyncio.sleep(10)
# Private WebSocket
async def private_ws_run(self, callback, channels):
while True:
try:
async with aiohttp.ClientSession() as session:
# トークンの取得
if self.token == '':
self.post_ws_auth()
response = await self.send()
self.token = response[0]['data']
# 変数
end_point_private = ''.join([self.URLS['privateWS'], '/', self.token])
# Private WebSocket
async with session.ws_connect(end_point_private,
receive_timeout=self.TIMEOUT) as client:
if len(channels) > 0:
await self.subscribe(client, channels)
async for response in client:
if response.type != WSMsgType.TEXT:
print('response:' + str(response))
break
elif 'error' in response[1]:
print(response[1])
break
else:
data = json.loads(response[1])
await self.handler(callback, data)
except Exception as e:
print(e)
print(traceback.format_exc().strip())
await asyncio.sleep(10)
if self.token != '':
self.token = ''
# 購読
# PUBLIC_CHANNELS : [{'channel':'ticker','symbol':'USD_JPY'},
# {'channel':'ticker','symbol':'EUR_JPY'} ... ]
#
# PRIVATE_CHANNELS : [{'channel':'executionEvents'},
# {'channel':'orderEvents'},
# {'channel':'positionEvents'},
# {'channel':'positionSummaryEvents','option':'PERIODIC'}]
#
async def subscribe(self, client, channels):
for channel in channels:
print(channel)
if channel['channel'] == 'ticker':
params = {'command':'subscribe', 'channel':'ticker', 'symbol': channel['symbol']}
elif channel['channel'] == 'executionEvents':
params = {'command':'subscribe', 'channel':'executionEvents'}
elif channel['channel'] == "orderEvents":
params = {'command':'subscribe', 'channel':'orderEvents'}
elif channel['channel'] == "positionEvents":
params = {'command':'subscribe', 'channel':'positionEvents'}
elif channel['channel'] == "positionSummaryEvents":
if channel['option'] == 'PERIODIC':
params = {'command':'subscribe', 'channel':'positionSummaryEvents', 'option':'PERIODIC'}
else:
params = {'command':'subscribe', 'channel':'positionSummaryEvents'}
await asyncio.wait([client.send_str(json.dumps(params))])
print('---- %s connect ----' %(channel))
await asyncio.sleep(2)
# トークンの延長
async def extend_token(self):
while True:
try:
await asyncio.sleep(self.EXTEND_TOKEN_TIME)
if self.token != '':
# トークンの延長
self.put_ws_auth(self.token)
response = await self.send()
except Exception as e:
print(e)
print(traceback.format_exc().strip())
# UTILS
# コールバック、ハンドラー
async def handler(self, func, *args):
return await func(*args)
利用サンプル
import asyncio
from gmocoinfx_api_wrapper import GMOCoinFX
class Sample():
# ---------------------------------------- #
# init
# ---------------------------------------- #
def __init__(self, api_key, api_secret):
self.gmocoinfx = GMOCoinFX(api_key=api_key, api_secret=api_secret)
# タスクの設定およびイベントループの開始
public_channels = [{'channel':'ticker','symbol':'USD_JPY'},
{'channel':'ticker','symbol':'EUR_JPY'},
{'channel':'ticker','symbol':'GBP_JPY'},
{'channel':'ticker','symbol':'AUD_JPY'}
]
private_channels = [{'channel':'executionEvents'},
{'channel':'orderEvents'},
{'channel':'positionEvents'},
{'channel':'positionSummaryEvents','option':'PERIODIC'}
]
loop = asyncio.get_event_loop()
tasks = [
self.gmocoinfx.private_ws_run(self.realtime,private_channels),
self.gmocoinfx.public_ws_run(self.realtime,public_channels),
self.gmocoinfx.extend_token(),
self.run()
]
loop.run_until_complete(asyncio.wait(tasks))
# ---------------------------------------- #
# bot main
# ---------------------------------------- #
async def run(self):
while(True):
await self.main(5)
await asyncio.sleep(0)
async def main(self, interval):
# main処理
# 取引所ステータスを取得
self.gmocoinfx.status()
response = await self.gmocoinfx.send()
print("================ status ===============")
print(response[0])
# 最新レートを取得
self.gmocoinfx.ticker()
response = await self.gmocoinfx.send()
print("================ ticker ===============")
print(response[0])
# 資産残高を取得
self.gmocoinfx.assets()
response = await self.gmocoinfx.send()
print("================ assets ===============")
print(response[0])
await asyncio.sleep(interval)
# リアルタイムデータの受信
async def realtime(self, data):
# ここにWebSocketから配信されるデータが落ちてきますので
# 適宜加工して利用してみてください。
print(data)
await asyncio.sleep(0)
# --------------------------------------- #
# main
# --------------------------------------- #
if __name__ == '__main__':
api_key=""
api_secret=""
Sample(api_key=api_key, api_secret=api_secret)
コメント
0 件のコメント :
コメントを投稿