e支店のAPIはクセが強めで、ぜんぜんリーダブルではないんですが、ユーザー向けツールの拡張的位置づけの某kabuステと違って、自社のサービス向けにしっかりと開発されている印象です。
抽象度を上げるラッパーさえ書いてしまえば、なんてことはない。
しかし、IssueもほったらかしのkabuステのAPIは今後どうなるんでしょうか。
一般信用の貸借銘柄が豊富なのは魅力なので、ぜひ頑張ってほしい所です。
python ebranchapi/__init__.py
import requests
import datetime as dt
import json
from ebranchapi import get_market_price
class Context(object):
def __init__(
self,
base_url=None,
user_id=None,
password=None,
):
self.base_url = base_url
self.user_id = user_id
self.password = password
self.request_no = 1
self.session_info = None
self.mapping = {
'xLISS': '所属',
'pDPP': '現在値',
'tDPP:T': '現在値時刻',
'pDPG': '現値前値比較',
'pDYWP': '前日比',
'pDYRP': '騰落率',
'pDOP': '始値',
'tDOP:T': '始値時刻',
'pDHP': '高値',
'tDHP:T': '高値時刻',
'pDLP': '安値',
'tDLP:T': '安値時刻',
'pDV': '出来高',
'pQAS': '売気配値種類',
'pQAP': '売気配値',
'pAV': '売気配数量',
'pQBS': '買気配値種類',
'pQBP': '買気配値',
'pBV': '買気配数量',
'xDVES': '配当落銘柄区分',
'xDCFS': '不連続要因銘柄区分',
'pDHF': '日通し高値フラグ',
'pDLF': '日通し安値フラグ',
'pDJ': '売買代金',
'pAAV': '売数量(成行)',
'pABV': '買数量(成行)',
'pQOV': '売-OVER',
'pGAV10': '売-10-数量',
'pGAP10': '売-10-値段',
'pGAV9': '売-9-数量',
'pGAP9': '売-9-値段',
'pGAV8': '売-8-数量',
'pGAP8': '売-8-値段',
'pGAV7': '売-7-数量',
'pGAP7': '売-7-値段',
'pGAV6': '売-6-数量',
'pGAP6': '売-6-値段',
'pGAV5': '売-5-数量',
'pGAP5': '売-5-値段',
'pGAV4': '売-4-数量',
'pGAP4': '売-4-値段',
'pGAV3': '売-3-数量',
'pGAP3': '売-3-値段',
'pGAV2': '売-2-数量',
'pGAP2': '売-2-値段',
'pGAV1': '売-1-数量',
'pGAP1': '売-1-値段',
'pGBV1': '買-1-数量',
'pGBP1': '買-1-値段',
'pGBV2': '買-2-数量',
'pGBP2': '買-2-値段',
'pGBV3': '買-3-数量',
'pGBP3': '買-3-値段',
'pGBV4': '買-4-数量',
'pGBP4': '買-4-値段',
'pGBV5': '買-5-数量',
'pGBP5': '買-5-値段',
'pGBV6': '買-6-数量',
'pGBP6': '買-6-値段',
'pGBV7': '買-7-数量',
'pGBP7': '買-7-値段',
'pGBV8': '買-8-数量',
'pGBP8': '買-8-値段',
'pGBV9': '買-9-数量',
'pGBP9': '買-9-値段',
'pGBV10': '買-10-数量',
'pGBP10': '買-10-値段',
'pQUV': '買-UNDER',
'pVWAP': 'VWAP',
'pPRP': '前日終値'}
self.get_market_price = get_market_price.EntitySpec(self)
# 以下、必要なエンドポイントを開発次第、追加していく
# 今んとこは get_market_price だけ
def req(self, url, params, headers=None):
params['p_no'] = str(self.request_no)
params['p_sd_date'] = dt.datetime.now().strftime('%Y.%m.%d-%H:%M:%S.%f')[:-3]
params['sJsonOfmt'] = '5'
params = json.dumps(params, ensure_ascii=False)
url = f"{url}?{params}"
res = requests.get(url, headers=headers)
res.encoding = 'shift-jis'
content = res.text
self.request_no += 1
return json.loads(content)
def login(self):
params = {
'sCLMID': 'CLMAuthLoginRequest',
'sUserId': self.user_id,
'sPassword': self.password,
}
res = self.req(f"{self.base_url}/auth/", params)
if int(res.get('p_errno', -1)) == 0 and int(res.get('sResultCode', -1)) == 0:
if res.get('sUrlRequest'):
self.session_info = {
'sUrlRequest': res.get('sUrlRequest'),
'sUrlMaster': res.get('sUrlMaster'),
'sUrlPrice': res.get('sUrlPrice'),
'sUrlEvent': res.get('sUrlEvent'),
'sZyoutoekiKazeiC': res.get('sZyoutoekiKazeiC')
}
else:
raise Exception("契約締結前書面が未読です。ブラウザーで確認してください。")
else:
raise Exception(f"ログイン失敗: {res.get('p_err')}, コード: {res.get('sResultCode')}")
def logout(self):
if not self.session_info:
return
params = {'sCLMID': 'CLMAuthLogoutRequest'}
res = self.req(self.session_info['sUrlRequest'], params)
if int(res.get('sResultCode', -1)) == 0:
self.session_info = None
return
else:
raise Exception(f"ログアウト失敗: {res.get('p_err')}, コード: {res.get('sResultCode')}")
def code_to_name(self, code):
return self.mapping.get(code, code)
python ebranchapi/get_market_price.py
class EntitySpec(object):
def __init__(self, ctx):
self.ctx = ctx
def __call__(self, **kwargs):
symbols = kwargs.get("symbols")
columns = kwargs.get("columns")
params = {
'sCLMID': 'CLMMfdsGetMarketPrice',
'sTargetIssueCode': ','.join(symbols),
'sTargetColumn': ','.join(columns),
}
res = self.ctx.req(
self.ctx.session_info['sUrlPrice'],
params)
res = res.get('aCLMMfdsMarketPrice', [])
return res
利用するときは、こんな感じ
import ebranchapi
from common import const
api = ebranchapi.Context(
base_url=const.BASE_URL, # 最後の/は含めない
user_id=const.EBRANCH_USER_ID,
password=const.EBRANCH_PASS,
)
api.login()
symbols = ["7203", "6758", "9984"]
columns = [ "pQAP", # 売気配値
"pQBP", # 買気配値
'pPRP', # 前日終値
]
data = api.get_market_price(symbols=symbols, columns=columns)
# => [
# {'sIssueCode': '7203', 'pQAP': '2720.0', 'pQBP': '2719.5', 'pPRP': '2365.5'},
# {'sIssueCode': '6758', 'pQAP': '3500', 'pQBP': '3499', 'pPRP': '3107'},
# {'sIssueCode': '9984', 'pQAP': '7070', 'pQBP': '7070', 'pPRP': '6070'}]