Intro
这个项目是上学的时候做的,作为在金融领域零基础的人先择了这样一个项目确实有一点点挑战,但最终做下来还是有些收获,希望通过这篇文章分享给各位。
这篇文章适合想用python做自动交易的初学者和进阶人士(或许会给你提供一些小的idea),以及想学习数据科学相关理论和实战代码的同学们。
文章会分为数据处理、建模、回测、以及自动交易四个大部分。
本文为第一部分:数据处理,包含项目介绍、数据集介绍、数据预分析和特征集建立四个章节。
所有代码+注释+数据在这里 https://download.csdn.net/download/zhaotian151/89099858
觉得文章有用可以适当支持,当然你也可以从这个文章里面一个个摘代码~
不建议还在上学同学直接抄作业哦,所有的项目都是宝贵的经验,是你上班之后确确实实可以用到的东西,希望大家上学的时候好好学习。
1. 项目介绍
近年来,外汇交易越来越受欢迎,作为一种高频市场,交易者需要在做出决定时考虑诸多因素,但又要兼顾快准狠。因此传统的人工交易可能由于各类因素影响,在交易过程中出现认为因素导致亏损。像传统的预测技术,比如ARCH模型(Autoregressive Conditional Heteroskedasticity Model,自回归条件异方差模型) 和ARMA模型(Auto-Regressive Moving Average Model,自回归滑动平均模型),主要是基于时间序列算法,在单独使用时可能会产生一些较为片面的结果。而机器学习技术通过挖掘数据背后的隐藏模式,可能会发现一些新的交易策略。机器自动交易则可以避免人为因素对交易判断产生的影响。
2. 数据集
这次使用的原始数据集格式为CSV,包括2005年1月1日18:00:00至2019年12月29日22:00:00欧元/美元的每小时外汇交易数据,共95927个样本。变量包括不同货币的开盘价、收盘价、最高价和最低价。这些是外汇市场中最基础的数据。用于训练模型的特征是从结合这些基础数据,通过不同的财务指标计算出的值。
数据集的基本信息如下:
3. 数据预处理
3.1 准备环节
Python的安装之类的就不讲了,直接从代码开始讲,以下的代码对于所有的数据预处理环节都是通用的。
首先导入本项目需要用到的包。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
然后导入数据,并且通过print大概看一下数据的样子。
data = pd.read_csv('EUR_USD_H1.csv')
print(data.head(5))
print(data.tail(5))
np.random.seed(0)
接下来看看数据里面有没有空值。
data.isnull().any()
看一下数据集的信息。
print(data.info())
由于咱们这次做的是和时间相关的,着重看一下有没有重复的时间点出现。
data.datetime.is_unique
OK,通过查看数据集的一些基本情况,发现这个数据集是不错的,基本不需要处理。但是我们要注意,外汇交易在节假日是不会进行的,所以我们出于好奇(严谨)来看一看我们的数据集中有多少不参与交易的节假日(注意周末本来就是不交易的,我们主要看的是工作日里面有多少日子不参与交易)。这里的代码不重要,不讲了,各位感兴趣的话可看看。
from datetime import datetime
time_ser = pd.Series(data['datetime'])
time_ser = pd.to_datetime(time_ser)
day = pd.DataFrame(index=data.index)
day['daytime'] = 0
for i in range(len(time_ser)):
day['daytime'][i] = time_ser [i].weekday()
day.daytime.value_counts()
#how many weekdays should be place trade?
from pandas import Series
date2 = pd.date_range('2005-01-01 18:00:00', '2019-12-29 22:00:00',freq='H')
ts = pd.Series(date2)
ts = pd.to_datetime(ts)
day2 = pd.DataFrame(index=ts.index)
day2['daytime'] = 0
for i in range(len(ts)):
day2['daytime'][i] = ts [i].weekday()
day2.daytime.value_counts()
#missing hours in timeframe from 2005-01-01 18:00:00' to '2019-12-29 22:00:00
missing_value=day2.daytime.value_counts()-day.daytime.value_counts()
missing_value=pd.DataFrame([missing_value])
missing_value
number = pd.date_range('2005-01-01', '2019-12-29',freq='H')
missing=missing_value[0]+missing_value[1]+missing_value[2]+missing_value[3]+missing_value[4]
print('Missing value of weekdays:',missing)
print('Percentage of missing data in weekdays:', missing/len(number)/7*5)
3.2 数据探索性分析(EDA)
首先我们要知道,但凡是建模,第一步都要做数据探索性分析。这一步骤可以通过了解数据集,了解变量间的相互关系以及变量与预测值之间的关系,从而帮助我们后期更好地进行特征工程和建立模型,是数据挖掘中十分重要的一步。
先来看看数据的基本情况。下面pd.concat这个代码可以直接把你的数据情况做成一张表,非常好用,各位请直接抄作业到自己的代码笔记里。
df=data
s1 = df.open.describe()
s2 = df.high.describe()
s3 = df.low.describe()
s4 = df.close.describe()
pd.concat({
'open':s1, 'high':s2, 'low':s3,'close':s4}, axis=1)
箱子图(box-plot)
plt.figure(figsize=(12,8))
sns.set_style('whitegrid')
sns.set_palette("muted")
s5 = pd.DataFrame([np.array(df.open), np.array(df.high), np.array(df.low),np.array(df.close)]).T
s5.columns = ['open', 'high', 'low','close']
sns.boxplot(data = s5)
#sns.boxplot(title = 'box plot 4 dimensions', data = s5)
plt.show()
直方图(Histogram)
df.hist(column=["open", "high","low","close"],figsize=(14,9),facecolor="steelblue")
plt.show()
4. 特征
其实做特征这一步也可以算是数据预处理中的一个步骤,但由于这次的基础数据集真的很基础,建模所用的特征基本都是基于这个数据集通过一些金融公式计算出来的,所以特征单独写一个章节。这章除了代码的部分,还会引入一些金融方面的知识点。
第一步还是先把需要使用的代码包和数据导入。
import pandas as pd
import talib
data = pd.read_csv('EUR_USD_H1.csv')
high = data["high"].values
close = data["close"].values
low = data["low"].values
open = data["open"].values
volume = data['volume'].values
4.1 简单移动平均(Simple Moving Average, SMA)
SMA是一种分析时间序列的常用工具,公式如下,n代表时间周期。
我们把基于不同时间周期(n)的SMA都算出来。
def sma_to_df(mid_point, list_fw, list_sw):
# Create the dataframes
sma_fw_list = ['SMA_'+str(i) for i in list_fw] # Columns name of fast window
sma_sw_list = ['SMA_'+str(i) for i in list_sw] # Columns name of slow window
sma_fw, sma_sw = pd.DataFrame(columns = sma_fw_list, index=list(mid_point.index)),pd.DataFrame(columns = sma_sw_list, index=list(mid_point.index)) # Setup two empty dataframes
k,j = 0,0 # Reset the index with 0
# Create the dataframes of Simple Moving Average with different windows
for i in list_fw:
sma = talib.SMA(mid_point, timeperiod=i)
sma_fw.iloc[:,k] = sma
k += 1
for i in list_sw:
sma = talib.SMA(mid_point, timeperiod=i)
sma_sw.iloc[:,j] = sma
j += 1
sma_fw = sma_fw.fillna(0