Colderleo's blog Colderleo's blog
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)

Colder Leo

热爱代码的打工人
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)
  • 金融量化
gaoliu
2021-10-06
目录

vnpy使用

# vnpy社区

  • https://www.vnpy.com/forum/
  • 注册账号,colderleo,g7
  • vnpy作者:陈晓优,QQ418225424

# 使用文档

https://www.vnpy.com/docs/cn/index.html

# 期权定价模型

隐含波动率 vnpy\app\option_master\pricing\black_76.py calculate_impv

# RQData

  • RQData通过vnpy试用

(418225424):最近很多人问RQData试用申请的问题,找米筐那边沟通了下,现在通过vn.py专用的RQDATA页面申请试用,不需要上传名片:![img](file:///C:\Users\gaoliu\AppData\Roaming\Tencent\QQTempSys\8LDO48C$8@[GWU0353$FOVS.png)https://www.ricequant.com/welcome/purchase?utm_source=vnpy 另外RQData也已经推出国内期权的数据服务,vn.py这边也已经全部完成对接支持,实盘可以和之前期货一样完全无缝使用

  • RQData替换为免费的天勤SDK

https://www.vnpy.com/forum/topic/2780-shi-yong-mian-fei-de-tian-qin-sdkshu-ju-ti-huan-fu-fei-de-rqdata

# https SSLError

https://www.cnblogs.com/hum0ro/p/9536033.html 只要安装一下几个requests依赖包就可以解决此问题。试了之后解决不了,应该是代理的原因。

pip install cryptography 
pip install pyOpenSSL
pip install certifi
1
2
3

# 各个平台的交易品种代码

vt_symbol,合约.交易所,如:IF1905.CFFEX

连上交易所后,在‘帮助-合约查询’中可以查到交易所的所有合约(区分大小写)。常用的:

  • XBTUSD.BITMEX
  • BTC-USDT.OKEX
  • btcusdt.HUOBI
  • au2004.SHFE,黄金-上海期货
  • IF2005.CFFEX,沪深300股指期货-中金
  • BTCUSD.BYBIT
  • BTCUSDT.BINANCE

# 源码

# cta_strategy 策略onticker

2.11每个策略只触发它自己对应的onticker。2.12版本加入了单策略多品种,还没看。

vnpy\app\cta_strategy\engine.py

    def process_tick_event(self, event: Event):
        """"""
        tick = event.data

        strategies = self.symbol_strategy_map[tick.vt_symbol]
        if not strategies:
            return

        self.check_stop_order(tick)

        for strategy in strategies:
            if strategy.inited:
                self.call_strategy_func(strategy, strategy.on_tick, tick)
1
2
3
4
5
6
7
8
9
10
11
12
13
# gateway的名字
# 通过下面的方式可以获取gateway的实例。
gateway_name = 'BINANCEF'
main_engine.get_gateway(gateway_name)

# 这里的gateway_name是在gateway初始化的时候定义的,例如 binancef_gateway.py中
class BinancefGateway(BaseGateway):
    def __init__(self, event_engine: EventEngine):
        super().__init__(event_engine, "BINANCEF")
1
2
3
4
5
6
7
8
# vt_symbol
# 通过vt_symbol获取gateway
	contract:ContractData = main_engine.get_contract(vt_symbol)
	if contract:
		gateway = main_engine.get_gateway(contract.gateway_name)

1
2
3
4
5
# gateway: _ensure_connection

vnpy\api\websocket\websocket_client.py

    def _ensure_connection(self):
        """"""
        triggered = False
        with self._ws_lock:
            if self._ws is None:
                self._ws = self._create_connection(
                    self.host,
                    sslopt={"cert_reqs": ssl.CERT_NONE},
                    http_proxy_host=self.proxy_host,
                    http_proxy_port=self.proxy_port,
                    header=self.header
                )
                triggered = True 
		# 上面的self._create_connection()函数如果失败会抛出异常,如果没有抛出异常则表示成功连接
        # 成功连接时执行下面的on_connected()
        if triggered:  
            self.on_connected()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 使用日志

各个模块的日志如果要打印出来,需要将其log type注册到event_engine中。

log_engine:LogEngine = main_engine.get_engine('log')
self.recorder_engine.event_engine.register(EVENT_RECORDER_LOG, \
	log_engine.process_log_event)
1
2
3

# bug 修改

# bybit加了一行类型转换

vnpy\gateway\bybit\bybit_gateway.py

class BybitRestApi(RestClient):
    def on_query_contract(self, data: dict, request: Request):
                # pricetick=d["price_filter"]["tick_size"],
                pricetick=float(d["price_filter"]["tick_size"]),
1
2
3
4
# spread添加精度保留小数

有的交易所会提示精度要求太高。

vnpy\app\spread_trading\template.py

class SpreadAlgoTemplate:
	def send_order(
        leg = self.spread.legs[vt_symbol]
        volume = round_to(volume, leg.min_volume)
        
        # add float precious round. some exchanges don't accept too high precious
        price = round(price, 6)
1
2
3
4
5
6
7
# data_recorder 写日志报错
    def write_log(self, msg: str):
        """"""
        log = LogData(msg=msg, gateway_name=APP_NAME)
        event = Event(type=EVENT_RECORDER_LOG, data=log)
        self.event_engine.put(event)

        # 原来的
        # event = Event(
        #     EVENT_RECORDER_LOG,
        #     msg
        # )
        # self.event_engine.put(event)
1
2
3
4
5
6
7
8
9
10
11
12

# 功能修改

# websocket加上额外的expcet类型

vnpy\api\websocket\websocket_client.py

E:\gaoliu\mycode\vntest\vnpy\api\websocket\websocket_client.py
    
class WebsocketClient:
    def _run(self):
        try:
            while self._active:
                try:
                    self._ensure_connection()
					...
                # ws is closed before recv function is called
                # For socket.error, see Issue #1608
                except (
                    websocket.WebSocketConnectionClosedException,
                    websocket.WebSocketBadStatusException,
                    socket.error,
                    websocket.WebSocketAddressException,  # 加上额外的expcet类型
                ):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# settings

vnpy\app\data_recorder\engine.py

    
    def load_setting(self):
    	# 原来的
    	setting = load_json(self.setting_filename)
        self.tick_recordings = setting.get("tick", {})
        self.bar_recordings = setting.get("bar", {})
	
    	# 修改
        self.tick_recordings = {}
        self.bar_recordings = {}
    
    
    def save_setting(self):
        # 修改为直接return

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 火币加上行情resubscribe

websocket重连时,重新订阅行情。后面用一个线程监控tick数据,如果3秒没有就resubscribe,这个不需要了。

class HuobiGateway(BaseGateway):
    def __init__(self, event_engine):
        self.subscribed: Dict[str, SubscribeRequest] = {}
            
    def resubscribe(self):
        for req in self.subscribed.values():
            self.subscribe(req)
            
    def subscribe(self, req: SubscribeRequest):
        self.subscribed[req.symbol] = req 
        
        
class HuobiTradeWebsocketApi(HuobiWebsocketApiBase):
    def on_login(self):
        self.gateway.write_log("交易Websocket API登录成功")
        self.gateway.resubscribe()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 日志加上gateway
vnpy\trader\object.py
class LogData(BaseData):
    def __post_init__(self):
        self.time = datetime.now()
        self.msg = f'{self.gateway_name}  {self.msg}'  # add
1
2
3
4
5
# 增加MainUi替换原来的MainWindow
  • 增加文件vnpy\trader\ui\main_ui.py
  • vnpy\trader\ui\widget.py 中增加 class GatewayWidget
编辑 (opens new window)
上次更新: 2022/04/24, 16:48:18
最近更新
01
通过模板实现结构体成员拷贝-按成员名匹配
05-07
02
c++17通过模板获取类成员的个数
05-01
03
avx-sse切换惩罚
04-30
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Colder Leo | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×