kabuステーションAPIの替わりに「立花証券e支店API」をPHPで使ってみる
kabuステーションAPI提供の「auカブコム証券」の運営元が変わり「三菱UFJ eスマート証券」となりました。
APIコミュニティの放置具合、ログイン時に毎回二要素認証が求められる技術力のなさ(その後改善)、バージョンアップの度に起動できない・インストール出来ないトラブルが発生するkabuステーションアプリと。
やる気の無さからAPIサービスも終了するかもしれないので、代替株取引APIとして「立花証券e支店API」を使ってみたのでシェアします。
立花証券e支店APIの利用条件
利用条件は特になく無料です。
※kabuステーションAPIは、3ヶ月以内の売買実績が必要です。
立花証券e支店APIの実行環境
指定のURLにアクセスするだけというシンプルな仕様です。URLにアクセスするだけなのでどんな環境からでも実行できます。
※kabuステーションAPIは、Windowsアプリ経由なので高価なWindows実行環境が必要になる。
APIの実行イメージ
https://kabuka.e-shiten.jp/xxxx/?{JSONデータ}
このURLにアクセスするだけです。仕様的にあれれ?と思うこともありますが、細かい事には目をつむります。
※URLにパスワードが含まれるのでブラウザからは利用しない方が良いです(履歴が残るという意味で)
PHPからAPIへのアクセス
送信は、リクエスト用の配列を「json_encode」→「urlencode」して「file_get_contents」するだけです。
受信は、API出力の文字コードが「SJIS」なので「mb_convert_encoding」で「UTF-8」にして「json_decode」で連想配列に変換するだけです。
//---JSON形式に変換後、URLエンコード
$send_url = "{$p_url}?" . urlencode(json_encode($p_send_ary));
$json = @file_get_contents($send_url , false);
if($json){
//---「SJIS」から「UTF-8」へ文字コード変換
$json_utf8 = mb_convert_encoding($json , "UTF-8" , "SJIS");
//---JSONから連想配列変換
$json_ary = json_decode($json_utf8 , true);
}
APIの認証処理
APIのURLに「auth/」パスを付与してアクセスします。認証に成功すると「sUrlRequest」が発行されるので、以後はそのURLに対してリクエストを投げます。
$send_ary = [
"sCLMID" => "CLMAuthLoginRequest" ,
"sUserId" => ES_LOGIN_ID ,
"sPassword" => ES_LOGIN_PASSWORD ,
"p_no" => $this->_sendCountGet() ,
"p_sd_date" => $this->_sendDateGet() ,
"sJsonOfmt" => "4" ,
];
リクエスト毎に連番と送信日時データが必要なので以下の処理で対応します。
private function _sendDateGet(){
$date = date("Y.m.d-H:i:s.") . sprintf("%03d" , $this->send_count);
return $date;
}
private function _sendCountGet(){
$this->send_count++;
return "{$this->send_count}";
}
ログアウト処理
$send_ary = [
"sCLMID" => "CLMAuthLogoutRequest" ,
"p_no" => $this->_sendCountGet() ,
"p_sd_date" => $this->_sendDateGet() ,
"sJsonOfmt" => "4" ,
];
情報取得系のAPIコマンド例
買付余力
$send_ary = [
"sCLMID" => "CLMZanKaiKanougaku" ,
"p_no" => $this->_sendCountGet() ,
"p_sd_date" => $this->_sendDateGet() ,
"sJsonOfmt" => "4" ,
];
現物保有銘柄一覧
$send_ary = [
"sCLMID" => "CLMGenbutuKabuList" ,
"p_no" => $this->_sendCountGet() ,
"p_sd_date" => $this->_sendDateGet() ,
"sJsonOfmt" => "4" ,
];
株価情報
株価(板)情報の取得にはリクエスト先URL「sUrlPrice」を使います。
/*
pDPP: 現在値
tDPP:T: 現在値時刻
pPRP: 前日終値
pDYWP: 前日比
pDYRP: 騰落率
pDV: 出来高
pDHP: 高値
pDLP: 安値
pDOP: 始値
*/
$send_ary = [
"sCLMID" => "CLMMfdsGetMarketPrice" ,
"sTargetIssueCode" => "{$p_code}" ,
"sTargetColumn" => "pDPP,tDPP:T,pPRP,pDYWP,pDYRP,pDV,pDHP,pDLP,pDOP" ,
"p_no" => $this->_sendCountGet() ,
"p_sd_date" => $this->_sendDateGet() ,
"sJsonOfmt" => "4" ,
];
注文一覧
$send_ary = [
"sCLMID" => "CLMOrderList" ,
"p_no" => $this->_sendCountGet() ,
"p_sd_date" => $this->_sendDateGet() ,
"sJsonOfmt" => "4" ,
];
注文詳細
変数「$eigyou_day」には、直近の営業日を入れています。
$send_ary = [
"sCLMID" => "CLMOrderListDetail" ,
"sOrderNumber" => "{$p_order_no}" ,
"sEigyouDay" => "{$eigyou_day}" ,
"p_no" => $this->_sendCountGet() ,
"p_sd_date" => $this->_sendDateGet() ,
"sJsonOfmt" => "4" ,
];
注文実行系のAPIコマンド例
現物新規注文
$send_ary = [
"sCLMID" => "CLMKabuNewOrder" ,
"sZyoutoekiKazeiC" => ES_ZYOUTOEKIKAZEIC_TOKUTEI ,
"sIssueCode" => "{$p_code}" ,
"sSizyouC" => ES_SIZYOUC_TOSHOU ,
"sBaibaiKubun" => ($p_side === "buy") ? ES_BAIBAIKUBUN_BUY : ES_BAIBAIKUBUN_SALE ,
"sCondition" => ES_CONDITION_NONE ,
"sOrderPrice" => "{$p_price}" ,
"sOrderSuryou" => "{$p_qty}" ,
"sGenkinShinyouKubun" => ES_GENKINSHINYOUKUBUN_GENBUTSU ,
"sOrderExpireDay" => "{$p_expire}" ,
"sGyakusasiOrderType" => ES_GYAKUSASIORDERTYPE_NONE ,
"sGyakusasiZyouken" => ES_GYAKUSASIZYOUKEN_NONE ,
"sGyakusasiPrice" => ES_GYAKUSASIPRICE_NONE ,
"sTatebiType" => ES_TATEBITYPE_NONE ,
"sSecondPassword" => ES_ORDER_PASSWORD ,
"p_no" => $this->_sendCountGet() ,
"p_sd_date" => $this->_sendDateGet() ,
"sJsonOfmt" => "4" ,
];
使用している定数
define('ES_ZYOUTOEKIKAZEIC_TOKUTEI' , "1"); //譲渡益課税区分:特定
define('ES_SIZYOUC_TOSHOU' , "00"); //市場:東証
define('ES_BAIBAIKUBUN_SALE' , "1"); //売買区分:売
define('ES_BAIBAIKUBUN_BUY' , "3"); //売買区分:買
define('ES_CONDITION_NONE' , "0"); //執行条件:指定なし
define('ES_GENKINSHINYOUKUBUN_GENBUTSU' , "0"); //現金信用区分:現物
define('ES_GYAKUSASIORDERTYPE_NONE' , "0"); //逆指値注文種別:通常
define('ES_GYAKUSASIZYOUKEN_NONE' , "0"); //逆指値条件:指定なし
define('ES_GYAKUSASIPRICE_NONE' , "*"); //逆指値値段:指定なし
define('ES_TATEBITYPE_NONE' , "*"); //建日種類:指定なし(現物または新規)
注文取り消し
$send_ary = [
"sCLMID" => "CLMKabuCancelOrder" ,
"sOrderNumber" => "{$p_order_no}" ,
"sEigyouDay" => "{$eigyou_day}" ,
"sSecondPassword" => ES_ORDER_PASSWORD ,
"p_no" => $this->_sendCountGet() ,
"p_sd_date" => $this->_sendDateGet() ,
"sJsonOfmt" => "4" ,
];
まとめ
こんなに簡単な処理で株取引APIを使えてしまいました。自分は現物株取引のみの利用なので実際に使っているコマンドはこれだけです(※当然エラー処理などは大量に追加しています)
大きなストレスであった「kabuステーションアプリを起動する」という動作が必要ないのが大きなメリットです。いや、実際APIってこれでよいはずでは?kabuステーションAPIが間違っているだけだと再認識しました。
ただし「立花証券e支店API」にしても、いつサービス終了するのかは分からないので、kabuステーションAPIと併用する事をおすすめします…といいながらも大半の資金を「eスマート証券」から「立花証券e支店」に移している自分でした!