基于AKShare的MFI量化交易策略实战解析

量化交易:止盈策略与回测 用代码表示大跌时买入,达到目标收益率时清仓,并回测输出收益率。 阅读详情

1. 从零开始:为什么选择AKShare和MFI指标?

如果你刚开始接触量化交易,面对一堆数据接口和复杂的指标,是不是有点无从下手?我刚开始的时候也一样,光是选数据源就纠结了好久。后来我发现,对于国内市场的初学者来说,AKShare 真的是一个宝藏工具。它完全免费,数据源稳定,覆盖了A股、港股、期货、基金等几乎所有你能想到的国内金融数据,而且接口调用方式非常“Pythonic”,对新手极其友好。你不用再去折腾各种付费API或者自己爬数据,省下来的时间和精力,可以更专注于策略逻辑本身。

那为什么是 MFI指标 呢?很多朋友可能更熟悉RSI(相对强弱指数)。MFI可以看作是RSI的“亲兄弟”,但它更“聪明”一点。RSI只考虑价格变化,而MFI在计算时,把成交量也加了进去。你可以把它理解为一个“带成交量的RSI”。这个设计让它能更好地反映资金流入流出的真实情况。想象一下,价格上涨但成交量萎缩,这可能只是虚高;而价格上涨伴随着成交量放大,则说明有真金白银在推动。MFI就是试图捕捉这种“钱”的动向,所以它也叫“资金流量指标”。

用AKShare获取数据,再用MFI来构建策略,这个组合特别适合新手入门。一方面,数据获取的门槛被降到了最低;另一方面,MFI的逻辑直观,不像一些复杂的机器学习模型那样是个黑箱。你能清楚地知道每一个买卖信号是怎么产生的,这对于建立对量化交易的“手感”和信心非常重要。我自己就是从这类简单的价量指标策略开始,一步步踩坑、优化,才慢慢深入到更复杂的领域。接下来,我就带你手把手走一遍完整的流程。

2. 实战第一步:搭建你的Python量化环境

工欲善其事,必先利其器。一个干净、稳定的开发环境是成功的第一步。我强烈建议你使用 Anaconda 来管理Python环境,它能很好地解决不同项目之间包版本冲突的噩梦。

首先,我们去Anaconda官网下载并安装最新版本。安装完成后,打开你的终端(Windows叫Anaconda Prompt)来创建一个专属的量化环境:

conda create -n quant_env python=3.9
conda activate quant_env

这里我指定了Python 3.9,这是一个在兼容性和稳定性上比较平衡的版本。环境名字叫 quant_env,你可以按自己喜欢来命名。激活环境后,我们开始安装核心的“三件套”:

pip install pandas numpy matplotlib

这三个是数据分析与可视化的基石。pandas 用来处理表格数据,numpy 负责数值计算,matplotlib 则是画图神器。接下来安装今天的主角:

pip install akshare
pip install TA-Lib

安装 akshare 通常很顺利。但 TA-Lib 可能会是个小坎,因为它底层有C库依赖。如果直接用 pip install TA-Lib 失败了,别慌。在Windows上,可以去这个非官方网站下载对应你Python版本和系统位数的 .whl 文件,比如 TA_Lib‑0.4.24‑cp39‑cp39‑win_amd64.whl,然后在文件所在目录执行 pip install 文件名.whl。Mac用户可以用 brew install ta-lib 先安装库,再 pip install TA-Lib。Linux用户一般用系统包管理器安装 ta-lib 开发包即可。

最后,我习惯再装一个 jupyter lab,它比传统的 jupyter notebook 界面更现代,操作也更方便,非常适合做交互式的数据分析和策略研究。

pip install jupyterlab

安装完成后,在终端输入 jupyter lab,浏览器就会自动打开一个清爽的工作界面。我们在里面新建一个Python笔记本,就可以开始我们的探索了。记得在代码开头,把必要的包都导入进来,这是我们的标准起手式:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import akshare as ak
import talib as ta
import warnings
warnings.filterwarnings('ignore') # 暂时忽略一些警告信息,让输出更干净

# 设置 matplotlib 支持中文显示,不然图表里的中文会变成方框
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

3. 用AKShare轻松获取A股行情数据

数据是量化交易的“粮食”。以前获取数据特别麻烦,要么花钱买,要么自己写爬虫,还要担心数据格式不统一、源不稳定。AKShare的出现,可以说把这个问题简化了90%。它把各大财经网站的数据接口封装成了统一的函数,我们只需要关心自己要什么数据,调用对应的函数就行。

比如,我们要获取上证指数(代码 sh000001)从2016年至今的日线数据,只需要一行代码:

# 获取上证指数日线数据
df_index = ak.stock_zh_a_daily(symbol="sh000001", start_date="2016-01-01", end_date="2023-12-31", adjust="qfq")
print(df_index.head())

看看返回的 DataFrame,你会看到 date, open, high, low, close, volume 这些熟悉的字段,数据非常规整。参数 adjust="qfq" 表示获取的是前复权数据,这非常重要,它能保证价格在除权除息后依然有连续性,回测结果才真实可信。

除了大盘指数,获取个股数据也一样简单。比如你想分析贵州茅台:

# 获取贵州茅台(股票代码600519)的日线数据
df_stock = ak.stock_zh_a_daily(symbol="sz000858", start_date="2020-01-01", adjust="qfq")

这里注意,AKShare里A股的代码符号,沪市是 sh 开头,深市是 sz 开头。有时候我们想批量获取多只股票的数据,比如沪深300成分股,AKShare也提供了支持。你可以先获取成分股列表,再循环调用接口。但这里有个小技巧,批量获取时最好在每次请求间加个短暂延时,避免给数据源服务器造成太大压力,这也是一个负责任的开发者应有的习惯。

# 示例:获取沪深300成分股列表(这里只是个思路示例)
# stock_hs300_constituent = ak.index_stock_cons_csindex(symbol="000300")
# 实际批量获取时,建议使用循环并加入 time.sleep(0.5)

拿到数据后,我们通常要做一些预处理。最基本的是把 date 列设置为索引,并按照时间排序,这样后续按时间序列计算才会正确。

df_index['date'] = pd.to_datetime(df_index['date'])
df_index.set_index('date', inplace=True)
df_index.sort_index(inplace=True) # 确保按日期升序排列

然后,我们计算一下每日的收益率,这在回测中会频繁用到:

df_index['ret'] = df_index['close'].pct_change() # 今日收盘价相对于昨日收盘价的涨跌幅

数据准备好了,就像食材已经洗净切好,接下来就要开始烹饪——计算我们的核心指标MFI了。

4. 深入理解MFI指标的计算与市场含义

MFI,全称 Money Flow Index,资金流量指数。光看名字有点抽象,我们把它拆开揉碎了讲。它的核心思想是:通过结合价格和成交量,来判断资金是流入还是流出某个标的。

它的计算步骤可以分解为以下几步,我结合代码和比喻来解释:

  1. 计算典型价格(Typical Price):这不是简单的收盘价,而是(最高价+最低价+收盘价)/ 3。你可以把它看作当天交易价格的一个“平均重心”。
    typical_price = (high + low + close) / 3
    
  2. 计算原始货币流(Raw Money Flow):用典型价格乘以当天的成交量。典型价格 * 成交量。这很好理解,价格代表单价,成交量代表数量,两者相乘就是一个粗略的“成交金额”概念。
    raw_money_flow = typical_price * volume
    
  3. 区分正负货币流:这是MFI的精华所在。它比较今天和昨天的原始货币流。
    • 如果今天的原始货币流 > 昨天的,那么今天的钱流就被记为 正货币流(Positive Money Flow)。这代表有资金在积极买入推动。
    • 反之,则记为 负货币流(Negative Money Flow)。代表资金在流出或买入意愿不强。
  4. 计算货币比率(Money Ratio):在设定的周期内(默认14天),将所有的正货币流求和,所有的负货币流也求和,然后计算两者的比值。MR = (14期正货币流总和) / (14期负货币流总和)。
  5. 计算MFI值:最后通过一个公式将货币比率转化为0到100之间振荡的指数。MFI = 100 - [100 / (1 + MR)]。

这个公式的结果就是,MFI值会在0到100之间波动。它被广泛应用的法则有两条:

  • 超买超卖:通常认为MFI > 80时,市场处于超买状态,价格上涨可能过度,有回调风险;MFI < 20时,市场处于超卖状态,价格可能被低估,有反弹机会。
  • 背离:当价格创出新高,但MFI指标没有同步创出新高(顶背离),这可能是上涨动力不足的预警信号;反之,价格创新低而MFI未创新低(底背离),则可能预示着下跌动能衰竭。

听起来是不是和RSI很像?关键区别就在于成交量。我举个例子:假设股价连续小幅上涨,但成交量逐日萎缩。RSI可能因为价格上涨而进入高位,发出超买信号。但MFI会因为成交量这个“权重”因子很小,而使得货币流增长缓慢,可能就不会进入超买区。MFI认为,没有成交量配合的上涨是“虚”的,这通常能过滤掉一些假突破。

在Python中,我们不需要自己从头实现这个计算过程,TA-Lib库已经提供了高度优化的函数。我们拿到数据后,直接调用即可:

# 假设 df 是已经预处理好的DataFrame,包含 high, low, close, volume 列
high = df['high'].values
low = df['low'].values
close = df['close'].values
volume = df['volume'].values

# 计算14日周期的MFI
df['mfi'] = ta.MFI(high, low, close, volume, timeperiod=14)

计算完成后,我们可以把价格走势和MFI指标画在一起看看,直观感受一下:

fig, axes = plt.subplots(2, 1, figsize=(16, 10), sharex=True)
axes[0].plot(df.index, df['close'], label='收盘价', color='royalblue', linewidth=1.5)
axes[0].set_title('上证指数收盘价走势', fontsize=15)
axes[0].legend()
axes[0].grid(True, linestyle='--', alpha=0.5)

axes[1].plot(df.index, df['mfi'], label='MFI(14)', color='darkorange', linewidth=1.5)
axes[1].axhline(y=80, color='r', linestyle='--', alpha=0.7, label='超买线 (80)')
axes[1].axhline(y=20, color='g', linestyle='--', alpha=0.7, label='超卖线 (20)')
axes[1].fill_between(df.index, 20, 80, color='lightgray', alpha=0.3)
axes[1].set_title('MFI资金流量指数', fontsize=15)
axes[1].legend()
axes[1].grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()

从图上,你就能清晰地看到MFI如何在0-100区间波动,以及在触及20和80线时,价格往往可能发生转折。但这只是视觉上的观察,要把它变成可交易的策略,我们还需要明确的买卖规则。

5. 构建你的第一个MFI交易策略信号

看懂了指标,接下来就是制定规则。最简单的MFI策略就是基于它的超买超卖特性。但这里有个细节需要注意:我们是在指标穿越阈值时交易,而不是在指标处于阈值之外时一直持有。

一个经典的入门级规则是这样的:

  • 买入信号:当MFI从下方(小于20)向上突破20线时,我们认为市场可能从超卖区域恢复,在收盘时买入。
  • 卖出信号:当MFI从上方(大于80)向下跌破80线时,我们认为市场可能从超买区域回落,在收盘时卖出。

为什么要在“穿越”的瞬间行动?因为如果等MFI回到20-80区间中部再行动,可能会错过很大一段行情。这个“金叉死叉”式的思路在技术指标应用中非常普遍。

我们用代码来实现这个信号标记:

# 初始化信号列
df['signal'] = 0

# 循环判断,从第15个数据开始(因为MFI需要前14个数据计算)
for i in range(14, len(df)):
    # 当前MFI大于20,且前一日MFI小于20,产生买入信号(1)
    if df['mfi'].iloc[i] > 20 and df['mfi'].iloc[i-1] <= 20:
        df.loc[df.index[i], 'signal'] = 1
    # 当前MFI小于80,且前一日MFI大于等于80,产生卖出信号(-1),我们这里用0代表空仓
    elif df['mfi'].iloc[i] < 80 and df['mfi'].iloc[i-1] >= 80:
        df.loc[df.index[i], 'signal'] = 0
    # 其他情况,信号保持不变(使用前向填充)
    else:
        df.loc[df.index[i], 'signal'] = df['signal'].iloc[i-1]

# 第一天没有前一天的信号,我们假设初始状态为空仓(0)
df['signal'].iloc[:14] = 0

这里我用了 signal 为1代表持有,0代表空仓。注意,我们标记的信号是收盘时产生的,实际交易发生在下一个交易日开盘。所以,我们需要根据信号来计算每天的仓位。

# 当天收盘产生的信号,用于决定第二天的仓位。所以将信号列整体向下移动一行。
df['position'] = df['signal'].shift(1)
# 对NaN值进行前向填充,意味着一旦开仓,在收到卖出信号前将一直持有。
df['position'].fillna(method='ffill', inplace=True)
# 同样,初始仓位设为0
df['position'].iloc[0] = 0

现在,我们可以把买卖信号在价格图上标注出来,看看它大概抓到了哪些转折点。

plt.figure(figsize=(16, 8))
plt.plot(df.index, df['close'], label='收盘价', alpha=0.7, linewidth=1)

# 找出买入和卖出的时间点
buy_signals = df[df['signal'].diff() == 1]  # 信号从0变为1的时点
sell_signals = df[df['signal'].diff() == -1] # 信号从1变为0的时点

plt.scatter(buy_signals.index, buy_signals['close'], color='red', marker='^', s=100, label='买入信号', zorder=5)
plt.scatter(sell_signals.index, sell_signals['close'], color='green', marker='v', s=100, label='卖出信号', zorder=5)

plt.title('MFI策略买卖信号示意图', fontsize=16)
plt.legend()
plt.grid(True, linestyle='--', alpha=0.5)
plt.show()

图上那些红色的向上箭头和绿色的向下箭头,就是策略自动生成的买卖点。看起来它成功避开了几段明显的下跌(比如2018年),也在上涨初期发出了买入信号。但这只是“看起来不错”,我们需要用严谨的回测来验证它的真实盈利能力。

6. 策略回测与绩效分析:你的策略真的赚钱吗?

策略回测是量化交易的“试金石”。一个想法在纸上画出来再美,不经过历史数据的检验,都是空中楼阁。回测的核心思想是:假设我们严格按照策略信号在过去进行交易,最终会得到怎样的收益曲线和风险指标?

我们从最简单的“净值曲线”开始计算。假设初始资金为1元,每天根据仓位计算资产变化:

  • 如果当天仓位为1(满仓),那么当天净值增长率 = 股票收益率。
  • 如果当天仓位为0(空仓),那么当天净值增长率 = 0(假设闲置资金无收益,更复杂的模型可以考虑现金利息)。
# 计算策略每日收益率:仓位 * 股票收益率
df['strategy_ret'] = df['position'] * df['ret']

# 计算策略净值曲线和基准(一直持有)净值曲线
df['strategy_net'] = (1 + df['strategy_ret']).cumprod()
df['benchmark_net'] = (1 + df['ret']).cumprod()

# 画出对比图
plt.figure(figsize=(15, 7))
plt.plot(df.index, df['strategy_net'], label='MFI策略净值', color='darkred', linewidth=2)
plt.plot(df.index, df['benchmark_net'], label='基准(买入持有)净值', color='steelblue', linewidth=2, alpha=0.7)
plt.title('MFI策略 vs 买入持有策略 净值对比', fontsize=16)
plt.legend()
plt.grid(True, linestyle='--', alpha=0.5)
plt.ylabel('净值')
plt.show()

光看净值曲线还不够,我们需要几个关键指标来量化策略的好坏。我通常最关注这几个:

  1. 累计收益率:策略从开始到结束的总收益。
  2. 年化收益率:把总收益折算到每年,方便比较不同时间长度的策略。
  3. 最大回撤:策略净值从最高点到之后最低点的最大跌幅。这个指标非常重要,它衡量了你可能承受的最大亏损,直接关系到你的心态能否扛得住。
  4. 夏普比率:衡量承担每单位风险所获得的超额回报。简单说,就是收益和风险的“性价比”。通常大于1算不错。
  5. Alpha & Beta:Alpha代表超越市场基准的收益(选股能力),Beta代表策略相对于市场的波动性(系统风险)。

下面是一个计算这些指标的通用函数,你可以把它收藏起来,以后回测任何策略都能用:

def evaluate_strategy(df):
    """评估策略表现"""
    # 计算总收益率和年化收益率(假设一年250个交易日)
    total_return = df[['strategy_net', 'benchmark_net']].iloc[-1] - 1
    days = len(df)
    annual_return = (1 + total_return) ** (250 / days) - 1

    # 计算最大回撤
    # 计算累计最大值
    roll_max = df[['strategy_net', 'benchmark_net']].cummax()
    # 计算当前净值距离历史最高点的回撤
    drawdown = (df[['strategy_net', 'benchmark_net']] - roll_max) / roll_max
    max_drawdown = drawdown.min() # 最大回撤是负数,取最小值

    # 计算夏普比率 (假设无风险利率为3%)
    risk_free_rate = 0.03
    # 策略日度超额收益率
    excess_ret = df['strategy_ret'] - risk_free_rate/250
    sharpe_ratio = np.sqrt(250) * excess_ret.mean() / excess_ret.std()

    # 计算Alpha和Beta
    # 策略和基准的日收益率序列
    strategy_ret_series = df['strategy_ret']
    benchmark_ret_series = df['ret']
    # 计算协方差矩阵
    cov_matrix = np.cov(strategy_ret_series, benchmark_ret_series)
    beta = cov_matrix[0, 1] / cov_matrix[1, 1]
    alpha = annual_return['strategy_net'] - annual_return['benchmark_net'] * beta

    # 整理结果
    result = {
        '累计收益率_策略': f"{total_return['strategy_net']:.2%}",
        '累计收益率_基准': f"{total_return['benchmark_net']:.2%}",
        '年化收益率_策略': f"{annual_return['strategy_net']:.2%}",
        '年化收益率_基准': f"{annual_return['benchmark_net']:.2%}",
        '最大回撤_策略': f"{max_drawdown['strategy_net']:.2%}",
        '最大回撤_基准': f"{max_drawdown['benchmark_net']:.2%}",
        '夏普比率': f"{sharpe_ratio:.2f}",
        'Alpha': f"{alpha:.2%}",
        'Beta': f"{beta:.2f}"
    }
    return pd.Series(result)

# 调用函数查看结果
performance = evaluate_strategy(df)
print(performance.to_string())

把这些数字和图表放在一起看,你对这个策略的表现就有了一个立体、客观的认识。比如,你可能会发现策略年化收益率比基准低,但最大回撤也小很多,夏普比率更高。这意味着策略用更小的波动和回撤,获得了相对不错的风险调整后收益,对于厌恶风险的投资者来说,这可能就是一个好策略。

7. 策略优化与参数调优:让策略更适应市场

用默认的20和80阈值跑了一遍,结果可能不错,也可能一般。但这就结束了吗?当然不。任何一个策略都需要进行参数优化,但优化不是漫无目的地穷举,而是有逻辑地寻找更稳健的参数组合。

MFI策略主要有两个可调参数:超卖阈值(L) 和 超买阈值(H)。默认是20和80。我们可以尝试不同的组合,看看哪个在历史数据上表现更优。但这里我必须强调一个重要的原则:防止过拟合。你不能为了追求历史最高收益而把参数调得极其敏感,这样策略在未来很可能失效。

一个常用的方法是参数网格搜索。我们设定一个合理的范围,比如超卖阈值从10到30,超买阈值从70到90,步长为5,遍历所有组合进行回测。

def backtest_mfi_params(df, L_list, H_list):
    """测试不同的MFI阈值参数组合"""
    results = []
    for L in L_list:
        for H in H_list:
            if L >= H: # 超卖线必须低于超买线
                continue
            # 重新计算信号和仓位(复用之前的逻辑,但用变量L, H)
            temp_df = df.copy()
            temp_df['signal'] = 0
            for i in range(14, len(temp_df)):
                if temp_df['mfi'].iloc[i] > L and temp_df['mfi'].iloc[i-1] <= L:
                    temp_df.loc[temp_df.index[i], 'signal'] = 1
                elif temp_df['mfi'].iloc[i] < H and temp_df['mfi'].iloc[i-1] >= H:
                    temp_df.loc[temp_df.index[i], 'signal'] = 0
                else:
                    temp_df.loc[temp_df.index[i], 'signal'] = temp_df['signal'].iloc[i-1]
            temp_df['position'] = temp_df['signal'].shift(1).ffill().fillna(0)
            temp_df['strategy_ret'] = temp_df['position'] * temp_df['ret']
            temp_df['strategy_net'] = (1 + temp_df['strategy_ret']).cumprod()

            # 计算关键指标
            total_ret = temp_df['strategy_net'].iloc[-1] - 1
            annual_ret = (1 + total_ret) ** (250/len(temp_df)) - 1
            roll_max = temp_df['strategy_net'].cummax()
            drawdown = (temp_df['strategy_net'] - roll_max) / roll_max
            max_dd = drawdown.min()

            results.append({
                'L': L,
                'H': H,
                '总收益': total_ret,
                '年化收益': annual_ret,
                '最大回撤': max_dd,
                '收益回撤比': annual_ret / abs(max_dd) if max_dd != 0 else None # 一个综合衡量指标
            })
    return pd.DataFrame(results)

# 定义参数范围
L_range = [15, 20, 25, 30]
H_range = [70, 75, 80, 85, 90]

# 运行回测
param_results = backtest_mfi_params(df, L_range, H_range)
# 按年化收益或收益回撤比排序查看
print(param_results.sort_values(by='年化收益', ascending=False).head(10))

通过这个表格,你可能会发现 (L=25, H=85) 的组合比默认的 (20, 80) 年化收益更高,或者回撤更小。但是,千万不要直接选择历史收益最高的那个! 更稳健的做法是,观察多个表现较好的参数组合,它们可能集中在某个区域(比如L在20-25,H在80-85),那么这个区域可能就是相对稳健的参数区间。你可以选择这个区间中部的参数,或者用这些较优参数分别跑一下不同时间段(比如牛市、熊市、震荡市)的表现,看看哪个参数组合在不同市场环境下都还算稳定。

8. 进阶思考:MFI策略的局限性与改进方向

走到这一步,你已经完成了一个完整量化策略从数据到回测的闭环。但作为一个有经验的开发者,我必须告诉你,这个简单的MFI策略离一个真正能投入实战的策略还有距离。认识到它的局限性,才是你进步的起点。

首先,这个策略有几个明显的弱点:

  1. 滞后性:所有基于价格和成交量计算的指标都有滞后性。MFI的金叉死叉信号出现时,行情可能已经走了一段。
  2. 震荡市亏损:在价格没有趋势、来回震荡的行情里,MFI会在超买超卖线附近频繁发出买卖信号,导致“左右挨打”,产生连续的微小亏损,俗称“滑点损耗”。
  3. 参数敏感性:我们刚才优化了参数,但市场风格会变。过去十年有效的参数,未来不一定有效。
  4. 忽略交易成本:我们的回测假设买卖没有手续费、没有冲击成本,这在现实中是不可能的。频繁交易会迅速侵蚀利润。

那么,有哪些可以尝试的改进方向呢?

  1. 增加过滤器:不要单独使用MFI。可以结合趋势指标,比如只有当价格在200日均线之上(牛市环境)时,才执行MFI的超卖买入信号;在均线之下时,只执行超买卖出信号甚至不操作。这可以避免在下跌趋势中盲目抄底。
  2. 优化出场规则:卖出不一定非要等MFI下穿80。可以结合跟踪止盈,比如从买入后的最高点回落7%就卖出,这样能更好地抓住趋势。
  3. 仓位管理:不要总是全仓进出。可以根据MFI值离开阈值的“深度”来动态调整仓位。比如MFI跌到10时,仓位可以加到80%;MFI刚上穿20时,只建仓30%。这属于金字塔加仓/减仓的思路。
  4. 多时间框架确认:看日线MFI信号时,也参考周线MFI的趋势。如果周线MFI也在低位向上,那么日线的买入信号可靠性更高。
  5. 引入其他指标进行确认:比如用成交量加权平均价(VWAP)、平均趋向指数(ADX)等来确认趋势强度,避免在无趋势时交易。

把这些思路用代码实现,就是对你编程和逻辑能力的很好锻炼。例如,增加一个200日均线过滤:

df['ma200'] = df['close'].rolling(window=200).mean()
df['trend'] = df['close'] > df['ma200'] # 判断是否处于上升趋势

# 修改信号生成逻辑:只在上升趋势中做多,下降趋势中只平仓不开仓
for i in range(200, len(df)): # 注意,因为用了200日均线,起始索引要调整
    if df['trend'].iloc[i]: # 上升趋势
        if df['mfi'].iloc[i] > 20 and df['mfi'].iloc[i-1] <= 20:
            df.loc[df.index[i], 'signal'] = 1
        elif df['mfi'].iloc[i] < 80 and df['mfi'].iloc[i-1] >= 80:
            df.loc[df.index[i], 'signal'] = 0
    else: # 下降趋势,只清仓,不开仓
        if df['mfi'].iloc[i] < 80 and df['mfi'].iloc[i-1] >= 80:
            df.loc[df.index[i], 'signal'] = 0
        # 即使出现买入信号,也不操作,信号维持原样

量化交易是一个不断迭代和优化的过程。今天这个基于AKShare和MFI的策略,为你提供了一个坚实的起点和完整的分析框架。最重要的是,你学会了如何获取数据、计算指标、构建规则、回测评估以及思考改进。接下来,你可以用这个框架去测试更多的指标(比如MACD、KDJ、布林带),或者尝试不同的资产(个股、ETF、期货),甚至开始学习如何将策略自动化。记住,在实盘之前,一定要用足够长的历史数据、考虑交易成本、并在模拟环境中充分测试。这条路很长,但每一步都算数,从这一个简单的策略开始,慢慢构建属于你自己的交易系统吧。

ARIMA+傅里叶+技术指标+深度学习的多源信号融合框架 时间序列预测不是单一模型的任务,而是对趋势惯性、周期节律与市场情绪的协同建模。ARIMA擅长捕捉线性趋势与记忆衰减,傅里叶变换可解析多尺度周期及其相位演化,技术指标(如BBW、MFI、IMR)则量化实时多空强度;三者需通过可解释的深度学习架构进行动态权重融合,而非端到端黑箱拟合。这种多源异构特征协同机制,显著提升信号鲁棒性与归因能力,广泛应用于量化交易决策、风控预警与策略回测等工程场景,尤其适合需兼顾准确性与可调试性的实盘系统。 阅读详情

相关推荐

akshare写etf动量滚动策略

导入包: import akshare as ak import pandas as pd import numpy as np import matplotlib 日线换周线: #日线换为周线数据 def transferToWeekLine(df,period='W'): data1=df stock_data = pd.DataFrame(data1) #设定转换周期period_type 转换为周是'W',月'M',季度线'Q',五分钟'5min',12

qq_26742269的博客 9225

AKShare 金融数据接口实战指南:从数据获取到量化分析

AKShare 是一个基于 Python 的开源金融数据接口库,旨在为量化交易者、金融分析师和研究人员提供便捷、高效的金融数据获取解决方案。该项目通过整合多种数据源,为用户提供包括股票、基金、期货、债券、外汇等在内的全面金融数据服务。 ## 核心功能特点 1. **多品种覆盖**:支持股票、基金、期货、债券、外汇、指数等多种金融产品数据 2. **多频率数据**:提供从分钟级到日线、周线、月线...

gitblog_00902的博客 3408

AI量化策略 篇二:金融数据接口库 Akshare

AKShare 是基于 Python 的财经数据接口库,目的是实现对股票、期货、期权、基金、外汇、债券、指数、加密货币等金融产品的基本面数据、实时和历史行情数据、衍生数据从数据采集、数据清洗到数据落地的一套工具,主要用于学术研究目的。AKShare 的特点是获取的是相对权威的财经数据网站公布的原始数据,通过利用原始数据进行各数据源之间的交叉验证,进而再加工,从而得出科学的结论。其中,Conda是一个开源的包、环境管理器,可以用于在同一个机器上安装不同版本的软件包及其依赖,并能够在不同的环境之间切换。

生活在别处 2523

基于AKShare与SMA指标的量化交易策略实战解析

本文详细解析了如何利用AKShare免费获取金融数据,并结合SMA(简单移动平均线)指标构建量化交易策略。通过Backtrader框架进行完整回测,从数据清洗、策略逻辑(双均线交叉)到代码实现、绩效评估与风险控制,为量化交易新手提供了一套清晰、可复现的实战入门指南。

n4o5p6q7r的博客 221

获取财经数据神器akshare 基本使用总结

AkShare是基于 Python 的开源数据接口库,目的是实现对期货、期权、基金等衍生金融产品和另类数据从数据采集、数据清洗加工,、到数据下载的工具,满足金融数据科学家,数据科学爱好者在数据获取方面的需求。 AkShare的特点是获取的是相对权威的财经数据网站公布的原始数据,通过利用原始数据进行

叶庭云 成为自己的光 3万+

政府科技管理者如何提升科技成果转化项目进场交易的备案效率?.docx

政府科技管理者如何提升科技成果转化项目进场交易的备案效率?

量化选股,一个策略搞定

今天我们不聊ds ,而是基于ds背后老板,我们聊聊量化投资。量化听起来很高大山,本质是通过技术选择合适的指标(策略)对市场上的股票进行买入和卖出。今天运行了下周五的数据,满足指标买入要求的大概是 40只左右,大家可以加入自选股中,做一个观察仓,如果发现有突破或是起量的趋势,可以逐步买入,建仓。最近,在IT领域最火的必然是deepseek了,不仅在应用领域火的一塌糊涂,在国家政客也频频提起,并受到相关领导人的多次接见。

825

山区道路边坡落石隐患检测数据集VOC+YOLO格式241张1类别.md

【重要提示】本页面仅为资源介绍,不含外部下载地址 亲爱的 优快云 用户: 感谢你浏览本资源页面,在这里提前向大家说明相关情况,避免后续产生误解。本资源我设置的初衷是 0 积分免费分享文档介绍,希望可以无偿给到有需要的朋友。但 优快云 平台存在自动调控机制,系统会根据资源下载热度、文件体积、平台规则等因素,自动修改资源所需下载积分,页面显示为 1 积分、2 积分或更高积分都属于平台自动调整结果,并非我手动修改设置,我没有权限自主锁定积分数值。 如果你打开页面后,发现下载所需积分不为 0,请务必谨慎考虑是否下载。一旦你支付积分完成下载,后续遇到资源内容和描述不符、文件损坏等问题,我无法承担对应的积分损失,也没有渠道为你办理积分退还。在此强烈建议,只有页面明确显示 0 积分的时候,再进行下载操作。 同时特别说明:这份资源介绍文案里,没有附带任何外部下载地址。资源本身是通过 优快云 官方上传通道上传的附件,正常情况下直接点击页面自带的下载按钮即可获取文件。页面找不到外部下载链接属于正常情况,并非资源缺失。 如果因为平台积分显示异常,导致你被扣取积分,积分退款、积分异常相关问题,请直接联系 优快云 官方客服咨询处理。平台规则由官方制定,我无法干预积分变动,望各位理解。

Python量化监控框架:从指标计算到批量监控的本地化实践

量化交易的核心在于通过数学模型和计算机技术对市场数据进行系统性分析,其原理是将投资逻辑转化为可执行的算法。在技术实现上,Python因其丰富的数据科学生态(如Pandas、NumPy)成为主流工具,能够高效处理金融时间序列数据。**资金流**和**波动率**是两类关键的市场分析指标,前者反映资金进出动向,后者衡量价格波动程度,对判断市场情绪和风险有重要价值。通过构建本地化的监控框架,开发者可以灵活计算、跟踪这些复杂指标,并将结果用于策略研究或预警系统。本文介绍的开源项目正是这样一个专注于指标计算与批量监控的

weixin_33875564的博客 309

高空作业栏杆检测数据集VOC+YOLO格式230张3类别.md

【重要提示】本页面仅为资源介绍,不含外部下载地址 亲爱的 优快云 用户: 感谢你浏览本资源页面,在这里提前向大家说明相关情况,避免后续产生误解。本资源我设置的初衷是 0 积分免费分享文档介绍,希望可以无偿给到有需要的朋友。但 优快云 平台存在自动调控机制,系统会根据资源下载热度、文件体积、平台规则等因素,自动修改资源所需下载积分,页面显示为 1 积分、2 积分或更高积分都属于平台自动调整结果,并非我手动修改设置,我没有权限自主锁定积分数值。 如果你打开页面后,发现下载所需积分不为 0,请务必谨慎考虑是否下载。一旦你支付积分完成下载,后续遇到资源内容和描述不符、文件损坏等问题,我无法承担对应的积分损失,也没有渠道为你办理积分退还。在此强烈建议,只有页面明确显示 0 积分的时候,再进行下载操作。 同时特别说明:这份资源介绍文案里,没有附带任何外部下载地址。资源本身是通过 优快云 官方上传通道上传的附件,正常情况下直接点击页面自带的下载按钮即可获取文件。页面找不到外部下载链接属于正常情况,并非资源缺失。 如果因为平台积分显示异常,导致你被扣取积分,积分退款、积分异常相关问题,请直接联系 优快云 官方客服咨询处理。平台规则由官方制定,我无法干预积分变动,望各位理解。

ti-cgt-c2000-22.6.0.LTS-windows-x64-installer

ti-cgt-c2000-22.6.0.LTS-windows-x64-installer

量化交易策略的设计与回测

利用上证指数的历史数据设计简单的策略并进行回测

Sukey666666的博客 1442

光伏板太阳能板尘土灰尘脏污检测数据集VOC+YOLO格式1006张3类别.md

【重要提示】本页面仅为资源介绍,不含外部下载地址 亲爱的 优快云 用户: 感谢你浏览本资源页面,在这里提前向大家说明相关情况,避免后续产生误解。本资源我设置的初衷是 0 积分免费分享文档介绍,希望可以无偿给到有需要的朋友。但 优快云 平台存在自动调控机制,系统会根据资源下载热度、文件体积、平台规则等因素,自动修改资源所需下载积分,页面显示为 1 积分、2 积分或更高积分都属于平台自动调整结果,并非我手动修改设置,我没有权限自主锁定积分数值。 如果你打开页面后,发现下载所需积分不为 0,请务必谨慎考虑是否下载。一旦你支付积分完成下载,后续遇到资源内容和描述不符、文件损坏等问题,我无法承担对应的积分损失,也没有渠道为你办理积分退还。在此强烈建议,只有页面明确显示 0 积分的时候,再进行下载操作。 同时特别说明:这份资源介绍文案里,没有附带任何外部下载地址。资源本身是通过 优快云 官方上传通道上传的附件,正常情况下直接点击页面自带的下载按钮即可获取文件。页面找不到外部下载链接属于正常情况,并非资源缺失。 如果因为平台积分显示异常,导致你被扣取积分,积分退款、积分异常相关问题,请直接联系 优快云 官方客服咨询处理。平台规则由官方制定,我无法干预积分变动,望各位理解。

某只股票量化对冲策略计算绘图

摘要 本文介绍了一个基于Python的量化对冲策略分析工具,使用akshare获取股票数据,通过pandas进行量化指标计算,并采用matplotlib可视化分析结果。代码实现了: 主要功能:获取股票数据(默认上证指数),计算包括主力资金、成本分布、妖股信号等12种量化指标 技术特点:使用指数移动平均(EMA)、滚动窗口计算高低点、多条件信号判断 可视化方案:生成4个子图分别展示价格走势、资金指标、信号触发和风险收益比 容错机制:数据获取失败时自动切换为随机数据,确保程序持续运行 使用说明:支持自定义股票代

qq_43596960的博客 1455

jlink驱动安装

jlink驱动下载安装及keil识别

qq_43868701的博客 3万+

相控阵雷达仿真入门:TWS与TAS模式实战解析(附代码示例)

本文深入解析相控阵雷达仿真中的TWS(边搜索边跟踪)与TAS(搜索加跟踪)模式,提供实战代码示例和优化策略。通过简化模型设计和对象化建模,帮助开发者快速构建高效仿真系统,适用于军事推演和装备评估。文章涵盖核心逻辑、数据结构设计及性能优化技巧,提升仿真效率与准确性。

weixin_30687051的博客 454

pyttsx3库 | 2行代码将文本转音频

腾讯视频 | Python网络爬虫与文本分析pyttsx3简介pyttsx3是一个款将文本转为语音的Python包,不同于其他Python包,pyttsx3真的可以文本转语音。安装pip...

大邓和他的Python 1320

GD32F103程序烧录全攻略:从SWD到串口的实战指南

本文提供了GD32F103微控制器程序烧录的全面实战指南,详细介绍了SWD、JTAG和串口(ISP)三种主流下载方式。文章重点解析了在Keil MDK中使用ST-Link进行SWD下载的完整步骤,包括硬件连接、软件配置和Flash算法设置,并针对烧录过程中的常见问题提供了实用的排坑解决方案,帮助开发者高效完成程序部署。

weixin_29191669的博客 438
上一篇: 高效视频采集实践:基于V4L2的mmap模式内存映射技术解析
下一篇: LaTeX简历模板终极指南:从Overleaf配置到中文支持全流程
code8
博客等级 码龄17年 65粉丝 1720原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值