Zweck: FMZ unterstützt die Top-One-Börse
Betriebsadresse
Default: port=6667 und address =
#!/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()
BOGEDer lange Code wird nur langsam verdaut.