QUANTAXIS探索(三)多股回测

QUANTAXIS单股回测( QUANTAXIS探索(二)策略运行)使用了QAStrategyStockBase类,但该类用于多股回测会有一些不方便之处,来看源代码,回测会调用debug函数,

def debug(self):
        ... ...
        #data可以对多只股票获取行情,是pandas多重索引
        data = QA.QA_quotation(self.code, self.start, self.end, source=QA.DATASOURCE.MONGO,
                               frequence=self.frequence, market=self.market_type, output=QA.OUTPUT_FORMAT.DATASTRUCT)
		#针对每一行进行迭代
        data.data.apply(self.x1, axis=1)

多股的数据示例如下:
在这里插入图片描述
由于代码针对每一行进行迭代,对于N个股票,则同一天会被迭代N次on_bar事件。虽然self.x1函数在换日时会调用self.self.on_dailyclose()函数,但最新的数据没有传过去,需要额外的处理逻辑,同时循环需要的次数也会增加。

为了简化处理,需要重写debug逻辑。

class MyStrategy(QAStrategyStockBase):
	def __init__(self,init_cash=1000000):
	'''
	原来的debug函数,现金是指定的,所以修改以动态定义初始现金
	'''
		self.init_cash=init_cash
		super().__init()
    def user_init(self):
        self.counter=0
    def debug(self):
            self.running_mode = 'backtest'
            self.database = pymongo.MongoClient(mongo_ip).QUANTAXIS
            user = QA_User(username=self.username, password=self.password
            port = user.new_portfolio(self.portfolio)
            # 每次重置账户历史,不然quantaxis对于同一标识的account,会保存所有历史运行数据
            try:
                port.drop_account(self.strategy_id)
            except:
                pass
            self.acc = port.new_accountpro(
                account_cookie=self.strategy_id, 
                init_cash=self.init_cash,
                market_type=self.market_type, 
                frequence=self.frequence
            	)
			# 适配多股结构
            self.positions={}
            for code in self.code:
                self.positions[code] = 0
            print(self.acc.market_type)
            data = QA.QA_quotation([code.upper() for code in self.code], 
            self.start, 
            self.end, 
            source=QA.DATASOURCE.MONGO,
            frequence=self.frequence, 
            market=self.market_type, output=QA.OUTPUT_FORMAT.DATASTRUCT)

            #data.data.apply(self.x1, axis=1)
            # 按日滚动回测
            data.data.groupby('date').apply(self.x_by_period)
            
    def x_by_period(self, group):           
            items=[]
            date=group.name
            for _,item in group.iterrows():    
				# 初始化on_bar中的数据
                item['code']=item.name[1]
                item['date']=date               
                items.append(item)
                self.latest_price[item.name[1]] = item['close']
                self._market_data.append(copy.deepcopy(item))
            if str(date)[0:10] != str(self.running_time)[0:10]:
                self.on_dailyclose()
                self.on_dailyopen()
                if self.market_type == QA.MARKET_TYPE.STOCK_CN:
                    print(f'backtest: {str(date)[0:10]} Settle!')
                    self.acc.settle()
            self._on_1min_bar()
            
            self.running_time = str(date)
            self.on_bar(items)
    def on_bar(self,data):
    '''
    data是一个list结构,对应当日所有股票的数据。
    data[0]为第一只,data[0]的结构是pd.Series
    可以用bar['code'],也可以用bar.code访问
    '''
        # 任意定义一个策略,T日买,T+10日卖
        # 这里使用了期货的概念,买开,卖平等,所以有BUY/SELL,'OPEN'/'CLOSE'等区分
        for bar in data:
            if self.counter % 15 == 0:
                    print('buy')
                    self.send_order('BUY','OPEN',code=bar.code,price=bar.open,volume=10000)            
            if self.counter % 15== 10:
                    print('sell')
                    self.send_order('SELL','CLOSE',code=bar.code,price=bar.open,volume=10000)
        self.counter+=1
    

策略运行:

if __name__ == "__main__":   
    code_list = ['000001','000002']
    s = MyStrategy(
        code=code_list,
        frequence="day",
        start="2020-05-01",
        end="2021-06-05",
        strategy_id="test",
    )
    s.run_backtest()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值