精华

量化投资的"Hello World":5行代码实现你的第一个选股策略

alphonsealphonse··1.3k 浏览

开篇:什么是量化投资?

想象你是一个经验丰富的菜市场买菜高手。每次买菜时,你都有自己的一套"规则":

  • 西红柿要挑红润饱满的
  • 价格比平时低20%时大量采购
  • 避开周末人多的时候去买

量化投资就是把这套"买菜经验"用代码写出来,让电脑帮你在股市里"买菜"。

传统投资靠感觉和经验,量化投资靠的是数据+规则+纪律执行。就像用GPS导航代替问路一样,虽然偶尔会绕路,但长期看更靠谱。

为什么从双均线开始?

双均线策略是量化投资的"九九乘法表",简单但包含了完整的投资逻辑:

  • 趋势判断:短期均线 > 长期均线 = 上涨趋势
  • 买卖信号:均线交叉 = 进出场时机
  • 风险控制:有明确的止损规则

10分钟搭建你的第一个策略

第1步:安装工具(2分钟)

pip install akshare pandas matplotlib numpy

第2步:获取数据(2分钟)

import akshare as ak
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, timedelta

# 设置中文字体显示
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

# 获取平安银行近2年数据
print("正在获取股票数据...")
stock_data = ak.stock_zh_a_hist(symbol="000001", 
                               period="daily", 
                               start_date="20220101", 
                               end_date="20241201")

# 数据预处理
stock_data['日期'] = pd.to_datetime(stock_data['日期'])
stock_data = stock_data.sort_values('日期').reset_index(drop=True)

print(f"获取到 {len(stock_data)} 条数据")
print("数据样例:")
print(stock_data[['日期', '开盘', '收盘', '成交量']].head())

001.jpg

第3步:核心策略(真正的5行代码!)

# 🎯 核心策略:双均线交叉(就这5行!)
stock_data['MA5'] = stock_data['收盘'].rolling(5).mean()
stock_data['MA20'] = stock_data['收盘'].rolling(20).mean()
stock_data['signal'] = 0
stock_data.loc[stock_data['MA5'] > stock_data['MA20'], 'signal'] = 1  # 买入信号
stock_data.loc[stock_data['MA5'] < stock_data['MA20'], 'signal'] = -1  # 卖出信号

print("策略核心逻辑:")
print("✅ 当5日均线 > 20日均线时:买入(做多)")
print("❌ 当5日均线 < 20日均线时:卖出(做空)")
print("⏸️  当5日均线 = 20日均线时:观望")

第4步:回测计算(3分钟)

# 计算收益率
stock_data['daily_return'] = stock_data['收盘'].pct_change()

# 策略收益(第二天按今天的信号执行)
stock_data['strategy_return'] = stock_data['signal'].shift(1) * stock_data['daily_return']

# 计算累计收益
stock_data['cumulative_strategy'] = (1 + stock_data['strategy_return'].fillna(0)).cumprod()
stock_data['cumulative_benchmark'] = (1 + stock_data['daily_return'].fillna(0)).cumprod()

# 去掉空值
stock_data = stock_data.dropna()

print(f"回测期间:{stock_data['日期'].min().strftime('%Y-%m-%d')} 至 {stock_data['日期'].max().strftime('%Y-%m-%d')}")
print(f"交易天数:{len(stock_data)} 天")

002.jpg

第5步:结果可视化(3分钟)

# 创建图表
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(14, 12))

# 子图1:股价与均线
ax1.plot(stock_data['日期'], stock_data['收盘'], label='收盘价', alpha=0.8, linewidth=1)
ax1.plot(stock_data['日期'], stock_data['MA5'], label='5日均线', color='orange', linewidth=2)
ax1.plot(stock_data['日期'], stock_data['MA20'], label='20日均线', color='red', linewidth=2)

# 标记买卖点
buy_signals = stock_data[(stock_data['signal'] == 1) & (stock_data['signal'].shift(1) != 1)]
sell_signals = stock_data[(stock_data['signal'] == -1) & (stock_data['signal'].shift(1) != -1)]

ax1.scatter(buy_signals['日期'], buy_signals['收盘'], color='red', marker='^', s=60, label='买入信号', zorder=5)
ax1.scatter(sell_signals['日期'], sell_signals['收盘'], color='green', marker='v', s=60, label='卖出信号', zorder=5)

ax1.set_title('平安银行(000001) - 股价与双均线策略', fontsize=14, fontweight='bold')
ax1.legend()
ax1.grid(True, alpha=0.3)

# 子图2:收益率对比
ax2.plot(stock_data['日期'], (stock_data['cumulative_strategy'] - 1) * 100, 
         label='双均线策略', color='red', linewidth=2)
ax2.plot(stock_data['日期'], (stock_data['cumulative_benchmark'] - 1) * 100, 
         label='买入持有', color='blue', linewidth=2)

ax2.set_title('累计收益率对比 (%)', fontsize=14, fontweight='bold')
ax2.legend()
ax2.grid(True, alpha=0.3)
ax2.set_ylabel('收益率 (%)')

# 子图3:信号分布
signal_counts = stock_data['signal'].value_counts().sort_index()
colors = ['green', 'gray', 'red']
labels = ['卖出信号', '观望', '买入信号']
bars = ax3.bar([-1, 0, 1], [signal_counts.get(-1, 0), signal_counts.get(0, 0), signal_counts.get(1, 0)], 
               color=colors, alpha=0.7)

ax3.set_title('交易信号分布', fontsize=14, fontweight='bold')
ax3.set_xlabel('信号类型')
ax3.set_ylabel('天数')
ax3.set_xticks([-1, 0, 1])
ax3.set_xticklabels(labels)

# 在柱子上添加数值
for i, bar in enumerate(bars):
    height = bar.get_height()
    ax3.text(bar.get_x() + bar.get_width()/2., height + 5,
             f'{int(height)}天', ha='center', va='bottom', fontweight='bold')

plt.tight_layout()
plt.show()

003.jpg

运行结果解读

当你运行完整代码后,会看到三个关键图表:

图1 - 股价与均线

  • 🔺红色三角:买入信号(金叉时刻)
  • 🔻绿色倒三角:卖出信号(死叉时刻)
  • 橙线:5日均线(短期趋势)
  • 红线:20日均线(长期趋势)

图2 - 收益对比

  • 红线:你的双均线策略累计收益
  • 蓝线:简单买入持有的累计收益

图3 - 信号分布

  • 显示策略在不同市场状态下的时间分配

第6步:策略表现分析

# 计算关键指标
total_strategy_return = stock_data['cumulative_strategy'].iloc[-1] - 1
total_benchmark_return = stock_data['cumulative_benchmark'].iloc[-1] - 1
excess_return = total_strategy_return - total_benchmark_return

# 计算最大回撤
def calculate_max_drawdown(cumulative_returns):
    peak = cumulative_returns.expanding().max()
    drawdown = (cumulative_returns - peak) / peak
    return drawdown.min()

strategy_max_dd = calculate_max_drawdown(stock_data['cumulative_strategy'])
benchmark_max_dd = calculate_max_drawdown(stock_data['cumulative_benchmark'])

# 计算胜率
win_trades = (stock_data['strategy_return'] > 0).sum()
total_trades = (stock_data['strategy_return'] != 0).sum()
win_rate = win_trades / total_trades if total_trades > 0 else 0

# 计算年化收益和波动率
trading_days = len(stock_data)
years = trading_days / 252

strategy_annual_return = (1 + total_strategy_return) ** (1/years) - 1
benchmark_annual_return = (1 + total_benchmark_return) ** (1/years) - 1

strategy_volatility = stock_data['strategy_return'].std() * np.sqrt(252)
benchmark_volatility = stock_data['daily_return'].std() * np.sqrt(252)

# 计算夏普比率(假设无风险利率为3%)
risk_free_rate = 0.03
strategy_sharpe = (strategy_annual_return - risk_free_rate) / strategy_volatility
benchmark_sharpe = (benchmark_annual_return - risk_free_rate) / benchmark_volatility

print("=" * 60)
print("📊 策略表现报告")
print("=" * 60)
print(f"📅 回测期间: {stock_data['日期'].min().strftime('%Y-%m-%d')} 至 {stock_data['日期'].max().strftime('%Y-%m-%d')}")
print(f"📈 交易天数: {trading_days} 天 ({years:.1f} 年)")
print()
print("💰 收益表现:")
print(f"   双均线策略总收益:  {total_strategy_return:>8.2%}")
print(f"   买入持有总收益:    {total_benchmark_return:>8.2%}")
print(f"   超额收益:          {excess_return:>8.2%}")
print()
print("📊 年化指标:")
print(f"   策略年化收益:      {strategy_annual_return:>8.2%}")
print(f"   基准年化收益:      {benchmark_annual_return:>8.2%}")
print(f"   策略年化波动:      {strategy_volatility:>8.2%}")
print(f"   基准年化波动:      {benchmark_volatility:>8.2%}")
print()
print("🎯 风险指标:")
print(f"   策略最大回撤:      {strategy_max_dd:>8.2%}")
print(f"   基准最大回撤:      {benchmark_max_dd:>8.2%}")
print(f"   策略夏普比率:      {strategy_sharpe:>8.2f}")
print(f"   基准夏普比率:      {benchmark_sharpe:>8.2f}")
print()
print("🎮 交易统计:")
print(f"   交易胜率:          {win_rate:>8.2%}")
print(f"   买入信号天数:      {(stock_data['signal'] == 1).sum():>8d} 天")
print(f"   卖出信号天数:      {(stock_data['signal'] == -1).sum():>8d} 天")
print(f"   观望天数:          {(stock_data['signal'] == 0).sum():>8d} 天")

# 结果判断
print()
print("🔍 策略评价:")
if excess_return > 0:
    print(f"✅ 策略跑赢基准 {excess_return:.2%},表现优秀!")
else:
    print(f"❌ 策略跑输基准 {abs(excess_return):.2%},需要优化。")

if strategy_sharpe > benchmark_sharpe:
    print(f"✅ 策略夏普比率更高,风险调整后收益更好。")
else:
    print(f"❌ 策略夏普比率较低,风险调整后收益不佳。")

if abs(strategy_max_dd) < abs(benchmark_max_dd):
    print(f"✅ 策略最大回撤更小,风险控制更好。")
else:
    print(f"❌ 策略最大回撤更大,风险控制需要改进。")

004.jpg

这5行代码教会了你什么?

1. 数据驱动决策

# 不是凭感觉,而是用数学公式
stock_data['MA5'] = stock_data['收盘'].rolling(5).mean()

每个买卖决定都基于具体的数值计算,消除了情绪干扰。

2. 规则明确执行

# 条件清晰,没有模糊地带
stock_data.loc[stock_data['MA5'] > stock_data['MA20'], 'signal'] = 1

什么时候买,什么时候卖,程序说了算。

3. 历史验证可行性

通过回测,你可以看到这个策略在过去两年的真实表现,而不是空想。

4. 量化风险收益

不只看收益,还要看回撤、夏普比率等风险指标。

现实检查:这个策略能赚钱吗?

诚实答案:不一定。

为什么可能不赚钱?

  1. 交易成本:每次买卖要手续费(约0.1-0.3%)
  2. 市场变化:过去有效的规律未来可能失效
  3. 过于简单:真实市场有更多变量
  4. 数据偏差:选择了对策略有利的股票和时间段

但这很重要!

这个练习的价值不在于赚钱,而在于:

  • ✅ 建立量化思维框架
  • ✅ 学会系统性分析方法
  • ✅ 掌握回测验证流程
  • ✅ 理解风险收益平衡

如何改进这个策略?

1. 风险控制优化

# 加入止损机制
max_loss = -0.05  # 最大亏损5%
stop_loss_signal = (stock_data['strategy_return'].cumsum() < max_loss)

2. 参数优化

# 测试不同均线组合
ma_pairs = [(5,10), (5,20), (10,30), (20,60)]
for short, long in ma_pairs:
    # 测试每种组合的效果

3. 多股票验证

# 在更多股票上测试
stock_list = ['000001', '000002', '600036', '600519']
for stock in stock_list:
    # 验证策略普适性

4. 市场环境适应

# 在不同市场状态下测试
bull_market = stock_data[stock_data['日期'].between('2020-01-01', '2021-01-01')]
bear_market = stock_data[stock_data['日期'].between('2021-01-01', '2022-01-01')]

完整代码整合

"""
量化投资 Hello World:双均线策略完整实现
适合量化投资初学者的第一个策略
"""

import akshare as ak
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

def get_stock_data(symbol="000001", start_date="20220101", end_date="20241201"):
    """获取股票数据"""
    print(f"正在获取 {symbol} 的历史数据...")
    data = ak.stock_zh_a_hist(symbol=symbol, period="daily", 
                             start_date=start_date, end_date=end_date)
    data['日期'] = pd.to_datetime(data['日期'])
    data = data.sort_values('日期').reset_index(drop=True)
    print(f"获取到 {len(data)} 条数据")
    return data

def dual_ma_strategy(data, short_window=5, long_window=20):
    """双均线策略核心逻辑"""
    # 🎯 核心5行代码
    data['MA5'] = data['收盘'].rolling(short_window).mean()
    data['MA20'] = data['收盘'].rolling(long_window).mean()
    data['signal'] = 0
    data.loc[data['MA5'] > data['MA20'], 'signal'] = 1   # 买入
    data.loc[data['MA5'] < data['MA20'], 'signal'] = -1  # 卖出
    
    return data

def backtest_strategy(data):
    """回测计算"""
    data['daily_return'] = data['收盘'].pct_change()
    data['strategy_return'] = data['signal'].shift(1) * data['daily_return']
    data['cumulative_strategy'] = (1 + data['strategy_return'].fillna(0)).cumprod()
    data['cumulative_benchmark'] = (1 + data['daily_return'].fillna(0)).cumprod()
    return data.dropna()

def plot_results(data):
    """绘制结果图表"""
    fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(14, 12))
    
    # 股价与均线
    ax1.plot(data['日期'], data['收盘'], label='收盘价', alpha=0.8)
    ax1.plot(data['日期'], data['MA5'], label='5日均线', color='orange', linewidth=2)
    ax1.plot(data['日期'], data['MA20'], label='20日均线', color='red', linewidth=2)
    
    # 买卖信号点
    buy_signals = data[(data['signal'] == 1) & (data['signal'].shift(1) != 1)]
    sell_signals = data[(data['signal'] == -1) & (data['signal'].shift(1) != -1)]
    
    ax1.scatter(buy_signals['日期'], buy_signals['收盘'], color='red', 
               marker='^', s=60, label='买入信号', zorder=5)
    ax1.scatter(sell_signals['日期'], sell_signals['收盘'], color='green', 
               marker='v', s=60, label='卖出信号', zorder=5)
    
    ax1.set_title('股价与双均线策略信号', fontsize=14, fontweight='bold')
    ax1.legend()
    ax1.grid(True, alpha=0.3)
    
    # 收益率对比
    ax2.plot(data['日期'], (data['cumulative_strategy'] - 1) * 100, 
             label='双均线策略', color='red', linewidth=2)
    ax2.plot(data['日期'], (data['cumulative_benchmark'] - 1) * 100, 
             label='买入持有', color='blue', linewidth=2)
    
    ax2.set_title('累计收益率对比 (%)', fontsize=14, fontweight='bold')
    ax2.legend()
    ax2.grid(True, alpha=0.3)
    ax2.set_ylabel('收益率 (%)')
    
    # 信号分布
    signal_counts = data['signal'].value_counts().sort_index()
    colors = ['green', 'gray', 'red']
    labels = ['卖出信号', '观望', '买入信号']
    bars = ax3.bar([-1, 0, 1], [signal_counts.get(-1, 0), signal_counts.get(0, 0), 
                                signal_counts.get(1, 0)], color=colors, alpha=0.7)
    
    ax3.set_title('交易信号分布', fontsize=14, fontweight='bold')
    ax3.set_xlabel('信号类型')
    ax3.set_ylabel('天数')
    ax3.set_xticks([-1, 0, 1])
    ax3.set_xticklabels(labels)
    
    for i, bar in enumerate(bars):
        height = bar.get_height()
        ax3.text(bar.get_x() + bar.get_width()/2., height + 5,
                f'{int(height)}天', ha='center', va='bottom', fontweight='bold')
    
    plt.tight_layout()
    plt.show()

def calculate_metrics(data):
    """计算策略表现指标"""
    total_strategy_return = data['cumulative_strategy'].iloc[-1] - 1
    total_benchmark_return = data['cumulative_benchmark'].iloc[-1] - 1
    
    # 最大回撤
    def max_drawdown(cumulative_returns):
        peak = cumulative_returns.expanding().max()
        drawdown = (cumulative_returns - peak) / peak
        return drawdown.min()
    
    strategy_max_dd = max_drawdown(data['cumulative_strategy'])
    benchmark_max_dd = max_drawdown(data['cumulative_benchmark'])
    
    # 胜率
    win_trades = (data['strategy_return'] > 0).sum()
    total_trades = (data['strategy_return'] != 0).sum()
    win_rate = win_trades / total_trades if total_trades > 0 else 0
    
    # 年化指标
    years = len(data) / 252
    strategy_annual_return = (1 + total_strategy_return) ** (1/years) - 1
    benchmark_annual_return = (1 + total_benchmark_return) ** (1/years) - 1
    
    strategy_volatility = data['strategy_return'].std() * np.sqrt(252)
    benchmark_volatility = data['daily_return'].std() * np.sqrt(252)
    
    # 夏普比率
    risk_free_rate = 0.03
    strategy_sharpe = (strategy_annual_return - risk_free_rate) / strategy_volatility
    benchmark_sharpe = (benchmark_annual_return - risk_free_rate) / benchmark_volatility
    
    return {
        'total_strategy_return': total_strategy_return,
        'total_benchmark_return': total_benchmark_return,
        'excess_return': total_strategy_return - total_benchmark_return,
        'strategy_max_dd': strategy_max_dd,
        'benchmark_max_dd': benchmark_max_dd,
        'win_rate': win_rate,
        'strategy_annual_return': strategy_annual_return,
        'benchmark_annual_return': benchmark_annual_return,
        'strategy_sharpe': strategy_sharpe,
        'benchmark_sharpe': benchmark_sharpe,
        'years': years,
        'trading_days': len(data)
    }

def print_report(data, metrics):
    """打印策略报告"""
    print("=" * 60)
    print("📊 双均线策略表现报告")
    print("=" * 60)
    print(f"📅 回测期间: {data['日期'].min().strftime('%Y-%m-%d')} 至 {data['日期'].max().strftime('%Y-%m-%d')}")
    print(f"📈 交易天数: {metrics['trading_days']} 天 ({metrics['years']:.1f} 年)")
    print()
    print("💰 收益表现:")
    print(f"   双均线策略总收益:  {metrics['total_strategy_return']:>8.2%}")
    print(f"   买入持有总收益:    {metrics['total_benchmark_return']:>8.2%}")
    print(f"   超额收益:          {metrics['excess_return']:>8.2%}")
    print()
    print("📊 年化指标:")
    print(f"   策略年化收益:      {metrics['strategy_annual_return']:>8.2%}")
    print(f"   基准年化收益:      {metrics['benchmark_annual_return']:>8.2%}")
    print()
    print("🎯 风险指标:")
    print(f"   策略最大回撤:      {metrics['strategy_max_dd']:>8.2%}")
    print(f"   基准最大回撤:      {metrics['benchmark_max_dd']:>8.2%}")
    print(f"   策略夏普比率:      {metrics['strategy_sharpe']:>8.2f}")
    print(f"   基准夏普比率:      {metrics['benchmark_sharpe']:>8.2f}")
    print()
    print("🎮 交易统计:")
    print(f"   交易胜率:          {metrics['win_rate']:>8.2%}")
    print(f"   买入信号天数:      {(data['signal'] == 1).sum():>8d} 天")
    print(f"   卖出信号天数:      {(data['signal'] == -1).sum():>8d} 天")
    
    # 策略评价
    print()
    print("🔍 策略评价:")
    if metrics['excess_return'] > 0:
        print(f"✅ 策略跑赢基准 {metrics['excess_return']:.2%},表现优秀!")
    else:
        print(f"❌ 策略跑输基准 {abs(metrics['excess_return']):.2%},需要优化。")
    
    if metrics['strategy_sharpe'] > metrics['benchmark_sharpe']:
        print("✅ 策略风险调整后收益更好。")
    else:
        print("❌ 策略风险调整后收益不佳。")

def main():
    """主函数:执行完整的策略回测流程"""
    try:
        # 1. 获取数据
        stock_data = get_stock_data("000001", "20220101", "20241201")
        
        # 2. 应用策略
        stock_data = dual_ma_strategy(stock_data)
        
        # 3. 回测计算
        stock_data = backtest_strategy(stock_data)
        
        # 4. 计算指标
        metrics = calculate_metrics(stock_data)
        
        # 5. 展示结果
        plot_results(stock_data)
        print_report(stock_data, metrics)
        
        print("\n🎉 恭喜!你已经完成了第一个量化策略的开发和回测!")
        print("💡 接下来可以尝试:")
        print("   - 测试不同的均线参数组合")
        print("   - 在其他股票上验证策略效果") 
        print("   - 加入止损止盈机制")
        print("   - 学习更多技术指标")
        
    except Exception as e:
        print(f"❌ 程序执行出错: {e}")
        print("💡 请检查网络连接和数据源是否正常")

if __name__ == "__main__":
    main()

总结

恭喜!你已经是一个量化投资者了。 🎉

通过这个简单的双均线策略,你已经掌握了:

  • ✅ 量化投资的基本思维
  • ✅ 数据获取和处理方法
  • ✅ 策略开发和回测流程
  • ✅ 风险收益分析框架

接下来的路还很长,但你已经迈出了最重要的第一步:用数据说话,用规则行动

常见问题解答

Q1: 为什么我的结果和文章中不一样?

A: 这很正常!原因可能有:

  • 数据获取时间不同(股价每天都在变化)
  • akshare数据源的细微差异
  • 复权方式不同

解决方案:重点关注策略逻辑是否正确,而不是具体数值。

Q2: 这个策略在实盘中能用吗?

A: 建议先不要!原因:

  • 没有考虑交易成本
  • 没有足够的样本外验证
  • 缺乏风险控制机制

建议:先在更多股票上验证,加入风控后再考虑小资金试验。

Q3: 如何判断策略是否过拟合?

A: 几个检验方法:

  • 在不同时间段测试
  • 在不同股票上测试
  • 样本外验证(用一半数据开发,另一半验证)
  • 参数敏感性测试

Q4: 程序运行报错怎么办?

A: 常见问题及解决:

# 1. 安装缺失的包
pip install akshare pandas matplotlib numpy

# 2. 网络问题导致数据获取失败
# 多试几次,或者换个时间段

# 3. 中文显示问题
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']

# 4. 数据格式问题
# 确保日期列格式正确
data['日期'] = pd.to_datetime(data['日期'])

进阶练习

完成基础版本后,可以尝试这些进阶练习:

练习1:参数优化

# 测试不同均线组合的效果
ma_combinations = [(3,7), (5,15), (10,30), (20,60)]
results = {}

for short, long in ma_combinations:
    # 这里插入你的策略代码,使用不同参数
    # 记录每种组合的收益率
    pass
    
# 找出最佳参数组合
best_combination = max(results.items(), key=lambda x: x[1])
print(f"最佳均线组合: {best_combination}")

练习2:多股票验证

# 在多只股票上测试策略稳定性
stock_list = ['000001', '000002', '600036', '600519', '000858']
all_results = []

for stock in stock_list:
    try:
        # 获取数据并应用策略
        data = get_stock_data(stock)
        data = dual_ma_strategy(data)
        data = backtest_strategy(data)
        
        # 记录结果
        total_return = data['cumulative_strategy'].iloc[-1] - 1
        all_results.append((stock, total_return))
        
    except Exception as e:
        print(f"股票 {stock} 处理失败: {e}")

# 分析结果分布
import numpy as np
returns = [r[1] for r in all_results]
print(f"平均收益: {np.mean(returns):.2%}")
print(f"收益标准差: {np.std(returns):.2%}")
print(f"胜率: {(np.array(returns) > 0).mean():.2%}")

练习3:加入止损机制

def enhanced_dual_ma_strategy(data, stop_loss_pct=0.05):
    """带止损的双均线策略"""
    data = dual_ma_strategy(data)  # 基础策略
    
    # 加入止损逻辑
    data['cumulative_return'] = (1 + data['strategy_return'].fillna(0)).cumprod()
    data['running_max'] = data['cumulative_return'].expanding().max()
    data['drawdown'] = (data['cumulative_return'] - data['running_max']) / data['running_max']
    
    # 当回撤超过阈值时,强制卖出
    stop_loss_signal = data['drawdown'] < -stop_loss_pct
    data.loc[stop_loss_signal, 'signal'] = -1
    
    return data

学习资源推荐

📚 入门书籍

  1. 《量化投资策略》 - 理查德·托托里罗
  2. 《Python量化交易实战》 - 张丹
  3. 《量化交易之路》 - 阿布

💻 在线平台

  1. 聚宽研究环境 - 免费的量化研究平台
  2. 优矿 - 通联数据的量化平台
  3. 果仁网 - 简单易用的因子回测平台

🎓 进阶课程

  1. 中国大学MOOC - 量化投资相关课程
  2. 网易云课堂 - Python金融数据分析
  3. B站 - 大量免费的量化教学视频

🔧 工具包

# 必备量化工具包
pip install akshare          # 数据获取
pip install tushare          # 备选数据源
pip install backtrader       # 专业回测框架
pip install pyfolio          # 策略分析
pip install empyrical        # 金融指标计算
pip install zipline          # 美股回测框架

写在最后

量化投资不是一夜暴富的魔法,而是一门需要持续学习和实践的技艺。这个简单的双均线策略,就像学武功时的马步一样,看似简单却是基础中的基础。

记住几个关键原则:

  1. 永远保持怀疑 - 任何策略都可能失效
  2. 严格风险控制 - 保住本金比赚钱更重要
  3. 持续学习改进 - 市场在进化,策略也要进化
  4. 实盘验证一切 - 回测再好也不等于实盘收益

最重要的是,开始行动比完美计划更重要。你已经迈出了第一步,接下来就是坚持学习和实践。

愿你在量化投资的道路上,既能享受数据之美,也能获得稳健收益!


本文完整代码已整理,复制粘贴即可运行。如有问题,欢迎在评论区交流!

评论 2

  • 我是宽客
    我是宽客

    很详细~^^

  • 十年
    十年

    量化投资第一课,即便是小白也能大致看得懂一些,关键是策略逻辑

0 / 2000