
量化交易涉及到的策略有若干,并且一个策略往往也需要大量的历史数据去验证它的效果。本着面向对象编程的原则,交易行为最好也进行封装。
那么思考,如果用类来封装,它的作用是什么,需要有哪些属性、实现哪些功能呢?
其实很简单,想象一下,有这么一个类:里面有很多的交易策略,我们将历史行情数据丢给它,它会自动计算出相应的各种指标(均线、布林带等),再根据我们选定的策略、每次交易数量、账户本金,自动完成对账户的 *** 作。
我们丢历史行情数据给它,它反馈给我们 *** 作后的账户详情。需要的不就是这么个玩意吗!
本次我们可以将第一篇布林带——泡泡玛特中的策略添加进去,方便未来考量它的综合表现。
代码如下:
其中account是我们上一篇账户封装中保存好的account.py文件,封装了有关账户的所有 *** 作
import pandas as pd
import akshare as ak
import numpy as np
import dateutil
import account #导入账户管理类
# 获取n日收盘均价
def get_ma(data, n):
# 创建列 ‘ma(n)’
ma = 'ma{}'.format(n)
data[ma] = np.nan
# 计算n日收盘均价并保存到data
for i in range(n, data.shape[0]) :
data[ma][i] = data['收盘'][i-n:i].mean()
return data
# 获取布林带上下轨
def get_boll(data):
data['upper'] = np.nan
data['lower'] = np.nan
# boll上下轨由20日均线计算得出
for i in range(20,data.shape[0]):
data['upper'][i] = data['ma20'][i] + 2*data['收盘'][i-20:i].std()
data['lower'][i] = data['ma20'][i] - 2*data['收盘'][i-20:i].std()
return data
class Trade:
"""
交易类,封装了和交易相关的所有 *** 作
"""
def __init__(self, symbol, data, trade_strategy, trade_amount = 100 , capital = 100000, start_date = '1900-01-01', end_date = '2099-01-01',max_volatility = None):
self.symbol = symbol
self.data = data
self.trade_amount = trade_amount
self.trade_strategy = trade_strategy
self.capital = capital
self.start_date = start_date
self.end_date = end_date
self.max_volatility = max_volatility
# 初始化数据
self.init_data()
# 创建账户,并初始化asset
self.account = account.Account(self.capital)
def init_data(self):
# 数据整理
self.data['日期'] = pd.to_datetime(self.data['日期'])
# 从指定日期前60日切片,是为了减少计算均线、布林带的范围,同时保证指定日期内的数据完整
self.data = self.data[self.data['日期'] >= pd.to_datetime(self.start_date) - dateutil.relativedelta.relativedelta(days = 60)][self.data['日期'] <= pd.to_datetime(self.end_date)].reset_index(drop = True)
# 分别获取ma5,ma10,ma20,ma30
for i in (3,5,8,10,12,15,20,30,35,40,45,50,60):
self.data = get_ma(self.data,i)
# 获取boll上下轨
self.data = get_boll(self.data)
# 取出指定期间内的数据
self.data = self.data[self.data['日期'] >= pd.to_datetime(self.start_date)].reset_index(drop = True)
def if_limit_move(self,high,low,rise):
# 有涨跌幅限制时,判断是否一字涨停或跌停
if self.max_volatility:
return True if high == low and rise >= self.max_volatility else False
def by_boll(self):
## 跌破下轨买入,突破上轨清仓
for i in range(0, self.data.shape[0]):
# 如果当天一字涨停或者跌停,无需交易
if self.if_limit_move(self.data.iloc[i].最高, self.data.iloc[i].最低, self.data.iloc[i].涨跌幅):
self.account.no_trade_update_asset(self.data.iloc[i].日期, self.symbol, self.data.iloc[i].收盘)
continue
# 布林带数据为空无需判断买卖时,只需更新资产数据
if pd.isnull(self.data.iloc[i]['ma20']) :
self.account.no_trade_update_asset(self.data.iloc[i].日期, self.symbol, self.data.iloc[i].收盘)
else:
if self.data.iloc[i].收盘 < self.data.iloc[i].lower and (self.account.asset.iloc[-1].cash >= self.data.iloc[i].收盘 * self.trade_amount ) :
self.account.trade_update(
self.data.iloc[i].日期,
'B',
self.symbol,
self.trade_amount,
self.data.iloc[i].收盘
)
# 当日收盘价上穿upper,且有持仓时,以收盘价清仓
elif self.data.iloc[i].收盘 > self.data.iloc[i].upper and (
self.symbol in self.account.position['symbol'].values and self.account.position[self.account.position['symbol'] == self.symbol].iloc[-1].amount > 0) :
self.account.trade_update(
self.data.iloc[i].日期,
'S',
self.symbol,
self.account.position[self.account.position['symbol'] == self.symbol].iloc[-1].amount,
self.data.iloc[i].收盘
)
# 无买卖 *** 作时,更新资产数据
else:
# date, symbol, price
self.account.no_trade_update_asset(self.data.iloc[i].日期, self.symbol, self.data.iloc[i].收盘)
def main(self):
#选择交易策略
if self.trade_strategy == 'boll' :
self.by_boll()
else :
pass
使用方式:
将该代码存放在quan_trade.py文件中,至此,账户和交易被连成了一个整体,并完整的封装了起来,后面使用时只需导入quan_trade.py文件,丢给它相应的数据及参数,就可以返回 *** 作后的账户数据
-
类创建需传入的参数:
-
symbol,交易股票的代码
-
data, 该股票的历史行情数据(DataFrame,其字段名需满足一定规范,如下图红圈所示)
-
trade_strategy, 交易策略(boll、mean ...)
-
trade_amount, 交易数量(默认值为100)
-
capital, 初始本金(默认值为10w)
-
start_date, 开始日期(默认值1900-01-01)
-
end_date, 截止日期(默认值2099-01-01,起始、截止日期的设置意味着默认时间范围不受限制)
-
max_volatility 涨跌限制(默认值为None,意味着无涨跌限制。应该传入对应股票单日的最大涨跌幅,比如A股主板,应该传入数字10)
-
-
方法:
-
self.main —— 调用此方法,会根据选定的策略更新账户所有相关数据
-
-
属性:
-
self.account —— Account的实例化对象,具备其所有的属性及方法
-
self.account.asset —— 资产详情 (日期、总资产、现金、股票资产、收益、收益率)
-
self.account.position —— 持 仓 (日期、股票代码、持仓市值、持仓数量、成本价、持仓收益、持仓收益率)
-
self.account.order —— 订单记录 (日期、交易方式 B/S、股票代码、交易数量、交易价格)
-
self.account.plot_profit_rate —— 调用此方法,绘制 self.account.asset 的收益率曲线
-
-
注:该文件中的内容可能随着后期需求,不断迭代完善。源码放在了https://github.com/kaiforone/quantized-trade.git,将始终保持最新版本
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)