交易封装

交易封装,第1张

量化交易涉及到的策略有若干,并且一个策略往往也需要大量的历史数据去验证它的效果。本着面向对象编程的原则,交易行为最好也进行封装。

那么思考,如果用类来封装,它的作用是什么,需要有哪些属性、实现哪些功能呢?

其实很简单,想象一下,有这么一个类:里面有很多的交易策略,我们将历史行情数据丢给它,它会自动计算出相应的各种指标(均线、布林带等),再根据我们选定的策略、每次交易数量、账户本金,自动完成对账户的 *** 作。

我们丢历史行情数据给它,它反馈给我们 *** 作后的账户详情。需要的不就是这么个玩意吗!

本次我们可以将第一篇布林带——泡泡玛特中的策略添加进去,方便未来考量它的综合表现。

代码如下:

其中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,将始终保持最新版本

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/726744.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-04-26
下一篇2022-04-26

发表评论

登录后才能评论

评论列表(0条)

    保存