【Python】bitflyer の API を使って注文をキャンセルする

公開日:2018-12-14
最終更新:2018-12-14
※この記事は外部サイト(https://www.doraxdora.com/blog/2018/03/21/...)からのクロス投稿です

今回は、注文の取消も実装してみたいと思います。

プログラムは前回のものを流用します。

【Python】bitflyer の API を使って注文を送信する

画面の修正

Main.html 注文取消ボタン用の列を追加
<div id="childOrderContainer">  
   <table id="childOrderTable">  
      <tr class="header">  
         <th style="width:20%">ID</th>  
         <th style="width:10%">売買</th>  
         <th style="width:10%">種別</th>  
         <th style="width:10%">値段</th>  
         <th style="width:10%">数量</th>  
         <th style="width:10%">注文日時</th>  
         <th style="width:10%">期限</th>  
         <th style="width:5%">取消</th>  
      </tr>  
   </table>  
</div>  
_ChildOrder.html

同じく注文取消ボタン用列の追加と、ボタンの表示

    <!DOCTYPE html>  
    <table id="childOrderTable">  
        <tr class="header">  
            <th style="width:20%">ID</th>  
            <th style="width:10%">売買</th>  
            <th style="width:10%">種別</th>  
            <th style="width:10%">値段</th>  
            <th style="width:10%">数量</th>  
            <th style="width:10%">注文日時</th>  
            <th style="width:10%">期限</th>  
            <th style="width:5%">取消</th>  
        </tr>  
        {% for item in data %}  
            <tr>  
                <td>{{ item["child_order_id"] }}</td>  
                <td>{{ item["side"] }}</td>  
                <td>{{ item["child_order_type"] }}</td>  
                <td>{{ item["price"] }}</td>  
                <td>{{ item["size"] }}</td>  
                <td>{{ parse_date (item["child_order_date"]) }}</td>  
                <td class="cnt">{{ parse_date (item["expire_date"]) }}</td>  
                <td><input type="button" value="取消" onclick="cancelOrder('{{ item["child_order_id"] }}')"</td>  
            </tr>  
        {% end %}  
    </table>  

style.css
注文取消しボタンのセンタリング

    td.cnt {  
        text-align:center;  
    }  

プログラムの修正

bfTool.py

注文取消し用リクエストハンドラ―を追加

class CancelChildOrderHandler(RequestHandler):  
    """  
    注文を取消  
    """  

def initialize(self):  
    logging.info("SendChildOrderHandler [initialize]")  

def post(self):  
    logging.info("SendChildOrderHandler [post]")  

    param = json.loads(self.request.body)  
    param["product_code"] = "FX_BTC_JPY"  
    logging.info(param)  

    api = BfApi()  
    data = api.send_req(api_path="/v1/me/cancelchildorder", http_method="POST", **param)  
    self.write(json.dumps(data, ensure_ascii=False))  

URLマッピングの追加

    app = tornado.web.Application([  
        (r"/", MainHandler),  
        (r"/ticker", SendWebSocket),  
        (r"/balance", GetBalanceHandler),  
        (r"/execution", GetExecutionHandler),  
        (r"/childOrder", GetChildOrderHandler),  
        (r"/sendOrder", SendChildOrderHandler),  
        (r"/cancelOrder", CancelChildOrderHandler)  
        ],  
        template_path=os.path.join(os.getcwd(), "templates"),  
        static_path=os.path.join(os.getcwd(), "static"),  
        js_path=os.path.join(os.getcwd(), "js"),  
    )  

取消ボタン押下時の処理

script.js
/**  
 * 注文をキャンセルします.  
 */  
function cancelOrder(order_id) {  

var param = {
child_order_id : order_id
}

$.ajax({
url: "http://localhost:8888/cancelOrder",
type: "POST",
data: JSON.stringify(param),
success: function(jsonResponse) {
jsonResponse = jsonResponse.replace( /\/g , "" );
var data = JSON.parse(jsonResponse);
updateChildOrder();
alert("注文をキャンセルしました。")
},
error: function() {
}
});
}


ついでに注文一覧を2秒毎に更新するように

script.js

/**  
 * 画面読み込み時の処理  
 */  
function initialize() {  

    // 各テーブルに空行を追加しておく  
    addEmptyRow("tickerTable", 10, 12);  
    addEmptyRow("executionTable", 10, 8);  

    // 初期表示時に一度データを取得  
    updateBalance();  
    updateExecution();  
    updateChildOrder();  

    var connection = new WebSocket('ws://127.0.0.1:8888/ticker');  
    connection.onmessage = function (e) {  
        var data = JSON.parse(e.data.replace( /\\/g , "" ));  

        var table = $("#tickerTable");  

        // 日付け変換  
        var date = new Date(data.timestamp);  
        data.timestamp = date.toLocaleString();  

        // テーブルに追加  
        var tr = document.createElement("tr");  
        $.each(data, function(i, cell){  
            var td = document.createElement("td");  
            td.innerHTML = cell;  
            tr.appendChild(td);  
        });  
        var rows = table.find("tr");  
        if (rows.length > 10) {  
            $("#tickerTable tr:last").remove();  
        }  
        $(tr).insertAfter("#tickerTable tr.header");  

    };  

    // 注文種別変更時の処理  
   $("#order_type").change(function () {  
       if($(this).val() == "MARKET") {  
            $("#order_price").prop("disabled", true);  
       } else {  
           $("#order_price").prop("disabled", false);  
       }  
   });  

   // 注文一覧を2秒ごとに更新  
   setInterval("updateChildOrder()", 2000);  
}

起動してみる

注文を出している状態。
取消ボタンをクリックします。

取消の完了メッセージが表示されます。

注文一覧からも注文がいなくなりました。

まとめ

何度か試している際に気付いたのが、 (bitflyer)サーバーに負荷がかかっている状態だと やっぱり注文も取消もしばらく時間がかかってしまうようですね。

注文が正常に受け付けられたとしても
注文一覧で取得できない状態ではまだ約定までは至らないような感じです。

まあしょうがないんですかね。

次回はSQLiteなんかと組み合わせてみましょうか。

ではでは。

記事が少しでもいいなと思ったらクラップを送ってみよう!
18
+1
@doraxdoraの技術ブログ 主に Java, C#, Python, Javascript の記事を載せていく予定。

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする