Top-One 通用协议Python2版本

Author: 小小梦, Created: 2018-07-06 11:38:24, Updated:

Top-One 通用协议Python2版本

用途:可以使 FMZ 支持 Top-One 交易所

运行地址 默认: port=6667, address = “127.0.0.1http://127.0.0.1:6667 也可以在运行时指定端口

  • 代码
#!/usr/bin/env python
# -*- coding: utf-8 -*

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import json
import urllib
import urllib2
import time
import hmac
import hashlib
import random
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

_MapToken = {}

def HttpGet(url):
    headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
    req = urllib2.Request(url,headers=headers)
    response = urllib2.urlopen(req)
    return json.loads(response.read())

def HttpPost(url, params):
    headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
    req = urllib2.Request(url,json.dumps(params,encoding="utf8", ensure_ascii=False),headers=headers)
     
    # 测试
    print('\033[1;35m HttpPost req : \033[0m')
    print("headers:", headers, "url:", url, "params:", json.dumps(params,encoding="utf8", ensure_ascii=False))

    response = urllib2.urlopen(req)
    return json.loads(response.read())

def Symbol2Pair(symbol):
    arrCurrency = symbol.split('_')
    if len(arrCurrency) != 2 :
        raise "symbol error!"

    return arrCurrency[0] + '/' + arrCurrency[1]

class MyExchange:

    market_url = "https://"
    trade_url = "https://"

    @staticmethod
    def GetToken(accessKey, secretKey):          
        currentTime = int(time.time())
        randomNum = random.randint(100000, 999999)

        params = {
            "appkey" : secretKey,
            "time"  : currentTime, 
            "random" : randomNum, 
        }

        data = urllib.urlencode(params)
        sha256 = hashlib.sha256()
        sha256.update(data.encode("utf-8"))
        sign = sha256.hexdigest()

        body = {
            "appid" : accessKey,
            "time" : currentTime, 
            "random" : randomNum,
            "sig" : sign 
        }

        resp = HttpGet("https://server.top.one/api/apiToken?" + urllib.urlencode(body))

        return resp
    
    @staticmethod
    def GetTicker(symbol):
        return {'error': 'not support!'}      

    @staticmethod
    def GetDepth(symbol):
        url = MyExchange.market_url + "depth.top.one/"
        params = {
            "method": "depth.query", 
            "params": [Symbol2Pair(symbol),10], 
            "id": 0
        }

        raw_data = HttpPost(url, params)
        
        print "GetDepth:"
        print raw_data     # 测试

        if raw_data["error"] != None:
            return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)}

        ret_data = {"data" : {"time" : raw_data['result'][0]['time'], "asks" : [], "bids" : []}}
        for bid in raw_data['result'][0]['bids']:
            ret_data['data']['bids'].append([bid[0],bid[1]])

        for ask in raw_data['result'][0]['asks']:
            ret_data['data']['asks'].append([ask[0],ask[1]])

        return ret_data

    @staticmethod
    def GetRecords(symbol, period):
        return {'error': 'not support!'}

    @staticmethod
    def GetTrades(symbol):
        return {'error': 'not support!'}

    @staticmethod
    def GetAccount(api_key, api_secret):
        url = MyExchange.trade_url + "trade.top.one/"
        params = {
            "method": "balance.query",
            "params": [_MapToken[api_key]],
            "id": 0
        }

        raw_data = HttpPost(url, params)

        print "GetAccount:"
        print raw_data      # 测试

        if 'error' in raw_data.keys() and raw_data["error"] != None:
            return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)}
        
        ret_data = {"data": []}
        if "result" in raw_data.keys():
            for asset in raw_data["result"]:
                ret_data["data"].append({"currency":asset["asset"], "free":asset["available"], "frozen":asset["freeze"]})
        ret_data["raw"] = raw_data     
        return ret_data


    @staticmethod
    def Trade(api_key, api_secret, symbol, order_side, price, amount):
        url = MyExchange.trade_url + "trade.top.one/"
        params = {
            "method" : "order.limit",
            "params" : [
                _MapToken[api_key],
                Symbol2Pair(symbol),
                order_side,                     
                amount,
                price,
                0
            ],
            "id" : 0
        }

        if price == -1 :
            params = {
                "method" : "order.market",
                "params" : [
                    _MapToken[api_key],
                    Symbol2Pair(symbol),
                    order_side,
                    amount,
                    0
                ],
                "id" : 0
            }

        raw_data = HttpPost(url, params)
        
        print "Trade:"
        print raw_data    # 测试

        if 'error' in raw_data.keys() and raw_data["error"] != None:
            return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)}

        ret_data = {"data": {'id':raw_data['result']['id']}}
        return ret_data

    @staticmethod
    def CancelOrder(api_key, api_secret, symbol, orders_id):
        url = MyExchange.trade_url + "trade.top.one/"
        params = {
            "method" : "order.cancel",
            "params" : [
                _MapToken[api_key],
                Symbol2Pair(symbol),
                orders_id
            ],
            "id" : 0 
        }

        raw_data = HttpPost(url, params)

        print "CancelOrder:"
        print raw_data    # 测试

        if 'error' in raw_data.keys() and raw_data["error"] != None:
            return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)}

        ret_data = {"data":True}
        try:
            result = raw_data['result'].encode('utf8')
        except:
            ret_data = {"data":False}
        ret_data['raw'] = raw_data
        return ret_data

    @staticmethod
    def GetOrder(api_key, api_secret, symbol, orders_id): 
        return {'error': 'not support!'}        

    @staticmethod
    def GetOrders(api_key, api_secret, symbol, pair):
        url = MyExchange.trade_url + "trade.top.one/"
        params = {
            "method" : "order.query", 
            "params" : [_MapToken[api_key], 0, 100],
            "id" : 0
        }

        raw_data = HttpPost(url, params)
        
        print "GetOrders:"
        print raw_data      # 测试
        
        arrRaw_data = []
        total = raw_data["result"]["total"]
        getNum = 0

        if 'error' in raw_data.keys() and raw_data["error"] != None:
            return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)}

        ret_data = {"data":[]}

        arrRaw_data.append(raw_data)
        for order in raw_data["result"]["records"]:
            if order['market'] != Symbol2Pair(symbol) :
                continue

            ret_data["data"].append(
                {
                    "id": order['id'],
                    "amount": order['amount'],
                    "price": order['price'],
                    "status": "open",                           
                    "deal_amount": order['deal_stock'],
                    "type": "buy" if order['side'] == 2 else "sell", 
                }
            )

        getNum = 100
        while getNum < total :
            url = MyExchange.trade_url + "trade.top.one/"
            params = {
                "method" : "order.query", 
                "params" : [_MapToken[api_key], getNum, (getNum + 100)],
                "id" : 0
            }

            raw_data = HttpPost(url, params)
            if 'error' in raw_data.keys() and raw_data["error"] != None:
                return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)}

            arrRaw_data.append(raw_data)
            for order in raw_data["result"]["records"]:
                if order['market'] != Symbol2Pair(symbol) :
                    continue

                ret_data["data"].append(
                    {
                        "id": order['id'],
                        "amount": order['amount'],
                        "price": order['price'],
                        "status": "open",                           
                        "deal_amount": order['deal_stock'],
                        "type": "buy" if order['side'] == 2 else "sell", 
                    }
                )

            getNum += 100

        ret_data['raw'] = arrRaw_data
        return ret_data


    @staticmethod
    def IO(api_key, api_secret, path, params):
        url = MyExchange.trade_url + path
        print(params, type(params))
        
        params["params"] = [_MapToken[api_key]]
        params["id"] = int(params["id"])
        
        print(params)
        raw_data = HttpPost(url, params)
        return {"data":raw_data}

class Server(BaseHTTPRequestHandler):

    def do_HEAD(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        
    def do_POST(self):
        global _MapToken

        self.data_string = self.rfile.read(int(self.headers['Content-Length']))
        data =json.loads(self.data_string.replace("'", '"'))
        sent_data = {}

        if data["access_key"] not in _MapToken.keys() :
            token = MyExchange.GetToken(data["access_key"], data["secret_key"])
            if token["error_code"] != 0:
                self.do_HEAD()
                self.wfile.write(json.dumps({"error" : json.dumps(token, encoding="utf8", ensure_ascii=False)}))
                return 

            _MapToken[data["access_key"]] = token["data"]["apitoken"]

            print "更新 token"      
            print _MapToken        

        if data['method'] == "ticker":
            symbol = data['params']['symbol'].upper()
            sent_data = MyExchange.GetTicker(symbol)
        elif data['method'] == "depth":
            symbol = data['params']['symbol'].upper()
            sent_data = MyExchange.GetDepth(symbol)
        elif data['method'] == "records":
            symbol = data['params']['symbol'].upper()
            period = data['params']['period']
            sent_data = MyExchange.GetRecords(symbol, int(period))
        elif data['method'] == "trades":
            symbol = data['params']['symbol'].upper()
            sent_data = MyExchange.GetTrades(symbol)
        elif data['method'] == "accounts":
            access_key = data["access_key"]
            secret_key = data["secret_key"]
            sent_data = MyExchange.GetAccount(access_key, secret_key)
        elif data['method'] == "trade":
            symbol = data['params']['symbol'].upper()
            access_key = data["access_key"]
            secret_key = data["secret_key"]
            order_side = 2 if data['params']['type'] == 'buy' else 1
            price = data['params']['price']
            amount = data['params']['amount']
            sent_data = MyExchange.Trade(access_key, secret_key, symbol, order_side, price, amount)
        elif data['method'] == "cancel":
            symbol = data['params']['symbol'].upper()
            access_key = data["access_key"]
            secret_key = data["secret_key"]
            orders_id = int(data['params']['id'])
            sent_data = MyExchange.CancelOrder(access_key, secret_key, symbol, orders_id)
        elif data['method'] == "order":
            symbol = data['params']['symbol'].upper()
            access_key = data["access_key"]
            secret_key = data["secret_key"]
            orders_id = int(data['params']['id'])
            sent_data = MyExchange.GetOrder(access_key, secret_key, symbol, orders_id)
        elif data['method'] == "orders":
            symbol = data['params']['symbol'].upper()
            access_key = data["access_key"]
            secret_key = data["secret_key"]
            pair = data['params']['symbol'].upper()
            sent_data = MyExchange.GetOrders(access_key, secret_key, symbol, pair)
        elif data['method'][:2] == "__":
            access_key = data["access_key"]
            secret_key = data["secret_key"]
            path = data["method"].split('_')[-1]
            params = data["params"]
            sent_data = MyExchange.IO(access_key, secret_key, path, params)

        if 'error' in sent_data.keys() and isinstance(sent_data["error"], unicode):     
            token = MyExchange.GetToken(data["access_key"], data["secret_key"])
            if token["error_code"] != 0:
                self.do_HEAD()
                self.wfile.write(json.dumps({"error" : json.dumps(token, encoding="utf8", ensure_ascii=False)}))
                return 
            _MapToken[data["access_key"]] = token["data"]["apitoken"]
            
            print "反馈给托管者之前, 更新 token"      
            print _MapToken        

        self.do_HEAD()
        self.wfile.write(json.dumps(sent_data))
        
def run(server_class=HTTPServer, handler_class=Server, port=6667, address = "127.0.0.1"):
    server_address = (address, port)
    httpd = server_class(server_address, handler_class)
    print 'Starting http server...'
    httpd.serve_forever()

if __name__ == "__main__":
    from sys import argv
    if len(argv) == 2:
        run(port=int(argv[1]))
    else:
        run()

More

BOGE 好长的代码,只能慢慢消化了