五 量化交易全流程( 十 )

< ma2trend = np.zeros(n)trend[con_long] = 1trend[con_short] = -1# 仓位变化 , 比如从﹣1到1 , 变化为2sig = np.zeros(n)# 当前总仓位pos = np.zeros(n)# 新仓位的开仓价pce = np.zeros(n)# 保存交易信息trade_info = [" " for i in range(n)]# 每次开仓一手new_pos = 1
策略逻辑如下 , 在这里 , 我们首先定义了目标仓位 , 然后基于目标仓位计算了仓位变化(新的仓位) , 假设这里是使用开盘价作为交易价格 , 同时还记录了交易的log信息 , 以便于理解策略逻辑和进行调试 。
for i in range(L2, n):# 正常情况下 , 仓位保持不变pos[i] = pos[i-1]# 昨天收盘 , 新出现多头趋势 , 开盘就开多头仓(如果有空头仓 , 则先平空头仓)if trend[i-1] > 0 and pos[i-1] <= 0:# 目标仓位pos[i] = new_pos# 计算仓位变化sig[i] = new_pos-pos[i-1]# 记录交易价格pce[i] = open[i]# 记录交易log信息trade_info[i]=u'long at %s' %(pce[i])# 昨天收盘 , 新出现空头趋势 , 开盘就开空头仓(如果有多头仓 , 则先平多头仓)elif trend[i-1] < 0 and pos[i-1] >= 0:# 目标仓位pos[i] = -new_pos# 计算仓位变化sig[i] = -new_pos-pos[i-1]# 记录交易价格pce[i] = open[i]# 记录交易log信息trade_info[i]=u'short at %s' %(pce[i])
当然 , 最终我们还是要将结果转化成 , 以便于进行最后的处理和观察 。
df = pd.DataFrame({'open':open, 'high':high, 'low' :low, 'close':close, 'ma1':ma1, 'ma2':ma2, 'trend':trend, \'sig':sig, 'pce':pce, 'pos':pos, 'trade_info':trade_info},\columns=['open','high','low','close','ma1','ma2','trend','sig','pos','pce','trade_info'])df['new_pos'] = df['pos'] - df['pos'].shift(1)df['old_pos'] = df['pos'] - df['new_pos']df['p&l_new'] = (df['close']-df['pce']) * df['new_pos']df['p&l_old'] = (df['close']-df['close'].shift(1)) * df['old_pos']df['p&l'] = df['p&l_new'] + df['p&l_old']del df['new_pos']del df['old_pos']del df['p&l_new']del df['p&l_old']df=df.dropna()print(df)np.sum(df['p&l'])
下面我们来看一下df的值 , 如图所示 。(买茅台属于亏钱状态)
换了一组股票测试:蔚蓝锂芯
不考虑手续费情况下是赚钱的 , 但如果考虑手续费每买一次就5块 , 或者买的量越大 , 按照资金量比例来算也是亏钱的 。
下面是完整代码:(拉取数据——测算收益)
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, L1, L2):self.host = '127.0.0.1'self.user = 'root'self.password='152617'self.port= 3306 self.db='stock_info'self.L1 = L1self.L2 = L2def 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