[Del]移除OkCoin和火币的老接口

This commit is contained in:
vn.py 2017-12-16 09:15:39 +08:00
parent ec88ac1ce3
commit 1dcd2239bd
17 changed files with 27 additions and 2708 deletions

View File

@ -1,18 +0,0 @@
# vn.huobi
### 简介
火币的比特币交易接口基于Rest API开发实现了官方提供API的全部功能。
### 特点
相比较于[火币官方](http://github.com/huobiapi/API_Docs/)给出的Python API实现vn.huobi的一些特点
1. 面向对象的API设计接近CTP API的结构对于国内用户而言更容易上手
2. 参考CTP API的设计主动函数调用的结果通过异步回调函数的方式推送到程序中适用于开发稳定可靠的实盘交易程序
### API版本
日期2015-12-02
链接:[http://github.com/huobiapi/API_Docs/wiki](http://github.com/huobiapi/API_Docs/wiki)

View File

@ -1,3 +0,0 @@
# encoding: UTF-8
from vnhuobi import TradeApi, DataApi

View File

@ -1,67 +0,0 @@
# encoding: utf-8
from vnhuobi import *
#----------------------------------------------------------------------
def testTrade():
"""测试交易"""
accessKey = ''
secretKey = ''
# 创建API对象并初始化
api = TradeApi()
api.DEBUG = True
api.init(accessKey, secretKey)
# 查询账户,测试通过
api.getAccountInfo()
# 查询委托,测试通过
#api.getOrders()
# 买入,测试通过
#api.buy(7100, 0.0095)
# 卖出,测试通过
#api.sell(7120, 0.0095)
# 撤单,测试通过
#api.cancelOrder(3915047376L)
# 查询杠杆额度,测试通过
#api.getLoanAvailable()
# 查询杠杆列表,测试通过
#api.getLoans()
# 阻塞
input()
#----------------------------------------------------------------------
def testData():
"""测试行情接口"""
api = DataApi()
api.init(0.5)
# 订阅成交推送,测试通过
#api.subscribeTick(SYMBOL_BTCCNY)
# 订阅报价推送,测试通过
#api.subscribeQuote(SYMBOL_BTCCNY)
# 订阅深度推送,测试通过
#api.subscribeDepth(SYMBOL_BTCCNY, 1)
# 查询K线数据测试通过
data = api.getKline(SYMBOL_BTCCNY, PERIOD_1MIN, 100)
print data
input()
if __name__ == '__main__':
#testTrade()
testData()

View File

@ -1,652 +0,0 @@
# encoding: utf-8
import urllib
import hashlib
import json
import requests
from time import time, sleep
from Queue import Queue, Empty
from threading import Thread
# 常量定义
COINTYPE_BTC = 1
COINTYPE_LTC = 2
ACCOUNTTYPE_CNY = 1
ACCOUNTTYPE_USD = 2
LOANTYPE_CNY = 1
LOANTYPE_BTC = 2
LOANTYPE_LTC = 3
LOANTYPE_USD = 4
MARKETTYPE_CNY = 'cny'
MARKETTYPE_USD = 'usd'
SYMBOL_BTCCNY = 'BTC_CNY'
SYMBOL_LTCCNY = 'LTC_CNY'
SYMBOL_BTCUSD = 'BTC_USD'
PERIOD_1MIN = '001'
PERIOD_5MIN = '005'
PERIOD_15MIN = '015'
PERIOD_30MIN = '030'
PERIOD_60MIN = '060'
PERIOD_DAILY = '100'
PERIOD_WEEKLY = '200'
PERIOD_MONTHLY = '300'
PERIOD_ANNUALLY = '400'
# API相关定义
HUOBI_TRADE_API = 'https://api.huobi.com/apiv3'
# 功能代码
FUNCTIONCODE_GETACCOUNTINFO = 'get_account_info'
FUNCTIONCODE_GETORDERS = 'get_orders'
FUNCTIONCODE_ORDERINFO = 'order_info'
FUNCTIONCODE_BUY = 'buy'
FUNCTIONCODE_SELL = 'sell'
FUNCTIONCODE_BUYMARKET = 'buy_market'
FUNCTIONCODE_SELLMARKET = 'sell_market'
FUNCTIONCODE_CANCELORDER = 'cancel_order'
FUNCTIONCODE_GETNEWDEALORDERS = 'get_new_deal_orders'
FUNCTIONCODE_GETORDERIDBYTRADEID = 'get_order_id_by_trade_id'
FUNCTIONCODE_WITHDRAWCOIN = 'withdraw_coin'
FUNCTIONCODE_CANCELWITHDRAWCOIN = 'cancel_withdraw_coin'
FUNCTIONCODE_GETWITHDRAWCOINRESULT = 'get_withdraw_coin_result'
FUNCTIONCODE_TRANSFER = 'transfer'
FUNCTIONCODE_LOAN = 'loan'
FUNCTIONCODE_REPAYMENT = 'repayment'
FUNCTIONCODE_GETLOANAVAILABLE = 'get_loan_available'
FUNCTIONCODE_GETLOANS = 'get_loans'
#----------------------------------------------------------------------
def signature(params):
"""生成签名"""
params = sorted(params.iteritems(), key=lambda d:d[0], reverse=False)
message = urllib.urlencode(params)
m = hashlib.md5()
m.update(message)
m.digest()
sig=m.hexdigest()
return sig
########################################################################
class TradeApi(object):
"""交易接口"""
DEBUG = True
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.accessKey = ''
self.secretKey = ''
self.active = False # API工作状态
self.reqID = 0 # 请求编号
self.reqQueue = Queue() # 请求队列
self.reqThread = Thread(target=self.processQueue) # 请求处理线程
#----------------------------------------------------------------------
def processRequest(self, req):
"""处理请求"""
# 读取方法和参数
method = req['method']
params = req['params']
optional = req['optional']
# 在参数中增加必须的字段
params['created'] = long(time())
params['access_key'] = self.accessKey
params['secret_key'] = self.secretKey
params['method'] = method
# 添加签名
sign = signature(params)
params['sign'] = sign
del params['secret_key']
# 添加选填参数
if optional:
params.update(optional)
# 发送请求
payload = urllib.urlencode(params)
r = requests.post(HUOBI_TRADE_API, params=payload)
if r.status_code == 200:
data = r.json()
return data
else:
return None
#----------------------------------------------------------------------
def processQueue(self):
"""处理请求队列中的请求"""
while self.active:
try:
req = self.reqQueue.get(block=True, timeout=1) # 获取请求的阻塞为一秒
callback = req['callback']
reqID = req['reqID']
data = self.processRequest(req)
# 请求失败
if 'code' in data and 'message' in data:
error = u'错误信息:%s' %data['message']
self.onError(error, req, reqID)
# 请求成功
else:
if self.DEBUG:
print callback.__name__
callback(data, req, reqID)
except Empty:
pass
#----------------------------------------------------------------------
def sendRequest(self, method, params, callback, optional=None):
"""发送请求"""
# 请求编号加1
self.reqID += 1
# 生成请求字典并放入队列中
req = {}
req['method'] = method
req['params'] = params
req['callback'] = callback
req['optional'] = optional
req['reqID'] = self.reqID
self.reqQueue.put(req)
# 返回请求编号
return self.reqID
####################################################
## 主动函数
####################################################
#----------------------------------------------------------------------
def init(self, accessKey, secretKey):
"""初始化"""
self.accessKey = accessKey
self.secretKey = secretKey
self.active = True
self.reqThread.start()
#----------------------------------------------------------------------
def exit(self):
"""退出"""
self.active = False
if self.reqThread.isAlive():
self.reqThread.join()
#----------------------------------------------------------------------
def getAccountInfo(self, market='cny'):
"""查询账户"""
method = FUNCTIONCODE_GETACCOUNTINFO
params = {}
callback = self.onGetAccountInfo
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def getOrders(self, coinType=COINTYPE_BTC, market='cny'):
"""查询委托"""
method = FUNCTIONCODE_GETORDERS
params = {'coin_type': coinType}
callback = self.onGetOrders
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def orderInfo(self, id_, coinType=COINTYPE_BTC, market='cny'):
"""获取委托详情"""
method = FUNCTIONCODE_ORDERINFO
params = {
'coin_type': coinType,
'id': id_
}
callback = self.onOrderInfo
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def buy(self, price, amount, coinType=COINTYPE_BTC,
tradePassword='', tradeId = '', market='cny'):
"""委托买入"""
method = FUNCTIONCODE_BUY
params = {
'coin_type': coinType,
'price': price,
'amount': amount
}
callback = self.onBuy
optional = {
'trade_password': tradePassword,
'trade_id': tradeId,
'market': market
}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def sell(self, price, amount, coinType=COINTYPE_BTC,
tradePassword='', tradeId = '', market='cny'):
"""委托卖出"""
method = FUNCTIONCODE_SELL
params = {
'coin_type': coinType,
'price': price,
'amount': amount
}
callback = self.onSell
optional = {
'trade_password': tradePassword,
'trade_id': tradeId,
'market': market
}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def buyMarket(self, amount, coinType=COINTYPE_BTC,
tradePassword='', tradeId = '', market='cny'):
"""市价买入"""
method = FUNCTIONCODE_BUYMARKET
params = {
'coin_type': coinType,
'amount': amount
}
callback = self.onBuyMarket
optional = {
'trade_password': tradePassword,
'trade_id': tradeId,
'market': market
}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def sellMarket(self, amount, coinType=COINTYPE_BTC,
tradePassword='', tradeId = '', market='cny'):
"""市价卖出"""
method = FUNCTIONCODE_SELLMARKET
params = {
'coin_type': coinType,
'amount': amount
}
callback = self.onSellMarket
optional = {
'trade_password': tradePassword,
'trade_id': tradeId,
'market': market
}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def cancelOrder(self, id_, coinType=COINTYPE_BTC, market='cny'):
"""撤销委托"""
method = FUNCTIONCODE_CANCELORDER
params = {
'coin_type': coinType,
'id': id_
}
callback = self.onCancelOrder
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def getNewDealOrders(self, market='cny'):
"""查询最新10条成交"""
method = FUNCTIONCODE_GETNEWDEALORDERS
params = {}
callback = self.onGetNewDealOrders
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def getOrderIdByTradeId(self, tradeId, coinType=COINTYPE_BTC,
market='cny'):
"""通过成交编号查询委托编号"""
method = FUNCTIONCODE_GETORDERIDBYTRADEID
params = {
'coin_type': coinType,
'trade_id': tradeId
}
callback = self.onGetOrderIdByTradeId
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def withdrawCoin(self, withdrawAddress, withdrawAmount,
coinType=COINTYPE_BTC, tradePassword='',
market='cny', withdrawFee=0.0001):
"""提币"""
method = FUNCTIONCODE_WITHDRAWCOIN
params = {
'coin_type': coinType,
'withdraw_address': withdrawAddress,
'withdraw_amount': withdrawAmount
}
callback = self.onWithdrawCoin
optional = {
'market': market,
'withdraw_fee': withdrawFee
}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def cancelWithdrawCoin(self, id_, market='cny'):
"""取消提币"""
method = FUNCTIONCODE_CANCELWITHDRAWCOIN
params = {'withdraw_coin_id': id_}
callback = self.onCancelWithdrawCoin
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def onGetWithdrawCoinResult(self, id_, market='cny'):
"""查询提币结果"""
method = FUNCTIONCODE_GETWITHDRAWCOINRESULT
params = {'withdraw_coin_id': id_}
callback = self.onGetWithdrawCoinResult
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def transfer(self, amountFrom, amountTo, amount,
coinType=COINTYPE_BTC ):
"""账户内转账"""
method = FUNCTIONCODE_TRANSFER
params = {
'amount_from': amountFrom,
'amount_to': amountTo,
'amount': amount,
'coin_type': coinType
}
callback = self.onTransfer
optional = {}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def loan(self, amount, loan_type=LOANTYPE_CNY,
market=MARKETTYPE_CNY):
"""申请杠杆"""
method = FUNCTIONCODE_LOAN
params = {
'amount': amount,
'loan_type': loan_type
}
callback = self.onLoan
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def repayment(self, id_, amount, repayAll=0,
market=MARKETTYPE_CNY):
"""归还杠杆"""
method = FUNCTIONCODE_REPAYMENT
params = {
'loan_id': id_,
'amount': amount
}
callback = self.onRepayment
optional = {
'repay_all': repayAll,
'market': market
}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def getLoanAvailable(self, market='cny'):
"""查询杠杆额度"""
method = FUNCTIONCODE_GETLOANAVAILABLE
params = {}
callback = self.onLoanAvailable
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
#----------------------------------------------------------------------
def getLoans(self, market='cny'):
"""查询杠杆列表"""
method = FUNCTIONCODE_GETLOANS
params = {}
callback = self.onGetLoans
optional = {'market': market}
return self.sendRequest(method, params, callback, optional)
####################################################
## 回调函数
####################################################
#----------------------------------------------------------------------
def onError(self, error, req, reqID):
"""错误推送"""
print error, reqID
#----------------------------------------------------------------------
def onGetAccountInfo(self, data, req, reqID):
"""查询账户回调"""
print data
#----------------------------------------------------------------------
def onGetOrders(self, data, req, reqID, fuck):
"""查询委托回调"""
print data
#----------------------------------------------------------------------
def onOrderInfo(self, data, req, reqID):
"""委托详情回调"""
print data
#----------------------------------------------------------------------
def onBuy(self, data, req, reqID):
"""买入回调"""
print data
#----------------------------------------------------------------------
def onSell(self, data, req, reqID):
"""卖出回调"""
print data
#----------------------------------------------------------------------
def onBuyMarket(self, data, req, reqID):
"""市价买入回调"""
print data
#----------------------------------------------------------------------
def onSellMarket(self, data, req, reqID):
"""市价卖出回调"""
print data
#----------------------------------------------------------------------
def onCancelOrder(self, data, req, reqID):
"""撤单回调"""
print data
#----------------------------------------------------------------------
def onGetNewDealOrders(self, data, req, reqID):
"""查询最新成交回调"""
print data
#----------------------------------------------------------------------
def onGetOrderIdByTradeId(self, data, req, reqID):
"""通过成交编号查询委托编号回调"""
print data
#----------------------------------------------------------------------
def onWithdrawCoin(self, data, req, reqID):
"""提币回调"""
print data
#----------------------------------------------------------------------
def onCancelWithdrawCoin(self, data, req, reqID):
"""取消提币回调"""
print data
#----------------------------------------------------------------------
def onGetWithdrawCoinResult(self, data, req, reqID):
"""查询提币结果回调"""
print data
#----------------------------------------------------------------------
def onTransfer(self, data, req, reqID):
"""转账回调"""
print data
#----------------------------------------------------------------------
def onLoan(self, data, req, reqID):
"""申请杠杆回调"""
print data
#----------------------------------------------------------------------
def onRepayment(self, data, req, reqID):
"""归还杠杆回调"""
print data
#----------------------------------------------------------------------
def onLoanAvailable(self, data, req, reqID):
"""查询杠杆额度回调"""
print data
#----------------------------------------------------------------------
def onGetLoans(self, data, req, reqID):
"""查询杠杆列表"""
print data
########################################################################
class DataApi(object):
"""行情接口"""
TICK_SYMBOL_URL = {
SYMBOL_BTCCNY: 'http://api.huobi.com/staticmarket/detail_btc_json.js',
SYMBOL_LTCCNY: 'http://api.huobi.com/staticmarket/detail_ltc_json.js',
SYMBOL_BTCUSD: 'http://api.huobi.com/usdmarket/detail_btc_json.js'
}
QUOTE_SYMBOL_URL = {
SYMBOL_BTCCNY: 'http://api.huobi.com/staticmarket/ticker_btc_json.js',
SYMBOL_LTCCNY: 'http://api.huobi.com/staticmarket/ticker_ltc_json.js',
SYMBOL_BTCUSD: 'http://api.huobi.com/usdmarket/ticker_btc_json.js'
}
DEPTH_SYMBOL_URL = {
SYMBOL_BTCCNY: 'http://api.huobi.com/staticmarket/depth_btc_json.js',
SYMBOL_LTCCNY: 'http://api.huobi.com/staticmarket/depth_ltc_json.js',
SYMBOL_BTCUSD: 'http://api.huobi.com/usdmarket/depth_btc_json.js'
}
KLINE_SYMBOL_URL = {
SYMBOL_BTCCNY: 'http://api.huobi.com/staticmarket/btc_kline_[period]_json.js',
SYMBOL_LTCCNY: 'http://api.huobi.com/staticmarket/btc_kline_[period]_json.js',
SYMBOL_BTCUSD: 'http://api.huobi.com/usdmarket/btc_kline_[period]_json.js'
}
DEBUG = True
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.active = False
self.taskInterval = 0 # 每轮请求延时
self.taskList = [] # 订阅的任务列表
self.taskThread = Thread(target=self.run) # 处理任务的线程
#----------------------------------------------------------------------
def init(self, interval, debug):
"""初始化"""
self.taskInterval = interval
self.DEBUG = debug
self.active = True
self.taskThread.start()
#----------------------------------------------------------------------
def exit(self):
"""退出"""
self.active = False
if self.taskThread.isAlive():
self.taskThread.join()
#----------------------------------------------------------------------
def run(self):
"""连续运行"""
while self.active:
for url, callback in self.taskList:
try:
r = requests.get(url)
if r.status_code == 200:
data = r.json()
if self.DEBUG:
print callback.__name__
callback(data)
except Exception, e:
print e
sleep(self.taskInterval)
#----------------------------------------------------------------------
def subscribeTick(self, symbol):
"""订阅实时成交数据"""
url = self.TICK_SYMBOL_URL[symbol]
task = (url, self.onTick)
self.taskList.append(task)
#----------------------------------------------------------------------
def subscribeQuote(self, symbol):
"""订阅实时报价数据"""
url = self.QUOTE_SYMBOL_URL[symbol]
task = (url, self.onQuote)
self.taskList.append(task)
#----------------------------------------------------------------------
def subscribeDepth(self, symbol, level=0):
"""订阅深度数据"""
url = self.DEPTH_SYMBOL_URL[symbol]
if level:
url = url.replace('json', str(level))
task = (url, self.onDepth)
self.taskList.append(task)
#----------------------------------------------------------------------
def onTick(self, data):
"""实时成交推送"""
print data
#----------------------------------------------------------------------
def onQuote(self, data):
"""实时报价推送"""
print data
#----------------------------------------------------------------------
def onDepth(self, data):
"""实时深度推送"""
print data
#----------------------------------------------------------------------
def getKline(self, symbol, period, length=0):
"""查询K线数据"""
url = self.KLINE_SYMBOL_URL[symbol]
url = url.replace('[period]', period)
if length:
url = url + '?length=' + str(length)
try:
r = requests.get(url)
if r.status_code == 200:
data = r.json()
return data
except Exception, e:
print e
return None

View File

@ -1,36 +0,0 @@
# vn.okcoin
贡献者:量衍投资
### 简介
OkCoin的比特币交易接口基于Websocket API开发实现了以下功能
1. 发送、撤销委托
2. 查询委托、持仓、资金、成交历史
3. 实时行情、成交、资金更新的推送
### 特点
相比较于[OkCoin官方](http://github.com/OKCoin/websocket/tree/master/python)给出的Python API实现vn.okcoin的一些特点
1. 同时支持OkCoin的中国站和国际站交易根据用户连接的站点会在内部自动切换结算货币CNY、USD
2. 采用面向对象的接口设计模式接近国内CTP接口的风格并对主动函数的调用参数做了大幅简化
3. 数据解包和签名生成两个热点函数使用了更加高效的实现方式
### 参数命名
函数的参数命名针对金融领域用户的习惯做了一些修改,具体对应如下:
* expiry原生命名的contract_type
* order: 原生命名的match_price
* leverage原生命名的lever_rate
* page原生命名的current_page
* length原生命名的page_length
### API版本
日期2016-06-29
链接:[http://www.okcoin.com/about/ws_getStarted.do](http://www.okcoin.com/about/ws_getStarted.do)

View File

@ -1,3 +0,0 @@
# encoding: UTF-8
from vnokcoin import OkCoinApi

View File

@ -1,47 +0,0 @@
# encoding: UTF-8
from vnokcoin import *
# 在OkCoin网站申请这两个Key分别对应用户名和密码
apiKey = ''
secretKey = ''
# 创建API对象
api = OkCoinApi()
# 连接服务器并等待1秒
api.connect(OKCOIN_USD, apiKey, secretKey, True)
sleep(1)
# 测试现货行情API
#api.subscribeSpotTicker(SYMBOL_BTC)
#api.subscribeSpotTradeData(SYMBOL_BTC)
api.subscribeSpotDepth(SYMBOL_BTC, DEPTH_20)
#api.subscribeSpotKline(SYMBOL_BTC, INTERVAL_1M)
# 测试现货交易API
#api.subscribeSpotTrades()
#api.subscribeSpotUserInfo()
#api.spotUserInfo()
#api.spotTrade(symbol, type_, price, amount)
#api.spotCancelOrder(symbol, orderid)
#api.spotOrderInfo(symbol, orderid)
# 测试期货行情API
#api.subscribeFutureTicker(SYMBOL_BTC, FUTURE_EXPIRY_THIS_WEEK)
#api.subscribeFutureTradeData(SYMBOL_BTC, FUTURE_EXPIRY_THIS_WEEK)
#api.subscribeFutureDepth(SYMBOL_BTC, FUTURE_EXPIRY_THIS_WEEK, DEPTH_20)
#api.subscribeFutureKline(SYMBOL_BTC, FUTURE_EXPIRY_THIS_WEEK, INTERVAL_1M)
#api.subscribeFutureIndex(SYMBOL_BTC)
# 测试期货交易API
#api.subscribeFutureTrades()
#api.subscribeFutureUserInfo()
#api.subscribeFuturePositions()
#api.futureUserInfo()
#api.futureTrade(symbol, expiry, type_, price, amount, order, leverage)
#api.futureCancelOrder(symbol, expiry, orderid)
#api.futureOrderInfo(symbol, expiry, orderid, status, page, length)
raw_input()

View File

@ -1,417 +0,0 @@
# encoding: UTF-8
import hashlib
import zlib
import json
from time import sleep
from threading import Thread
import websocket
# OKCOIN网站
OKCOIN_CNY = 'wss://real.okcoin.cn:10440/websocket/okcoinapi'
OKCOIN_USD = 'wss://real.okcoin.com:10440/websocket/okcoinapi'
# 账户货币代码
CURRENCY_CNY = 'cny'
CURRENCY_USD = 'usd'
# 电子货币代码
SYMBOL_BTC = 'btc'
SYMBOL_LTC = 'ltc'
SYMBOL_ETH = 'eth'
# 行情深度
DEPTH_20 = 20
DEPTH_60 = 60
# K线时间区间
INTERVAL_1M = '1min'
INTERVAL_3M = '3min'
INTERVAL_5M = '5min'
INTERVAL_15M = '15min'
INTERVAL_30M = '30min'
INTERVAL_1H = '1hour'
INTERVAL_2H = '2hour'
INTERVAL_4H = '4hour'
INTERVAL_6H = '6hour'
INTERVAL_1D = 'day'
INTERVAL_3D = '3day'
INTERVAL_1W = 'week'
# 交易代码,需要后缀货币名才能完整
TRADING_SYMBOL_BTC = 'btc_'
TRADING_SYMBOL_LTC = 'ltc_'
TRADING_SYMBOL_ETH = 'eth_'
# 委托类型
TYPE_BUY = 'buy'
TYPE_SELL = 'sell'
TYPE_BUY_MARKET = 'buy_market'
TYPE_SELL_MARKET = 'sell_market'
# 期货合约到期类型
FUTURE_EXPIRY_THIS_WEEK = 'this_week'
FUTURE_EXPIRY_NEXT_WEEK = 'next_week'
FUTURE_EXPIRY_QUARTER = 'quarter'
# 期货委托类型
FUTURE_TYPE_LONG = 1
FUTURE_TYPE_SHORT = 2
FUTURE_TYPE_SELL = 3
FUTURE_TYPE_COVER = 4
# 期货是否用现价
FUTURE_ORDER_MARKET = 1
FUTURE_ORDER_LIMIT = 0
# 期货杠杆
FUTURE_LEVERAGE_10 = 10
FUTURE_LEVERAGE_20 = 20
# 委托状态
ORDER_STATUS_NOTTRADED = 0
ORDER_STATUS_PARTTRADED = 1
ORDER_STATUS_ALLTRADED = 2
ORDER_STATUS_CANCELLED = -1
ORDER_STATUS_CANCELLING = 4
########################################################################
class OkCoinApi(object):
"""基于Websocket的API对象"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.apiKey = '' # 用户名
self.secretKey = '' # 密码
self.host = '' # 服务器地址
self.currency = '' # 货币类型usd或者cny
self.ws = None # websocket应用对象
self.thread = None # 工作线程
#######################
## 通用函数
#######################
#----------------------------------------------------------------------
def readData(self, evt):
"""解压缩推送收到的数据"""
# 创建解压器
decompress = zlib.decompressobj(-zlib.MAX_WBITS)
# 将原始数据解压成字符串
inflated = decompress.decompress(evt) + decompress.flush()
# 通过json解析字符串
data = json.loads(inflated)
return data
#----------------------------------------------------------------------
def generateSign(self, params):
"""生成签名"""
l = []
for key in sorted(params.keys()):
l.append('%s=%s' %(key, params[key]))
l.append('secret_key=%s' %self.secretKey)
sign = '&'.join(l)
return hashlib.md5(sign.encode('utf-8')).hexdigest().upper()
#----------------------------------------------------------------------
def onMessage(self, ws, evt):
"""信息推送"""
print 'onMessage'
data = self.readData(evt)
print data
#----------------------------------------------------------------------
def onError(self, ws, evt):
"""错误推送"""
print 'onError'
print evt
#----------------------------------------------------------------------
def onClose(self, ws):
"""接口断开"""
print 'onClose'
#----------------------------------------------------------------------
def onOpen(self, ws):
"""接口打开"""
print 'onOpen'
#----------------------------------------------------------------------
def connect(self, host, apiKey, secretKey, trace=False):
"""连接服务器"""
self.host = host
self.apiKey = apiKey
self.secretKey = secretKey
if self.host == OKCOIN_CNY:
self.currency = CURRENCY_CNY
else:
self.currency = CURRENCY_USD
websocket.enableTrace(trace)
self.ws = websocket.WebSocketApp(host,
on_message=self.onMessage,
on_error=self.onError,
on_close=self.onClose,
on_open=self.onOpen)
self.thread = Thread(target=self.ws.run_forever)
self.thread.start()
#----------------------------------------------------------------------
def reconnect(self):
"""重新连接"""
# 首先关闭之前的连接
self.close()
# 再执行重连任务
self.ws = websocket.WebSocketApp(self.host,
on_message=self.onMessage,
on_error=self.onError,
on_close=self.onClose,
on_open=self.onOpen)
self.thread = Thread(target=self.ws.run_forever)
self.thread.start()
#----------------------------------------------------------------------
def close(self):
"""关闭接口"""
if self.thread and self.thread.isAlive():
self.ws.close()
self.thread.join()
#----------------------------------------------------------------------
def sendMarketDataRequest(self, channel):
"""发送行情请求"""
# 生成请求
d = {}
d['event'] = 'addChannel'
d['binary'] = True
d['channel'] = channel
# 使用json打包并发送
j = json.dumps(d)
# 若触发异常则重连
try:
self.ws.send(j)
except websocket.WebSocketConnectionClosedException:
pass
#----------------------------------------------------------------------
def sendTradingRequest(self, channel, params):
"""发送交易请求"""
# 在参数字典中加上api_key和签名字段
params['api_key'] = self.apiKey
params['sign'] = self.generateSign(params)
# 生成请求
d = {}
d['event'] = 'addChannel'
d['binary'] = True
d['channel'] = channel
d['parameters'] = params
# 使用json打包并发送
j = json.dumps(d)
# 若触发异常则重连
try:
self.ws.send(j)
except websocket.WebSocketConnectionClosedException:
pass
#######################
## 现货相关
#######################
#----------------------------------------------------------------------
def subscribeSpotTicker(self, symbol):
"""订阅现货普通报价"""
self.sendMarketDataRequest('ok_sub_spot%s_%s_ticker' %(self.currency, symbol))
#----------------------------------------------------------------------
def subscribeSpotDepth(self, symbol, depth):
"""订阅现货深度报价"""
self.sendMarketDataRequest('ok_sub_spot%s_%s_depth_%s' %(self.currency, symbol, depth))
#----------------------------------------------------------------------
def subscribeSpotTradeData(self, symbol):
"""订阅现货成交记录"""
self.sendMarketDataRequest('ok_sub_spot%s_%s_trades' %(self.currency, symbol))
#----------------------------------------------------------------------
def subscribeSpotKline(self, symbol, interval):
"""订阅现货K线"""
self.sendMarketDataRequest('ok_sub_spot%s_%s_kline_%s' %(self.currency, symbol, interval))
#----------------------------------------------------------------------
def spotTrade(self, symbol, type_, price, amount):
"""现货委托"""
params = {}
params['symbol'] = str(symbol+self.currency)
params['type'] = str(type_)
params['price'] = str(price)
params['amount'] = str(amount)
channel = 'ok_spot%s_trade' %(self.currency)
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def spotCancelOrder(self, symbol, orderid):
"""现货撤单"""
params = {}
params['symbol'] = str(symbol+self.currency)
params['order_id'] = str(orderid)
channel = 'ok_spot%s_cancel_order' %(self.currency)
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def spotUserInfo(self):
"""查询现货账户"""
channel = 'ok_spot%s_userinfo' %(self.currency)
self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def spotOrderInfo(self, symbol, orderid):
"""查询现货委托信息"""
params = {}
params['symbol'] = str(symbol+self.currency)
params['order_id'] = str(orderid)
channel = 'ok_spot%s_orderinfo' %(self.currency)
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def subscribeSpotTrades(self):
"""订阅现货成交信息"""
channel = 'ok_sub_spot%s_trades' %(self.currency)
self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def subscribeSpotUserInfo(self):
"""订阅现货账户信息"""
channel = 'ok_sub_spot%s_userinfo' %(self.currency)
self.sendTradingRequest(channel, {})
#######################
## 期货相关
#######################
#----------------------------------------------------------------------
def subscribeFutureTicker(self, symbol, expiry):
"""订阅期货普通报价"""
self.sendMarketDataRequest('ok_sub_future%s_%s_ticker_%s' %(self.currency, symbol, expiry))
#----------------------------------------------------------------------
def subscribeFutureDepth(self, symbol, expiry, depth):
"""订阅期货深度报价"""
self.sendMarketDataRequest('ok_sub_future%s_%s_depth_%s_%s' %(self.currency, symbol,
expiry, depth))
#----------------------------------------------------------------------
def subscribeFutureTradeData(self, symbol, expiry):
"""订阅期货成交记录"""
self.sendMarketDataRequest('ok_sub_future%s_%s_trade_%s' %(self.currency, symbol, expiry))
#----------------------------------------------------------------------
def subscribeFutureKline(self, symbol, expiry, interval):
"""订阅期货K线"""
self.sendMarketDataRequest('ok_sub_future%s_%s_kline_%s_%s' %(self.currency, symbol,
expiry, interval))
#----------------------------------------------------------------------
def subscribeFutureIndex(self, symbol):
"""订阅期货指数"""
self.sendMarketDataRequest('ok_sub_future%s_%s_index' %(self.currency, symbol))
#----------------------------------------------------------------------
def futureTrade(self, symbol, expiry, type_, price, amount, order, leverage):
"""期货委托"""
params = {}
params['symbol'] = str(symbol+self.currency)
params['type'] = str(type_)
params['price'] = str(price)
params['amount'] = str(amount)
params['contract_type'] = str(expiry)
params['match_price'] = str(order)
params['lever_rate'] = str(leverage)
channel = 'ok_future%s_trade' %(self.currency)
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def futureCancelOrder(self, symbol, expiry, orderid):
"""期货撤单"""
params = {}
params['symbol'] = str(symbol+self.currency)
params['order_id'] = str(orderid)
params['contract_type'] = str(expiry)
channel = 'ok_future%s_cancel_order' %(self.currency)
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def futureUserInfo(self):
"""查询期货账户"""
channel = 'ok_future%s_userinfo' %(self.currency)
self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def futureOrderInfo(self, symbol, expiry, orderid, status, page, length):
"""查询期货委托信息"""
params = {}
params['symbol'] = str(symbol+self.currency)
params['order_id'] = str(orderid)
params['contract_type'] = expiry
params['status'] = status
params['current_page'] = page
params['page_length'] = length
channel = 'ok_future%s_orderinfo' %(self.currency)
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def subscribeFutureTrades(self):
"""订阅期货成交信息"""
channel = 'ok_sub_future%s_trades' %(self.currency)
self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def subscribeFutureUserInfo(self):
"""订阅期货账户信息"""
channel = 'ok_sub_future%s_userinfo' %(self.currency)
self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def subscribeFuturePositions(self):
"""订阅期货持仓信息"""
channel = 'ok_sub_future%s_positions' %(self.currency)
self.sendTradingRequest(channel, {})

View File

@ -1,7 +0,0 @@
{
"accessKey": "火币网站申请",
"secretKey": "火币网站申请",
"interval": 0.5,
"market": "cny",
"debug": false
}

View File

@ -1,11 +0,0 @@
# encoding: UTF-8
from vnpy.trader import vtConstant
from huobiGateway import HuobiGateway
gatewayClass = HuobiGateway
gatewayName = 'HUOBI'
gatewayDisplayName = u'火币'
gatewayType = vtConstant.GATEWAYTYPE_BTC
gatewayQryEnabled = True

View File

@ -1,667 +0,0 @@
# encoding: UTF-8
'''
vn.huobi的gateway接入
'''
import os
import json
from datetime import datetime
from copy import copy
from threading import Condition
from Queue import Queue
from threading import Thread
from vnpy.api.huobi import vnhuobi
from vnpy.trader.vtGateway import *
from vnpy.trader.vtFunction import getJsonPath
SYMBOL_BTCCNY = 'BTCCNY'
SYMBOL_LTCCNY = 'LTCCNY'
SYMBOL_BTCUSD = 'BTCUSD'
SYMBOL_MAP = {}
SYMBOL_MAP[(vnhuobi.COINTYPE_BTC, 'cny')] = SYMBOL_BTCCNY
SYMBOL_MAP[(vnhuobi.COINTYPE_LTC, 'cny')] = SYMBOL_LTCCNY
SYMBOL_MAP[(vnhuobi.COINTYPE_BTC, 'usd')] = SYMBOL_BTCUSD
SYMBOL_MAP_REVERSE = {v: k for k, v in SYMBOL_MAP.items()}
MDSYMBOL_MAP = {}
MDSYMBOL_MAP['btccny'] = SYMBOL_BTCCNY
MDSYMBOL_MAP['ltccny'] = SYMBOL_LTCCNY
MDSYMBOL_MAP['btcusd'] = SYMBOL_BTCUSD
DIRECTION_MAP = {}
DIRECTION_MAP[1] = DIRECTION_LONG
DIRECTION_MAP[2] = DIRECTION_SHORT
STATUS_MAP = {}
STATUS_MAP[0] = STATUS_NOTTRADED
STATUS_MAP[1] = STATUS_PARTTRADED
STATUS_MAP[2] = STATUS_ALLTRADED
STATUS_MAP[3] = STATUS_CANCELLED
STATUS_MAP[5] = STATUS_UNKNOWN
STATUS_MAP[7] = STATUS_UNKNOWN
########################################################################
class HuobiGateway(VtGateway):
"""火币接口"""
#----------------------------------------------------------------------
def __init__(self, eventEngine, gatewayName='HUOBI'):
"""Constructor"""
super(HuobiGateway, self).__init__(eventEngine, gatewayName)
self.market = 'cny'
self.tradeApi = HuobiTradeApi(self)
self.dataApi = HuobiDataApi(self)
self.fileName = self.gatewayName + '_connect.json'
self.filePath = getJsonPath(self.fileName, __file__)
#----------------------------------------------------------------------
def connect(self):
"""连接"""
# 载入json文件
try:
f = file(self.filePath)
except IOError:
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'读取连接配置出错,请检查'
self.onLog(log)
return
# 解析json文件
setting = json.load(f)
try:
accessKey = str(setting['accessKey'])
secretKey = str(setting['secretKey'])
interval = setting['interval']
market = setting['market']
debug = setting['debug']
except KeyError:
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'连接配置缺少字段,请检查'
self.onLog(log)
return
# 初始化接口
self.tradeApi.connect(accessKey, secretKey, market, debug)
self.writeLog(u'交易接口初始化成功')
self.dataApi.connect(interval, market, debug)
self.writeLog(u'行情接口初始化成功')
# 启动查询
self.initQuery()
self.startQuery()
#----------------------------------------------------------------------
def writeLog(self, content):
"""发出日志"""
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = content
self.onLog(log)
#----------------------------------------------------------------------
def subscribe(self, subscribeReq):
"""订阅行情,自动订阅全部行情,无需实现"""
pass
#----------------------------------------------------------------------
def sendOrder(self, orderReq):
"""发单"""
self.tradeApi.sendOrder(orderReq)
#----------------------------------------------------------------------
def cancelOrder(self, cancelOrderReq):
"""撤单"""
self.tradeApi.cancel(cancelOrderReq)
#----------------------------------------------------------------------
def qryAccount(self):
"""查询账户资金"""
pass
#----------------------------------------------------------------------
def qryPosition(self):
"""查询持仓"""
pass
#----------------------------------------------------------------------
def close(self):
"""关闭"""
self.tradeApi.exit()
self.dataApi.exit()
#----------------------------------------------------------------------
def initQuery(self):
"""初始化连续查询"""
if self.qryEnabled:
self.qryFunctionList = [self.tradeApi.queryWorkingOrders, self.tradeApi.queryAccount]
self.startQuery()
#----------------------------------------------------------------------
def query(self, event):
"""注册到事件处理引擎上的查询函数"""
for function in self.qryFunctionList:
function()
#----------------------------------------------------------------------
def startQuery(self):
"""启动连续查询"""
self.eventEngine.register(EVENT_TIMER, self.query)
#----------------------------------------------------------------------
def setQryEnabled(self, qryEnabled):
"""设置是否要启动循环查询"""
self.qryEnabled = qryEnabled
########################################################################
class HuobiTradeApi(vnhuobi.TradeApi):
"""交易接口"""
#----------------------------------------------------------------------
def __init__(self, gateway):
"""Constructor"""
super(HuobiTradeApi, self).__init__()
self.gateway = gateway
self.gatewayName = gateway.gatewayName
self.localID = 0 # 本地委托号
self.localSystemDict = {} # key:localID, value:systemID
self.systemLocalDict = {} # key:systemID, value:localID
self.workingOrderDict = {} # key:localID, value:order
self.reqLocalDict = {} # key:reqID, value:localID
self.cancelDict = {} # key:localID, value:cancelOrderReq
self.tradeID = 0 # 本地成交号
#----------------------------------------------------------------------
def onError(self, error, req, reqID):
"""错误推送"""
err = VtErrorData()
err.gatewayName = self.gatewayName
err.errorMsg = str(error)
err.errorTime = datetime.now().strftime('%H:%M:%S')
self.gateway.onError(err)
#----------------------------------------------------------------------
def onGetAccountInfo(self, data, req, reqID):
"""查询账户回调"""
# 推送账户数据
account = VtAccountData()
account.gatewayName = self.gatewayName
account.accountID = 'HUOBI'
account.vtAccountID = '.'.join([account.accountID, self.gatewayName])
account.balance = data['net_asset']
self.gateway.onAccount(account)
# 推送持仓数据
if self.market == 'cny':
posCny = VtPositionData()
posCny.gatewayName = self.gatewayName
posCny.symbol = 'CNY'
posCny.exchange = EXCHANGE_HUOBI
posCny.vtSymbol = '.'.join([posCny.symbol, posCny.exchange])
posCny.vtPositionName = posCny.vtSymbol
posCny.position = data['available_cny_display']
posCny.frozen = data['frozen_cny_display']
self.gateway.onPosition(posCny)
posLtc = VtPositionData()
posLtc.gatewayName = self.gatewayName
posLtc.symbol = 'LTC'
posLtc.exchange = EXCHANGE_HUOBI
posLtc.vtSymbol = '.'.join([posLtc.symbol, posLtc.exchange])
posLtc.vtPositionName = posLtc.vtSymbol
posLtc.position = data['available_ltc_display']
posLtc.frozen = data['frozen_ltc_display']
self.gateway.onPosition(posLtc)
else:
posUsd = VtPositionData()
posUsd.gatewayName = self.gatewayName
posUsd.symbol = 'USD'
posUsd.exchange = EXCHANGE_HUOBI
posUsd.vtSymbol = '.'.join([posUsd.symbol, posUsd.exchange])
posUsd.vtPositionName = posUsd.vtSymbol
posUsd.position = data['available_usd_display']
posUsd.frozen = data['frozen_usd_display']
self.gateway.onPosition(posUsd)
posBtc = VtPositionData()
posBtc.gatewayName = self.gatewayName
posBtc.symbol = 'BTC'
posBtc.exchange = EXCHANGE_HUOBI
posBtc.vtSymbol = '.'.join([posBtc.symbol, posBtc.exchange])
posBtc.vtPositionName = posBtc.vtSymbol
posBtc.position = data['available_btc_display']
posBtc.frozen = data['frozen_btc_display']
self.gateway.onPosition(posBtc)
#----------------------------------------------------------------------
def onGetOrders(self, data, req, reqID):
"""查询委托回调"""
for d in data:
order = VtOrderData()
order.gatewayName = self.gatewayName
# 合约代码
params = req['params']
coin = params['coin_type']
order.symbol = SYMBOL_MAP[(coin, self.market)]
order.exchange = EXCHANGE_HUOBI
order.vtSymbol = '.'.join([order.symbol, order.exchange])
# 委托号
systemID = d['id']
self.localID += 1
localID = str(self.localID)
self.systemLocalDict[systemID] = localID
self.localSystemDict[localID] = systemID
order.orderID = localID
order.vtOrderID = '.'.join([order.orderID, order.gatewayName])
# 其他信息
order.direction = DIRECTION_MAP[d['type']]
order.offset = OFFSET_NONE
order.price = float(d['order_price'])
order.totalVolume = float(d['order_amount'])
order.tradedVolume = float(d['processed_amount'])
order.orderTime = d['order_time']
# 委托状态
if order.tradedVolume == 0:
order.status = STATUS_NOTTRADED
else:
order.status = STATUS_PARTTRADED
# 缓存病推送
self.workingOrderDict[localID] = order
self.gateway.onOrder(order)
#----------------------------------------------------------------------
def onOrderInfo(self, data, req, reqID):
"""委托详情回调"""
systemID = data['id']
localID = self.systemLocalDict[systemID]
order = self.workingOrderDict.get(localID, None)
if not order:
return
# 记录最新成交的金额
newTradeVolume = float(data['processed_amount']) - order.tradedVolume
if newTradeVolume:
trade = VtTradeData()
trade.gatewayName = self.gatewayName
trade.symbol = order.symbol
trade.vtSymbol = order.vtSymbol
self.tradeID += 1
trade.tradeID = str(self.tradeID)
trade.vtTradeID = '.'.join([trade.tradeID, trade.gatewayName])
trade.volume = newTradeVolume
trade.price = data['processed_price']
trade.direction = order.direction
trade.offset = order.offset
trade.exchange = order.exchange
trade.tradeTime = datetime.now().strftime('%H:%M:%S')
self.gateway.onTrade(trade)
# 更新委托状态
order.tradedVolume = float(data['processed_amount'])
order.status = STATUS_MAP.get(data['status'], STATUS_UNKNOWN)
if newTradeVolume:
self.gateway.onOrder(order)
if order.status == STATUS_ALLTRADED or order.status == STATUS_CANCELLED:
del self.workingOrderDict[order.orderID]
#----------------------------------------------------------------------
def onBuy(self, data, req, reqID):
"""买入回调"""
localID = self.reqLocalDict[reqID]
systemID = data['id']
self.localSystemDict[localID] = systemID
self.systemLocalDict[systemID] = localID
# 撤单
if localID in self.cancelDict:
req = self.cancelDict[localID]
self.cancel(req)
del self.cancelDict[localID]
# 推送委托信息
order = self.workingOrderDict[localID]
if data['result'] == 'success':
order.status = STATUS_NOTTRADED
self.gateway.onOrder(order)
#----------------------------------------------------------------------
def onSell(self, data, req, reqID):
"""卖出回调"""
localID = self.reqLocalDict[reqID]
systemID = data['id']
self.localSystemDict[localID] = systemID
self.systemLocalDict[systemID] = localID
# 撤单
if localID in self.cancelDict:
req = self.cancelDict[localID]
self.cancel(req)
del self.cancelDict[localID]
# 推送委托信息
order = self.workingOrderDict[localID]
if data['result'] == 'success':
order.status = STATUS_NOTTRADED
self.gateway.onOrder(order)
#----------------------------------------------------------------------
def onBuyMarket(self, data, req, reqID):
"""市价买入回调"""
print data
#----------------------------------------------------------------------
def onSellMarket(self, data, req, reqID):
"""市价卖出回调"""
print data
#----------------------------------------------------------------------
def onCancelOrder(self, data, req, reqID):
"""撤单回调"""
if data['result'] == 'success':
systemID = req['params']['id']
localID = self.systemLocalDict[systemID]
order = self.workingOrderDict[localID]
order.status = STATUS_CANCELLED
del self.workingOrderDict[localID]
self.gateway.onOrder(order)
#----------------------------------------------------------------------
def onGetNewDealOrders(self, data, req, reqID):
"""查询最新成交回调"""
print data
#----------------------------------------------------------------------
def onGetOrderIdByTradeId(self, data, req, reqID):
"""通过成交编号查询委托编号回调"""
print data
#----------------------------------------------------------------------
def onWithdrawCoin(self, data, req, reqID):
"""提币回调"""
print data
#----------------------------------------------------------------------
def onCancelWithdrawCoin(self, data, req, reqID):
"""取消提币回调"""
print data
#----------------------------------------------------------------------
def onGetWithdrawCoinResult(self, data, req, reqID):
"""查询提币结果回调"""
print data
#----------------------------------------------------------------------
def onTransfer(self, data, req, reqID):
"""转账回调"""
print data
#----------------------------------------------------------------------
def onLoan(self, data, req, reqID):
"""申请杠杆回调"""
print data
#----------------------------------------------------------------------
def onRepayment(self, data, req, reqID):
"""归还杠杆回调"""
print data
#----------------------------------------------------------------------
def onLoanAvailable(self, data, req, reqID):
"""查询杠杆额度回调"""
print data
#----------------------------------------------------------------------
def onGetLoans(self, data, req, reqID):
"""查询杠杆列表"""
print data
#----------------------------------------------------------------------
def connect(self, accessKey, secretKey, market, debug=False):
"""连接服务器"""
self.market = market
self.DEBUG = debug
self.init(accessKey, secretKey)
# 查询未成交委托
self.getOrders(vnhuobi.COINTYPE_BTC, self.market)
if self.market == vnhuobi.MARKETTYPE_CNY:
# 只有人民币市场才有莱特币
self.getOrders(vnhuobi.COINTYPE_LTC, self.market)
# ----------------------------------------------------------------------
def queryWorkingOrders(self):
"""查询活动委托状态"""
for order in self.workingOrderDict.values():
# 如果尚未返回委托号,则无法查询
if order.orderID in self.localSystemDict:
systemID = self.localSystemDict[order.orderID]
coin, market = SYMBOL_MAP_REVERSE[order.symbol]
self.orderInfo(systemID, coin, market)
# ----------------------------------------------------------------------
def queryAccount(self):
"""查询活动委托状态"""
self.getAccountInfo(self.market)
# ----------------------------------------------------------------------
def sendOrder(self, req):
"""发送委托"""
# 检查是否填入了价格,禁止市价委托
if req.priceType != PRICETYPE_LIMITPRICE:
err = VtErrorData()
err.gatewayName = self.gatewayName
err.errorMsg = u'火币接口仅支持限价单'
err.errorTime = datetime.now().strftime('%H:%M:%S')
self.gateway.onError(err)
return None
# 发送限价委托
coin, market = SYMBOL_MAP_REVERSE[req.symbol]
if req.direction == DIRECTION_LONG:
reqID = self.buy(req.price, req.volume, coinType=coin, market=self.market)
else:
reqID = self.sell(req.price, req.volume, coinType=coin, market=self.market)
self.localID += 1
localID = str(self.localID)
self.reqLocalDict[reqID] = localID
# 推送委托信息
order = VtOrderData()
order.gatewayName = self.gatewayName
order.symbol = req.symbol
order.exchange = EXCHANGE_HUOBI
order.vtSymbol = '.'.join([order.symbol, order.exchange])
order.orderID = localID
order.vtOrderID = '.'.join([order.orderID, order.gatewayName])
order.direction = req.direction
order.offset = OFFSET_UNKNOWN
order.price = req.price
order.volume = req.volume
order.orderTime = datetime.now().strftime('%H:%M:%S')
order.status = STATUS_UNKNOWN
self.workingOrderDict[localID] = order
self.gateway.onOrder(order)
# 返回委托号
return order.vtOrderID
# ----------------------------------------------------------------------
def cancel(self, req):
"""撤单"""
localID = req.orderID
if localID in self.localSystemDict:
systemID = self.localSystemDict[localID]
coin, market = SYMBOL_MAP_REVERSE[req.symbol]
self.cancelOrder(systemID, coin, self.market)
else:
self.cancelDict[localID] = req
########################################################################
class HuobiDataApi(vnhuobi.DataApi):
"""行情接口"""
#----------------------------------------------------------------------
def __init__(self, gateway):
"""Constructor"""
super(HuobiDataApi, self).__init__()
self.market = 'cny'
self.gateway = gateway
self.gatewayName = gateway.gatewayName
self.tickDict = {} # key:symbol, value:tick
#----------------------------------------------------------------------
def onTick(self, data):
"""实时成交推送"""
print data
#----------------------------------------------------------------------
def onQuote(self, data):
"""实时报价推送"""
ticker = data['ticker']
symbol = MDSYMBOL_MAP[ticker['symbol']]
if symbol not in self.tickDict:
tick = VtTickData()
tick.gatewayName = self.gatewayName
tick.symbol = symbol
tick.exchange = EXCHANGE_HUOBI
tick.vtSymbol = '.'.join([tick.symbol, tick.exchange])
self.tickDict[symbol] = tick
else:
tick = self.tickDict[symbol]
tick.highPrice = ticker['high']
tick.lowPrice = ticker['low']
tick.lastPrice = ticker['last']
tick.volume = ticker['vol']
#----------------------------------------------------------------------
def onDepth(self, data):
"""实时深度推送"""
symbol = MDSYMBOL_MAP[data['symbol']]
if symbol not in self.tickDict:
tick = VtTickData()
tick.gatewayName = self.gatewayName
tick.symbol = symbol
tick.exchange = EXCHANGE_HUOBI
tick.vtSymbol = '.'.join([tick.symbol, tick.exchange])
self.tickDict[symbol] = tick
else:
tick = self.tickDict[symbol]
tick.bidPrice1, tick.bidVolume1 = data['bids'][0]
tick.bidPrice2, tick.bidVolume2 = data['bids'][1]
tick.bidPrice3, tick.bidVolume3 = data['bids'][2]
tick.bidPrice4, tick.bidVolume4 = data['bids'][3]
tick.bidPrice5, tick.bidVolume5 = data['bids'][4]
tick.askPrice1, tick.askVolume1 = data['asks'][0]
tick.askPrice2, tick.askVolume2 = data['asks'][1]
tick.askPrice3, tick.askVolume3 = data['asks'][2]
tick.askPrice4, tick.askVolume4 = data['asks'][3]
tick.askPrice5, tick.askVolume5 = data['asks'][4]
now = datetime.now()
tick.time = now.strftime('%H:%M:%S')
tick.date = now.strftime('%Y%m%d')
self.gateway.onTick(tick)
#----------------------------------------------------------------------
def connect(self, interval, market, debug=False):
"""连接服务器"""
self.market = market
self.init(interval, debug)
# 订阅行情并推送合约信息
if self.market == vnhuobi.MARKETTYPE_CNY:
self.subscribeQuote(vnhuobi.SYMBOL_BTCCNY)
self.subscribeQuote(vnhuobi.SYMBOL_LTCCNY)
self.subscribeDepth(vnhuobi.SYMBOL_BTCCNY, 5)
self.subscribeDepth(vnhuobi.SYMBOL_LTCCNY, 5)
contract = VtContractData()
contract.gatewayName = self.gatewayName
contract.symbol = SYMBOL_BTCCNY
contract.exchange = EXCHANGE_HUOBI
contract.vtSymbol = '.'.join([contract.symbol, contract.exchange])
contract.name = u'人民币现货BTC'
contract.size = 1
contract.priceTick = 0.01
contract.productClass = PRODUCT_SPOT
self.gateway.onContract(contract)
contract = VtContractData()
contract.gatewayName = self.gatewayName
contract.symbol = SYMBOL_LTCCNY
contract.exchange = EXCHANGE_HUOBI
contract.vtSymbol = '.'.join([contract.symbol, contract.exchange])
contract.name = u'人民币现货LTC'
contract.size = 1
contract.priceTick = 0.01
contract.productClass = PRODUCT_SPOT
self.gateway.onContract(contract)
else:
self.subscribeQuote(vnhuobi.SYMBOL_BTCUSD)
self.subscribeDepth(vnhuobi.SYMBOL_BTCUSD)
contract = VtContractData()
contract.gatewayName = self.gatewayName
contract.symbol = SYMBOL_BTCUSD
contract.exchange = EXCHANGE_HUOBI
contract.vtSymbol = '.'.join([contract.symbol, contract.exchange])
contract.name = u'美元现货BTC'
contract.size = 1
contract.priceTick = 0.01
contract.productClass = PRODUCT_SPOT
self.gateway.onContract(contract)

View File

@ -38,7 +38,7 @@ STATUS_MAP[-1] = STATUS_CANCELLED
######################################################################## ########################################################################
class LbankGateway(VtGateway): class LbankGateway(VtGateway):
"""链行接口""" """LBANK接口"""
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def __init__(self, eventEngine, gatewayName='LBANK'): def __init__(self, eventEngine, gatewayName='LBANK'):
@ -195,7 +195,7 @@ class LbankApi(LbankApi):
tick.gatewayName = self.gatewayName tick.gatewayName = self.gatewayName
tick.symbol = symbol tick.symbol = symbol
tick.exchange = EXCHANGE_LHANG tick.exchange = EXCHANGE_LBANK
tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) tick.vtSymbol = '.'.join([tick.symbol, tick.exchange])
self.tickDict[symbol] = tick self.tickDict[symbol] = tick
else: else:
@ -217,7 +217,7 @@ class LbankApi(LbankApi):
tick.gatewayName = self.gatewayName tick.gatewayName = self.gatewayName
tick.symbol = symbol tick.symbol = symbol
tick.exchange = EXCHANGE_LHANG tick.exchange = EXCHANGE_LBANK
tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) tick.vtSymbol = '.'.join([tick.symbol, tick.exchange])
self.tickDict[symbol] = tick self.tickDict[symbol] = tick
else: else:
@ -265,7 +265,7 @@ class LbankApi(LbankApi):
posCny = VtPositionData() posCny = VtPositionData()
posCny.gatewayName = self.gatewayName posCny.gatewayName = self.gatewayName
posCny.symbol = 'CNY' posCny.symbol = 'CNY'
posCny.exchange = EXCHANGE_LHANG posCny.exchange = EXCHANGE_LBANK
posCny.vtSymbol = '.'.join([posCny.symbol, posCny.exchange]) posCny.vtSymbol = '.'.join([posCny.symbol, posCny.exchange])
posCny.vtPositionName = posCny.vtSymbol posCny.vtPositionName = posCny.vtSymbol
posCny.frozen = d['freeze']['cny'] posCny.frozen = d['freeze']['cny']
@ -275,7 +275,7 @@ class LbankApi(LbankApi):
posBtc = VtPositionData() posBtc = VtPositionData()
posBtc.gatewayName = self.gatewayName posBtc.gatewayName = self.gatewayName
posBtc.symbol = 'BTC' posBtc.symbol = 'BTC'
posBtc.exchange = EXCHANGE_LHANG posBtc.exchange = EXCHANGE_LBANK
posBtc.vtSymbol = '.'.join([posBtc.symbol, posBtc.exchange]) posBtc.vtSymbol = '.'.join([posBtc.symbol, posBtc.exchange])
posBtc.vtPositionName = posBtc.vtSymbol posBtc.vtPositionName = posBtc.vtSymbol
posBtc.frozen = d['freeze']['btc'] posBtc.frozen = d['freeze']['btc']
@ -285,7 +285,7 @@ class LbankApi(LbankApi):
posZec = VtPositionData() posZec = VtPositionData()
posZec.gatewayName = self.gatewayName posZec.gatewayName = self.gatewayName
posZec.symbol = 'ZEC' posZec.symbol = 'ZEC'
posZec.exchange = EXCHANGE_LHANG posZec.exchange = EXCHANGE_LBANK
posZec.vtSymbol = '.'.join([posZec.symbol, posZec.exchange]) posZec.vtSymbol = '.'.join([posZec.symbol, posZec.exchange])
posZec.vtPositionName = posZec.vtSymbol posZec.vtPositionName = posZec.vtSymbol
posZec.frozen = d['freeze']['zec'] posZec.frozen = d['freeze']['zec']
@ -379,7 +379,7 @@ class LbankApi(LbankApi):
order.gatewayName = self.gatewayName order.gatewayName = self.gatewayName
order.symbol = SYMBOL_MAP[data['symbol']] order.symbol = SYMBOL_MAP[data['symbol']]
order.exchange = EXCHANGE_LHANG order.exchange = EXCHANGE_LBANK
order.vtSymbol = '.'.join([order.symbol, order.exchange]) order.vtSymbol = '.'.join([order.symbol, order.exchange])
systemID = d['order_id'] systemID = d['order_id']
@ -419,7 +419,7 @@ class LbankApi(LbankApi):
contract = VtContractData() contract = VtContractData()
contract.gatewayName = self.gatewayName contract.gatewayName = self.gatewayName
contract.symbol = SYMBOL_BTCCNY contract.symbol = SYMBOL_BTCCNY
contract.exchange = EXCHANGE_LHANG contract.exchange = EXCHANGE_LBANK
contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) contract.vtSymbol = '.'.join([contract.symbol, contract.exchange])
contract.name = u'人民币现货BTC' contract.name = u'人民币现货BTC'
contract.size = 1 contract.size = 1
@ -430,7 +430,7 @@ class LbankApi(LbankApi):
contract = VtContractData() contract = VtContractData()
contract.gatewayName = self.gatewayName contract.gatewayName = self.gatewayName
contract.symbol = SYMBOL_ZECCNY contract.symbol = SYMBOL_ZECCNY
contract.exchange = EXCHANGE_LHANG contract.exchange = EXCHANGE_LBANK
contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) contract.vtSymbol = '.'.join([contract.symbol, contract.exchange])
contract.name = u'人民币现货ZEC' contract.name = u'人民币现货ZEC'
contract.size = 1 contract.size = 1
@ -441,12 +441,11 @@ class LbankApi(LbankApi):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sendOrder(self, req): def sendOrder(self, req):
"""发单""" """发单"""
"""发送委托"""
# 检查是否填入了价格,禁止市价委托 # 检查是否填入了价格,禁止市价委托
if req.priceType != PRICETYPE_LIMITPRICE: if req.priceType != PRICETYPE_LIMITPRICE:
err = VtErrorData() err = VtErrorData()
err.gatewayName = self.gatewayName err.gatewayName = self.gatewayName
err.errorMsg = u'链行接口仅支持限价单' err.errorMsg = u'LBANK接口仅支持限价单'
err.errorTime = datetime.now().strftime('%H:%M:%S.%f')[:-3] err.errorTime = datetime.now().strftime('%H:%M:%S.%f')[:-3]
self.gateway.onError(err) self.gateway.onError(err)
return None return None
@ -470,7 +469,7 @@ class LbankApi(LbankApi):
order.gatewayName = self.gatewayName order.gatewayName = self.gatewayName
order.symbol = req.symbol order.symbol = req.symbol
order.exchange = EXCHANGE_LHANG order.exchange = EXCHANGE_LBANK
order.vtSymbol = '.'.join([order.symbol, order.exchange]) order.vtSymbol = '.'.join([order.symbol, order.exchange])
order.orderID = localID order.orderID = localID

View File

@ -1,7 +0,0 @@
{
"host": "CNY",
"apiKey": "OKCOIN网站申请",
"secretKey": "OKCOIN网站申请",
"trace": false,
"leverage": 20
}

View File

@ -1,11 +0,0 @@
# encoding: UTF-8
from vnpy.trader import vtConstant
from okcoinGateway import OkcoinGateway
gatewayClass = OkcoinGateway
gatewayName = 'OKCOIN'
gatewayDisplayName = u'币行'
gatewayType = vtConstant.GATEWAYTYPE_BTC
gatewayQryEnabled = True

View File

@ -1,734 +0,0 @@
# encoding: UTF-8
'''
vn.okcoin的gateway接入
注意
1. 前仅支持USD和CNY的现货交易USD的期货合约交易暂不支持
'''
import os
import json
from datetime import datetime
from time import sleep
from copy import copy
from threading import Condition
from Queue import Queue
from threading import Thread
from time import sleep
from vnpy.api.okcoin import vnokcoin
from vnpy.trader.vtGateway import *
from vnpy.trader.vtFunction import getJsonPath
# 价格类型映射
priceTypeMap = {}
priceTypeMap['buy'] = (DIRECTION_LONG, PRICETYPE_LIMITPRICE)
priceTypeMap['buy_market'] = (DIRECTION_LONG, PRICETYPE_MARKETPRICE)
priceTypeMap['sell'] = (DIRECTION_SHORT, PRICETYPE_LIMITPRICE)
priceTypeMap['sell_market'] = (DIRECTION_SHORT, PRICETYPE_MARKETPRICE)
priceTypeMapReverse = {v: k for k, v in priceTypeMap.items()}
# 方向类型映射
directionMap = {}
directionMapReverse = {v: k for k, v in directionMap.items()}
# 委托状态印射
statusMap = {}
statusMap[-1] = STATUS_CANCELLED
statusMap[0] = STATUS_NOTTRADED
statusMap[1] = STATUS_PARTTRADED
statusMap[2] = STATUS_ALLTRADED
statusMap[4] = STATUS_UNKNOWN
############################################
## 交易合约代码
############################################
# USD
BTC_USD_SPOT = 'BTC_USD_SPOT'
BTC_USD_THISWEEK = 'BTC_USD_THISWEEK'
BTC_USD_NEXTWEEK = 'BTC_USD_NEXTWEEK'
BTC_USD_QUARTER = 'BTC_USD_QUARTER'
LTC_USD_SPOT = 'LTC_USD_SPOT'
LTC_USD_THISWEEK = 'LTC_USD_THISWEEK'
LTC_USD_NEXTWEEK = 'LTC_USD_NEXTWEEK'
LTC_USD_QUARTER = 'LTC_USD_QUARTER'
ETH_USD_SPOT = 'ETH_USD_SPOT'
ETH_USD_THISWEEK = 'ETH_USD_THISWEEK'
ETH_USD_NEXTWEEK = 'ETH_USD_NEXTWEEK'
ETH_USD_QUARTER = 'ETH_USD_QUARTER'
# CNY
BTC_CNY_SPOT = 'BTC_CNY_SPOT'
LTC_CNY_SPOT = 'LTC_CNY_SPOT'
ETH_CNY_SPOT = 'ETH_CNY_SPOT'
# 印射字典
spotSymbolMap = {}
spotSymbolMap['ltc_usd'] = LTC_USD_SPOT
spotSymbolMap['btc_usd'] = BTC_USD_SPOT
spotSymbolMap['ETH_usd'] = ETH_USD_SPOT
spotSymbolMap['ltc_cny'] = LTC_CNY_SPOT
spotSymbolMap['btc_cny'] = BTC_CNY_SPOT
spotSymbolMap['eth_cny'] = ETH_CNY_SPOT
spotSymbolMapReverse = {v: k for k, v in spotSymbolMap.items()}
############################################
## Channel和Symbol的印射
############################################
channelSymbolMap = {}
# USD
channelSymbolMap['ok_sub_spotusd_btc_ticker'] = BTC_USD_SPOT
channelSymbolMap['ok_sub_spotusd_ltc_ticker'] = LTC_USD_SPOT
channelSymbolMap['ok_sub_spotusd_eth_ticker'] = ETH_USD_SPOT
channelSymbolMap['ok_sub_spotusd_btc_depth_20'] = BTC_USD_SPOT
channelSymbolMap['ok_sub_spotusd_ltc_depth_20'] = LTC_USD_SPOT
channelSymbolMap['ok_sub_spotusd_eth_depth_20'] = ETH_USD_SPOT
# CNY
channelSymbolMap['ok_sub_spotcny_btc_ticker'] = BTC_CNY_SPOT
channelSymbolMap['ok_sub_spotcny_ltc_ticker'] = LTC_CNY_SPOT
channelSymbolMap['ok_sub_spotcny_eth_ticker'] = ETH_CNY_SPOT
channelSymbolMap['ok_sub_spotcny_btc_depth_20'] = BTC_CNY_SPOT
channelSymbolMap['ok_sub_spotcny_ltc_depth_20'] = LTC_CNY_SPOT
channelSymbolMap['ok_sub_spotcny_eth_depth_20'] = ETH_CNY_SPOT
########################################################################
class OkcoinGateway(VtGateway):
"""OkCoin接口"""
#----------------------------------------------------------------------
def __init__(self, eventEngine, gatewayName='OKCOIN'):
"""Constructor"""
super(OkcoinGateway, self).__init__(eventEngine, gatewayName)
self.api = Api(self)
self.leverage = 0
self.connected = False
self.fileName = self.gatewayName + '_connect.json'
self.filePath = getJsonPath(self.fileName, __file__)
#----------------------------------------------------------------------
def connect(self):
"""连接"""
# 载入json文件
try:
f = file(self.filePath)
except IOError:
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'读取连接配置出错,请检查'
self.onLog(log)
return
# 解析json文件
setting = json.load(f)
try:
host = str(setting['host'])
apiKey = str(setting['apiKey'])
secretKey = str(setting['secretKey'])
trace = setting['trace']
leverage = setting['leverage']
except KeyError:
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'连接配置缺少字段,请检查'
self.onLog(log)
return
# 初始化接口
self.leverage = leverage
if host == 'CNY':
host = vnokcoin.OKCOIN_CNY
else:
host = vnokcoin.OKCOIN_USD
self.api.active = True
self.api.connect(host, apiKey, secretKey, trace)
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'接口初始化成功'
self.onLog(log)
# 启动查询
self.initQuery()
self.startQuery()
#----------------------------------------------------------------------
def subscribe(self, subscribeReq):
"""订阅行情"""
pass
#----------------------------------------------------------------------
def sendOrder(self, orderReq):
"""发单"""
return self.api.spotSendOrder(orderReq)
#----------------------------------------------------------------------
def cancelOrder(self, cancelOrderReq):
"""撤单"""
self.api.spotCancel(cancelOrderReq)
#----------------------------------------------------------------------
def qryAccount(self):
"""查询账户资金"""
self.api.spotUserInfo()
#----------------------------------------------------------------------
def qryPosition(self):
"""查询持仓"""
pass
#----------------------------------------------------------------------
def close(self):
"""关闭"""
self.api.active = False
self.api.close()
#----------------------------------------------------------------------
def initQuery(self):
"""初始化连续查询"""
if self.qryEnabled:
# 需要循环的查询函数列表
self.qryFunctionList = [self.qryAccount]
self.qryCount = 0 # 查询触发倒计时
self.qryTrigger = 2 # 查询触发点
self.qryNextFunction = 0 # 上次运行的查询函数索引
self.startQuery()
#----------------------------------------------------------------------
def query(self, event):
"""注册到事件处理引擎上的查询函数"""
self.qryCount += 1
if self.qryCount > self.qryTrigger:
# 清空倒计时
self.qryCount = 0
# 执行查询函数
function = self.qryFunctionList[self.qryNextFunction]
function()
# 计算下次查询函数的索引如果超过了列表长度则重新设为0
self.qryNextFunction += 1
if self.qryNextFunction == len(self.qryFunctionList):
self.qryNextFunction = 0
#----------------------------------------------------------------------
def startQuery(self):
"""启动连续查询"""
self.eventEngine.register(EVENT_TIMER, self.query)
#----------------------------------------------------------------------
def setQryEnabled(self, qryEnabled):
"""设置是否要启动循环查询"""
self.qryEnabled = qryEnabled
########################################################################
class Api(vnokcoin.OkCoinApi):
"""OkCoin的API实现"""
#----------------------------------------------------------------------
def __init__(self, gateway):
"""Constructor"""
super(Api, self).__init__()
self.gateway = gateway # gateway对象
self.gatewayName = gateway.gatewayName # gateway对象名称
self.active = False # 若为True则会在断线后自动重连
self.cbDict = {}
self.tickDict = {}
self.orderDict = {}
self.localNo = 0 # 本地委托号
self.localNoQueue = Queue() # 未收到系统委托号的本地委托号队列
self.localNoDict = {} # key为本地委托号value为系统委托号
self.orderIdDict = {} # key为系统委托号value为本地委托号
self.cancelDict = {} # key为本地委托号value为撤单请求
self.initCallback()
#----------------------------------------------------------------------
def onMessage(self, ws, evt):
"""信息推送"""
data = self.readData(evt)[0]
channel = data['channel']
callback = self.cbDict[channel]
callback(data)
#----------------------------------------------------------------------
def onError(self, ws, evt):
"""错误推送"""
error = VtErrorData()
error.gatewayName = self.gatewayName
error.errorMsg = str(evt)
self.gateway.onError(error)
#----------------------------------------------------------------------
def onClose(self, ws):
"""接口断开"""
# 如果尚未连上,则忽略该次断开提示
if not self.gateway.connected:
return
self.gateway.connected = False
self.writeLog(u'服务器连接断开')
# 重新连接
if self.active:
def reconnect():
while not self.gateway.connected:
self.writeLog(u'等待10秒后重新连接')
sleep(10)
if not self.gateway.connected:
self.reconnect()
t = Thread(target=reconnect)
t.start()
#----------------------------------------------------------------------
def onOpen(self, ws):
"""连接成功"""
self.gateway.connected = True
self.writeLog(u'服务器连接成功')
# 连接后查询账户和委托数据
self.spotUserInfo()
self.spotOrderInfo(vnokcoin.TRADING_SYMBOL_LTC, '-1')
self.spotOrderInfo(vnokcoin.TRADING_SYMBOL_BTC, '-1')
self.spotOrderInfo(vnokcoin.TRADING_SYMBOL_ETH, '-1')
# 连接后订阅现货的成交和账户数据
self.subscribeSpotTrades()
self.subscribeSpotUserInfo()
self.subscribeSpotTicker(vnokcoin.SYMBOL_BTC)
self.subscribeSpotTicker(vnokcoin.SYMBOL_LTC)
self.subscribeSpotTicker(vnokcoin.SYMBOL_ETH)
self.subscribeSpotDepth(vnokcoin.SYMBOL_BTC, vnokcoin.DEPTH_20)
self.subscribeSpotDepth(vnokcoin.SYMBOL_LTC, vnokcoin.DEPTH_20)
self.subscribeSpotDepth(vnokcoin.SYMBOL_ETH, vnokcoin.DEPTH_20)
# 如果连接的是USD网站则订阅期货相关回报数据
if self.currency == vnokcoin.CURRENCY_USD:
self.subscribeFutureTrades()
self.subscribeFutureUserInfo()
self.subscribeFuturePositions()
# 返回合约信息
if self.currency == vnokcoin.CURRENCY_CNY:
l = self.generateCnyContract()
else:
l = self.generateUsdContract()
for contract in l:
contract.gatewayName = self.gatewayName
self.gateway.onContract(contract)
#----------------------------------------------------------------------
def writeLog(self, content):
"""快速记录日志"""
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = content
self.gateway.onLog(log)
#----------------------------------------------------------------------
def initCallback(self):
"""初始化回调函数"""
# USD_SPOT
self.cbDict['ok_sub_spotusd_btc_ticker'] = self.onTicker
self.cbDict['ok_sub_spotusd_ltc_ticker'] = self.onTicker
self.cbDict['ok_sub_spotusd_eth_ticker'] = self.onTicker
self.cbDict['ok_sub_spotusd_btc_depth_20'] = self.onDepth
self.cbDict['ok_sub_spotusd_ltc_depth_20'] = self.onDepth
self.cbDict['ok_sub_spotusd_eth_depth_20'] = self.onDepth
self.cbDict['ok_spotusd_userinfo'] = self.onSpotUserInfo
self.cbDict['ok_spotusd_orderinfo'] = self.onSpotOrderInfo
self.cbDict['ok_sub_spotusd_userinfo'] = self.onSpotSubUserInfo
self.cbDict['ok_sub_spotusd_trades'] = self.onSpotSubTrades
self.cbDict['ok_spotusd_trade'] = self.onSpotTrade
self.cbDict['ok_spotusd_cancel_order'] = self.onSpotCancelOrder
# CNY_SPOT
self.cbDict['ok_sub_spotcny_btc_ticker'] = self.onTicker
self.cbDict['ok_sub_spotcny_ltc_ticker'] = self.onTicker
self.cbDict['ok_sub_spotcny_eth_ticker'] = self.onTicker
self.cbDict['ok_sub_spotcny_btc_depth_20'] = self.onDepth
self.cbDict['ok_sub_spotcny_ltc_depth_20'] = self.onDepth
self.cbDict['ok_sub_spotcny_eth_depth_20'] = self.onDepth
self.cbDict['ok_spotcny_userinfo'] = self.onSpotUserInfo
self.cbDict['ok_spotcny_orderinfo'] = self.onSpotOrderInfo
self.cbDict['ok_sub_spotcny_userinfo'] = self.onSpotSubUserInfo
self.cbDict['ok_sub_spotcny_trades'] = self.onSpotSubTrades
self.cbDict['ok_spotcny_trade'] = self.onSpotTrade
self.cbDict['ok_spotcny_cancel_order'] = self.onSpotCancelOrder
# USD_FUTURES
#----------------------------------------------------------------------
def onTicker(self, data):
""""""
if 'data' not in data:
return
channel = data['channel']
symbol = channelSymbolMap[channel]
if symbol not in self.tickDict:
tick = VtTickData()
tick.symbol = symbol
tick.vtSymbol = symbol
tick.gatewayName = self.gatewayName
self.tickDict[symbol] = tick
else:
tick = self.tickDict[symbol]
rawData = data['data']
tick.highPrice = float(rawData['high'])
tick.lowPrice = float(rawData['low'])
tick.lastPrice = float(rawData['last'])
tick.volume = float(rawData['vol'])
#tick.date, tick.time = generateDateTime(rawData['timestamp'])
newtick = copy(tick)
self.gateway.onTick(newtick)
#----------------------------------------------------------------------
def onDepth(self, data):
""""""
if 'data' not in data:
return
channel = data['channel']
symbol = channelSymbolMap[channel]
if symbol not in self.tickDict:
tick = VtTickData()
tick.symbol = symbol
tick.vtSymbol = symbol
tick.gatewayName = self.gatewayName
self.tickDict[symbol] = tick
else:
tick = self.tickDict[symbol]
if 'data' not in data:
return
rawData = data['data']
tick.bidPrice1, tick.bidVolume1 = rawData['bids'][0]
tick.bidPrice2, tick.bidVolume2 = rawData['bids'][1]
tick.bidPrice3, tick.bidVolume3 = rawData['bids'][2]
tick.bidPrice4, tick.bidVolume4 = rawData['bids'][3]
tick.bidPrice5, tick.bidVolume5 = rawData['bids'][4]
tick.askPrice1, tick.askVolume1 = rawData['asks'][-1]
tick.askPrice2, tick.askVolume2 = rawData['asks'][-2]
tick.askPrice3, tick.askVolume3 = rawData['asks'][-3]
tick.askPrice4, tick.askVolume4 = rawData['asks'][-4]
tick.askPrice5, tick.askVolume5 = rawData['asks'][-5]
tick.date, tick.time = generateDateTime(rawData['timestamp'])
newtick = copy(tick)
self.gateway.onTick(newtick)
#----------------------------------------------------------------------
def onSpotUserInfo(self, data):
"""现货账户资金推送"""
rawData = data['data']
info = rawData['info']
funds = rawData['info']['funds']
# 持仓信息
for symbol in ['btc', 'ltc','eth', self.currency]:
if symbol in funds['free']:
pos = VtPositionData()
pos.gatewayName = self.gatewayName
pos.symbol = symbol
pos.vtSymbol = symbol
pos.vtPositionName = symbol
pos.direction = DIRECTION_NET
pos.frozen = float(funds['freezed'][symbol])
pos.position = pos.frozen + float(funds['free'][symbol])
self.gateway.onPosition(pos)
# 账户资金
account = VtAccountData()
account.gatewayName = self.gatewayName
account.accountID = self.gatewayName
account.vtAccountID = account.accountID
account.balance = float(funds['asset']['net'])
self.gateway.onAccount(account)
#----------------------------------------------------------------------
def onSpotSubUserInfo(self, data):
"""现货账户资金推送"""
if 'data' not in data:
return
rawData = data['data']
info = rawData['info']
# 持仓信息
for symbol in ['btc', 'ltc','eth', self.currency]:
if symbol in info['free']:
pos = VtPositionData()
pos.gatewayName = self.gatewayName
pos.symbol = symbol
pos.vtSymbol = symbol
pos.vtPositionName = symbol
pos.direction = DIRECTION_NET
pos.frozen = float(info['freezed'][symbol])
pos.position = pos.frozen + float(info['free'][symbol])
self.gateway.onPosition(pos)
#----------------------------------------------------------------------
def onSpotSubTrades(self, data):
"""成交和委托推送"""
if 'data' not in data:
return
rawData = data['data']
# 本地和系统委托号
orderId = str(rawData['orderId'])
localNo = self.orderIdDict[orderId]
# 委托信息
if orderId not in self.orderDict:
order = VtOrderData()
order.gatewayName = self.gatewayName
order.symbol = spotSymbolMap[rawData['symbol']]
order.vtSymbol = order.symbol
order.orderID = localNo
order.vtOrderID = '.'.join([self.gatewayName, order.orderID])
order.price = float(rawData['tradeUnitPrice'])
order.totalVolume = float(rawData['tradeAmount'])
order.direction, priceType = priceTypeMap[rawData['tradeType']]
self.orderDict[orderId] = order
else:
order = self.orderDict[orderId]
order.tradedVolume = float(rawData['completedTradeAmount'])
order.status = statusMap[rawData['status']]
self.gateway.onOrder(copy(order))
# 成交信息
if 'sigTradeAmount' in rawData and float(rawData['sigTradeAmount'])>0:
trade = VtTradeData()
trade.gatewayName = self.gatewayName
trade.symbol = spotSymbolMap[rawData['symbol']]
trade.vtSymbol = order.symbol
trade.tradeID = str(rawData['id'])
trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID])
trade.orderID = localNo
trade.vtOrderID = '.'.join([self.gatewayName, trade.orderID])
trade.price = float(rawData['sigTradePrice'])
trade.volume = float(rawData['sigTradeAmount'])
trade.direction, priceType = priceTypeMap[rawData['tradeType']]
trade.tradeTime = datetime.now().strftime('%H:%M:%S')
self.gateway.onTrade(trade)
#----------------------------------------------------------------------
def onSpotOrderInfo(self, data):
"""委托信息查询回调"""
rawData = data['data']
for d in rawData['orders']:
self.localNo += 1
localNo = str(self.localNo)
orderId = str(d['order_id'])
self.localNoDict[localNo] = orderId
self.orderIdDict[orderId] = localNo
if orderId not in self.orderDict:
order = VtOrderData()
order.gatewayName = self.gatewayName
order.symbol = spotSymbolMap[d['symbol']]
order.vtSymbol = order.symbol
order.orderID = localNo
order.vtOrderID = '.'.join([self.gatewayName, order.orderID])
order.price = d['price']
order.totalVolume = d['amount']
order.direction, priceType = priceTypeMap[d['type']]
self.orderDict[orderId] = order
else:
order = self.orderDict[orderId]
order.tradedVolume = d['deal_amount']
order.status = statusMap[d['status']]
self.gateway.onOrder(copy(order))
#----------------------------------------------------------------------
def generateSpecificContract(self, contract, symbol):
"""生成合约"""
new = copy(contract)
new.symbol = symbol
new.vtSymbol = symbol
new.name = symbol
return new
#----------------------------------------------------------------------
def generateCnyContract(self):
"""生成CNY合约信息"""
contractList = []
contract = VtContractData()
contract.exchange = EXCHANGE_OKCOIN
contract.productClass = PRODUCT_SPOT
contract.size = 1
contract.priceTick = 0.01
contractList.append(self.generateSpecificContract(contract, BTC_CNY_SPOT))
contractList.append(self.generateSpecificContract(contract, LTC_CNY_SPOT))
contractList.append(self.generateSpecificContract(contract, ETH_CNY_SPOT))
return contractList
#----------------------------------------------------------------------
def generateUsdContract(self):
"""生成USD合约信息"""
contractList = []
# 现货
contract = VtContractData()
contract.exchange = EXCHANGE_OKCOIN
contract.productClass = PRODUCT_SPOT
contract.size = 1
contract.priceTick = 0.01
contractList.append(self.generateSpecificContract(contract, BTC_USD_SPOT))
contractList.append(self.generateSpecificContract(contract, LTC_USD_SPOT))
contractList.append(self.generateSpecificContract(contract, ETH_USD_SPOT))
# 期货
contract.productClass = PRODUCT_FUTURES
contractList.append(self.generateSpecificContract(contract, BTC_USD_THISWEEK))
contractList.append(self.generateSpecificContract(contract, BTC_USD_NEXTWEEK))
contractList.append(self.generateSpecificContract(contract, BTC_USD_QUARTER))
contractList.append(self.generateSpecificContract(contract, LTC_USD_THISWEEK))
contractList.append(self.generateSpecificContract(contract, LTC_USD_NEXTWEEK))
contractList.append(self.generateSpecificContract(contract, LTC_USD_QUARTER))
contractList.append(self.generateSpecificContract(contract, ETH_USD_THISWEEK))
contractList.append(self.generateSpecificContract(contract, ETH_USD_NEXTWEEK))
contractList.append(self.generateSpecificContract(contract, ETH_USD_QUARTER))
return contractList
#----------------------------------------------------------------------
def onSpotTrade(self, data):
"""委托回报"""
rawData = data['data']
orderId = rawData['order_id']
# 尽管websocket接口的委托号返回是异步的但经过测试是
# 符合先发现回的规律因此这里通过queue获取之前发送的
# 本地委托号,并把它和推送的系统委托号进行映射
localNo = self.localNoQueue.get_nowait()
self.localNoDict[localNo] = orderId
self.orderIdDict[orderId] = localNo
# 检查是否有系统委托号返回前就发出的撤单请求,若有则进
# 行撤单操作
if localNo in self.cancelDict:
req = self.cancelDict[localNo]
self.spotCancel(req)
del self.cancelDict[localNo]
#----------------------------------------------------------------------
def onSpotCancelOrder(self, data):
"""撤单回报"""
pass
#----------------------------------------------------------------------
def spotSendOrder(self, req):
"""发单"""
symbol = spotSymbolMapReverse[req.symbol][:4]
type_ = priceTypeMapReverse[(req.direction, req.priceType)]
self.spotTrade(symbol, type_, str(req.price), str(req.volume))
# 本地委托号加1并将对应字符串保存到队列中返回基于本地委托号的vtOrderID
self.localNo += 1
self.localNoQueue.put(str(self.localNo))
vtOrderID = '.'.join([self.gatewayName, str(self.localNo)])
return vtOrderID
#----------------------------------------------------------------------
def spotCancel(self, req):
"""撤单"""
symbol = spotSymbolMapReverse[req.symbol][:4]
localNo = req.orderID
if localNo in self.localNoDict:
orderID = self.localNoDict[localNo]
self.spotCancelOrder(symbol, orderID)
else:
# 如果在系统委托号返回前客户就发送了撤单请求,则保存
# 在cancelDict字典中等待返回后执行撤单任务
self.cancelDict[localNo] = req
#----------------------------------------------------------------------
def generateDateTime(s):
"""生成时间"""
dt = datetime.fromtimestamp(float(s)/1e3)
time = dt.strftime("%H:%M:%S.%f")
date = dt.strftime("%Y%m%d")
return date, time

View File

@ -81,15 +81,15 @@ EXCHANGE_ICE = 'ICE' # ICE交易所
EXCHANGE_LME = 'LME' # LME交易所 EXCHANGE_LME = 'LME' # LME交易所
EXCHANGE_OANDA = 'OANDA' # OANDA外汇做市商 EXCHANGE_OANDA = 'OANDA' # OANDA外汇做市商
EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所 EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所
EXCHANGE_HUOBI = 'HUOBI' # 火币比特币交易所 EXCHANGE_HUOBI = 'HUOBI' # 火币比特币交易所
EXCHANGE_LHANG = 'LHANG' # 链行比特币交易所 EXCHANGE_LBANK = 'LBANK' # LBANK比特币交易所
EXCHANGE_KORBIT = 'KORBIT' # KORBIT韩国交易所
EXCHANGE_KORBIT = 'KORBIT' # KORBIT 韩国交易所 EXCHANGE_ZB = 'ZB' # 比特币中国比特币交易所
EXCHANGE_ZB = 'ZB' # ZB 中国比特币交易所 (比特币中国) EXCHANGE_OKEX = 'OKEX' # OKEX比特币交易所
EXCHANGE_OKEX = 'OKEX' # OKEX 中国比特币交易所 (okcoin) EXCHANGE_ZAIF = "ZAIF" # ZAIF日本比特币交易所
EXCHANGE_ZAIF = "ZAIF" # ZAIF 日本比特币交易所 EXCHANGE_COINCHECK = "COINCHECK" # COINCHECK日本比特币交易所
EXCHANGE_COINCHECK = "COINCHECK" # COINCHECK 日本比特币交易所
# 货币类型 # 货币类型
CURRENCY_USD = 'USD' # 美元 CURRENCY_USD = 'USD' # 美元

View File

@ -77,15 +77,15 @@ EXCHANGE_ICE = 'ICE' # ICE交易所
EXCHANGE_LME = 'LME' # LME交易所 EXCHANGE_LME = 'LME' # LME交易所
EXCHANGE_OANDA = 'OANDA' # OANDA外汇做市商 EXCHANGE_OANDA = 'OANDA' # OANDA外汇做市商
EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所 EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所
EXCHANGE_HUOBI = 'HUOBI' # 火币比特币交易所 EXCHANGE_HUOBI = 'HUOBI' # 火币比特币交易所
EXCHANGE_LHANG = 'LHANG' # 链行比特币交易所 EXCHANGE_LBANK = 'LBANK' # LBANK比特币交易所
EXCHANGE_KORBIT = 'KORBIT' # KORBIT韩国交易所
EXCHANGE_KORBIT = 'KORBIT' # KORBIT 韩国交易所 EXCHANGE_ZB = 'ZB' # 比特币中国比特币交易所
EXCHANGE_ZB = 'ZB' # ZB 中国比特币交易所 (比特币中国) EXCHANGE_OKEX = 'OKEX' # OKEX比特币交易所
EXCHANGE_OKEX = 'OKEX' # OKEX 中国比特币交易所 (okcoin) EXCHANGE_ZAIF = "ZAIF" # ZAIF日本比特币交易所
EXCHANGE_ZAIF = "ZAIF" # ZAIF 日本比特币交易所 尚未实现 EXCHANGE_COINCHECK = "COINCHECK" # COINCHECK日本比特币交易所
EXCHANGE_COINCHECK = "COINCHECK" # COINCHECK 日本比特币交易所
# 货币类型 # 货币类型
CURRENCY_USD = 'USD' # 美元 CURRENCY_USD = 'USD' # 美元