如何通过股票数据 API 计算 RSI、MACD 与移动平均线MA

在量化交易和技术分析中,RSI(相对强弱指数)、MACD(移动平均收敛发散指标)和移动平均线(MA)是三个最经典且广泛应用的技术指标。它们能帮助交易者识别市场趋势、动量和潜在的反转点。本文将详细介绍如何通过常见的市场数据 API 获取高质量的金融数据,并使用 Python 手动计算这些核心指标,为你构建量化策略打下坚实基础。

一、数据获取与指标计算

1. 环境准备与数据获取

安装必要的 Python 库并获取 K 线数据。

python 复制代码
# 安装必要的库
# pip install requests pandas numpy matplotlib

import requests
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 设置API请求头(所有iTick接口通用)
headers = {
    "accept": "application/json",
    "token": "你的API_Token"  # 请替换为你的实际Token
}

def fetch_kline_from_itick(symbol='700.HK', region='HK', k_type=8, limit=100):
    """
    从iTick API获取历史K线数据

    参数:
    symbol: 标的代码,如'700.HK'代表腾讯控股
    region: 市场区域,如'HK'(港股)、'US'(美股)、'CN'(A股)
    k_type: K线周期,1=1分,2=5分,...,8=日线
    limit: 获取的K线数量
    """
    url = f"https://api.itick.org/stock/kline?region={region}&code={symbol}&kType={k_type}&limit={limit}"
    try:
        response = requests.get(url, headers=headers)
        data = response.json()
        if data["code"] == 0:  # 请求成功
            kline_list = data["data"]
            df = pd.DataFrame(kline_list)
            # 重命名和格式化列
            df.rename(columns={'t': 'timestamp', 'o': 'open', 'h': 'high',
                               'l': 'low', 'c': 'close', 'v': 'volume'}, inplace=True)
            df['datetime'] = pd.to_datetime(df['timestamp'], unit='s')
            df.set_index('datetime', inplace=True)
            df.sort_index(inplace=True)  # 确保按时间排序
            print(f"成功获取 {symbol} 的 {len(df)} 条K线数据")
            return df[['open', 'high', 'low', 'close', 'volume']]
        else:
            print(f"请求失败: {data['msg']}")
            return None
    except Exception as e:
        print(f"获取数据时发生错误: {e}")
        return None

# 示例:获取腾讯控股(0700.HK)的日线数据
df = fetch_kline_from_itick(symbol='700.HK', region='HK', k_type=8, limit=200)
print(df.head())

2. 计算移动平均线 (MA)

移动平均线是最基础的趋势指标,用于平滑价格数据。

python 复制代码
def calculate_ma(df, windows=[5, 10, 20]):
    """
    计算简单移动平均线 (SMA)
    """
    for window in windows:
        df[f'MA_{window}'] = df['close'].rolling(window=window).mean()
    return df

# 计算5日、10日、20日移动平均线
df = calculate_ma(df, [5, 10, 20])
print(df[['close', 'MA_5', 'MA_10', 'MA_20']].tail())

3. 计算指数平滑移动平均线 (EMA) 与 MACD

MACD 是一个趋势动量指标,由快线(DIF)、慢线(DEA)和柱状图(MACD Histogram)组成。

python 复制代码
def calculate_ema(series, period):
    """计算指数移动平均线 (EMA)"""
    return series.ewm(span=period, adjust=False).mean()

def calculate_macd(df, fast=12, slow=26, signal=9):
    """
    计算MACD指标
    标准参数通常为:快线周期12,慢线周期26,信号线周期9
    """
    # 计算快慢EMA
    df['EMA_Fast'] = calculate_ema(df['close'], fast)
    df['EMA_Slow'] = calculate_ema(df['close'], slow)
    # 计算DIF(差离值)
    df['DIF'] = df['EMA_Fast'] - df['EMA_Slow']
    # 计算DEA(信号线,即DIF的EMA)
    df['DEA'] = calculate_ema(df['DIF'], signal)
    # 计算MACD柱状图 (通常表示为2*(DIF-DEA))
    df['MACD_Hist'] = 2 * (df['DIF'] - df['DEA'])
    return df

# 计算MACD
df = calculate_macd(df)
print(df[['close', 'DIF', 'DEA', 'MACD_Hist']].tail())

4. 计算相对强弱指数 (RSI)

RSI 是动量振荡器,用于衡量价格变动的速度和幅度,判断超买或超卖状态。

python 复制代码
def calculate_rsi(df, window=14):
    """
    计算相对强弱指数 (RSI)
    """
    # 计算价格变化
    delta = df['close'].diff()
    # 分离上涨和下跌
    gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
    # 计算相对强度 (RS) 和 RSI
    rs = gain / loss
    df[f'RSI_{window}'] = 100 - (100 / (1 + rs))
    return df

# 计算14日RSI
df = calculate_rsi(df, window=14)
print(df[['close', 'RSI_14']].tail())

二、 数据可视化

计算完成后,将价格和指标可视化能更直观地进行分析。

python 复制代码
def plot_indicators(df, symbol='700.HK'):
    """绘制价格、移动平均线、MACD和RSI图表"""
    fig, axes = plt.subplots(3, 1, figsize=(14, 12), gridspec_kw={'height_ratios': [3, 2, 2]})

    # 子图1:价格与移动平均线
    axes[0].plot(df.index, df['close'], label='Close Price', linewidth=1.5, color='black')
    colors = ['blue', 'orange', 'green']
    for i, period in enumerate([5, 10, 20]):
        if f'MA_{period}' in df.columns:
            axes[0].plot(df.index, df[f'MA_{period}'], label=f'MA{period}', alpha=0.8, color=colors[i])
    axes[0].set_title(f'{symbol} - Price & Moving Averages')
    axes[0].set_ylabel('Price')
    axes[0].legend(loc='upper left')
    axes[0].grid(True, alpha=0.3)

    # 子图2:MACD
    axes[1].plot(df.index, df['DIF'], label='DIF', color='blue', linewidth=1.5)
    axes[1].plot(df.index, df['DEA'], label='DEA', color='red', linewidth=1.5)
    # 用柱状图表示MACD Histogram,绿色为正,红色为负
    colors_hist = ['green' if x >= 0 else 'red' for x in df['MACD_Hist']]
    axes[1].bar(df.index, df['MACD_Hist'], color=colors_hist, alpha=0.5, width=0.8, label='MACD Hist')
    axes[1].axhline(y=0, color='grey', linestyle='--', linewidth=0.8)
    axes[1].set_ylabel('MACD')
    axes[1].legend(loc='upper left')
    axes[1].grid(True, alpha=0.3)

    # 子图3:RSI
    axes[2].plot(df.index, df['RSI_14'], label='RSI 14', color='purple', linewidth=1.5)
    axes[2].axhline(y=70, color='red', linestyle='--', alpha=0.7, label='Overbought (70)')
    axes[2].axhline(y=30, color='green', linestyle='--', alpha=0.7, label='Oversold (30)')
    axes[2].axhline(y=50, color='grey', linestyle='--', alpha=0.5)
    axes[2].set_ylabel('RSI')
    axes[2].set_ylim(0, 100)
    axes[2].legend(loc='upper left')
    axes[2].grid(True, alpha=0.3)
    axes[2].set_xlabel('Date')

    plt.tight_layout()
    plt.show()

# 绘制图表
plot_indicators(df, '700.HK')

三、 进阶:构建简单的交易信号

基于计算出的指标,我们可以生成基础的交易信号。

python 复制代码
def generate_signals(df):
    """基于MACD和RSI生成简单的交易信号"""
    df['signal'] = 0  # 初始化信号列

    # 规则1:RSI超卖(<30)且MACD金叉(DIF上穿DEA)作为潜在买入信号
    rsi_oversold = df['RSI_14'] < 30
    macd_golden_cross = (df['DIF'] > df['DEA']) & (df['DIF'].shift(1) <= df['DEA'].shift(1))
    df.loc[rsi_oversold & macd_golden_cross, 'signal'] = 1  # 买入信号

    # 规则2:RSI超买(>70)且MACD死叉(DIF下穿DEA)作为潜在卖出信号
    rsi_overbought = df['RSI_14'] > 70
    macd_death_cross = (df['DIF'] < df['DEA']) & (df['DIF'].shift(1) >= df['DEA'].shift(1))
    df.loc[rsi_overbought & macd_death_cross, 'signal'] = -1  # 卖出信号

    return df

df_with_signals = generate_signals(df)
signal_points = df_with_signals[df_with_signals['signal'] != 0]
print("交易信号点:")
print(signal_points[['close', 'RSI_14', 'DIF', 'DEA', 'signal']])

四、 总结与应用建议

通过市场 API,我们可以便捷地获取高质量的金融数据,并利用 Python 的强大计算能力,从底层实现 RSI、MACD 和移动平均线等核心指标的计算。这为你自主开发、测试和优化量化策略提供了极大的灵活性和透明度。

几点关键建议:

  1. 理解指标本质:不要盲目使用指标。理解 RSI 的超买超卖、MACD 的金叉死叉以及均线排列背后的市场含义至关重要。
  2. 多指标结合:单个指标可能存在缺陷(如 RSI 在强趋势中的钝化)。结合趋势指标(如 MA)和动量指标(如 RSI, MACD)进行综合判断,可以提高信号的可靠性。
  3. 参数优化与回测:指标的周期参数(如 RSI 的周期、MACD 的快慢线)并非一成不变。你需要针对不同的市场和标的,进行严格的回测来寻找更优的参数组合。
  4. 风险管理:任何技术指标都不能保证 100%的准确。在实际应用中,务必结合严格的资金管理和止损策略。

温馨提示:本文仅供代码参考,不构成任何投资建议。市场有风险,投资需谨慎

参考文档:https://blog.itick.org/rsi-strategy-hands-on-guide-with-itick-data-python

GitHub:https://github.com/itick-org/

相关推荐
x70x802 小时前
Go中nil的使用
开发语言·后端·golang
70asunflower2 小时前
Python with 语句与上下文管理完全教程
linux·服务器·python
MasonYyp2 小时前
DSPy优化提示词
大数据·人工智能
happyboy19862112 小时前
2026 大专大数据技术专业零基础能考的证书有哪些?
大数据
大公产经晚间消息2 小时前
天九企服董事长戈峻出席欧洲经贸峰会“大进步日”
大数据·人工智能·物联网
deephub2 小时前
为什么标准化要用均值0和方差1?
人工智能·python·机器学习·标准化
hnxaoli2 小时前
win10程序(十五)归档文件的xlsx目录自动分卷
python
喵手2 小时前
Python爬虫零基础入门【第九章:实战项目教学·第8节】限速器进阶:令牌桶 + 动态降速(429/5xx)!
爬虫·python·令牌桶·python爬虫工程化实战·python爬虫零基础入门·限速器·动态降速
深度学习lover2 小时前
<项目代码>yolo毛毛虫识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·毛毛虫识别