社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

【Python技术】同时获取股票及ETF数据改造示例

子晓聊技术 • 4 月前 • 172 次点击  

之前写的不少akshare代码基本是获取股票数据,有星球同学想看ETF数据,  这里代码稍微改造一下。
先说明我之前获取股票代码基本是用的
df = ak.stock_zh_a_hist(
    symbol=_symbol,
    period=period_type,
    start_date=start.strftime("%Y%m%d"),
    end_date=end.strftime("%Y%m%d"),
    adjust="qfq"
)

这个akshare代码底层是爬取东方财富的股票, 为啥没用新浪的接口, 主要是频繁爬取新浪财经-A -个股的历史行情数据, 容易封 IP。

1、 先说新浪接口方式
stock_data = ak.stock_zh_a_daily(symbol=stock_code, start_date=start_date, end_date=end_date)

返回的数据
名称
类型
描述
date
object
交易日
open
float64
开盘价
high
float64
最高价
low
float64
最低价
close
float64
收盘价
volume
float64
成交量; 注意单位: 股
amount
float64
成交额; 注意单位: 元
outstanding_share
float64
流动股本; 注意单位: 股
turnover
float64
换手率=成交量/流动股本

2、 增加 股票、ETF分类,类似我上面的截图。


# 资产选择    asset_type = st.radio("资产类型", ["股票""ETF"], horizontal=True)    code = st.text_input(f"{asset_type}代码""600519" if asset_type == "股票" else "510300")    start_date = st.date_input("开始日期", datetime(2024108))    end_date = st.date_input("结束日期", datetime.now())    show_volume = st.checkbox("显示成交量分析"True)    # 数据获取    data = get_asset_data(code, asset_type, start_date, end_date)def get_asset_data(symbol, asset_type, start, end):    """获取A股前复权数据"""    try:        code = f"{symbol}"        if(asset_type == '股票'):            df = ak.stock_zh_a_hist(                symbol=code, period="daily",                start_date=start.strftime("%Y%m%d"),                end_date=end.strftime("%Y%m%d"),                adjust="qfq"            )        if (asset_type == 'ETF'):            df = ak.fund_etf_hist_em(                symbol=code, period="daily",                start_date=start.strftime("%Y%m%d"),                end_date=end.strftime("%Y%m%d"),                adjust="qfq"            )        df = df.rename(columns={            '日期''date''开盘''open''收盘''close',            '最高''high''最低''low''成交量''volume'        })        



我用之前的神奇九转代码改造,完整例子如下:
# -*- coding: utf-8 -*-import akshare as akimport pandas as pdimport streamlit as stimport plotly.graph_objects as gofrom datetime import datetime# 神奇九转核心算法def calculate_nine_turns(df):    """计算九转序列"""    df['up_condition'] = df['close'] > df['close'].shift(4)    df['down_condition'] = df['close'] < df['close'].shift(4)    # 连续计数逻辑    for condition in ['up''down']:        streak = 0        streaks = []        for idx in range(len(df)):            if df[f'{condition}_condition'].iloc[idx]:                streak = streak + 1 if streak 9 else 9            else:                streak = 0            streaks.append(streak)        df[f'{condition}_streak'] = streaks    # 生成买卖信号    df['ma20'] = df['close'].rolling(20).mean()    #df['buy_signal'] = (df['down_streak'] == 9) & (df['close'] > df['ma20'])    df['buy_signal'] = (df['down_streak'] == 9)    #df['sell_signal'] = (df['up_streak'] == 9) & (df['close'] < df['ma20'])    df['sell_signal'] = (df['up_streak'] == 9)    return df# 数据获取def get_asset_data(symbol, asset_type, start, end):    """获取A股前复权数据"""    try:        code = f"{symbol}"        if(asset_type == '股票'):            df = ak.stock_zh_a_hist(                symbol=code, period="daily",                start_date=start.strftime("%Y%m%d"),                end_date=end.strftime("%Y%m%d"),                adjust="qfq"            )        if (asset_type == 'ETF'):            df = ak.fund_etf_hist_em(                symbol=code, period="daily",                start_date=start.strftime("%Y%m%d"),                end_date=end.strftime("%Y%m%d"),                adjust="qfq"            )        df = df.rename(columns={            '日期''date''开盘''open''收盘''close',            '最高''high''最低''low''成交量''volume'        })        df['date'] = pd.to_datetime(df['date'])        return df.set_index('date').sort_index()    except Exception as e:        st.error(f"数据获取失败:{str(e)}")        return None# 可视化def plot_kline_with_signals(df):    fig = go.Figure()    # 主K线    fig.add_trace(go.Candlestick(        x=df.index,        open=df['open'],        high=df['high'],        low=df['low'],        close=df['close'],        increasing_line_color='#FF4500',        decreasing_line_color=


    
'#1E90FF',        name='K线'    ))    # 九转标记    up_points = df[df['up_streak'] >= 1]    down_points = df[df['down_streak'] >= 1]    # up_points = df[df['up_streak'] >= 6]    # down_points = df[df['down_streak'] >= 6]    # 上涨序列    fig.add_trace(go.Scatter(        x=up_points.index,        y=up_points['high'] * 1.02,        mode='text',        text=up_points['up_streak'].astype(str),        textfont=dict(color='#FF4500', size=14),        name='上涨九转'    ))    # 下跌序列    fig.add_trace(go.Scatter(        x=down_points.index,        y=down_points['low'] * 0.98,        mode='text',        text=down_points['down_streak'].astype(str),        textfont=dict(color='#1E90FF', size=14),        name='下跌九转'    ))    # 买卖信号    buy_signals = df[df['buy_signal']]    sell_signals = df[df['sell_signal']]    fig.add_trace(go.Scatter(        x=buy_signals.index,        y=buy_signals['low'] * 0.95,        mode='markers',        marker=dict(color='green', size=12, symbol='triangle-up'),        name='买入信号'    ))    fig.add_trace(go.Scatter(        x=sell_signals.index,        y=sell_signals['high'] * 1.05,        mode='markers',        marker=dict(color='red', size=12, symbol='triangle-down'),        name='卖出信号'    ))    fig.update_layout(        title='神奇九转策略分析',        xaxis_rangeslider_visible=False,        hovermode='x unified',        height=600    )    return figdef app():    st.title("A股神奇九转策略分析系统")    # 资产选择    asset_type = st.radio("资产类型", ["股票""ETF"], horizontal=True)    code = st.text_input(f"{asset_type}代码""600519" if asset_type == "股票" else "510300")    start_date = st.date_input("开始日期", datetime(2024108))    end_date = st.date_input("结束日期", datetime.now())    show_volume = st.checkbox("显示成交量分析"True)    # 数据获取    data = get_asset_data(code, asset_type, start_date, end_date)    if data is not None:        analyzed_data = calculate_nine_turns(data)    # 主显示区    col1, col2 = st.columns([31])    with col1:        st.plotly_chart(plot_kline_with_signals(analyzed_data), use_container_width=True)    with col2:        st.subheader("实时信号")        if analyzed_data['buy_signal'].any():            last_buy = analyzed_data[analyzed_data['buy_signal']].iloc[-1]            st.success(f"""            **买入信号**              {last_buy.name.strftime('%Y-%m-%d')}              价格:{last_buy['close']:.2f}              """)        if analyzed_data['sell_signal'].any():            last_sell = analyzed_data[analyzed_data['sell_signal']].iloc[-1]            st.error(f"""            **卖出信号**              {last_sell.name.strftime(


    
'%Y-%m-%d')}              价格:{last_sell['close']:.2f}              """)    # 成交量分析    if show_volume:        st.subheader("成交量分析")        df_vol = analyzed_data[['volume']].copy()        df_vol['vol_ma5'] = df_vol['volume'].rolling(5).mean()        st.area_chart(df_vol, use_container_width=True)if __name__ == "__main__":    app()

相关文章推荐:
【Python技术】股票计算最大回测率、总收益率
【Python技术】神奇九转:量化市场拐点的经典技术理论



Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/181279
 
172 次点击