diff --git a/docs/csv_loader.md b/docs/csv_loader.md index 5b186a76..e1f7fc43 100644 --- a/docs/csv_loader.md +++ b/docs/csv_loader.md @@ -2,7 +2,7 @@ CSV载入模块在vnpy根目录下vnpy\app\csv_loader文件夹内,engine.py里面的CsvLoaderEngine类负责载入功能实现。 -## 1. 初始化 +## 初始化配置 初始化数据载入相关信息,可以分成3类: - CSV文件路径 @@ -26,7 +26,7 @@ CSV载入模块在vnpy根目录下vnpy\app\csv_loader文件夹内,engine.py里   -## 2. 数据载入 +## 数据载入 从文件路径中读取CSV文件,然后在每一次迭代中载入数据到数据库中。 ``` diff --git a/docs/cta_backtester.md b/docs/cta_backtester.md index d1c24b08..758ad0ce 100644 --- a/docs/cta_backtester.md +++ b/docs/cta_backtester.md @@ -1,14 +1,47 @@ # CTA回测模块 CTA回测模块是基于PyQt5和pyqtgraph的图形化回测工具。启动VN Trader后,在菜单栏中点击“功能-> CTA回测”即可进入该图形化回测界面,如下图。CTA回测模块主要实现3个功能:历史行情数据的下载、策略回测、参数优化。 + ![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_backtester/cta_backtester.png)   +## 加载启动 +进入图形化回测界面“CTA回测”后,会立刻完成初始化工作:初始化回测引擎、初始化RQData客户端。 -## 1.下载数据 -数据下载功能是基于RQData的get_price()函数实现的。 ``` -get_price(order_book_ids, start_date='2013-01-04', end_date='2014-01-04', frequency='1d', fields=None, adjust_type='pre', skip_suspended =False, market='cn') + def init_engine(self): + """""" + self.write_log("初始化CTA回测引擎") + + self.backtesting_engine = BacktestingEngine() + # Redirect log from backtesting engine outside. + self.backtesting_engine.output = self.write_log + + self.write_log("策略文件加载完成") + + self.init_rqdata() + + def init_rqdata(self): + """ + Init RQData client. + """ + result = rqdata_client.init() + if result: + self.write_log("RQData数据接口初始化成功") +``` + +  + + +## 下载数据 +在开始策略回测之前,必须保证数据库内有充足的历史数据。故vnpy提供了历史数据一键下载的功能。 +下载数据功能主要是基于RQData的get_price()函数实现的。 +``` +get_price( + order_book_ids, start_date='2013-01-04', end_date='2014-01-04', + frequency='1d', fields=None, adjust_type='pre', skip_suspended =False, + market='cn' +) ``` @@ -20,27 +53,339 @@ get_price(order_book_ids, start_date='2013-01-04', end_date='2014-01-04', freque 填写完字段信息后,点击下方“下载数据”按钮启动下载程序,下载成功如图所示。 + ![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_backtester/data_loader.png)   -## 2.加载启动 +## 策略回测 +下载完历史数据后,需要配置以下字段:交易策略、手续费率、交易滑点、合约乘数、价格跳动、回测资金。 +这些字段主要对应BacktesterEngine类的run_backtesting函数。 +``` +def run_backtesting( + self, class_name: str, vt_symbol: str, interval: str, start: datetime, + end: datetime, rate: float, slippage: float, size: int, pricetick: float, + capital: int, setting: dict +): +``` + +点击下方的“开始回测”按钮可以开始回测: +首先会弹出如图所示的参数配置窗口,用于调整策略参数。该设置对应的是run_backtesting()函数的setting字典。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_backtester/parameter_setting.png) + + + +点击“确认”按钮后开始运行回测,同时日志界面会输出相关信息,如图。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_backtester/backtesting_log.png) + +回测完成后会显示统计数字图表。 + +  + +### 统计数据 +用于显示回测完成后的相关统计数值, 如结束资金、总收益率、夏普比率、收益回撤比。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_backtester/show_result.png) + +  + +### 图表分析 +以下四个图分别是代表账号净值、净值回撤、每日盈亏、盈亏分布。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_backtester/show_result_chat.png) + + +  + +## 参数优化 +vnpy提供2种参数优化的解决方案:穷举算法、遗传算法 + + +  + +### 穷举算法 + +穷举算法原理: +- 输入需要优化的参数名、优化区间、优化步进,以及优化目标。 +``` + def add_parameter( + self, name: str, start: float, end: float = None, step: float = None + ): + """""" + if not end and not step: + self.params[name] = [start] + return + + if start >= end: + print("参数优化起始点必须小于终止点") + return + + if step <= 0: + print("参数优化步进必须大于0") + return + + value = start + value_list = [] + + while value <= end: + value_list.append(value) + value += step + + self.params[name] = value_list + + def set_target(self, target_name: str): + """""" + self.target_name = target_name +``` + +  + + +- 形成全局参数组合, 数据结构为[{key: value, key: value}, {key: value, key: value}]。 +``` + def generate_setting(self): + """""" + keys = self.params.keys() + values = self.params.values() + products = list(product(*values)) + + settings = [] + for p in products: + setting = dict(zip(keys, p)) + settings.append(setting) + + return settings +``` +  + + +- 遍历全局中的每一个参数组合:遍历的过程即运行一次策略回测,并且返回优化目标数值;然后根据目标数值排序,输出优化结果。 +``` + def run_optimization(self, optimization_setting: OptimizationSetting, output=True): + """""" + # Get optimization setting and target + settings = optimization_setting.generate_setting() + target_name = optimization_setting.target_name + + if not settings: + self.output("优化参数组合为空,请检查") + return + + if not target_name: + self.output("优化目标未设置,请检查") + return + + # Use multiprocessing pool for running backtesting with different setting + pool = multiprocessing.Pool(multiprocessing.cpu_count()) + + results = [] + for setting in settings: + result = (pool.apply_async(optimize, ( + target_name, + self.strategy_class, + setting, + self.vt_symbol, + self.interval, + self.start, + self.rate, + self.slippage, + self.size, + self.pricetick, + self.capital, + self.end, + self.mode + ))) + results.append(result) + + pool.close() + pool.join() + + # Sort results and output + result_values = [result.get() for result in results] + result_values.sort(reverse=True, key=lambda result: result[1]) + + if output: + for value in result_values: + msg = f"参数:{value[0]}, 目标:{value[1]}" + self.output(msg) + + return result_values +``` -## 3.策略回测 +注意:可以使用multiprocessing库来创建多进程实现并行优化。例如:若用户计算机是2核,优化时间为原来1/2;若计算机是10核,优化时间为原来1/10。 -### 3.1统计数据 +  -### 3.2图表分析 +穷举算法操作: + +- 点击“参数优化”按钮,会弹出“优化参数配置”窗口,用于设置优化目标(如最大化夏普比率、最大化收益回撤比)和设置需要优化的参数以及优化区间,如图。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_backtester/optimize_setting.png) + +- 设置好需要优化的参数后,点击“优化参数配置”窗口下方的“确认”按钮开始进行调用CPU多核进行多进程并行优化,同时日志会输出相关信息。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_backtester/optimize_log.png) + +- 点击“优化结果”按钮可以看出优化结果,如图的参数组合是基于目标数值(夏普比率)由高到低的顺序排列的。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_backtester/optimize_result.png) + + +  + +### 遗传算法 + +遗传算法原理: + +- 输入需要优化的参数名、优化区间、优化步进,以及优化目标; + +- 形成全局参数组合,该组合的数据结构是列表内镶嵌元组,即\[[(key, value), (key, value)] , [(key, value), (key,value)]],与穷举算法的全局参数组合的数据结构不同。这样做的目的是有利于参数间进行交叉互换和变异。 +``` + def generate_setting_ga(self): + """""" + settings_ga = [] + settings = self.generate_setting() + for d in settings: + param = [tuple(i) for i in d.items()] + settings_ga.append(param) + return settings_ga +``` + +  + + +- 形成个体:调用random()函数随机从全局参数组合中获取参数。 +``` + def generate_parameter(): + """""" + return random.choice(settings) +``` + +  + + +- 定义个体变异规则: 即发生变异时,旧的个体完全被新的个体替代。 +``` + def mutate_individual(individual, indpb): + """""" + size = len(individual) + paramlist = generate_parameter() + for i in range(size): + if random.random() < indpb: + individual[i] = paramlist[i] + return individual, +``` + +  + + +- 定义评估函数:入参的是个体,即[(key, value), (key, value)]形式的参数组合,然后通过dict()转化成setting字典,然后运行回测,输出目标优化数值,如夏普比率、收益回撤比。(注意,修饰器@lru_cache作用是缓存计算结果,避免遇到相同的输入重复计算,大大降低运行遗传算法的时间) +``` +@lru_cache(maxsize=1000000) +def _ga_optimize(parameter_values: tuple): + """""" + setting = dict(parameter_values) + + result = optimize( + ga_target_name, + ga_strategy_class, + setting, + ga_vt_symbol, + ga_interval, + ga_start, + ga_rate, + ga_slippage, + ga_size, + ga_pricetick, + ga_capital, + ga_end, + ga_mode + ) + return (result[1],) + + +def ga_optimize(parameter_values: list): + """""" + return _ga_optimize(tuple(parameter_values)) +``` + +  + +- 运行遗传算法:调用deap库的算法引擎来运行遗传算法,其具体流程如下。 +1)先定义优化方向,如夏普比率最大化; +2)然后随机从全局参数组合获取个体,并形成族群; +3)对族群内所有个体进行评估(即运行回测),并且剔除表现不好个体; +4)剩下的个体会进行交叉或者变异,通过评估和筛选后形成新的族群;(到此为止是完整的一次种群迭代过程); +5)多次迭代后,种群内差异性减少,整体适应性提高,最终输出建议结果。该结果为帕累托解集,可以是1个或者多个参数组合。 + +注意:由于用到了@lru_cache, 迭代中后期的速度回提高非常多,因为很多重复的输入都避免了再次的回测,直接在内存中查询并且返回计算结果。 +``` +from deap import creator, base, tools, algorithms +creator.create("FitnessMax", base.Fitness, weights=(1.0,)) +creator.create("Individual", list, fitness=creator.FitnessMax) + ...... + # Set up genetic algorithem + toolbox = base.Toolbox() + toolbox.register("individual", tools.initIterate, creator.Individual, generate_parameter) + toolbox.register("population", tools.initRepeat, list, toolbox.individual) + toolbox.register("mate", tools.cxTwoPoint) + toolbox.register("mutate", mutate_individual, indpb=1) + toolbox.register("evaluate", ga_optimize) + toolbox.register("select", tools.selNSGA2) + + total_size = len(settings) + pop_size = population_size # number of individuals in each generation + lambda_ = pop_size # number of children to produce at each generation + mu = int(pop_size * 0.8) # number of individuals to select for the next generation + + cxpb = 0.95 # probability that an offspring is produced by crossover + mutpb = 1 - cxpb # probability that an offspring is produced by mutation + ngen = ngen_size # number of generation + + pop = toolbox.population(pop_size) + hof = tools.ParetoFront() # end result of pareto front + + stats = tools.Statistics(lambda ind: ind.fitness.values) + np.set_printoptions(suppress=True) + stats.register("mean", np.mean, axis=0) + stats.register("std", np.std, axis=0) + stats.register("min", np.min, axis=0) + stats.register("max", np.max, axis=0) + + algorithms.eaMuPlusLambda( + pop, + toolbox, + mu, + lambda_, + cxpb, + mutpb, + ngen, + stats, + halloffame=hof + ) + + # Return result list + results = [] + + for parameter_values in hof: + setting = dict(parameter_values) + target_value = ga_optimize(parameter_values)[0] + results.append((setting, target_value, {})) + + return results +``` + -## 4.参数优化 diff --git a/docs/cta_strategy.md b/docs/cta_strategy.md index 4c697367..1ac9d3e6 100644 --- a/docs/cta_strategy.md +++ b/docs/cta_strategy.md @@ -1,7 +1,7 @@ # CTA策略模块 -## 1. 模块构成 +## 模块构成 CTA策略模块主要由7部分构成,如下图: @@ -14,21 +14,163 @@ CTA策略模块主要由7部分构成,如下图: - engine:定义了CTA策略实盘引擎,其中包括:RQData客户端初始化和数据载入、策略的初始化和启动、推送Tick订阅行情到策略中、挂撤单操作、策略的停止和移除等。 - ui:基于PyQt5的GUI图形应用。 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_strategy/seix_elementos.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_strategy/seix_elementos.png "enter image title here")   -## 2. 历史数据 +## 历史数据 + +### 回测历史数据 +回测所需要的历史数据可通过运行getdata.py文件进行下载。该文件处于根目录下tests\backtesting文件夹内。 +下载历史数据的原理是调用RQData的get_price()函数把数据下载到内存里面;再通过generate_bar_from_row()函数,以固定格式把数据从内存载入到硬盘数据库中。 + +下面介绍具体流程: + +- 填写RQData的账号密码,初始化RQData +``` +import rqdatac as rq + + +USERNAME = "" +PASSWORD = "" +FIELDS = ["open", "high", "low", "close", "volume"] + +rq.init(USERNAME, PASSWORD, ("rqdatad-pro.ricequant.com", 16011)) +``` + +  + +- 定义数据插入格式。需要插入的数据包括:合约代码、交易所、K线周期、开盘价、最高价、最低价、收盘价、成交量、数据库名称、vt_symbol(注意:K线周期可以是"1m"、"1h"、"d"、"w"。to_pydatetime()用于时间转换成datetime格式) +``` +def generate_bar_from_row(row, symbol, exchange): + """""" + bar = DbBarData() + + bar.symbol = symbol + bar.exchange = exchange + bar.interval = "1m" + bar.open_price = row["open"] + bar.high_price = row["high"] + bar.low_price = row["low"] + bar.close_price = row["close"] + bar.volume = row["volume"] + bar.datetime = row.name.to_pydatetime() + bar.gateway_name = "DB" + bar.vt_symbol = f"{symbol}.{exchange}" + + return bar +``` + +  + +- 定义数据下载函数。主要调用RQData的get_price()获取指定合约或合约列表的历史数据(包含起止日期,日线或分钟线)。目前仅支持中国市场的股票、期货、ETF和上金所现货的行情数据,如黄金、铂金和白银产品。(注意:起始日期默认是2013-01-04,结束日期默认是2014-01-04) + +``` +def download_minute_bar(vt_symbol): + """下载某一合约的分钟线数据""" + print(f"开始下载合约数据{vt_symbol}") + symbol, exchange = vt_symbol.split(".") + + start = time() + + df = rq.get_price(symbol, start_date="2018-01-01", end_date="2019-01-01", frequency="1m", fields=FIELDS) + + with DB.atomic(): + for ix, row in df.iterrows(): + print(row.name) + bar = generate_bar_from_row(row, symbol, exchange) + DbBarData.replace(bar.__data__).execute() + + end = time() + cost = (end - start) * 1000 + + print( + "合约%s的分钟K线数据下载完成%s - %s,耗时%s毫秒" + % (symbol, df.index[0], df.index[-1], cost) + ) + +```   -## 3. 策略开发 + +### 实盘历史数据 +在实盘中,RQData通过实时载入数据进行策略的初始化。该功能主要在CTA实盘引擎engine.py内实现。 +下面介绍具体流程: +- 配置json文件:在用户目录下.vntrader文件夹找到vt_setting.json,输入RQData的账号和密码,如图。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_strategy/RQData_setting.png "enter image title here") + +- 初始化RQData客户端:从vt_setting.json中读取RQData的账户、密码到rq_client.init()函数进行初始化 + +``` + def init_rqdata(self): + """ + Init RQData client. + """ + username = SETTINGS["rqdata.username"] + password = SETTINGS["rqdata.password"] + if not username or not password: + return + + import rqdatac + + self.rq_client = rqdatac + self.rq_client.init(username, password, + ('rqdatad-pro.ricequant.com', 16011)) +``` + + +- RQData载入实盘数据:输入vt_symbol后,首先会转换成符合RQData格式的rq_symbol,通过get_price()函数下载数据,并且插入到数据库中。 + +``` + def query_bar_from_rq( + self, vt_symbol: str, interval: Interval, start: datetime, end: datetime + ): + """ + Query bar data from RQData. + """ + symbol, exchange_str = vt_symbol.split(".") + rq_symbol = to_rq_symbol(vt_symbol) + if rq_symbol not in self.rq_symbols: + return None + + end += timedelta(1) # For querying night trading period data + + df = self.rq_client.get_price( + rq_symbol, + frequency=interval.value, + fields=["open", "high", "low", "close", "volume"], + start_date=start, + end_date=end + ) + + data = [] + for ix, row in df.iterrows(): + bar = BarData( + symbol=symbol, + exchange=Exchange(exchange_str), + interval=interval, + datetime=row.name.to_pydatetime(), + open_price=row["open"], + high_price=row["high"], + low_price=row["low"], + close_price=row["close"], + volume=row["volume"], + gateway_name="RQ" + ) + data.append(bar) +``` + +  + +## 策略开发 CTA策略模板提供完整的信号生成和委托管理功能,用户可以基于该模板自行开发策略。新策略可以放在根目录下vnpy\app\cta_strategy\strategies文件夹内,也可以放在用户运行的文件内(VN Station模式)。注意:策略文件命名是以下划线模式,如boll_channel_strategy.py;而策略类命名采用的是驼峰式,如BollChannelStrategy。 下面通过BollChannelStrategy策略示例,来展示策略开发的具体步骤: -### 3.1 参数设置 +### 参数设置 定义策略参数并且初始化策略变量。策略参数为策略类的公有属性,用户可以通过创建新的实例来调用或者改变策略参数。 @@ -54,7 +196,7 @@ CTA策略模板提供完整的信号生成和委托管理功能,用户可以 short_stop = 0 ``` -### 3.2 类的初始化 +### 类的初始化 初始化分3步: - 通过super( )的方法继承CTA策略模板,在__init__( )函数传入CTA引擎、策略名称、vt_symbol、参数设置。 - 调用K线生成模块:通过时间切片来把Tick数据合成1分钟K线数据,然后更大的时间周期数据,如15分钟K线。 @@ -71,7 +213,7 @@ CTA策略模板提供完整的信号生成和委托管理功能,用户可以 self.am = ArrayManager() ``` -### 3.3 策略的初始化、启动、停止 +### 策略的初始化、启动、停止 通过“CTA策略”组件的相关功能按钮实现。 注意:函数load_bar(10),代表策略初始化需要载入10个交易日的历史数据。该历史数据可以是Tick数据,也可以是K线数据。 @@ -96,7 +238,7 @@ CTA策略模板提供完整的信号生成和委托管理功能,用户可以 """ self.write_log("策略停止") ``` -### 3.4 Tick数据回报 +### Tick数据回报 策略订阅某品种合约行情,交易所会推送Tick数据到该策略上。 由于BollChannelStrategy是基于15分钟K线来生成交易信号的,故收到Tick数据后,需要用到K线生成模块里面的update_tick函数,通过时间切片的方法,聚合成1分钟K线数据,并且推送到on_bar函数。 @@ -109,7 +251,7 @@ CTA策略模板提供完整的信号生成和委托管理功能,用户可以 self.bg.update_tick(tick) ``` -### 3.5 K线数据回报 +### K线数据回报 收到推送过来的1分钟K线数据后,通过K线生成模块里面的update_bar函数,以分钟切片的方法,合成15分钟K线数据,并且推送到on_15min_bar函数。 ``` @@ -120,7 +262,7 @@ CTA策略模板提供完整的信号生成和委托管理功能,用户可以 self.bg.update_bar(bar) ``` -### 3.6 15分钟K线数据回报 +### 15分钟K线数据回报 负责CTA信号的生成,由3部分组成: - 清空未成交委托:为了防止之前下的单子在上一个15分钟没有成交,但是下一个15分钟可能已经调整了价格,就用cancel_all()方法立刻撤销之前未成交的所有委托,保证策略在当前这15分钟开始时的整个状态是清晰和唯一的。 @@ -169,7 +311,7 @@ CTA策略模板提供完整的信号生成和委托管理功能,用户可以 self.put_event() ``` -### 3.7 委托回报、成交回报、停止单回报 +### 委托回报、成交回报、停止单回报 在策略中可以直接pass,其具体逻辑应用交给回测/实盘引擎负责。 ``` @@ -197,10 +339,10 @@ CTA策略模板提供完整的信号生成和委托管理功能,用户可以   -## 4. 回测研究 +## 回测研究 backtesting.py定义了回测引擎,下面主要介绍相关功能函数,以及回测引擎应用示例: -### 4.1 加载策略 +### 加载策略 把CTA策略逻辑,对应合约品种,以及参数设置(可在策略文件外修改)载入到回测引擎中。 ``` @@ -213,7 +355,7 @@ backtesting.py定义了回测引擎,下面主要介绍相关功能函数,以 ```   -### 4.2 载入历史数据 +### 载入历史数据 负责载入对应品种的历史数据,大概有4个步骤: - 根据数据类型不同,分成K线模式和Tick模式; @@ -254,7 +396,7 @@ backtesting.py定义了回测引擎,下面主要介绍相关功能函数,以 ```   -### 4.3 撮合成交 +### 撮合成交 载入CTA策略以及相关历史数据后,策略会根据最新的数据来计算相关指标。若符合条件会生成交易信号,发出具体委托(buy/sell/short/cover),并且在下一根K线成交。 @@ -349,7 +491,7 @@ backtesting.py定义了回测引擎,下面主要介绍相关功能函数,以   -### 4.4 计算策略盈亏情况 +### 计算策略盈亏情况 基于收盘价、当日持仓量、合约规模、滑点、手续费率等计算总盈亏与净盈亏,并且其计算结果以DataFrame格式输出,完成基于逐日盯市盈亏统计。 @@ -404,7 +546,7 @@ backtesting.py定义了回测引擎,下面主要介绍相关功能函数,以 -### 4.5 计算策略统计指标 +### 计算策略统计指标 calculate_statistics函数是基于逐日盯市盈亏情况(DateFrame格式)来计算衍生指标,如最大回撤、年化收益、盈亏比、夏普比率等。 ``` @@ -456,7 +598,7 @@ calculate_statistics函数是基于逐日盯市盈亏情况(DateFrame格式) ```   -### 4.6 统计指标绘图 +### 统计指标绘图 通过matplotlib绘制4幅图: - 资金曲线图 - 资金回撤图 @@ -495,7 +637,7 @@ calculate_statistics函数是基于逐日盯市盈亏情况(DateFrame格式)   -### 4.7 回测引擎使用示例 +### 回测引擎使用示例 - 导入回测引擎和CTA策略 - 设置回测相关参数,如:品种、K线周期、回测开始和结束日期、手续费、滑点、合约规模、起始资金 @@ -533,10 +675,10 @@ engine.show_chart()   -## 5. 参数优化 +## 参数优化 参数优化模块主要由3部分构成: -### 5.1 参数设置 +### 参数设置 - 设置参数优化区间:如boll_window设置起始值为18,终止值为24,步进为2,这样就得到了[18, 20, 22, 24] 这4个待优化的参数了。 - 设置优化目标字段:如夏普比率、盈亏比、总收益率等。 @@ -598,7 +740,7 @@ class OptimizationSetting:   -### 5.2 参数对组合回测 +### 参数对组合回测 多进程优化时,每个进程都会运行optimize函数,输出参数对组合以及目标优化字段的结果。其步骤如下: - 调用回测引擎 @@ -652,7 +794,7 @@ def optimize(   -### 5.3 多进程优化 +### 多进程优化 - 根据CPU的核数来创建进程:若CPU为4核,则创建4个进程 - 在每个进程都调用apply_async( )的方法运行参数对组合回测,其回测结果添加到results中 (apply_async是异步非阻塞的,即不用等待当前进程执行完毕,随时根据系统调度来进行进程切换。) @@ -697,5 +839,215 @@ def optimize(   -## 6. 实盘运行 +## 实盘运行 +在实盘环境,用户可以基于编写好的CTA策略来创建新的实例,一键初始化、启动、停止策略。 + +### 创建策略实例 +用户可以基于编写好的CTA策略来创建新的实例,策略实例的好处在于同一个策略可以同时去运行多个品种合约,并且每个实例的参数可以是不同的。 +在创建实例的时候需要填写如图的实例名称、合约品种、参数设置。注意:实例名称不能重名;合约名称是vt_symbol的格式,如IF1905.CFFEX。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/cta_strategy/add_strategy.png) + +创建策略流程如下: +- 检查策略实例重名 +- 添加策略配置信息(strategy_name, vt_symbol, setting)到strategies字典上 +- 添加该策略要订阅行情的合约信息到symbol_strategy_map字典中; +- 把策略配置信息保存到json文件内; +- 在图形化界面更新状态信息。 + +``` + def add_strategy( + self, class_name: str, strategy_name: str, vt_symbol: str, setting: dict + ): + """ + Add a new strategy. + """ + if strategy_name in self.strategies: + self.write_log(f"创建策略失败,存在重名{strategy_name}") + return + + strategy_class = self.classes[class_name] + + strategy = strategy_class(self, strategy_name, vt_symbol, setting) + self.strategies[strategy_name] = strategy + + # Add vt_symbol to strategy map. + strategies = self.symbol_strategy_map[vt_symbol] + strategies.append(strategy) + + # Update to setting file. + self.update_strategy_setting(strategy_name, setting) + + self.put_strategy_event(strategy) +``` + +  + +### 初始化策略 +- 调用策略类的on_init()回调函数,并且载入历史数据; +- 恢复上次退出之前的策略状态; +- 调用接口的subcribe()函数订阅指定行情信息; +- 策略初始化状态变成True,并且更新到日志上。 + +``` + def _init_strategy(self): + """ + Init strategies in queue. + """ + while not self.init_queue.empty(): + strategy_name = self.init_queue.get() + strategy = self.strategies[strategy_name] + + if strategy.inited: + self.write_log(f"{strategy_name}已经完成初始化,禁止重复操作") + continue + + self.write_log(f"{strategy_name}开始执行初始化") + + # Call on_init function of strategy + self.call_strategy_func(strategy, strategy.on_init) + + # Restore strategy data(variables) + data = self.strategy_data.get(strategy_name, None) + if data: + for name in strategy.variables: + value = data.get(name, None) + if value: + setattr(strategy, name, value) + + # Subscribe market data + contract = self.main_engine.get_contract(strategy.vt_symbol) + if contract: + req = SubscribeRequest( + symbol=contract.symbol, exchange=contract.exchange) + self.main_engine.subscribe(req, contract.gateway_name) + else: + self.write_log(f"行情订阅失败,找不到合约{strategy.vt_symbol}", strategy) + + # Put event to update init completed status. + strategy.inited = True + self.put_strategy_event(strategy) + self.write_log(f"{strategy_name}初始化完成") + + self.init_thread = None +``` + +  + +### 启动策略 +- 检查策略初始化状态; +- 检查策略启动状态,避免重复启动; +- 调用策略类的on_start()函数启动策略; +- 策略启动状态变成True,并且更新到图形化界面上。 + +``` + def start_strategy(self, strategy_name: str): + """ + Start a strategy. + """ + strategy = self.strategies[strategy_name] + if not strategy.inited: + self.write_log(f"策略{strategy.strategy_name}启动失败,请先初始化") + return + + if strategy.trading: + self.write_log(f"{strategy_name}已经启动,请勿重复操作") + return + + self.call_strategy_func(strategy, strategy.on_start) + strategy.trading = True + + self.put_strategy_event(strategy) +``` + +  + +### 停止策略 +- 检查策略启动状态; +- 调用策略类的on_stop()函数停止策略; +- 更新策略启动状态为False; +- 对所有为成交的委托(市价单/限价单/本地停止单)进行撤单操作; +- 在图形化界面更新策略状态。 + +``` + def stop_strategy(self, strategy_name: str): + """ + Stop a strategy. + """ + strategy = self.strategies[strategy_name] + if not strategy.trading: + return + + # Call on_stop function of the strategy + self.call_strategy_func(strategy, strategy.on_stop) + + # Change trading status of strategy to False + strategy.trading = False + + # Cancel all orders of the strategy + self.cancel_all(strategy) + + # Update GUI + self.put_strategy_event(strategy) +``` + +  + +### 编辑策略 +- 重新配置策略参数字典setting; +- 更新参数字典到策略中; +- 在图像化界面更新策略状态。 + +``` + def edit_strategy(self, strategy_name: str, setting: dict): + """ + Edit parameters of a strategy. + """ + strategy = self.strategies[strategy_name] + strategy.update_setting(setting) + + self.update_strategy_setting(strategy_name, setting) + self.put_strategy_event(strategy) +``` + +  + +### 移除策略 +- 检查策略状态,只有停止策略后从可以移除策略; +- 从json文件移除策略配置信息(strategy_name, vt_symbol, setting); +- 从symbol_strategy_map字典中移除该策略订阅的合约信息; +- 从strategy_orderid_map字典移除活动委托记录; +- 从strategies字典移除该策略的相关配置信息。 + +``` + def remove_strategy(self, strategy_name: str): + """ + Remove a strategy. + """ + strategy = self.strategies[strategy_name] + if strategy.trading: + self.write_log(f"策略{strategy.strategy_name}移除失败,请先停止") + return + + # Remove setting + self.remove_strategy_setting(strategy_name) + + # Remove from symbol strategy map + strategies = self.symbol_strategy_map[strategy.vt_symbol] + strategies.remove(strategy) + + # Remove from active orderid map + if strategy_name in self.strategy_orderid_map: + vt_orderids = self.strategy_orderid_map.pop(strategy_name) + + # Remove vt_orderid strategy map + for vt_orderid in vt_orderids: + if vt_orderid in self.orderid_strategy_map: + self.orderid_strategy_map.pop(vt_orderid) + + # Remove from strategies + self.strategies.pop(strategy_name) + + return True +``` diff --git a/docs/database.md b/docs/database.md new file mode 100644 index 00000000..282e0e20 --- /dev/null +++ b/docs/database.md @@ -0,0 +1,85 @@ +# 数据库配置 + +VN Trader目前支持以下四种数据库: + + * [SQLite](#sqlite)(默认) + * [MySQL](#sqlmysqlpostgresql) + * [PostgreSQL](#sqlmysqlpostgresql) + * [MongoDB](#mongodb) + +如果需要配置数据库,请点击配置。然后按照各个数据库所需的字段填入相对应的值即可。 + +--- +## SQLite +需要填写以下字段: + + | 字段名 | 值 | + --------- |---- | + database.driver | sqlite | + database.database | 数据库文件(相对于trader目录) | + +SQLite的例子: + + | 字段名 | 值 | + --------- |---- | + database.driver | sqlite | + database.database | database.db | + + +--- +## SQL(MySQL,PostgreSQL) + +需要填写以下字段: + + | 字段名 | 值 | + --------- |---- | + database.driver | "mysql"或"postgresql" | + database.host | 地址 | + database.port | 端口 | + database.database | 数据库名 | + database.user | 用户名 | + database.password | 密码 | + +MySQL的例子: + + | 字段名 | 值 | + --------- |---- | + database.driver | mysql | + database.host | localhost | + database.port | 3306 | + database.database | vnpy | + database.user | root | + database.password | .... | + +> vnpy不会主动为关系型数据库创建数据库,所以请确保你所填的database.database字段对应的数据库已经创建好了 +> 若未创建数据库,请手动连上数据库并运行该命令:```create database <你填的database.database>;``` + +--- +## MongoDB + +需要填写以下字段: + + | 字段名 | 值 | 是否必填| + --------- |---- | ---| + database.driver | "mysql"或"postgresql" | 必填 | + database.host | 地址| 必填 | + database.port | 端口| 必填 | + database.database | 数据库名| 必填 | + database.user | 用户名| 可选 | + database.password | 密码| 可选 | + database.authentication_source | [创建用户所用的数据库][AuthSource]| 可选 | + +MongoDB的带认证例子: + + | 字段名 | 值 | + --------- |---- | + database.driver | mongodb | + database.host | localhost | + database.port | 27017 | + database.database | vnpy | + database.user | root | + database.password | .... | + database.authentication_source | vnpy | + + +[AuthSource]: https://docs.mongodb.com/manual/core/security-users/#user-authentication-database \ No newline at end of file diff --git a/docs/datarecoder.md b/docs/datarecoder.md new file mode 100644 index 00000000..f417bd00 --- /dev/null +++ b/docs/datarecoder.md @@ -0,0 +1,265 @@ +# 行情记录 +行情记录模块用于实时行情的收录: +- 连接上接口后并且启动行情记录模块; +- 通过本地合约(vt_symbol)添加记录任务; +- 后台会自动调用行情API接口的suscribe()函数自动订阅行情; +- 行情信息通过database_manager模块的save_bar_data()函数/save_tick_data()函数载入到数据库中。 + +注意:目前vnpy支持的数据库为SQLite/ MySQL/ PostgreSQL/ MongoDB。若用户使用MongoDB,则行情记录数据直接载入到MongoDB中。 + +  + + + +## 加载启动 +进入VN Trader后,首先登陆接口,如连接CTP;然后在菜单栏中点击“功能”->"行情记录“后,会弹出行情记录窗口,如图。 +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/data_recoder/datarecoder.png) + +此时行情记录模块的启动状态为True,会启动while循环,可以添加任务实现实时行情记录。 +``` + def start(self): + """""" + self.active = True + self.thread.start() + + def run(self): + """""" + while self.active: + try: + task = self.queue.get(timeout=1) + task_type, data = task + + if task_type == "tick": + database_manager.save_tick_data([data]) + elif task_type == "bar": + database_manager.save_bar_data([data]) + + except Empty: + continue +``` + +  + +## 开始收录 + +- 在“本地代码”选择输入需要订阅的行情,如rb1905.SHFE; +- 然后点击后边“K线记录”或者“Tick记录”中的“添加”选项,会把记录特定品种任务添加到data_recorder_setting.json上,并且显示到“K线记录列表”或者“Tick记录列表”中,如图。 +- 通过queue.put()与queue.get()异步完成收录行情信息任务。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/data_recoder/start.png) + +  + +下面介绍行情收录的具体原理:若无合约记录的历史,用户需要先添加行情记录任务,如连接CTP接口后记录rb1905.SHFE的tick数据,然后调用add_tick_recording()函数执行下面工作: +1) 先创建tick_recordings字典; +2) 调用接口的suscribe()函数订阅行情; +3 )保存该tick_recordings字典到json文件上; +4) 推送行情记录事件。 + +``` + def add_tick_recording(self, vt_symbol: str): + """""" + if vt_symbol in self.tick_recordings: + self.write_log(f"已在Tick记录列表中:{vt_symbol}") + return + + contract = self.main_engine.get_contract(vt_symbol) + if not contract: + self.write_log(f"找不到合约:{vt_symbol}") + return + + self.tick_recordings[vt_symbol] = {} + "symbol": contract.symbol, + "exchange": contract.exchange.value, + "gateway_name": contract.gateway_name + } + + self.subscribe(contract) + self.save_setting() + self.put_event() + + self.write_log(f"添加Tick记录成功:{vt_symbol}") +``` + +下面对add_tick_recording()函数里面调用的子函数进行扩展: + +### 订阅行情 + +调用main_engine的suscribe()函数来订阅行情,需要填入的信息为symbol、exchange、gateway_name +``` + def subscribe(self, contract: ContractData): + """""" + req = SubscribeRequest( + symbol=contract.symbol, + exchange=contract.exchange + ) + self.main_engine.subscribe(req, contract.gateway_name) +``` + +  + +### 将订阅信息保存到json文件 + +- 主要把tick_recordings或者bar_recordings通过save_json()函数保存到C:\Users\Administrator\\.vntrader文件夹内的data_recorder_setting.json上。 +- 该json文件用于存放行情记录的任务,当每次启动行情模块后,会调用load_setting()函数来得到tick_recordings和bar_recordings字典,进而开始记录的任务。 +``` +setting_filename = "data_recorder_setting.json" + def save_setting(self): + """""" + setting = { + "tick": self.tick_recordings, + "bar": self.bar_recordings + } + save_json(self.setting_filename, setting) + + def load_setting(self): + """""" + setting = load_json(self.setting_filename) + self.tick_recordings = setting.get("tick", {}) + self.bar_recordings = setting.get("bar", {}) +``` + +  + +### 推送行情记录事件 + +- 创建行情记录列表tick_symbols和bar_symbols,并且缓存在data字典里; +- 创建evnte对象,其类型是EVENT_RECORDER_UPDATE, 内容是data字典; +- 调用event_engine的put()函数推送event事件。 + +``` + def put_event(self): + """""" + tick_symbols = list(self.tick_recordings.keys()) + tick_symbols.sort() + + bar_symbols = list(self.bar_recordings.keys()) + bar_symbols.sort() + + data = { + "tick": tick_symbols, + "bar": bar_symbols + } + + event = Event( + EVENT_RECORDER_UPDATE, + data + ) + self.event_engine.put(event) +``` + +  + +### 注册行情记录事件 + +register_event()函数分别注册2种事件:EVENT_CONTRACT、EVENT_TICK +- EVENT_CONTRACT事件,调用的是process_contract_event()函数: 从tick_recordings和bar_recordings字典获取需要订阅的合约品种;然后使用subscribe()函数进行订阅行情。 +- EVENT_TICK事件,调用的是process_tick_event()函数:从tick_recordings和bar_recordings字典获取需要订阅的合约品种;然后使用record_tick()和record_bar()函数,把行情记录任务推送到queue队列中等待执行。 + +``` + def register_event(self): + """""" + self.event_engine.register(EVENT_TICK, self.process_tick_event) + self.event_engine.register(EVENT_CONTRACT, self.process_contract_event) + + def process_tick_event(self, event: Event): + """""" + tick = event.data + + if tick.vt_symbol in self.tick_recordings: + self.record_tick(tick) + + if tick.vt_symbol in self.bar_recordings: + bg = self.get_bar_generator(tick.vt_symbol) + bg.update_tick(tick) + + def process_contract_event(self, event: Event): + """""" + contract = event.data + vt_symbol = contract.vt_symbol + + if (vt_symbol in self.tick_recordings or vt_symbol in self.bar_recordings): + self.subscribe(contract) + + def record_tick(self, tick: TickData): + """""" + task = ("tick", copy(tick)) + self.queue.put(task) + + def record_bar(self, bar: BarData): + """""" + task = ("bar", copy(bar)) + self.queue.put(task) + + def get_bar_generator(self, vt_symbol: str): + """""" + bg = self.bar_generators.get(vt_symbol, None) + + if not bg: + bg = BarGenerator(self.record_bar) + self.bar_generators[vt_symbol] = bg + + return bg +``` + +  + +### 执行记录行情任务 + +在while循环中,从queue队列读取任务,调用save_tick_data()或者save_bar_data()函数来记录数据,并且载入到数据库中。 +``` + def run(self): + """""" + while self.active: + try: + task = self.queue.get(timeout=1) + task_type, data = task + + if task_type == "tick": + database_manager.save_tick_data([data]) + elif task_type == "bar": + database_manager.save_bar_data([data]) + + except Empty: + continue +``` + +  + + + + +## 移除记录 + +- 从tick_recordings字典移除vt_symbol +- 调用save_setting()函数保存json配置文件 +- 推送最新的tick_recordings字典来继续记录行情,原来移除合约品种不再记录。 +``` + def remove_tick_recording(self, vt_symbol: str): + """""" + if vt_symbol not in self.tick_recordings: + self.write_log(f"不在Tick记录列表中:{vt_symbol}") + return + + self.tick_recordings.pop(vt_symbol) + self.save_setting() + self.put_event() + + self.write_log(f"移除Tick记录成功:{vt_symbol}") +``` + +  + +## 停止记录 + +- 记录行情状态改为False, 停止while循环; +- 调用join()函数关掉线程。 + +``` + def close(self): + """""" + self.active = False + + if self.thread.isAlive(): + self.thread.join() +``` \ No newline at end of file diff --git a/docs/gateway.md b/docs/gateway.md index 0d004e43..0587a8d3 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -2,52 +2,366 @@ ## 如何连接 +从gateway文件夹上引入接口程序,通过add_gateway()函数调动,最终展示到图形化操作界面VN Trader中。 + +在菜单栏中点击"系统"->"连接CTP”按钮会弹出如图账号配置窗口,输入账号、密码等相关信息即连接接口,并立刻进行查询工作: 如查询账号信息、查询持仓、查询委托信息、查询成交信息等。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/gateway/login.png) + +  + ### 加载需要用的接口 +加载接口示例在根目录"tests\trader"文件夹的run.py文件中。 +- 从gateway文件夹引入接口类文件,如from vnpy.gateway.ctp import CtpGateway; +- 创建事件引擎对象并且通过add_gateway()函数添加接口程序; +- 创建图形化对象main_window,以VN Trader操作界面展示出来。 + + +``` +from vnpy.gateway.ctp import CtpGateway + +def main(): + """""" + qapp = create_qapp() + main_engine = MainEngine(event_engine) + main_engine.add_gateway(CtpGateway) + main_window = MainWindow(main_engine, event_engine) + main_window.showMaximized() + qapp.exec() +``` + +  + ### VN Trader界面操作 +打开cmd窗口,使用命令“Python run.py"即可进入VN Trader操作界面。在左上方的菜单栏中点击"系统"->"连接CTP”按钮会弹出账号配置窗口,输入账号、密码等相关信息即连接接口。 + +连接接口的流程首先是初始化账户信息,然后调用connet()函数来连接交易端口和行情端口。 +- 交易端口:查询用户相关信息(如账户资金、持仓、委托记录、成交记录)、查询可交易合约信息、挂撤单操作; +- 行情端口:接收订阅的行情信息推送、接收用户相关信息(如账户资金更新、持仓更新、委托推送、成交推送)更新的回调推送。 + + +  + ### 修改json配置文件 +接口配置相关保存在json文件中,放在如图C盘用户目录下的.vntrader文件夹内。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/gateway/.vntrader.png) + +所以要修改接口配置文件,用户即可以在图形化界面VN Trader内修改,也可以直接在.vntrader修改json文件。 +另外将json配置文件分离于vnpy的好处在于:避免每次升级都要重新配置json文件。 + + +  + ### 可交易的合约查看 +先登录接口,然后在菜单栏中点击"帮助"->"查询合约”按钮会空白的“查询合约”窗口。点击“查询”按钮后才会显示查询结果,如图。 + +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/gateway/query_contract.png) + + + +  ## 接口分类 -做一个表 +| 接口 |类型 | +| ------ | :------: | +| CTP | 期货 | +| OES | 国内股票 | +| IB | 外盘股票、期货、期权 | +| FUTU | 国内股票、港股、美股 | +| TIGER | 国内股票、港股、美股 | +| BITMEX | 数字货币 | +| OKEX | 数字货币 | +| HUOBI | 数字货币 | + + + +  ## 接口详解 -### CTP(ctp) +### CTP #### 如何加载 +run.py文件提供了接口加载示例:先从gateway上调用ctpGateway类;然后通过add_gateway()函数添加到main_engine上。 +``` +from vnpy.gateway.ctp import CtpGateway +main_engine.add_gateway(CtpGateway) +``` + +  + #### 相关字段 +- 用户名:username +- 密码:password: +- 经纪商编号:brokerid +- 交易服务器地址:td_address +- 行情服务器地址:md_address +- 产品名称:product_info +- 授权编码:auth_code + +  + #### 获取账号 -#### 其他特点 +- 仿真账号:从SimNow网站上获取。只需输入手机号码和短信验证即可。(短信验证有时只能在工作日正常工作时段收到)SimNow的用户名为6位纯数字,经纪商编号为9999,并且提供2套环境用于盘中仿真交易以及盘后的测试。 + +- 实盘账号:在期货公司开户,通过联系客户经理可以开通。用户名为纯数字,经纪商编号也是4位纯数字。(每个期货公司的经纪商编号都不同)另外,实盘账号也可以开通仿真交易功能,同样需要联系客户经理。 -### 宽睿柜台(oes) +  + +### 宽睿柜台(OES) #### 如何加载 +先从gateway上调用OesGateway类;然后通过add_gateway()函数添加到main_engine上。 +``` +from vnpy.gateway.oes import OesGateway +main_engine.add_gateway(OesGateway) +``` + +  + + #### 相关字段 +- 用户名:username +- 密码:password +- 硬盘序列号:hdd_serial +- 交易委托服务器:td_ord_server +- 交易回报服务器:td_rpt_server +- 交易查询服务器:td_qry_server +- 行情推送服务器:md_tcp_server +- 行情查询服务器:md_qry_server + +  + + #### 获取账号 +测试账号请联系宽睿科技申请 + +  + #### 其他特点 +宽睿柜台提供内网UDP低延时组播行情以及实时成交信息推送。 -### 盈透证券(ib) +  -### 老虎证券(tiger) +### 盈透证券(IB) + +#### 如何加载 + +先从gateway上调用IbGateway类;然后通过add_gateway()函数添加到main_engine上。 +``` +from vnpy.gateway.oes import IbGateway +main_engine.add_gateway(IbGateway) +``` + +  + + +#### 相关字段 + +- TWS地址:127.0.0.1 +- TWS端口:7497 +- 客户号:1 + + +  + + +#### 获取账号 + +在盈透证券开户并且入金后可以获得API接入权限。拥有实盘账号后才可以申请开通仿真交易账号。 + +  + +#### 其他特点 +可交易品种几乎覆盖全球的股票、期权、期权;手续费相对较低。 + +  + +### 富途证券(FUTU) + +#### 如何加载 + +先从gateway上调用FutuGateway类;然后通过add_gateway()函数添加到main_engine上。 +``` +from vnpy.gateway.oes import FutuGateway +main_engine.add_gateway(FutuGateway) +``` + +  + + +#### 相关字段 + +- 地址:127.0.0.1 +- 密码: +- 端口:11111 +- 市场:HK 或 US +- 环境:TrdEnv.REAL 或 TrdEnv.SIMULATE + + +  + + +#### 获取账号 + +在富途证券开户并且入金后可以获得API接入权限。拥有实盘账号后才可以申请开通仿真交易账号。 + + + + + + +  + +### 老虎证券(TIGER) + + +#### 如何加载 + +先从gateway上调用TigerGateway类;然后通过add_gateway()函数添加到main_engine上。 +``` +from vnpy.gateway.oes import TigerGateway +main_engine.add_gateway(TigerGateway) +``` + +  + + +#### 相关字段 + +- 用户ID:tiger_id +- 环球账户:account +- 标准账户:standard_account +- 秘钥:private_key + + + +  + + +#### 获取账号 + +在老虎证券开户并且入金后可以获得API接入权限。拥有实盘账号后才可以申请开通仿真交易账号。 + + +  + + +### BITMEX + +#### 如何加载 + +先从gateway上调用BitmexGateway类;然后通过add_gateway()函数添加到main_engine上。 +``` +from vnpy.gateway.oes import BitmexGateway +main_engine.add_gateway(BitmexGateway) +``` + +  + + +#### 相关字段 + +- 用户ID:ID +- 密码:Secret +- 会话数:3 +- 服务器:REAL 或 TESTNET +- 代理地址: +- 代理端口: + + + +  + + +#### 获取账号 + +在BITMEX官网开户并且入金后可以获得API接入权限。 + + + +  ### OKEX -### 火币 \ No newline at end of file +#### 如何加载 + +先从gateway上调用OkexGateway类;然后通过add_gateway()函数添加到main_engine上。 +``` +from vnpy.gateway.oes import OkexGateway +main_engine.add_gateway(OkexGateway) +``` + +  + + +#### 相关字段 + +- API秘钥:API Key +- 密码秘钥:Secret Key +- 会话数:3 +- 密码:passphrase +- 代理地址: +- 代理端口: + + + +  + + +#### 获取账号 + +在OKEX官网开户并且入金后可以获得API接入权限。 + + + +  + +### 火币 + +#### 如何加载 + +先从gateway上调用HuobiGateway类;然后通过add_gateway()函数添加到main_engine上。 +``` +from vnpy.gateway.oes import HuobiGateway +main_engine.add_gateway(HuobiGateway) +``` + +  + + +#### 相关字段 + +- API秘钥:API Key +- 密码秘钥:Secret Key +- 会话数:3 +- 代理地址: +- 代理端口: + + + +  + + +#### 获取账号 + +在火币官网开户并且入金后可以获得API接入权限。 \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index c9ce72c3..2d50b2ef 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,15 +1,125 @@ # vn.py文档 * 快速入门 - * [项目简介](introduction.md) - * [环境安装](install.md) - * [基本使用](quickstart.md) + * [项目简介](https://www.vnpy.com/docs/cn/introduction.html#introduction) + * [安装指南](https://www.vnpy.com/docs/cn/install.html#an-zhuang-zhi-nan) + * [Windows安装](https://www.vnpy.com/docs/cn/install.html#windows) + * [使用VNConda](https://www.vnpy.com/docs/cn/install.html#shi-yong-vnconda) + * [下载VNConda](https://www.vnpy.com/docs/cn/install.html#xia-zai-vnconda-python-3-7-64-wei) + * [安装VNConda](https://www.vnpy.com/docs/cn/install.html#an-zhuang-vnconda) + * [登陆VNStation](https://www.vnpy.com/docs/cn/install.html#deng-lu-vnstation) + * [使用VNStation](https://www.vnpy.com/docs/cn/install.html#shi-yong-vnstation) + * [更新VNStation](https://www.vnpy.com/docs/cn/install.html#geng-xin-vnstation) + * [手动安装](https://www.vnpy.com/docs/cn/install.html#shou-dong-an-zhuang) + * [下载并安装最新版Anaconda3.7 64位](https://www.vnpy.com/docs/cn/install.html#xia-zai-bing-an-zhuang-zui-xin-ban-anaconda3-7-64-wei) + * [下载并解压vnpy](https://www.vnpy.com/docs/cn/install.html#xia-zai-bing-jie-ya-vnpy) + * [安装vnpy](https://www.vnpy.com/docs/cn/install.html#an-zhuang-vnpy) + * [启动VN Trader](https://www.vnpy.com/docs/cn/install.html#qi-dong-vn-trader) + * [Ubuntu安装](https://www.vnpy.com/docs/cn/install.html#ubuntu) + * [下载并安装最新版本的Anaconda或者Miniconda](https://www.vnpy.com/docs/cn/install.html#xia-zai-bing-an-zhuang-zui-xin-ban-ben-de-anaconda-huo-zhe-miniconda-python-3-7-64-wei) + * [下载并解压vnpy](https://www.vnpy.com/docs/cn/install.html#xia-zai-bing-jie-ya-vnpy1) + * [安装vnpy](https://www.vnpy.com/docs/cn/install.html#an-zhuang-vnpy1) + * [启动VN Trader](https://www.vnpy.com/docs/cn/install.html#qi-dong-vn-trader1) + * [基本使用](https://www.vnpy.com/docs/cn/quickstart.html#ji-ben-shi-yong) + * [启动VN Trader](https://www.vnpy.com/docs/cn/quickstart.html#qi-dong-vntrader) + * [VN Station模式](https://www.vnpy.com/docs/cn/quickstart.html#vn-station-mo-shi) + * [脚本模式](https://www.vnpy.com/docs/cn/quickstart.html#jiao-ben-mo-shi) + + * [连接接口](https://www.vnpy.com/docs/cn/quickstart.html#lian-jie-jie-kou) + * [订阅行情](https://www.vnpy.com/docs/cn/quickstart.html#ding-yue-xing-qing) + * [委托交易](https://www.vnpy.com/docs/cn/quickstart.html#wei-tuo-jiao-yi) + * [数据监控](https://www.vnpy.com/docs/cn/quickstart.html#shu-ju-jian-kong) + * [行情组件](https://www.vnpy.com/docs/cn/quickstart.html#xing-qing-zu-jian) + * [活动组件](https://www.vnpy.com/docs/cn/quickstart.html#id8) + * [成交组件](https://www.vnpy.com/docs/cn/quickstart.html#cheng-jiao-zu-jian) + * [委托组件](https://www.vnpy.com/docs/cn/quickstart.html#wei-tuo-zu-jian) + * [持仓组件](https://www.vnpy.com/docs/cn/quickstart.html#chi-cang-zu-jian) + * [资金组件](https://www.vnpy.com/docs/cn/quickstart.html#zi-jin-zu-jian) + * [日志组件](https://www.vnpy.com/docs/cn/quickstart.html#ri-zhi-zu-jian) + + * [应用模块](https://www.vnpy.com/docs/cn/quickstart.html#ying-yong-mo-kuai) + * [CTA策略](https://www.vnpy.com/docs/cn/quickstart.html#cta-ce-lue) + * [CSV载入](https://www.vnpy.com/docs/cn/quickstart.html#csv-zai-ru) + * [CTA回测]() + * [行情记录]() + * [算法交易]() * 应用模块 - * [CTA策略](cta_strategy.md) - * [CSV载入](csv_loader.md) + * [CSV载入](https://www.vnpy.com/docs/cn/csv_loader.html#csv-zai-ru-mo-kuai) + * [初始化配置](https://www.vnpy.com/docs/cn/csv_loader.html#chu-shi-hua-pei-zhi) + * [数据载入](https://www.vnpy.com/docs/cn/csv_loader.html#shu-ju-zai-ru) -* [交易接口](gateway.md) + * [CTA策略](https://www.vnpy.com/docs/cn/cta_strategy.html#cta-ce-lue-mo-kuai) + * [模块构成](https://www.vnpy.com/docs/cn/cta_strategy.html#mo-kuai-gou-cheng) + * [历史数据](https://www.vnpy.com/docs/cn/cta_strategy.html#li-shi-shu-ju) + * [回测历史数据](https://www.vnpy.com/docs/cn/cta_strategy.html#hui-ce-li-shi-shu-ju) + * [实盘历史数据](https://www.vnpy.com/docs/cn/cta_strategy.html#shi-pan-li-shi-shu-ju) + + * [策略开发](https://www.vnpy.com/docs/cn/cta_strategy.html#ce-lue-kai-fa) + * [参数设置](https://www.vnpy.com/docs/cn/cta_strategy.html#can-shu-she-zhi) + * [类的初始化](https://www.vnpy.com/docs/cn/cta_strategy.html#lei-de-chu-shi-hua) + * [策略的初始化、启动、停止](https://www.vnpy.com/docs/cn/cta_strategy.html#ce-lue-de-chu-shi-hua-qi-dong-ting-zhi) + * [Tick数据回报](https://www.vnpy.com/docs/cn/cta_strategy.html#tick-shu-ju-hui-bao) + * [K线数据回报](https://www.vnpy.com/docs/cn/cta_strategy.html#k-xian-shu-ju-hui-bao) + * [15分钟K线数据回报](https://www.vnpy.com/docs/cn/cta_strategy.html#fen-zhong-k-xian-shu-ju-hui-bao) + * [委托回报、成交回报、停止单回报](https://www.vnpy.com/docs/cn/cta_strategy.html#wei-tuo-hui-bao-cheng-jiao-hui-bao-ting-zhi-dan-hui-bao) + + + * [回测研究](https://www.vnpy.com/docs/cn/cta_strategy.html#hui-ce-yan-jiu) + * [加载策略](https://www.vnpy.com/docs/cn/cta_strategy.html#jia-zai-ce-lue) + * [载入历史数据](https://www.vnpy.com/docs/cn/cta_strategy.html#zai-ru-li-shi-shu-ju) + * [撮合成交](https://www.vnpy.com/docs/cn/cta_strategy.html#cuo-he-cheng-jiao) + * [计算策略盈亏情况](https://www.vnpy.com/docs/cn/cta_strategy.html#ji-suan-ce-lue-ying-yu-qing-kuang) + * [计算策略统计指标](https://www.vnpy.com/docs/cn/cta_strategy.html#ji-suan-ce-lue-tong-ji-zhi-biao) + * [统计指标绘图](https://www.vnpy.com/docs/cn/cta_strategy.html#tong-ji-zhi-biao-hui-tu) + * [回测引擎使用示例](https://www.vnpy.com/docs/cn/cta_strategy.html#hui-ce-yin-qing-shi-yong-shi-li) + + + * [参数优化](https://www.vnpy.com/docs/cn/cta_strategy.html#can-shu-you-hua) + * [参数设置](https://www.vnpy.com/docs/cn/cta_strategy.html#can-shu-she-zhi1) + * [参数对组合回测](https://www.vnpy.com/docs/cn/cta_strategy.html#can-shu-dui-zu-he-hui-ce) + * [多进程优化](https://www.vnpy.com/docs/cn/cta_strategy.html#duo-jin-cheng-you-hua) + + * [实盘运行](https://www.vnpy.com/docs/cn/cta_strategy.html#shi-pan-yun-xing) + * [创建策略实例](https://www.vnpy.com/docs/cn/cta_strategy.html#chuang-jian-ce-lue-shi-li) + * [初始化策略](https://www.vnpy.com/docs/cn/cta_strategy.html#chu-shi-hua-ce-lue) + * [启动策略](https://www.vnpy.com/docs/cn/cta_strategy.html#qi-dong-ce-lue) + * [停止策略](https://www.vnpy.com/docs/cn/cta_strategy.html#ting-zhi-ce-lue) + * [编辑策略](https://www.vnpy.com/docs/cn/cta_strategy.html#bian-ji-ce-lue) + * [移除策略](https://www.vnpy.com/docs/cn/cta_strategy.html#yi-chu-ce-lue) + + + * [CTA回测](https://www.vnpy.com/docs/cn/cta_backtester.html#cta-hui-ce-mo-kuai) + * [加载启动](https://www.vnpy.com/docs/cn/cta_backtester.html#jia-zai-qi-dong) + * [下载数据](https://www.vnpy.com/docs/cn/cta_backtester.html#xia-zai-shu-ju) + * [策略回测](https://www.vnpy.com/docs/cn/cta_backtester.html#ce-lue-hui-ce) + * [统计数据](https://www.vnpy.com/docs/cn/cta_backtester.html#tong-ji-shu-ju) + * [图表分析](https://www.vnpy.com/docs/cn/cta_backtester.html#tu-biao-fen-xi) + * [参数优化](https://www.vnpy.com/docs/cn/cta_backtester.html#can-shu-you-hua) + * [穷举算法](https://www.vnpy.com/docs/cn/cta_backtester.html#qiong-ju-suan-fa) + * [遗传算法](https://www.vnpy.com/docs/cn/cta_backtester.html#yi-chuan-suan-fa) + + +* [交易接口](https://www.vnpy.com/docs/cn/gateway.html#jiao-yi-jie-kou) + * [如何连接](https://www.vnpy.com/docs/cn/gateway.html#ru-he-lian-jie) + * [加载需要用的接口](https://www.vnpy.com/docs/cn/gateway.html#jia-zai-xu-yao-yong-de-jie-kou) + * [VN Trader界面操作](https://www.vnpy.com/docs/cn/gateway.html#vn-trader-jie-mian-cao-zuo) + * [修改json配置文件](https://www.vnpy.com/docs/cn/gateway.html#xiu-gai-json-pei-zhi-wen-jian) + * [可交易的合约查看](https://www.vnpy.com/docs/cn/gateway.html#ke-jiao-yi-de-he-yue-cha-kan) + * [接口分类](https://www.vnpy.com/docs/cn/gateway.html#jie-kou-fen-lei) + * [接口详解](https://www.vnpy.com/docs/cn/gateway.html#jie-kou-xiang-jie) + * [CTP](https://www.vnpy.com/docs/cn/gateway.html#ctp) + * [宽睿柜台(OES)](https://www.vnpy.com/docs/cn/gateway.html#kuan-rui-ju-tai-oes) + * [盈透证券(IB)](https://www.vnpy.com/docs/cn/gateway.html#ying-tou-zheng-quan-ib) + * [富途证券(FUTU)](https://www.vnpy.com/docs/cn/gateway.html#fu-tu-zheng-quan-futu) + * [老虎证券(TIGER)](https://www.vnpy.com/docs/cn/gateway.html#lao-hu-zheng-quan-tiger) + * [BITMEX](https://www.vnpy.com/docs/cn/gateway.html#bitmex) + * [OKEX](https://www.vnpy.com/docs/cn/gateway.html#okex) + +* [配置数据库](https://www.vnpy.com/docs/cn/database.html#shu-ju-ku-pei-zhi) + * [SQLite](https://www.vnpy.com/docs/cn/database.html#sqlite) + * [SQL(MySQL,PostgreSQL)](https://www.vnpy.com/docs/cn/database.html#sql-mysql-postgresql) + * [MongoDB](https://www.vnpy.com/docs/cn/database.html#mongodb) * [RPC应用](rpc.md) * [贡献代码](contribution.md) \ No newline at end of file diff --git a/docs/quickstart.md b/docs/quickstart.md index 4ee1bfb3..5e499429 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -1,25 +1,25 @@ # 基本使用 -## 1. 启动VN Trader -### 1.1 VN Station模式 +## 启动VNTrader +### VN Station模式 登陆VN Station后,点击VN Trade Lite快速进入VN Trader(只有CTP接口);或者点击VN Trader Pro先选择如下图的底层接口和上层应用,再进入VN Trader。 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/VnTrader_Pro.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/VnTrader_Pro.png "enter image title here") -### 1.2 脚本模式 +### 脚本模式 在文件夹tests\trader中找到run.py文件。按住“Shift” + 鼠标右键进入cmd窗口,输入下面命令进入如图VN Trader ``` python run.py ``` -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/Vntrader.PNG "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/Vntrader.PNG "enter image title here")   -## 2. 连接接口 +## 连接接口 以SinNow仿真交易账号登陆CTP接口为例:点击菜单栏的“系统”->“连接CTP”后,弹出如上图所示CTP接口的配置对话框,输入以下内容后即可登录: - 用户名username:111111 (6位纯数字账号) - 密码password:1111111 (需要修改一次密码用于盘后测试) @@ -34,18 +34,18 @@ python run.py   -## 3. 订阅行情 +## 订阅行情 在交易组件输入交易所和合约代码,并且按“Enter”键即可订阅器行情。如订阅IF股指期货,交易所:CFFEX,名称:IF905;铁矿石期货,交易所:DCE,名称:i1905。 此时行情组件会显示最新行情信息;交易组件会显示合约名称,并且在下方显示深度行情报价:如最新价、买一价、卖一价。(数字货币品种可以显示十档行情) -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/subcribe_contract.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/subcribe_contract.png "enter image title here")   -## 4. 委托交易 +## 委托交易 交易组件适用于手动交易。除了在行情订阅中输入的交易所和合约代码以外,还需要填写以下5个字段:委托方向、开平仓类型、委托类型、委托价格和委托数量。(若委托类型为市价单,委托价格可不填。) 发出委托同时本地缓存委托相关信息,并且显示到委托组件和活动组件,其委托状态为“提交中”,然后等待委托回报。 @@ -59,14 +59,14 @@ python run.py   -## 5. 数据监控 +## 数据监控 数据监控由以下组件构成,并且附带2个辅助功能:选定以下任一组件,鼠标右键可以选择“调整列宽”(特别适用于屏幕分辨率较低),或者选择“保存数据”(csv格式) -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/2_optiones.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/2_optiones.png "enter image title here") -### 5.1 行情组件 +### 行情组件 用于对订阅的行情进行实时监控,如下图,监控内容可以分成3类: - 合约信息:合约代码、交易所、合约名称 @@ -75,30 +75,30 @@ python run.py - 其他信息:数据推送时间、接口 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/subcribe_contract_module.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/subcribe_contract_module.png "enter image title here") -### 5.2 活动组件 +### 活动组件 活动组件用于存放还未成交的委托,如限价单或者没有立刻成交的市价单,委托状态永远是“提交中”。在该组件中鼠标双击任一委托可以完成撤单操作。 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/active_order.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/active_order.png "enter image title here") -### 5.3 成交组件 +### 成交组件 成交组件用于存放已成交的委托,需要注意3个字段信息:价格、数量、时间。他们都是交易所推送过来的成交信息,而不是委托信息。 注意:有些接口会独立推送成交信息,如CTP接口;有些接口则需要从委托信息里面提取成交相关字段,如Tiger接口。 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/trade.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/trade.png "enter image title here") -### 5.4 委托组件 +### 委托组件 委托组件用于存放用户发出的所有委托信息,其委托状态可以是提交中、已撤销、部分成交、全部成交、拒单等等。 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/order.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/order.png "enter image title here") -### 5.5 持仓组件 +### 持仓组件 持仓组件用于记录其历史持仓。其中需要了解以下字段含义 - 方向:期货品种具有多空方向;而股票品种方向为“净”持仓。 - 昨仓:其出现衍生于上期所特有的平今、平昨模式的需要 @@ -108,9 +108,9 @@ python run.py 若平仓离场,持仓数量清零,浮动盈亏变成实际盈亏从而影响账号余额变化。故以下字段:数量、昨仓、冻结、均价、盈亏均为“0”,如下图。 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/query_position.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/query_position.png "enter image title here") -### 5.6 资金组件 +### 资金组件 资金组件显示了账号的基础信息,如下图需要注意3个字段信息: - 可用资金:可以用于委托的现金 - 冻结:委托操作冻结的金额(与保证金不是一个概念) @@ -118,58 +118,58 @@ python run.py 注意:若全部平仓,浮动盈亏变成实际盈亏,保证金和浮动盈亏清零,总资金等于可用资金 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/query_account.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/query_account.png "enter image title here") -### 5.7 日志组件 +### 日志组件 日志组件用于显示接口登陆信息以及委托报错信息,如下图。 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/write_log.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/write_log.png "enter image title here")   -## 6. 应用模块 +## 应用模块 vnpy官方目前提供2个应用模块组件,分别是用于自动交易的“CTA策略”组件;把第三方数据文件导入到数据库的“CSV载入”组件。在菜单栏中点击“功能”,即显示应用模块,如下图: -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/application.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/application.png "enter image title here") -### 6.1 CTA策略 +### CTA策略 CTA策略组件默认使用RQData的数据进行自动交易,故需要配置好RQData相关数据。 1) 在用户目录下.vntrader文件夹找到vt_setting.json,输入RQData的账号和密码,保存退出后启动CTA策略组件,会显示“RQData数据接口初始化成功”,如图: -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/RQData.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/RQData.png "enter image title here") 2)在左上方的菜单栏选择策略,如“AtrRsiStrategy”,然后点击右边的“添加策略”按钮,用于策略实例创建,选择策略适用品种和修改该测试示例的参数,如图: -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/trader_2.PNG "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/trader_2.PNG "enter image title here") 3)每一个策略示例都有其“初始化”、“启动”、“停止”、“编辑”、“移除”按钮。注意在启动策略前必须先初始化,移除策略前需要先停止策略。右上方菜单栏有批量处理功能,方便用户快速启动、停止策略,如图: -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/turtle_strategy.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/turtle_strategy.png "enter image title here")   -### 6.2 CSV载入 +### CSV载入 CSV文件是用户最主要的历史数据来源之一,用户只需根据CSV文件中的表头字段,以及时间格式灵活配置,即可实现一键载入历史数据。 CSV载入操作分为3步: 1)打开CSV文件,查看表头字段以及时间格式,如图: -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/csv_format.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/csv_format.png "enter image title here") 2)点击菜单栏的“功能”->“CSV载入”,进入界面后选择要载入的CSV文件,并且修改相关表头字段和时间格式(若有需要的话)。如下图: -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/csv_loader.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/csv_loader.png "enter image title here") 3)点击“载入数据”后,成功界面如下图所示。 -![enter image description here](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/exito_csv_load.png "enter image title here") +![](https://vnpy-community.oss-cn-shanghai.aliyuncs.com/forum_experience/yazhang/quick_start/exito_csv_load.png "enter image title here")