1. 增加vn.trader里OKCOIN比特币交易所的接入
2. 增加CTA模块回测中的部分业绩分析数据:盈亏比等 3. 修复之前vn.okcoin里的几个BUG
This commit is contained in:
parent
e405e760f4
commit
e7582dd01f
@ -15,9 +15,9 @@ api.connect(OKCOIN_USD, apiKey, secretKey, True)
|
||||
sleep(1)
|
||||
|
||||
# 测试现货行情API
|
||||
api.subscribeSpotTicker(SYMBOL_BTC)
|
||||
#api.subscribeSpotTicker(SYMBOL_BTC)
|
||||
#api.subscribeSpotTradeData(SYMBOL_BTC)
|
||||
#api.subscribeSpotDepth(SYMBOL_BTC, DEPTH_20)
|
||||
api.subscribeSpotDepth(SYMBOL_BTC, DEPTH_20)
|
||||
#api.subscribeSpotKline(SYMBOL_BTC, INTERVAL_1M)
|
||||
|
||||
# 测试现货交易API
|
||||
|
@ -41,7 +41,7 @@ INTERVAL_1W = 'week'
|
||||
|
||||
# 交易代码,需要后缀货币名才能完整
|
||||
TRADING_SYMBOL_BTC = 'btc_'
|
||||
TRADING_SYMBOL_LTS = 'ltc_'
|
||||
TRADING_SYMBOL_LTC = 'ltc_'
|
||||
|
||||
# 委托类型
|
||||
TYPE_BUY = 'buy'
|
||||
@ -86,6 +86,7 @@ class OkCoinApi(object):
|
||||
self.apiKey = '' # 用户名
|
||||
self.secretKey = '' # 密码
|
||||
self.host = '' # 服务器地址
|
||||
|
||||
self.currency = '' # 货币类型(usd或者cny)
|
||||
|
||||
self.ws = None # websocket应用对象
|
||||
@ -164,11 +165,7 @@ class OkCoinApi(object):
|
||||
|
||||
self.thread = Thread(target=self.ws.run_forever)
|
||||
self.thread.start()
|
||||
|
||||
#######################
|
||||
## 现货相关
|
||||
#######################
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def sendMarketDataRequest(self, channel):
|
||||
"""发送行情请求"""
|
||||
@ -198,8 +195,12 @@ class OkCoinApi(object):
|
||||
|
||||
# 使用json打包并发送
|
||||
j = json.dumps(d)
|
||||
self.ws.send(j)
|
||||
|
||||
self.ws.send(j)
|
||||
|
||||
#######################
|
||||
## 现货相关
|
||||
#######################
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def subscribeSpotTicker(self, symbol):
|
||||
"""订阅现货普通报价"""
|
||||
@ -224,8 +225,8 @@ class OkCoinApi(object):
|
||||
def spotTrade(self, symbol, type_, price, amount):
|
||||
"""现货委托"""
|
||||
params = {}
|
||||
params['symbol'] = str(symbol)
|
||||
params['type'] = str(type_+self.currency)
|
||||
params['symbol'] = str(symbol+self.currency)
|
||||
params['type'] = str(type_)
|
||||
params['price'] = str(price)
|
||||
params['amount'] = str(amount)
|
||||
|
||||
@ -258,7 +259,7 @@ class OkCoinApi(object):
|
||||
params['symbol'] = str(symbol+self.currency)
|
||||
params['order_id'] = str(orderid)
|
||||
|
||||
channel = 'ok_spot%s_orderinfo'
|
||||
channel = 'ok_spot%s_orderinfo' %(self.currency)
|
||||
|
||||
self.sendTradingRequest(channel, params)
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
本文件中包含的是CTA模块的回测引擎,回测引擎的API和CTA引擎一致,
|
||||
可以使用和实盘相同的代码进行回测。
|
||||
'''
|
||||
from __future__ import division
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from collections import OrderedDict
|
||||
@ -504,6 +505,11 @@ class BacktestingEngine(object):
|
||||
capitalList = [] # 盈亏汇总的时间序列
|
||||
drawdownList = [] # 回撤的时间序列
|
||||
|
||||
winningResult = 0 # 盈利次数
|
||||
losingResult = 0 # 亏损次数
|
||||
totalWinning = 0 # 总盈利金额
|
||||
totalLosing = 0 # 总亏损金额
|
||||
|
||||
for time, result in resultDict.items():
|
||||
capital += result.pnl
|
||||
maxCapital = max(capital, maxCapital)
|
||||
@ -519,6 +525,19 @@ class BacktestingEngine(object):
|
||||
totalCommission += result.commission
|
||||
totalSlippage += result.slippage
|
||||
|
||||
if result.pnl >= 0:
|
||||
winningResult += 1
|
||||
totalWinning += result.pnl
|
||||
else:
|
||||
losingResult += 1
|
||||
totalLosing += result.pnl
|
||||
|
||||
# 计算盈亏相关数据
|
||||
winningRate = winningResult/totalResult*100 # 胜率
|
||||
averageWinning = totalWinning/winningResult # 平均每笔盈利
|
||||
averageLosing = totalLosing/losingResult # 平均每笔亏损
|
||||
profitLossRatio = -averageWinning/averageLosing # 盈亏比
|
||||
|
||||
# 返回回测结果
|
||||
d = {}
|
||||
d['capital'] = capital
|
||||
@ -531,7 +550,12 @@ class BacktestingEngine(object):
|
||||
d['timeList'] = timeList
|
||||
d['pnlList'] = pnlList
|
||||
d['capitalList'] = capitalList
|
||||
d['drawdownList'] = drawdownList
|
||||
d['drawdownList'] = drawdownList
|
||||
d['winningRate'] = winningRate
|
||||
d['averageWinning'] = averageWinning
|
||||
d['averageLosing'] = averageLosing
|
||||
d['profitLossRatio'] = profitLossRatio
|
||||
|
||||
return d
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@ -551,6 +575,11 @@ class BacktestingEngine(object):
|
||||
self.output(u'平均每笔盈利:\t%s' %formatNumber(d['capital']/d['totalResult']))
|
||||
self.output(u'平均每笔滑点:\t%s' %formatNumber(d['totalSlippage']/d['totalResult']))
|
||||
self.output(u'平均每笔佣金:\t%s' %formatNumber(d['totalCommission']/d['totalResult']))
|
||||
|
||||
self.output(u'胜率\t\t%s%%' %formatNumber(d['winningRate']))
|
||||
self.output(u'平均每笔盈利\t%s' %formatNumber(d['averageWinning']))
|
||||
self.output(u'平均每笔亏损\t%s' %formatNumber(d['averageLosing']))
|
||||
self.output(u'盈亏比:\t%s' %formatNumber(d['profitLossRatio']))
|
||||
|
||||
# 绘图
|
||||
import matplotlib.pyplot as plt
|
||||
@ -651,11 +680,11 @@ class TradingResult(object):
|
||||
self.exit = exit # 平仓价格
|
||||
self.volume = volume # 交易数量(+/-代表方向)
|
||||
|
||||
self.turnover = (self.entry+self.exit)*size # 成交金额
|
||||
self.commission = self.turnover*rate # 手续费成本
|
||||
self.slippage = slippage*2*size # 滑点成本
|
||||
self.turnover = (self.entry+self.exit)*size*abs(volume) # 成交金额
|
||||
self.commission = self.turnover*rate # 手续费成本
|
||||
self.slippage = slippage*2*size*abs(volume) # 滑点成本
|
||||
self.pnl = ((self.exit - self.entry) * volume * size
|
||||
- self.commission - self.slippage) # 净盈亏
|
||||
- self.commission - self.slippage) # 净盈亏
|
||||
|
||||
|
||||
########################################################################
|
||||
|
@ -259,21 +259,21 @@ if __name__ == '__main__':
|
||||
# 设置使用的历史数据库
|
||||
engine.setDatabase(MINUTE_DB_NAME, 'IF0000')
|
||||
|
||||
## 在引擎中创建策略对象
|
||||
#d = {'atrLength': 11}
|
||||
#engine.initStrategy(AtrRsiStrategy, d)
|
||||
# 在引擎中创建策略对象
|
||||
d = {'atrLength': 11}
|
||||
engine.initStrategy(AtrRsiStrategy, d)
|
||||
|
||||
## 开始跑回测
|
||||
#engine.runBacktesting()
|
||||
# 开始跑回测
|
||||
engine.runBacktesting()
|
||||
|
||||
## 显示回测结果
|
||||
#engine.showBacktestingResult()
|
||||
# 显示回测结果
|
||||
engine.showBacktestingResult()
|
||||
|
||||
# 跑优化
|
||||
setting = OptimizationSetting() # 新建一个优化任务设置对象
|
||||
setting.setOptimizeTarget('capital') # 设置优化排序的目标是策略净盈利
|
||||
setting.addParameter('atrLength', 11, 12, 1) # 增加第一个优化参数atrLength,起始11,结束12,步进1
|
||||
setting.addParameter('atrMa', 20, 30, 5) # 增加第二个优化参数atrMa,起始20,结束30,步进1
|
||||
engine.runOptimization(AtrRsiStrategy, setting) # 运行优化函数,自动输出结果
|
||||
## 跑优化
|
||||
#setting = OptimizationSetting() # 新建一个优化任务设置对象
|
||||
#setting.setOptimizeTarget('capital') # 设置优化排序的目标是策略净盈利
|
||||
#setting.addParameter('atrLength', 11, 12, 1) # 增加第一个优化参数atrLength,起始11,结束12,步进1
|
||||
#setting.addParameter('atrMa', 20, 30, 5) # 增加第二个优化参数atrMa,起始20,结束30,步进1
|
||||
#engine.runOptimization(AtrRsiStrategy, setting) # 运行优化函数,自动输出结果
|
||||
|
||||
|
7
vn.trader/okcoinGateway/OKCOIN_connect.json
Normal file
7
vn.trader/okcoinGateway/OKCOIN_connect.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"host": "CNY",
|
||||
"apiKey": "OKCOIN网站申请",
|
||||
"secretKey": "OKCOIN网站申请",
|
||||
"trace": false,
|
||||
"leverage": 20
|
||||
}
|
0
vn.trader/okcoinGateway/__init__.py
Normal file
0
vn.trader/okcoinGateway/__init__.py
Normal file
657
vn.trader/okcoinGateway/okcoinGateway.py
Normal file
657
vn.trader/okcoinGateway/okcoinGateway.py
Normal file
@ -0,0 +1,657 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
'''
|
||||
vn.okcoin的gateway接入
|
||||
|
||||
注意:
|
||||
1. 该接口尚处于测试阶段,用于实盘请谨慎
|
||||
2. 目前仅支持USD和CNY的现货交易,USD的期货合约交易暂不支持
|
||||
'''
|
||||
|
||||
|
||||
import os
|
||||
import json
|
||||
from datetime import datetime
|
||||
from copy import copy
|
||||
from threading import Condition
|
||||
|
||||
import vnokcoin
|
||||
from vtGateway import *
|
||||
|
||||
# 价格类型映射
|
||||
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'
|
||||
|
||||
# CNY
|
||||
BTC_CNY_SPOT = 'BTC_CNY_SPOT'
|
||||
LTC_CNY_SPOT = 'LTC_CNY_SPOT'
|
||||
|
||||
# 印射字典
|
||||
spotSymbolMap = {}
|
||||
spotSymbolMap['ltc_usd'] = LTC_USD_SPOT
|
||||
spotSymbolMap['btc_usd'] = BTC_USD_SPOT
|
||||
spotSymbolMap['ltc_cny'] = LTC_CNY_SPOT
|
||||
spotSymbolMap['btc_cny'] = BTC_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_btc_depth_20'] = BTC_USD_SPOT
|
||||
channelSymbolMap['ok_sub_spotusd_ltc_depth_20'] = LTC_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_btc_depth_20'] = BTC_CNY_SPOT
|
||||
channelSymbolMap['ok_sub_spotcny_ltc_depth_20'] = LTC_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
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def connect(self):
|
||||
"""连接"""
|
||||
# 载入json文件
|
||||
fileName = self.gatewayName + '_connect.json'
|
||||
fileName = os.getcwd() + '/okcoinGateway/' + fileName
|
||||
|
||||
try:
|
||||
f = file(fileName)
|
||||
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.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):
|
||||
"""关闭"""
|
||||
pass
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
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.cbDict = {}
|
||||
self.tickDict = {}
|
||||
self.orderDict = {}
|
||||
|
||||
self.lastOrderID = ''
|
||||
self.orderCondition = Condition()
|
||||
|
||||
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):
|
||||
"""接口断开"""
|
||||
self.gateway.connected = True
|
||||
self.writeLog(u'服务器连接断开')
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
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.subscribeSpotTrades()
|
||||
self.subscribeSpotUserInfo()
|
||||
|
||||
self.subscribeSpotTicker(vnokcoin.SYMBOL_BTC)
|
||||
self.subscribeSpotTicker(vnokcoin.SYMBOL_LTC)
|
||||
|
||||
self.subscribeSpotDepth(vnokcoin.SYMBOL_BTC, vnokcoin.DEPTH_20)
|
||||
self.subscribeSpotDepth(vnokcoin.SYMBOL_LTC, 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_btc_depth_20'] = self.onDepth
|
||||
self.cbDict['ok_sub_spotusd_ltc_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_btc_depth_20'] = self.onDepth
|
||||
self.cbDict['ok_sub_spotcny_ltc_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'].replace(',', ''))
|
||||
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'][0]
|
||||
tick.askPrice2, tick.askVolume2 = rawData['asks'][1]
|
||||
tick.askPrice3, tick.askVolume3 = rawData['asks'][2]
|
||||
tick.askPrice4, tick.askVolume4 = rawData['asks'][3]
|
||||
tick.askPrice5, tick.askVolume5 = rawData['asks'][4]
|
||||
|
||||
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', 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', 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'])
|
||||
if orderID not in self.orderDict:
|
||||
order = VtOrderData()
|
||||
order.gatewayName = self.gatewayName
|
||||
|
||||
order.symbol = spotSymbolMap[rawData['symbol']]
|
||||
order.vtSymbol = order.symbol
|
||||
|
||||
order.orderID = str(rawData['orderId'])
|
||||
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 = str(rawData['orderId'])
|
||||
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']:
|
||||
orderID = str(d['order_id'])
|
||||
|
||||
if orderID not in self.orderDict:
|
||||
order = VtOrderData()
|
||||
order.gatewayName = self.gatewayName
|
||||
|
||||
order.symbol = spotSymbolMap[d['symbol']]
|
||||
order.vtSymbol = order.symbol
|
||||
|
||||
order.orderID = str(d['order_id'])
|
||||
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))
|
||||
|
||||
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))
|
||||
|
||||
# 期货
|
||||
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))
|
||||
|
||||
return contractList
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onSpotTrade(self, data):
|
||||
"""委托回报"""
|
||||
rawData = data['data']
|
||||
self.lastOrderID = rawData['order_id']
|
||||
|
||||
# 收到委托号后,通知发送委托的线程返回委托号
|
||||
self.orderCondition.acquire()
|
||||
self.orderCondition.notify()
|
||||
self.orderCondition.release()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
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))
|
||||
|
||||
# 等待发单回调推送委托号信息
|
||||
self.orderCondition.acquire()
|
||||
self.orderCondition.wait()
|
||||
self.orderCondition.release()
|
||||
|
||||
vtOrderID = '.'.join([self.gatewayName, self.lastOrderID])
|
||||
self.lastOrderID = ''
|
||||
return vtOrderID
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def spotCancel(self, req):
|
||||
"""撤单"""
|
||||
symbol = spotSymbolMapReverse[req.symbol][:4]
|
||||
self.spotCancelOrder(symbol, req.orderID)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
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
|
382
vn.trader/okcoinGateway/vnokcoin.py
Normal file
382
vn.trader/okcoinGateway/vnokcoin.py
Normal file
@ -0,0 +1,382 @@
|
||||
# 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'
|
||||
|
||||
# 行情深度
|
||||
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_'
|
||||
|
||||
# 委托类型
|
||||
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 sendMarketDataRequest(self, channel):
|
||||
"""发送行情请求"""
|
||||
# 生成请求
|
||||
d = {}
|
||||
d['event'] = 'addChannel'
|
||||
d['binary'] = True
|
||||
d['channel'] = channel
|
||||
|
||||
# 使用json打包并发送
|
||||
j = json.dumps(d)
|
||||
self.ws.send(j)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
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)
|
||||
self.ws.send(j)
|
||||
|
||||
#######################
|
||||
## 现货相关
|
||||
#######################
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
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.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, {})
|
||||
|
||||
|
@ -89,6 +89,9 @@ class MainWindow(QtGui.QMainWindow):
|
||||
connectOandaAction = QtGui.QAction(u'连接OANDA', self)
|
||||
connectOandaAction.triggered.connect(self.connectOanda)
|
||||
|
||||
connectOkcoinAction = QtGui.QAction(u'连接OKCOIN', self)
|
||||
connectOkcoinAction.triggered.connect(self.connectOkcoin)
|
||||
|
||||
connectDbAction = QtGui.QAction(u'连接数据库', self)
|
||||
connectDbAction.triggered.connect(self.mainEngine.dbConnect)
|
||||
|
||||
@ -137,6 +140,8 @@ class MainWindow(QtGui.QMainWindow):
|
||||
sysMenu.addAction(connectIbAction)
|
||||
if 'OANDA' in self.mainEngine.gatewayDict:
|
||||
sysMenu.addAction(connectOandaAction)
|
||||
if 'OKCOIN' in self.mainEngine.gatewayDict:
|
||||
sysMenu.addAction(connectOkcoinAction)
|
||||
sysMenu.addSeparator()
|
||||
if 'Wind' in self.mainEngine.gatewayDict:
|
||||
sysMenu.addAction(connectWindAction)
|
||||
@ -239,6 +244,11 @@ class MainWindow(QtGui.QMainWindow):
|
||||
"""连接OANDA"""
|
||||
self.mainEngine.connect('OANDA')
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def connectOkcoin(self):
|
||||
"""连接OKCOIN"""
|
||||
self.mainEngine.connect('OKCOIN')
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def test(self):
|
||||
"""测试按钮用的函数"""
|
||||
|
@ -69,6 +69,7 @@ EXCHANGE_GLOBEX = 'GLOBEX' # CME电子交易平台
|
||||
EXCHANGE_IDEALPRO = 'IDEALPRO' # IB外汇ECN
|
||||
|
||||
EXCHANGE_OANDA = 'OANDA' # OANDA外汇做市商
|
||||
EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所
|
||||
|
||||
# 货币类型
|
||||
CURRENCY_USD = 'USD' # 美元
|
||||
|
@ -114,6 +114,13 @@ class MainEngine(object):
|
||||
self.gatewayDict['OANDA'].setQryEnabled(True)
|
||||
except Exception, e:
|
||||
print e
|
||||
|
||||
try:
|
||||
from okcoinGateway.okcoinGateway import OkcoinGateway
|
||||
self.addGateway(OkcoinGateway, 'OKCOIN')
|
||||
self.gatewayDict['OKCOIN'].setQryEnabled(True)
|
||||
except Exception, e:
|
||||
print e
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def addGateway(self, gateway, gatewayName=None):
|
||||
|
Loading…
Reference in New Issue
Block a user