七天打造一套量化交易系统:Day1-数据分类、获取、清洗与存储

七天打造一套量化交易系统:Day1-数据分类、获取、清洗与存储

数据是量化交易的基础,重要性不言而喻。无论是股票、期货、期权、基金、ETF等等,甚至包括比特币,这些投资标的历史行情数据都可以用作回测分析,本篇将分享如何选择可靠的数据源,如何进行数据获取,如何清洗常见的错误数据,如何进行有效地存储,方便后期使用。

本系列搭建的量化交易系统主要针对的投资标的是股票和期货,其他的投资标的后边有机会我们再进行分享。那么接下来的内容都是围绕这两个投资标的进行展开。

数据的分类

行情数据是量化中使用最多的数据,从价、量的变化中寻找规律,我们拿到的一般是交易所下发的切片数据,国内股票行情3秒1次,期货行情一般是1秒2次。对一段时间内的切片数据进行汇总形成k线图(开、高、低、收、成交量等),再加入一些算法就形成了各种技术指标(MA、MACD、BOLL、KDJ等)。

针对股票还需要关注的数据有:年报季报、龙虎榜单、资金流向等数据,这些数据可以用在后面的多因子选股模型中。

针对大宗商品期货需要关注的数据有:仓单数据、现货报价、席位持仓、席位盈亏,对龙虎榜单上的数据进行分析也很有意思,能够发现很多正向指标和反向指标。

数据的获取

获取这些数据,方式也很多,下面分享几个中常用的方式:

1、通达信接口

from mootdx.reader import Reader
# 读取通达信行历史情数据
# market: 参数 `std` 为标准市场(就是股票), `ext` 为扩展市场(期货,黄金等)
# tdxdir: 是通达信的数据目录, 根据自己的情况修改
reader = Reader.factory(market='std', tdxdir='D:/software/new_tdx')
# 读取日线数据
r = reader.daily(symbol='sh000001')
# 读取分钟数据
r = reader.minute(symbol='sh000001')

# 获取通达信中的实时行情
from mootdx.quotes import Quotes
# 标准市场
client = Quotes.factory(market='std', multithread=True, heartbeat=True, bestip=True, timeout=15)
# k 线数据
r = client.bars(symbol='000001', frequency=0, offset=10)

2、聚宽接口

上述代码用于获取股票的财务数据,字段的含义以及其他数据的获取方式可以参考聚宽的接口文档。

3、期货CTP接口

def OnRtnDepthMarketData(self, pDepthMarketData: 'CThostFtdcDepthMarketDataField') -> "void":
	log.info(api_struct_serialize(pDepthMarketData))

具体代码参考之前的文章 CTP-API开发系列之九:行情登录及订阅代码

4、爬虫脚本
如果部分数据没有标准的接口可以直接使用,就需要我们编写爬虫脚本,定时拉取。比如龙虎榜数据,可以从交易所官网、东方财富等网站拉取。

之前写过一篇爬虫的文章,可以参考一下。期货仓单数据获取

数据的清洗

对数据的清洗是一项细活,需要不断积累完善,一般需要多个数据源进行校准,保证数据的准确性,对空值、极大值的处理,时间序列对齐等等。

数据的存储

在我们的量化系统中,MarketDataEngine 行情管理引擎的作用就是,通过 ExchangeMarketDataListener 接收不同交易接口的行情 ,在onMarketData 函数中进行统一处理,并实时转发给所有需要用到的模块中(MarketDataReceivers)。同时,存储在内存中的行情数据也可以进行落地存储。

class MarketDataEngine
{
private:
	class ExchangeMarketDataListener : public MarketDataListener
	{
	private:
		Exchange* const exchange;
		MarketDataDispatcher* const dispatcher;

	public:
		ExchangeMarketDataListener(Exchange* ex, MarketDataDispatcher* disp)
			: exchange(ex), dispatcher(disp)
		{}

		void onMarketData(MarketData& data);
	};

	TradeEngine* const tradeEngine;
	const char* const tradeEngineHomeDir;

	std::unique_ptr<MarketDataDispatcher> dispatcher;
	std::set<std::shared_ptr<ExchangeMarketDataListener> > listeners;

	typedef std::set<std::shared_ptr<MarketDataReceiver> > MarketDataReceivers_t;
	MarketDataReceivers_t receivers;

	std::shared_ptr<MarketDataReceiver> createMarketDatareceiver(const char* exchangeID, const char* brokerID, const char* userID,
		const char* password, const std::vector<std::string>& uris, const char* path, const char* channel);

	void init();

public:
	MarketDataEngine(TradeEngine* te, const char* homeDir)
		: tradeEngine(te), tradeEngineHomeDir(homeDir)
	{
		init();
	}

	~MarketDataEngine()
	{
		receivers.clear();
	}
};

数据存储的目的是方便后期的使用,主要是用于回测、数据模型的训练。在后面的章节中,我们再继续使用这些数据。

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-22 07:04:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-22 07:04:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-22 07:04:02       45 阅读
  4. Python语言-面向对象

    2024-07-22 07:04:02       55 阅读

热门阅读

  1. 初识数据结构中的“栈”

    2024-07-22 07:04:02       17 阅读
  2. 44、PHP 实现数据流中的中位数(含源码)

    2024-07-22 07:04:02       16 阅读
  3. Python面试题:Python中的单例模式及其实现

    2024-07-22 07:04:02       18 阅读
  4. JVM 中的OopMap与安全点

    2024-07-22 07:04:02       17 阅读
  5. 在 Ubuntu 22.04/20.04 安装 CVAT 和 SAM 指南

    2024-07-22 07:04:02       20 阅读
  6. C++多线程编程中的锁详解

    2024-07-22 07:04:02       18 阅读
  7. 生成对抗网络(GAN):目标检测的新前沿

    2024-07-22 07:04:02       15 阅读
  8. 机器学习浅讲

    2024-07-22 07:04:02       16 阅读
  9. 动态内存规划

    2024-07-22 07:04:02       17 阅读