Merge pull request #1 from vnpy/dev

merge upstream dev
This commit is contained in:
recotra 2017-02-13 10:09:42 +08:00 committed by GitHub
commit 1c49d1e1b7
14 changed files with 1105 additions and 29 deletions

View File

@ -558,7 +558,7 @@ class DataApi(object):
self.taskThread = Thread(target=self.run) # 处理任务的线程 self.taskThread = Thread(target=self.run) # 处理任务的线程
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def init(self, interval, debug=True): def init(self, interval):
"""初始化""" """初始化"""
self.taskInterval = interval self.taskInterval = interval
self.DEBUG = debug self.DEBUG = debug
@ -567,8 +567,8 @@ class DataApi(object):
self.taskThread.start() self.taskThread.start()
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def stop(self): def exit(self):
"""停止""" """退出"""
self.active = False self.active = False
if self.taskThread.isAlive(): if self.taskThread.isAlive():

View File

@ -1,7 +1,13 @@
[ [
{ {
"name": "double ema", "name": "double ema",
"className": "DoubleEmaDemo", "className": "EmaDemoStrategy",
"vtSymbol": "IF1602" "vtSymbol": "IF1702"
},
{
"name": "atr rsi",
"className": "AtrRsiStrategy",
"vtSymbol": "IC1702"
} }
] ]

View File

@ -13,7 +13,7 @@ import multiprocessing
import pymongo import pymongo
from ctaBase import * from ctaBase import *
from ctaSetting import * from strategy import *
from vtConstant import * from vtConstant import *
from vtGateway import VtOrderData, VtTradeData from vtGateway import VtOrderData, VtTradeData
@ -881,6 +881,7 @@ def optimize(strategyClass, setting, targetName,
engine = BacktestingEngine() engine = BacktestingEngine()
engine.setBacktestingMode(mode) engine.setBacktestingMode(mode)
engine.setStartDate(startDate, initDays) engine.setStartDate(startDate, initDays)
engine.setEndDate(endDate)
engine.setSlippage(slippage) engine.setSlippage(slippage)
engine.setRate(rate) engine.setRate(rate)
engine.setSize(size) engine.setSize(size)

View File

@ -23,7 +23,7 @@ from collections import OrderedDict
from datetime import datetime, timedelta from datetime import datetime, timedelta
from ctaBase import * from ctaBase import *
from ctaSetting import STRATEGY_CLASS from strategy import STRATEGY_CLASS
from eventEngine import * from eventEngine import *
from vtConstant import * from vtConstant import *
from vtGateway import VtSubscribeReq, VtOrderReq, VtCancelOrderReq, VtLogData from vtGateway import VtSubscribeReq, VtOrderReq, VtCancelOrderReq, VtLogData

View File

@ -314,6 +314,55 @@ class HistoryDataEngine(object):
#----------------------------------------------------------------------
def downloadEquityDailyBarts(self, symbol):
"""
下载股票的日行情symbol是股票代码
"""
print u'开始下载%s日行情' %symbol
# 查询数据库中已有数据的最后日期
cl = self.dbClient[DAILY_DB_NAME][symbol]
cx = cl.find(sort=[('datetime', pymongo.DESCENDING)])
if cx.count():
last = cx[0]
else:
last = ''
# 开始下载数据
import tushare as ts
if last:
start = last['date'][:4]+'-'+last['date'][4:6]+'-'+last['date'][6:]
data = ts.get_k_data(symbol,start)
if not data.empty:
# 创建datetime索引
self.dbClient[DAILY_DB_NAME][symbol].ensure_index([('datetime', pymongo.ASCENDING)],
unique=True)
for index, d in data.iterrows():
bar = CtaBarData()
bar.vtSymbol = symbol
bar.symbol = symbol
try:
bar.open = d.get('open')
bar.high = d.get('high')
bar.low = d.get('low')
bar.close = d.get('close')
bar.date = d.get('date').replace('-', '')
bar.time = ''
bar.datetime = datetime.strptime(bar.date, '%Y%m%d')
bar.volume = d.get('volume')
except KeyError:
print d
flt = {'datetime': bar.datetime}
self.dbClient[DAILY_DB_NAME][symbol].update_one(flt, {'$set':bar.__dict__}, upsert=True)
print u'%s下载完成' %symbol
else:
print u'找不到合约%s' %symbol
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def loadMcCsv(fileName, dbName, symbol): def loadMcCsv(fileName, dbName, symbol):
"""将Multicharts导出的csv格式的历史数据插入到Mongo数据库中""" """将Multicharts导出的csv格式的历史数据插入到Mongo数据库中"""
@ -393,6 +442,7 @@ if __name__ == '__main__':
#e = HistoryDataEngine() #e = HistoryDataEngine()
#sleep(1) #sleep(1)
#e.downloadEquityDailyBar('000001') #e.downloadEquityDailyBar('000001')
#e.downloadEquityDailyBarts('000001')
# 这里将项目中包含的股指日内分钟线csv导入MongoDB作者电脑耗时大约3分钟 # 这里将项目中包含的股指日内分钟线csv导入MongoDB作者电脑耗时大约3分钟
loadMcCsv('IF0000_1min.csv', MINUTE_DB_NAME, 'IF0000') loadMcCsv('IF0000_1min.csv', MINUTE_DB_NAME, 'IF0000')

View File

@ -1,14 +0,0 @@
# encoding: UTF-8
'''
在本文件中引入所有希望在系统中使用的策略类
这个字典中保存了需要运行的策略的名称和策略类的映射关系
用户的策略类写好后先在该文件中引入并设置好名称然后
在CTA_setting.json中写入具体每个策略对象的类和合约设置
'''
from ctaDemo import DoubleEmaDemo
STRATEGY_CLASS = {}
STRATEGY_CLASS['DoubleEmaDemo'] = DoubleEmaDemo

View File

@ -0,0 +1,31 @@
# encoding: UTF-8
'''
动态载入所有的策略类
'''
import os
import importlib
# 用来保存策略类的字典
STRATEGY_CLASS = {}
# 获取目录路径
path = os.path.abspath(os.path.dirname(__file__))
# 遍历strategy目录下的文件
for root, subdirs, files in os.walk(path):
for name in files:
# 只有文件名中包含strategy且非.pyc的文件才是策略文件
if 'strategy' in name and '.pyc' not in name:
# 模块名称需要上前缀
moduleName = 'ctaAlgo.strategy.' + name.replace('.py', '')
# 使用importlib动态载入模块
module = importlib.import_module(moduleName)
# 遍历模块下的对象,只有名称中包含'Strategy'的才是策略类
for k in dir(module):
if 'Strategy' in k:
v = module.__getattribute__(k)
STRATEGY_CLASS[k] = v

View File

@ -17,9 +17,9 @@ from ctaTemplate import CtaTemplate
######################################################################## ########################################################################
class DoubleEmaDemo(CtaTemplate): class EmaDemoStrategy(CtaTemplate):
"""双指数均线策略Demo""" """双指数均线策略Demo"""
className = 'DoubleEmaDemo' className = 'EmaDemoStrategy'
author = u'用Python的交易员' author = u'用Python的交易员'
# 策略参数 # 策略参数
@ -59,7 +59,7 @@ class DoubleEmaDemo(CtaTemplate):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def __init__(self, ctaEngine, setting): def __init__(self, ctaEngine, setting):
"""Constructor""" """Constructor"""
super(DoubleEmaDemo, self).__init__(ctaEngine, setting) super(EmaDemoStrategy, self).__init__(ctaEngine, setting)
# 注意策略类中的可变对象属性通常是list和dict等在策略初始化时需要重新创建 # 注意策略类中的可变对象属性通常是list和dict等在策略初始化时需要重新创建
# 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险, # 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险,
@ -188,10 +188,10 @@ class DoubleEmaDemo(CtaTemplate):
######################################################################################## ########################################################################################
class OrderManagementDemo(CtaTemplate): class OrderManagementDemoStrategy(CtaTemplate):
"""基于tick级别细粒度撤单追单测试demo""" """基于tick级别细粒度撤单追单测试demo"""
className = 'OrderManagementDemo' className = 'OrderManagementDemoStrategy'
author = u'用Python的交易员' author = u'用Python的交易员'
# 策略参数 # 策略参数
@ -216,7 +216,7 @@ class OrderManagementDemo(CtaTemplate):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def __init__(self, ctaEngine, setting): def __init__(self, ctaEngine, setting):
"""Constructor""" """Constructor"""
super(OrderManagementDemo, self).__init__(ctaEngine, setting) super(OrderManagementDemoStrategy, self).__init__(ctaEngine, setting)
self.lastOrder = None self.lastOrder = None
self.orderType = '' self.orderType = ''

View File

@ -0,0 +1,6 @@
{
"accessKey": "3f669293-60e6dd7f-8e39c295-5aae5",
"secretKey": "7050aec8-43fc680d-06471837-57e38",
"interval": 0.5,
"market": "cny"
}

View File

View File

@ -0,0 +1,347 @@
# 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
import vnhuobi
from vtGateway import *
########################################################################
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)
#----------------------------------------------------------------------
def connect(self):
"""连接"""
# 载入json文件
fileName = self.gatewayName + '_connect.json'
path = os.path.abspath(os.path.dirname(__file__))
fileName = os.path.join(path, 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:
accessKey = str(setting['accessKey'])
secretKey = str(setting['secretKey'])
interval = setting['interval']
market = setting['market']
except KeyError:
log = VtLogData()
log.gatewayName = self.gatewayName
log.logContent = u'连接配置缺少字段,请检查'
self.onLog(log)
return
# 初始化接口
self.tradeApi.connect(accessKey, secretKey)
self.writeLog(u'交易接口初始化成功')
self.dataApi.connect(interval)
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):
"""发单"""
pass
#----------------------------------------------------------------------
def cancelOrder(self, cancelOrderReq):
"""撤单"""
pass
#----------------------------------------------------------------------
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.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 HuobiTradeApi(vnhuobi.TradeApi):
"""交易接口"""
#----------------------------------------------------------------------
def __init__(self, gateway):
"""Constructor"""
super(HuobiTradeApi, self).__init__()
self.gateway = gateway
self.gatewayName = gateway.gatewayName
#----------------------------------------------------------------------
def onError(self, error, 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, reqID):
"""查询账户回调"""
# 推送账户数据
account = VtAccountData()
account.gatewayName = self.gatewayName
account.balance = data['net_asset']
self.gateway.onAccount(account)
# 推送持仓数据
if self.market == 'cny':
posCny = VtPositionData()
posCny.gatewayName = self.gatewayName
posCny.position = data['available_cny_display']
posCny.frozen = data['frozen_cny_display']
self.gateway.onPosition(posCny)
posLtc = VtPositionData()
posLtc.gatewayName = self.gatewayName
posLtc.position = data['available_ltc_display']
posLtc.frozen = data['frozen_ltc_display']
self.gateway.onPosition(posLtc)
else:
posUsd = VtPositionData()
posUsd.gatewayName = self.gatewayName
posUsd.position = data['available_usd_display']
posUsd.frozen = data['frozen_usd_display']
self.gateway.onPosition(posUsd)
posBtc = VtPositionData()
posBtc.gatewayName = self.gatewayName
posBtc.position = data['available_btc_display']
posBtc.frozen = data['frozen_btc_display']
self.gateway.onPosition(posBtc)
#----------------------------------------------------------------------
def onGetOrders(self, data, reqID):
"""查询委托回调"""
for d in data:
order = VtOrderData()
order.gatewayName = self.gatewayName
order
#----------------------------------------------------------------------
def onOrderInfo(self, data, reqID):
"""委托详情回调"""
print data
#----------------------------------------------------------------------
def onBuy(self, data, reqID):
"""买入回调"""
print data
#----------------------------------------------------------------------
def onSell(self, data, reqID):
"""卖出回调"""
print data
#----------------------------------------------------------------------
def onBuyMarket(self, data, reqID):
"""市价买入回调"""
print data
#----------------------------------------------------------------------
def onSellMarket(self, data, reqID):
"""市价卖出回调"""
print data
#----------------------------------------------------------------------
def onCancelOrder(self, data, reqID):
"""撤单回调"""
print data
#----------------------------------------------------------------------
def onGetNewDealOrders(self, data, reqID):
"""查询最新成交回调"""
print data
#----------------------------------------------------------------------
def onGetOrderIdByTradeId(self, data, reqID):
"""通过成交编号查询委托编号回调"""
print data
#----------------------------------------------------------------------
def onWithdrawCoin(self, data, reqID):
"""提币回调"""
print data
#----------------------------------------------------------------------
def onCancelWithdrawCoin(self, data, reqID):
"""取消提币回调"""
print data
#----------------------------------------------------------------------
def onGetWithdrawCoinResult(self, data, reqID):
"""查询提币结果回调"""
print data
#----------------------------------------------------------------------
def onTransfer(self, data, reqID):
"""转账回调"""
print data
#----------------------------------------------------------------------
def onLoan(self, data, reqID):
"""申请杠杆回调"""
print data
#----------------------------------------------------------------------
def onRepayment(self, data, reqID):
"""归还杠杆回调"""
print data
#----------------------------------------------------------------------
def onLoanAvailable(self, data, reqID):
"""查询杠杆额度回调"""
print data
#----------------------------------------------------------------------
def onGetLoans(self, data, reqID):
"""查询杠杆列表"""
print data
#----------------------------------------------------------------------
def connect(self, accessKey, secretKey, market):
"""连接服务器"""
self.market = market
self.init(accessKey, secretKey)
########################################################################
class HuobiDataApi(vnhuobi.DataApi):
"""行情接口"""
#----------------------------------------------------------------------
def __init__(self, gateway):
"""Constructor"""
super(HuobiDataApi, self).__init__()
self.gateway = gateway
#----------------------------------------------------------------------
def onTick(self, data):
"""实时成交推送"""
print data
#----------------------------------------------------------------------
def onQuote(self, data):
"""实时报价推送"""
print data
#----------------------------------------------------------------------
def onDepth(self, data):
"""实时深度推送"""
print data
#----------------------------------------------------------------------
def connect(self, interval):
"""连接服务器"""
self.init(interval)

View File

@ -0,0 +1,650 @@
# 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_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, reqID)
# 请求成功
else:
if self.DEBUG:
print callback.__name__
callback(data, 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
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, reqID):
"""错误推送"""
print error, reqID
#----------------------------------------------------------------------
def onGetAccountInfo(self, data, reqID):
"""查询账户回调"""
print data
#----------------------------------------------------------------------
def onGetOrders(self, data, reqID):
"""查询委托回调"""
print data
#----------------------------------------------------------------------
def onOrderInfo(self, data, reqID):
"""委托详情回调"""
print data
#----------------------------------------------------------------------
def onBuy(self, data, reqID):
"""买入回调"""
print data
#----------------------------------------------------------------------
def onSell(self, data, reqID):
"""卖出回调"""
print data
#----------------------------------------------------------------------
def onBuyMarket(self, data, reqID):
"""市价买入回调"""
print data
#----------------------------------------------------------------------
def onSellMarket(self, data, reqID):
"""市价卖出回调"""
print data
#----------------------------------------------------------------------
def onCancelOrder(self, data, reqID):
"""撤单回调"""
print data
#----------------------------------------------------------------------
def onGetNewDealOrders(self, data, reqID):
"""查询最新成交回调"""
print data
#----------------------------------------------------------------------
def onGetOrderIdByTradeId(self, data, reqID):
"""通过成交编号查询委托编号回调"""
print data
#----------------------------------------------------------------------
def onWithdrawCoin(self, data, reqID):
"""提币回调"""
print data
#----------------------------------------------------------------------
def onCancelWithdrawCoin(self, data, reqID):
"""取消提币回调"""
print data
#----------------------------------------------------------------------
def onGetWithdrawCoinResult(self, data, reqID):
"""查询提币结果回调"""
print data
#----------------------------------------------------------------------
def onTransfer(self, data, reqID):
"""转账回调"""
print data
#----------------------------------------------------------------------
def onLoan(self, data, reqID):
"""申请杠杆回调"""
print data
#----------------------------------------------------------------------
def onRepayment(self, data, reqID):
"""归还杠杆回调"""
print data
#----------------------------------------------------------------------
def onLoanAvailable(self, data, reqID):
"""查询杠杆额度回调"""
print data
#----------------------------------------------------------------------
def onGetLoans(self, data, 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):
"""初始化"""
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

@ -4,8 +4,7 @@
vn.okcoin的gateway接入 vn.okcoin的gateway接入
注意 注意
1. 该接口尚处于测试阶段用于实盘请谨慎 1. 前仅支持USD和CNY的现货交易USD的期货合约交易暂不支持
2. 目前仅支持USD和CNY的现货交易USD的期货合约交易暂不支持
''' '''