1.每笔tick里面包含有每日开盘价的信息;
!!!!这个好!!!!
这一个月一直在做通达信的公式转换。。。把通达信的策略自动转成vnpy的策略在放在vnpy的回测引擎里跑。。。然后在输出K线图
真的要疯了!!!!!
另外感觉vnpy的回测引擎是做实盘用的吧。。。我理解的回测其实直接用数据库的bar生成一张df 在通过df进行各种计算就可以了,没必要一根一根的for循环吧。
下面是这段时间目前做出来的效果
funcat的包也看过,感觉写的好复杂,有些函数它还没有实现,有的算法又太慢了。。。
用Python的交易员 wrote:
还真没查过这个,不过手续费率可能是在外部系统设置的,不提供查询了。建议直接问光大期货的人吧
我是看的ctp接口说明,找到的这两个方法。
目前情况是两个查询接口运行的时候都没报错,回调函数只有保证金的有反应,手续费没有反应,
现在不清楚vnpy调用ctp原接口的时候,是封装了所有ctp的接口函数,还是只封装了一部分。
我想的是保证金可以查的话,那应该是100%封装了。如果是的话,那就应该是不提供查询了。
修改了ctpGate的代码,想实现保证金和手续费的查询:
def queryMarginRate(self):
"""查询保证金率"""
self.reqid += 1
req = {
"BrokerID": self.brokerid,
"InvestorID": self.userid,
"InstrumentID": 'rb1910',
"HedgeFlag": THOST_FTDC_HF_Speculation,
}
self.reqQryInstrumentMarginRate(req, self.reqid)
def onRspQryInstrumentMarginRate(self, data: dict, error: dict, reqid: int, last: bool):
"""保证金回调"""
for k, v in data.items():
print(k, ':', v)
def queryCommissionRate(self):
"""手续费查询"""
self.reqid += 1
req = {
"BrokerID": self.brokerid,
"InvestorID": self.userid,
"InstrumentID": 'rb1910',
# "HedgeFlag": THOST_FTDC_HF_Speculation,
# "ExchangeID":'SHFE'
}
self.reqQryInstrumentCommissionRate(req, self.reqid)
def onRspQryInstrumentCommissionRate(self, data: dict, error: dict, reqid: int, last: bool):
"""手续费回调"""
for k, v in data.items():
print(k, ':', v)
目前的情况是保证金可以查询出来,手续费不行。用得都是光大期货的ta和md address。
不知道是手续费的字典参数不对,还是说回调方法不太对。
求大神们指导!
from vnpy.event.eventEngine import EventEngine
from vnpy.trader.vtEngine import MainEngine
from vnpy.trader.vtObject import VtSubscribeReq,VtOrderReq
from vnpy.trader.vtConstant import *
from vnpy.trader.vtEvent import EVENT_TICK
from vnpy.trader.gateway import ctpGateway
def get_tick(event):
print event
tick = event.dict_['data']
print tick
for k,v in tick.__dict__.items():
print k,',',v
def main():
ee = EventEngine()
ee.register(EVENT_TICK,get_tick)
me = MainEngine(ee)
me.addGateway(ctpGateway)
me.connect('CTP')
req = VtSubscribeReq()
req.symbol = 'rb1910'
me.subscribe(req,'CTP')
order_req = VtOrderReq()
order_req.symbol = 'rb1910'
order_req.direction = DIRECTION_LONG
order_req.offset = OFFSET_OPEN
order_req.price = 3800
order_req.priceType = PRICETYPE_LIMITPRICE
order_req.volume = 1
me.sendOrder(order_req,'CTP')
if __name__ == '__main__':
main()
在家下了个2.01 还没能跑起来,就用1.9的写一个吧。
发单的可能有点不对,但基本上是这个套路了。
收tick,初始化引擎,注册事件(vnpy1.9自带的引擎dataEngine 和新的oms都有注册过),登录,订阅,等着就行了。
发单的话,就是做一个发单请求然后传给对应的函数就可以了。
实际用的时候退出的时候要做一个退出的方法,不然反复链接后会出问题(simnow的账号是这样的,实盘还没用过)
我在项目中也碰到了一个日志输出的问题,我是基于以前vnpy的日志引擎做了下修改,
@singleton #自己写的单例装饰器
class LogEngine:
"""日志引擎"""
# 日志级别
LEVEL_DEBUG = logging.DEBUG
LEVEL_INFO = logging.INFO
LEVEL_WARN = logging.WARN
LEVEL_ERROR = logging.ERROR
LEVEL_CRITICAL = logging.CRITICAL
def __init__(self, fileName=''):
"""
初始化日志引擎
:param fileName: 日志文件名,主要是测试用
"""
self.logger = logging.getLogger()
# 设置日志格式
# self.formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
self.formatter = logging.Formatter(
'%(asctime)s %(levelname)s: %(module)s.%(funcName)s %(lineno)d line %(message)s')
self.consoleHandler = None
self.fileHandler = None
# 设置日志级别
self.setLogLevel()
# 设置输出
if globalSetting['logConsole']:
self.addConsoleHandler()
if globalSetting['logFile']:
self.addFileHandler(fileName)
# 添加NullHandler防止无handler的错误输出
nullHandler = logging.NullHandler()
self.logger.addHandler(nullHandler)
self.initFunc()
# 日志级别函数映射
self.levelFunctionDict = {
self.LEVEL_DEBUG: self.debug,
self.LEVEL_INFO: self.info,
self.LEVEL_WARN: self.warn,
self.LEVEL_ERROR: self.error,
self.LEVEL_CRITICAL: self.critical,
}
def setLogLevel(self,level=globalSetting["logLevel"]):
"""设置日志级别"""
levelDict = {
"debug": self.LEVEL_DEBUG,
"info": self.LEVEL_INFO,
"warn": self.LEVEL_WARN,
"error": self.LEVEL_ERROR,
"critical": self.LEVEL_CRITICAL,
}
self.level = levelDict.get(level, self.LEVEL_CRITICAL)
# handler内输出级别可以单独设置,但是级别必须高于日志级别
self.logger.setLevel(self.level)
def addConsoleHandler(self):
if not globalSetting["logActive"]:
# 如果配置文件里没有开启日志记录,则不开启日志记录
return
"""添加终端输出"""
if not self.consoleHandler:
self.consoleHandler = logging.StreamHandler()
self.consoleHandler.setLevel(self.level)
self.consoleHandler.setFormatter(self.formatter)
self.logger.addHandler(self.consoleHandler)
def delConsoleHandler(self):
"""移除终端显示"""
if self.consoleHandler:
self.logger.removeHandler(self.consoleHandler)
self.consoleHandler = None
def addFileHandler(self, filename=''):
"""添加文件输出"""
if not globalSetting["logActive"]:
# 如果配置文件里没有开启日志记录,则不开启日志记录
return
if not self.fileHandler:
if not filename:
filename = 'ft_' + datetime.now().strftime('%Y%m%d') + '.log'
# filepath = getTempPath(filename)
filepath = getLogPath(filename)
self.fileHandler = logging.FileHandler(filepath)
self.fileHandler.setLevel(self.level)
self.fileHandler.setFormatter(self.formatter)
self.logger.addHandler(self.fileHandler)
def delFileHandler(self):
"""移除文件输出"""
if self.fileHandler:
self.logger.removeHandler(self.fileHandler)
self.fileHandler = None
def initFunc(self):
"""初始化各种记录方法"""
self.debug = self.logger.debug
self.info = self.logger.info
self.warn = self.logger.warning
self.error = self.logger.error
self.critical = self.logger.critical
self.exception = self.logger.exception
logger = LogEngine()
用的时候 就把它当一个模块使用 from *** import logger
logger.info(msg)
关于你的方法我做了下实验:
def func1():
pass
setattr(func1,'b',1)
print(func1.b)
def func2():
print(func2.b)
setattr(func2,'b',2)
func2()
def func3():
print(b)
setattr(func3,'b',3)
func3()
func 1和2 是可以的
func3 就报错
不知道你的函数 采用:
@Logger()
def my_func():
my_func.logger.info("0000")
这种方式行不行
最近关于vnpy的负面消息很多啊,什么要倒闭、被收购之类的,希望都是谣言,我是从16年开始就一直在用,vnpy对我很有帮助,真心希望这个项目能做下去