def simulate_trade(self, trade_list, trade_dates, close_dict, max_num=None):
    # 模拟交易过程,并获取每个交易日和持有日的资金列表和资产列表,返回这两个列表
    position = {} # 持仓字典,格式为{股票1: 持仓数量,}
    cash = 100000 # 初始资金,单位为元
    cash_list = [cash] # 资金列表,记录每个交易日的资金情况
    asset_list = [cash] # 资产列表,记录每个交易日和持有日的总资产情况
    date_list = []
    # 将trade_list转换成买入字典和卖出字典
    buy_dict = {} # 买入字典,格式为{日期: [股票1, 股票2],}
    sell_dict = {} # 卖出字典,格式为{日期: [股票1, 股票2],}
    for buy_date, sell_date, codes in trade_list:
        for code in codes:
            buy_dict.setdefault(buy_date, []).append(code)
            sell_dict.setdefault(sell_date, []).append(code)
        date_list.append(buy_date)
        date_list.append(sell_date)
    date_list = sorted(list(set(date_list)))
    # 遍历每个交易日和持有日,模拟交易过程
    for date in trade_dates:
        # 检查是否是交易日
        if date in date_list:
            # 检查是否有需要卖出的股票
            for code in sell_dict.get(date, []):
                # 获取当天该股票的收盘价作为卖出价
                if code not in close_dict:
                    continue
                sell_price = close_dict[code].loc[date]
                # 检查是否可以交易
                while np.isnan(sell_price):
                    date = pd.to_datetime(date) + pd.Timedelta(days=1)
                    date = date.strftime('%Y-%m-%d')
                    if date not in close_dict:
                        break
                    sell_price = close_dict[code].loc[date]
                if np.isnan(sell_price):
                    continue
                # 计算卖出所得的资金,并更新持仓和资金
                if code in position:
                    sell_amount = position[code] * sell_price
                else:
                    print('%s持仓中找不到%s:
%s' % (date, code, ', '.join(position.keys())))
                    continue
                cash += sell_amount
                position.pop(code)
            # 检查是否有需要买入的股票
            for code in buy_dict.get(date, []):
                # 获取当天该股票的收盘价作为买入价
                if code not in close_dict:
                    continue
                buy_price = close_dict[code].loc[date]
                # 检查是否可以交易
                while np.isnan(buy_price):
                    date = pd.to_datetime(date) + pd.Timedelta(days=1)
                    date = date.strftime('%Y-%m-%d')
                    if date not in close_dict:
                        break
                    buy_price = close_dict[code].loc[date]
                if np.isnan(buy_price):
                    continue
                # 计算可以买入的数量,并更新持仓和资金
                buy_amount = cash / len(buy_dict[date]) # 平均分配资金
                buy_volume = int(buy_amount / buy_price / 100) * 100 # 向下取整到100的倍数
                if max_num is not None: # 检查是否需要限制买入股票数量
                    buy_volume = min(buy_volume, int(cash / max_num / buy_price / 100) * 100)
                if code in position:
                    max_volume = int(0.1 * cash / position[code] / buy_price / 100) * 100 # 检查是否需要限制股票的仓位
                    buy_volume = min(buy_volume, max_volume)
                if buy_volume > 0: # 检查资金是否足够买入
                    cash -= buy_volume * buy_price
                    position[code] = position.get(code, 0) + buy_volume
                    if max_num is not None and len(position) > max_num: # 检查是否需要卖出股票
                        excess_codes = sorted(position, key=lambda x: position[x], reverse=True)[max_num:]
                        for code in excess_codes:
                            sell_price = close_dict[code].loc[date]
                            if np.isnan(sell_price) or code not in position:
                                continue
                            sell_volume = position[code]
                            sell_amount = sell_volume * sell_price
                            cash += sell_amount
                            position.pop(code)
            # 计算当天的总资产
            cash_list.append(cash)
            total_asset = cash
            for code, volume in position.items():
                if code not in close_dict:
                    continue
                if date in close_dict[code].index:
                    price = close_dict[code].loc[date]
                else:
                    sub = close_dict[code].loc[:date]
                    if len(sub) == 0:
                        logger.info('can not find %s for %s in
%s' % (date, code, sub))
                    price = sub.iloc[-1]
                total_asset += volume * price
            # 将当天的总资产加入到资金列表和资产列表中
            asset_list.append(total_asset)
    return cash_list, asset_list
Python 模拟交易函数:支持多种购买策略和交易日检查

原文地址: https://www.cveoy.top/t/topic/nMJ0 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录