
这几天刷某音,看到有位博主天天晒自己在A股"开超市"的盈利视频。比如6月12日盈利4106元,整个6月目前已经盈利6550元,看得花姐心里直痒痒~那问题来了:在A股搞这个"超市模式",真的像他说的那么赚钱吗?我们还是用实打实的数据来说话

我定了一个简单的策略:
1、股票市值要介于50到200亿之间
2、股票出现日线底分型(某相邻的3个K,中间的K最低价和最高价是3个K中最小值,且中间的K收红,这里只做一个简单的判断,不处理K线的包含关系):

3、这个底分型处于近10个K线的最低点,如下图:

4、11号和10号k相比,如果11号K放量(11k成交量/10K成交量>=1.3) 5、开仓K的开盘价涨幅不超过2%
满足上面5个条件我就买100股。如果开仓以后又出现符合上面5个条件的会继续开仓。期间不设置止损,当股票收益达到某个设定值以后就平仓。
策略有了,接下来看看回测结果。
原计划是根据每天市值动态调整股票池,但是这个数据不好找,于是我简化了下:以2024年6月13日的市值作为筛选基础,选出当时市值在50~200亿之间的所有股票作为股票池
第一次回测我初始资金设置了10万,手续费是5元(买卖一次就花费10元),盈利10%就平仓。回测日期是2024年1月1日到2025年6月13日。
开仓321次,不算没平仓的,盈利221次,胜率68.85%,总收益22.96%,这战绩还不错,相信跑赢了大多数人。

第二次回测,盈利设置成了20%其它的不变。 开仓189次,盈利94个,胜率49.74%,总收益20.65%,没有盈利10%的好,不过也差不太多。

接下来是回测代码
首先是行情数据,一开始打算选baostock和掘金量化的API的,但是下载速度太慢,于是改成从通达信软件直接导出txt行情数据。行情文件名如下格式:

读取txt行情文件我单独写了一个方法
python
import pandas as pd
from datetime import datetime
def read_tdx_txt(file_path, encoding='gbk'):
"""
读取通达信导出的txt格式行情数据
参数:
file_path (str): 文件路径
encoding (str): 文件编码,默认'gbk'(通达信导出文件常用编码)
返回:
pandas.DataFrame: 包含日期、开盘价、最高价、最低价、收盘价、成交量的DataFrame
"""
# 定义通达信导出的txt文件列名
columns = ['date', 'open', 'high', 'low', 'close', 'volume','amount']
# 读取文件,处理逗号分隔和表头
df = pd.read_csv(
file_path,
sep=',', # 逗号分隔符
encoding=encoding, # 使用指定编码
header=1, # 第二行(索引1)作为表头
skiprows=0, # 跳过开头的说明行
skipfooter=1, # 跳过末尾的"数据来源"行
engine='python', # 用于支持skipfooter参数
names=columns,
parse_dates=['date'], # 自动解析日期列
dtype={
'open': float, # 开盘价为浮点型
'high': float, # 最高价为浮点型
'low': float, # 最低价为浮点型
'close': float, # 收盘价为浮点型
'volume': int, # 成交量为整数型
'amount': float # 成交额为浮点型
}
)
df.sort_values(by='date', inplace=True) # 按日期排序
return df
if __name__ == "__main__":
file_path = r'F:\tdx_hq\BJ#430198.txt' # 替换为你的文件路径
df = read_tdx_txt(file_path)
print(df) # 打印前几行数据
回测代码,为了让回测速度快一些,我直接把行情都读取到内存中了,速度是比直接读TXT要快很多,感兴趣的可以把代码复制一份自己改改
回测框架逻辑如下:循环所有交易日,检查持仓是否达到止盈条件,满足就平仓,遍历股票池,是否符合"底分型+量价配合"条件,如果符合则开仓,每天记录账户的净值、持仓和现金方便后期统计。
完整代码如下:
python
import pandas as pd
import numpy as np
import os
import data_utils
# ===参数===
initial_cash = 100000
buy_fee = sell_fee = 5
position_size = 100 # 每次买100股
data_path = r'F:\tdx_hq' # 存行情CSV的路径
start_date = pd.to_datetime('2024-01-01') # 回测起始日期
# ===读取股票池===
stock_pool = pd.read_excel('stock_pool.xlsx')['代码'].astype(str).tolist()
# ===一次性读取所有股票数据===
stock_data = {}
for stock in stock_pool:
df = data_utils.read_tdx_txt(os.path.join(data_path, f'{stock}.txt'))
df = df.sort_values('date').reset_index(drop=True)
stock_data[stock] = df
# ===初始化状态===
portfolio = {} # 当前持仓:key = stock_日期, value = dict
trade_log = [] # 交易记录
daily_account = [] # 每日账户信息
cash = initial_cash #现金
# ===获取所有交易日(并集)===
all_dates = sorted(
d for d in set().union(*[df['date'].tolist() for df in stock_data.values()])
if d >= start_date
)
# ===辅助函数:判断底分型===
def is_bottom_fractal(prices):
return prices[1] < prices[0] and prices[1] < prices[2]
# ===回测主循环===
for current_date in all_dates:
print(current_date)
stock_value = 0 #持有的股票总市值
# ===先遍历所有持仓,检查是否平仓===
closed_positions = []
for key, pos in portfolio.items():
stock = pos['stock']
df = stock_data[stock]
idx_list = df.index[df['date'] == current_date].tolist()
if not idx_list:
continue
idx = idx_list[0]
close_price = df.loc[idx, 'close']
ret = (close_price - pos['buy_price']) / pos['buy_price']
if ret >= 0.2:
# 满足收益,平仓
cash += close_price * position_size - sell_fee
closed_positions.append(key)
for r in trade_log:
if r['stock'] == stock and r['buy_date'] == pos['buy_date'] and r['sell_date'] is None:
r['sell_date'] = current_date
r['sell_price'] = close_price
r['return'] = round(ret, 4)
break
for key in closed_positions:
del portfolio[key]
# ===遍历所有股票,判断是否开仓===
for stock in stock_pool:
df = stock_data[stock]
idx_list = df.index[df['date'] == current_date].tolist()
if not idx_list:
continue
idx = idx_list[0]
if idx < 13:
continue
open_n = df.loc[idx, 'open']
close_n = df.loc[idx, 'close']
close_n1 = df.loc[idx - 1, 'close']
volume_n1 = df.loc[idx - 1, 'volume']
volume_n2 = df.loc[idx - 2, 'volume']
recent_low = df.loc[idx - 12:idx, 'low'].min()
# 判断底分型 + n-2 是最低点 + 开盘涨幅 + 成交量放大
if not is_bottom_fractal(df.loc[idx - 3:idx - 1, 'low'].values):
continue
if not is_bottom_fractal(df.loc[idx - 3:idx - 1, 'high'].values):
continue
if not df.loc[idx-2,'open']<df.loc[idx-2,'close']:
continue
if df.loc[idx - 2, 'low'] != recent_low:
continue
if (open_n - close_n1) / close_n1 > 0.02:
continue
if volume_n1 < 1.3 * volume_n2:
continue
# 满足开仓条件,直接开仓
if cash >= open_n * position_size + buy_fee:
cash -= open_n * position_size + buy_fee
portfolio_key = f"{stock}_{current_date.strftime('%Y%m%d')}"
portfolio[portfolio_key] = {
'stock': stock,
'buy_price': open_n,
'buy_date': current_date
}
trade_log.append({
'stock': stock,
'buy_date': current_date,
'buy_price': open_n,
'sell_date': None,
'sell_price': None,
'return': None
})
# 计算持仓的市值
for key, pos in portfolio.items():
stock = pos['stock']
df = stock_data[stock]
idx_list = df.index[df['date'] == current_date].tolist()
if not idx_list:
continue
idx = idx_list[0]
close_price = df.loc[idx, 'close']
stock_value += close_price * position_size
# ===记录每日账户信息===
daily_account.append({
'date': current_date,
'cash': round(cash, 2),
'total_value': round(stock_value+cash, 2),
'stock_value': round(stock_value, 2)
})
# ===输出结果===
trade_df = pd.DataFrame(trade_log)
account_df = pd.DataFrame(daily_account)
trade_df.to_csv('交易记录.csv', index=False, encoding='utf-8-sig')
account_df.to_csv('账户净值.csv', index=False, encoding='utf-8-sig')
这个策略虽说比较简单,但胜在清晰易操作,回测效果也挺稳健。特别是第一版策略(10%止盈)胜率高、回撤小,算是一个不错的"短线半自动超市模型"了。
当然,这只是历史回测,未来未必完全复制。但从策略逻辑看,它符合人性的"逢低潜伏、放量买入"的思路,有一定的实操价值。
以前写个策略要花很多时间,现在只要有清晰的想法,扔给AI就能快速产出,剩下只需人工检查逻辑、微调参数,大大提高了效率。
今天的策略分享就到这啦,喜欢的粉丝记得点个赞、转发支持一下!