五 量化交易全流程( 九 )


得到的结论为:你的最终收益可能跟股票走势没有关系 , 股票价格回升 , 但你的账户依旧在亏损 。
2、 For循环回测
诚然 , 如果能使用向量化的方法 , 就尽量使用向量化的方法 , 因为向量化的方法代码简洁 , 而且效率很高 。不过 , 仍然有很多逻辑是向量化方法无法实现的 。遇到这种情况 , 我们就不得不使用For循环的方法 。不过值得注意的是 , 在中 , For循环的效率是比较低的 , 比如 , 对或者 进行循环操作 , For循环的效率都比较低 。所以碰到循环的时候 , 最好先转化成NumPy里的数据结构 , 再进行循环 。为了让大家对效率有一个直观的感受 , 这里我们做一个小实验 , 来测一下速度差异 。
首先 , 生成两个同样大小的数组 , 一个是NumPy的array , 一个是里的,代码如下:
import numpy as npimport pandas as pd# 生成ndarraya = np.arange(100)# 生成Seriess = pd.Series(a)# 随机生成索引i = np.random.randint(0, 99)# 使用魔法函数%timeit来测算运行时间# 测算ndarray的时间%timeit a[i]# 测算Seried的效率%timeit s[i]
使用魔法函数%来测算运行时间结果为:=1us
可以看到 , 所花的时间是的20倍左右 , 可以说差距是非常的大了 。由于篇幅有限 , 这里不会对其中的原理进行分析 , 感兴趣的朋友可以自行搜索关于性能优化的内容 。
总之 , 我们知道了在循环上具有非常大的效率优势 , 所以这里使用来获取测试数据 , 代码如下:
import mysql.connectorimport pymysqlimport pandas as pdimport numpy as npimport talib as tafrom mpl_finance import candlestick_ohlcimport matplotlib as mplimport matplotlib.pyplot as pltimport matplotlib.dates as mdatesimport datetimempl.rcParams['font.sans-serif'] = ['SimHei']# 指定默认字体mpl.rcParams['axes.unicode_minus'] = False# 解决保存图像是负号'-'显示为方块的问题class StockData:def __init__(self):self.host = '127.0.0.1'self.user = 'root'self.password='152617'self.port= 3306 self.db='stock_info'def data_convert(self, sql_data):# 拉取数据库对数据进行转换sql_data["open"] = sql_data['open'].astype(float)sql_data["high"] = sql_data['high'].astype(float)sql_data["low"] = sql_data['low'].astype(float)sql_data["close"] = sql_data['close'].astype(float)sql_data["volume"] = sql_data['volume'].astype(float)sql_data = http://www.kingceram.com/post/sql_data.dropna()return sql_datadef get_stock_data(self, stock_code, start_date, end_date):# 拉取数据stock_dataconn = pymysql.connect(host=self.host, user=self.user, password=self.password, port=self.port, db=self.db, charset='utf8')cur = conn.cursor()sql = f"select * from `stocks` where stock_code = {stock_code} and date > {start_date} and date < {end_date}"cur.execute(sql)data = http://www.kingceram.com/post/cur.fetchall()data = pd.DataFrame(data)data = data.rename(columns={0:"date", 1: "stock_code", 2: "open", 3: "high", 4: "low", 5: "close", 6: "volume"})stock_data = http://www.kingceram.com/post/self.data_convert(data)cur.close()conn.close()return stock_datasd = StockData()stock_code = '002245'start_date = '20230104'end_date = '20230904'stock_dt = sd.get_stock_data(stock_code, start_date, end_date)print(stock_dt)
初始化相关的变量 , 在这里 , 我们对每一个变量 , 都使用一个单独的 , 比如pos就代表了总的仓位 , 代码如下:
open = df.open.valueshigh = df.high.valueslow = df.low.valuesclose= df.close.values# 总的样本数量n = len(close)# 两条均线的参数L1 = 3L2 = 7# 使用talib计算移动均线ma1 = ta.SMA(df.close.values,timeperiod=L1)ma2 = ta.SMA(df.close.values,timeperiod=L2)# 计算趋势con_long = ma1 > ma2con_short = ma1