# coding=utf-8 import ujson from binance.websocket.spot.websocket_client import SpotWebsocketClient as WebsocketClient from binance.spot import Spot import time import requests import datetime import pymysql import math import pymongo g_spot_client = Spot() class Pair: def __init__(self): pass depth_u = 0 depth_U = 0 depth_ts = 0 bids = {} asks = {} g_btcusdt = None g_btcusdt = None def init_db(): mc = pymongo.MongoClient("mongodb://127.0.0.1:27020/") mdb = mc["border2"] return mc, mdb def get_depth(client, pair): new_pair = Pair() d = client.depth(pair, limit=5000) new_pair.bids = d["bids"] new_pair.asks = d["asks"] new_pair.depth_u = d["lastUpdateId"] print(pair, ": get_depth: init", new_pair.depth_u) #print(new_pair.bids) return new_pair def dict2number(dict_in): dict_out = {} #print("dict2number", dict_in) for id in dict_in: #print("dict2number", id) #price = (int(float(id[0])) / 100) * 100 #price = float(id[0]) quantity = float(id[1]) #pricestr = str(price) dict_out[id[0]] = quantity return dict_out def dict2save(mdb, pair, dict_in, ts): mdbc = mdb[pair] s_append = {} s_append["unixdt"] = int(ts / 1000) #cnt = 0 for id in dict_in: # print(cnt, id) #if cnt >= 50: #break # bids_append[id] = top_bids[id] s_append[id[0]] = id[1] #cnt += 1 print("dict2save", s_append) mdbc.insert_one(s_append) def classify_order(dict_in): dict_out = {} for id in dict_in: price = int(int(float(id))/100)*100 pricestr = str(price) if pricestr in dict_out: dict_out[pricestr] = dict_out[pricestr]+dict_in[id] else: dict_out[pricestr] = dict_in[id] return dict_out def stat_order(pair, bids_in, asks_in, ts, old_ts): print(pair, ": stat_order cmp", ts, old_ts) if ts - old_ts < 1000 * 60 * 5: return False bids = dict2number(bids_in) asks = dict2number(asks_in) bids_classify = classify_order(bids) asks_classify = classify_order(asks) print("bids_classify", bids_classify) top_bids = sorted(bids_classify.items(), key=lambda x: x[1], reverse=False) top_asks = sorted(asks_classify.items(), key=lambda x: x[1], reverse=False) print("top_bids", top_bids) mc, mdb = init_db() dict2save(mdb, pair + "_bids", top_bids, ts) dict2save(mdb, pair + "_asks", top_asks, ts) print(pair, ": stat_order OK at", ts) return True def merge_order(dst, src): new_dst = [] for dst_item in dst: found = False for src_item in src: #print("dst", dst_item, "src", src_item) if dst_item[0] == src_item[0]: new_dst.append(src_item) found = True break if found is False: #print("merge_order dst copy", dst_item) new_dst.append(dst_item) return new_dst def handler_order(pair, pair_name, msg_in, client): ts = msg_in["E"] dU = msg_in["U"] du = msg_in["u"] need_reinit = False if pair is not None: if (dU == pair.depth_u + 1) or ( (du > pair.depth_u) and (pair.depth_ts == 0) and (pair.depth_u != 0)): bids = msg_in["b"] asks = msg_in["a"] #print("merge_order dst", pair.bids) #print("merge_order src", bids) #print("handle", pair_name, ts, dU, du, pair.depth_u) pair.bids = merge_order(pair.bids, bids) pair.asks = merge_order(pair.asks, asks) pair.depth_U = dU pair.depth_u = du if stat_order(pair_name, pair.bids, pair.asks, ts, pair.depth_ts): pair.depth_ts = ts print(pair_name, ": append", du) else: if (dU != pair.depth_u + 1) and (pair.depth_u != 0): need_reinit = True else: pass if need_reinit: pair = get_depth(client, pair_name) print(pair_name, ": reinit", pair.depth_u, dU, pair.depth_ts) return pair def order_handler(message): #print(message) global g_spot_client global g_btcusdt global g_ethusdt if message["stream"] == "btcusdt@depth": ddata = message["data"] if ddata["e"] == "depthUpdate": g_btcusdt = handler_order(g_btcusdt, "BTCUSDT", ddata, g_spot_client) elif message["stream"] == "ethusdt@depth": ddata = message["data"] if ddata["e"] == "depthUpdate": g_ethusdt = handler_order(g_ethusdt, "ETHUSDT", ddata, g_spot_client) else: pass def check_order(): global g_spot_client global g_btcusdt global g_ethusdt ws_client = WebsocketClient() ws_client.start() ws_client.instant_subscribe( stream=['btcusdt@depth', 'ethusdt@depth'], callback=order_handler, ) g_btcusdt = get_depth(g_spot_client, "BTCUSDT") g_ethusdt = get_depth(g_spot_client, "ETHUSDT") check_order()