python股票均线系统应用

通道线、均线交叉、葛兰碧Granville买卖八法标注

#股票均线系统应用
import akshare as ak
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# 获取股票数据
def get_stock_data(stock_code, start_date, end_date):
    stock_df = ak.stock_zh_a_hist(symbol=stock_code, period="daily", start_date=start_date, end_date=end_date, adjust="qfq")
    stock_df['日期'] = pd.to_datetime(stock_df['日期'])
    stock_df.set_index('日期', inplace=True)
    return stock_df

# 计算均线
def calculate_ma(data, ma_periods=[5, 10, 20, 30, 60, 120]):
    for period in ma_periods:
        data[f'MA{period}'] = data['收盘'].rolling(window=period).mean()
    return data

# 识别均线多头排列
def identify_bullish_arrangement(data, ma_periods=[5, 10, 20, 30, 60, 120]):
    ma_columns = [f'MA{period}' for period in ma_periods]
    data['bullish_arrangement'] = (data[ma_columns].diff(axis=1).iloc[:, 1:] > 0).all(axis=1)
    return data

# 识别均线交叉信号
def identify_ma_cross(data, short_ma=5, long_ma=20):
    data['ma_cross'] = np.where(data[f'MA{short_ma}'] > data[f'MA{long_ma}'], 1, -1)
    data['ma_cross_signal'] = data['ma_cross'].diff()
    return data

# 计算葛兰碧八大法则买卖点
def granville_rules(data):
    close = data['收盘']
    ma = data['MA20']
    data['buy_signal'] = 0
    data['sell_signal'] = 0

    # 法则 1: 均线从下降逐渐走平且略向上方抬头,而股价从均线下方向上方突破,为买进信号
    data.loc[(ma.shift(1) < ma) & (close > ma) & (close.shift(1) <= ma.shift(1)), 'buy_signal'] = 1
    # 法则 2: 股价位于均线之上运行,回档时未跌破均线后又再度上升时为买进时机
    data.loc[(close > ma) & (close.shift(1) < ma) & (close > close.shift(1)), 'buy_signal'] = 1
    # 法则 3: 股价位于均线之上运行,回档时跌破均线,但短期均线继续呈上升趋势,此时为买进时机
    data.loc[(close < ma) & (close.shift(1) > ma) & (ma.shift(1) < ma), 'buy_signal'] = 1
    # 法则 4: 股价位于均线以下运行,突然暴跌,距离均线太远,极有可能向均线靠近(物极必反,下跌反弹),此时为买进时机
    data.loc[(close < ma) & ((ma - close) / ma > 0.1), 'buy_signal'] = 1

    # 法则 5: 股价位于均线之上运行,连续数日大涨,离均线愈来愈远,说明近期内购买股票者获利丰厚,随时都会产生获利回吐的卖压,应暂时卖出持股
    data.loc[(close > ma) & ((close - ma) / ma > 0.1), 'sell_signal'] = 1
    # 法则 6: 均线从上升逐渐走平,而股价从均线上方向下跌破均线时说明卖压渐重,应卖出所持股票
    data.loc[(ma.shift(1) > ma) & (close < ma) & (close.shift(1) >= ma.shift(1)), 'sell_signal'] = 1
    # 法则 7: 股价位于均线下方运行,反弹时未突破均线,且均线跌势减缓,趋于水平后又出现下跌趋势,此时为卖出时机
    data.loc[(close < ma) & (close.shift(1) > ma) & (ma.shift(1) > ma), 'sell_signal'] = 1
    # 法则 8: 股价反弹后在均线上方徘徊,而均线却继续下跌,宜卖出所持股票
    data.loc[(close > ma) & (ma.shift(1) > ma), 'sell_signal'] = 1

    return data

# 计算均线通道策略
def calculate_ma_channel(data, ma_period=20):
    ma = data[f'MA{ma_period}']
    std = data['收盘'].rolling(window=ma_period).std()
    data['upper_channel'] = ma + 2 * std
    data['lower_channel'] = ma - 2 * std
    return data

# 绘制图形
def plot_data(data, ma_periods, stock_code):  # 添加 stock_code 参数
    plt.figure(figsize=(16, 10))
    plt.plot(data['收盘'], label='Close Price')  
    for period in ma_periods:
        plt.plot(data[f'MA{period}'], label=f'MA{period}')
    plt.plot(data['upper_channel'], label='Upper Channel', linestyle='--', color='r')
    plt.plot(data['lower_channel'], label='Lower Channel', linestyle='--', color='g')

    # 绘制均线交叉信号
    buy_cross = data[data['ma_cross_signal'] == 2].index
    sell_cross = data[data['ma_cross_signal'] == -2].index
    plt.scatter(buy_cross, data.loc[buy_cross, '收盘'], marker='^', color='g', label='MA Cross Buy Signal')
    plt.scatter(sell_cross, data.loc[sell_cross, '收盘'], marker='v', color='r', label='MA Cross Sell Signal')

    # 绘制葛兰碧八大法则买卖点
    buy_points = data[data['buy_signal'] == 1].index
    sell_points = data[data['sell_signal'] == 1].index
    plt.scatter(buy_points, data.loc[buy_points, '收盘'], marker='o', color='b', label='Granville Buy Signal')
    plt.scatter(sell_points, data.loc[sell_points, '收盘'], marker='x', color='m', label='Granville Sell Signal')

    plt.title(f'Stock Price with MA and Channel - Stock Code: {stock_code}')  # 修改标题
    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.legend()
    plt.grid(True)
    plt.show()

if __name__ == "__main__":
    stock_code = "600938"  # 贵州茅台
    start_date = "20241201"
    end_date = "20250523"
    ma_periods=[5, 10, 20, 30]
    # 获取数据
    stock_data = get_stock_data(stock_code, start_date, end_date)

    # 计算均线
    stock_data = calculate_ma(stock_data)

    # 识别均线多头排列
    stock_data = identify_bullish_arrangement(stock_data)

    # 识别均线交叉信号
    stock_data = identify_ma_cross(stock_data)

    # 计算葛兰碧八大法则买卖点
    stock_data = granville_rules(stock_data)

    # 计算均线通道策略
    stock_data = calculate_ma_channel(stock_data)

    # 绘制图形
    plot_data(stock_data, ma_periods, stock_code)  # 传递 stock_code 参数