历史数据

回测历史数据

回测所需要的历史数据可通过运行getdata.py文件进行下载。该文件处于根目录下tests\backtesting文件夹内。下载历史数据的原理是调用RQData的get_price()函数把数据下载到内存里面;再通过generate_bar_from_row()函数,以固定格式把数据从内存载入到硬盘数据库中。

下面介绍具体流程:

  • 填写RQData的账号密码,初始化RQData
  1. import rqdatac as rq
  2.  
  3.  
  4. USERNAME = ""
  5. PASSWORD = ""
  6. FIELDS = ["open", "high", "low", "close", "volume"]
  7.  
  8. rq.init(USERNAME, PASSWORD, ("rqdatad-pro.ricequant.com", 16011))
  • 定义数据插入格式。需要插入的数据包括:合约代码、交易所、K线周期、开盘价、最高价、最低价、收盘价、成交量、数据库名称、vt_symbol(注意:K线周期可以是”1m”、”1h”、”d”、”w”。to_pydatetime()用于时间转换成datetime格式)
  1. def generate_bar_from_row(row, symbol, exchange):
  2. """"""
  3. bar = DbBarData()
  4.  
  5. bar.symbol = symbol
  6. bar.exchange = exchange
  7. bar.interval = "1m"
  8. bar.open_price = row["open"]
  9. bar.high_price = row["high"]
  10. bar.low_price = row["low"]
  11. bar.close_price = row["close"]
  12. bar.volume = row["volume"]
  13. bar.datetime = row.name.to_pydatetime()
  14. bar.gateway_name = "DB"
  15. bar.vt_symbol = f"{symbol}.{exchange}"
  16.  
  17. return bar
  • 定义数据下载函数。主要调用RQData的get_price()获取指定合约或合约列表的历史数据(包含起止日期,日线或分钟线)。目前仅支持中国市场的股票、期货、ETF和上金所现货的行情数据,如黄金、铂金和白银产品。(注意:起始日期默认是2013-01-04,结束日期默认是2014-01-04)
  1. def download_minute_bar(vt_symbol):
  2. """下载某一合约的分钟线数据"""
  3. print(f"开始下载合约数据{vt_symbol}")
  4. symbol, exchange = vt_symbol.split(".")
  5.  
  6. start = time()
  7.  
  8. df = rq.get_price(symbol, start_date="2018-01-01", end_date="2019-01-01", frequency="1m", fields=FIELDS)
  9.  
  10. with DB.atomic():
  11. for ix, row in df.iterrows():
  12. print(row.name)
  13. bar = generate_bar_from_row(row, symbol, exchange)
  14. DbBarData.replace(bar.__data__).execute()
  15.  
  16. end = time()
  17. cost = (end - start) * 1000
  18.  
  19. print(
  20. "合约%s的分钟K线数据下载完成%s - %s,耗时%s毫秒"
  21. % (symbol, df.index[0], df.index[-1], cost)
  22. )

实盘历史数据

在实盘中,RQData通过实时载入数据进行策略的初始化。该功能主要在CTA实盘引擎engine.py内实现。下面介绍具体流程:

  • 配置json文件:在用户目录下.vntrader文件夹找到vt_setting.json,输入RQData的账号和密码,如图。enter image title here

  • 初始化RQData客户端:从vt_setting.json中读取RQData的账户、密码到rq_client.init()函数进行初始化

  1. def init_rqdata(self):
  2. """
  3. Init RQData client.
  4. """
  5. username = SETTINGS["rqdata.username"]
  6. password = SETTINGS["rqdata.password"]
  7. if not username or not password:
  8. return
  9.  
  10. import rqdatac
  11.  
  12. self.rq_client = rqdatac
  13. self.rq_client.init(username, password,
  14. ('rqdatad-pro.ricequant.com', 16011))
  • RQData载入实盘数据:输入vt_symbol后,首先会转换成符合RQData格式的rq_symbol,通过get_price()函数下载数据,并且插入到数据库中。
  1. def query_bar_from_rq(
  2. self, vt_symbol: str, interval: Interval, start: datetime, end: datetime
  3. ):
  4. """
  5. Query bar data from RQData.
  6. """
  7. symbol, exchange_str = vt_symbol.split(".")
  8. rq_symbol = to_rq_symbol(vt_symbol)
  9. if rq_symbol not in self.rq_symbols:
  10. return None
  11.  
  12. end += timedelta(1) # For querying night trading period data
  13.  
  14. df = self.rq_client.get_price(
  15. rq_symbol,
  16. frequency=interval.value,
  17. fields=["open", "high", "low", "close", "volume"],
  18. start_date=start,
  19. end_date=end
  20. )
  21.  
  22. data = []
  23. for ix, row in df.iterrows():
  24. bar = BarData(
  25. symbol=symbol,
  26. exchange=Exchange(exchange_str),
  27. interval=interval,
  28. datetime=row.name.to_pydatetime(),
  29. open_price=row["open"],
  30. high_price=row["high"],
  31. low_price=row["low"],
  32. close_price=row["close"],
  33. volume=row["volume"],
  34. gateway_name="RQ"
  35. )
  36. data.append(bar)