环境:dify 14.2 docker版本;
模型:glm-4-flash;
工具:Akshare,Ta-lib;
一、背景
作为在股市中历经磨砺的资深投资者,由于工作繁忙,无暇投入过多时间进行看盘。个人的看盘思路粗狂又简洁,主要关注股票市场的新闻动态、行情走势以及技术指标的趋势。虽然在投资方面表现尚有待提升,然而对股市充满热忱。为了更加高效地为国家经济贡献力量,特此打造一个大模型股票分析师,以助力自身在股市中更有力地拼搏🐶。
二、实现思路
通过 Akshare 接口获取股票行情数据与财经新闻数据,运用 ta-lib 对行情进行计算,得出主要的几个关键技术指标,同时提供指标分析参考。利用大模型对技术指标和财经新闻进行综合分析,并给出个股的长、中、短期投资参考意见。
三、实现步骤
-
开发行情服务:通过 Python 将 akshare 的特定数据接口进行封装,包括个股信息,个股行情,个股新闻,作成数据 API 接口,指定端口8081;
from flask import Flask, request, jsonify import akshare as ak import datetime app = Flask(__name__) # 辅助函数,用于验证日期格式是否符合要求(简单验证,可进一步完善) def validate_date(date_text): try: datetime.datetime.strptime(date_text, '%Y%m%d') return True except ValueError: return False # 接口1:获取中国A股历史股票数据 @app.route('/api/public/stock_zh_a_hist', methods=['GET']) def get_stock_zh_a_hist(): symbol = request.args.get('symbol', default="600000") period = request.args.get('period', default="daily") start_date = request.args.get('start_date', default="20220101") end_date = request.args.get('end_date', default="20221231") adjust = request.args.get('adjust', default="qfq") if not validate_date(start_date) or not validate_date(end_date): return jsonify({"error": "Invalid date format"}), 400 try: if period == "daily": data = ak.stock_zh_a_hist(symbol=symbol, start_date=start_date, end_date=end_date, adjust=adjust) elif period == "weekly": data = ak.stock_zh_a_hist_weekly(symbol=symbol, start_date=start_date, end_date=end_date, adjust=adjust) elif period == "monthly": data = ak.stock_zh_a_hist_monthly(symbol=symbol, start_date=start_date, end_date=end_date, adjust=adjust) else: return jsonify({"error": "Invalid period parameter"}), 400 result = data.to_dict(orient='records') return jsonify(result) except Exception as e: return jsonify({"error": str(e)}), 500 # 接口2:获取个股信息 @app.route('/api/public/stock_individual_info_em', methods=['GET']) def get_stock_individual_info_em(): symbol = request.args.get('symbol', default="603777") timeout = request.args.get('timeout', default=None, type=float) try: if timeout: data = ak.stock_individual_info_em(symbol=symbol, timeout=timeout) else: data = ak.stock_individual_info_em(symbol=symbol) return jsonify({"item": data['item'], "value": data['value']}) except Exception as e: return jsonify({"error": str(e)}), 500 # 接口3:获取股票相关新闻 @app.route('/api/public/stock_news_em', methods=['GET']) def get_stock_news_em(): symbol = request.args.get('symbol', default="300059") try: data = ak.stock_news_em(symbol=symbol) result = { "关键词": data['关键词'], "新闻标题": data['新闻标题'], "新闻内容": data['新闻内容'], "发布时间": data['发布时间'], "文章来源": data['文章来源'], "新闻链接": data['新闻链接'] } return jsonify(result) except Exception as e: return jsonify({"error": str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=8081)
-
开发指标分析服务:通过 Python 将 ta-lib 与 akshare 进行整合,以构建一个技术指标分析服务,技术指标包换布林带,CCI,BBI,MACD等常见技术指标,并对指标结果提供分析参考,指定端口20012;
from flask import Flask, request import akshare as ak import talib import pandas as pd import datetime app = Flask(__name__) @app.route('/stock_indicators', methods=['POST']) def stock_indicators(): try: data = request.get_json() stock_code = data.get('stock_code') # 获取当前日期 end_date_str = datetime.datetime.now().strftime('%Y%m%d') # 计算两个月前的日期 start_date = datetime.datetime.now() - datetime.timedelta(days=60) start_date_str = start_date.strftime('%Y%m%d') # 使用akshare获取近一个月的股票行情数据 stock_df = ak.stock_zh_a_hist(symbol=stock_code, period='daily', start_date=start_date_str, end_date=end_date_str, adjust='qfq') stock_df.set_index('日期', inplace=True) stock_df['收盘'] = pd.to_numeric(stock_df['收盘']) stock_df['开盘'] = pd.to_numeric(stock_df['开盘']) stock_df['最高'] = pd.to_numeric(stock_df['最高']) stock_df['最低'] = pd.to_numeric(stock_df['最低']) stock_df['成交量'] = pd.to_numeric(stock_df['成交量']) # 计算BBANDS指标 upper_band, middle_band, lower_band = talib.BBANDS(stock_df['收盘'], timeperiod=20, nbdevup=2, nbdevdn=2) # 计算CCI指标 cci = talib.CCI(stock_df['最高'], stock_df['最低'], stock_df['收盘'], timeperiod=14) # 计算RSI指标 rsi = talib.RSI(stock_df['收盘'], timeperiod=14) # 计算OBV指标 obv = talib.OBV(stock_df['收盘'], stock_df['成交量']) # 计算ATR指标 atr = talib.ATR(stock_df['最高'], stock_df['最低'], stock_df['收盘'], timeperiod=14) # 计算WILLR指标 willr = talib.WILLR(stock_df['最高'], stock_df['最低'], stock_df['收盘'], timeperiod=14) # 新增指标计算部分 # 计算DEMA指标 dema = talib.DEMA(stock_df['收盘'], timeperiod=30) # 计算MAMA指标及相关辅助指标 mama, fama = talib.MAMA(stock_df['收盘']) # 计算TRIMA指标 trima = talib.TRIMA(stock_df['收盘'], timeperiod=30) # 计算ADXR指标 adxr = talib.ADXR(stock_df['最高'], stock_df['最低'], stock_df['收盘'], timeperiod=14) # 计算MACD指标 macd, macdsignal, macdhist = talib.MACD(stock_df['收盘'], fastperiod=12, slowperiod=26, signalperiod=9) # 计算MFI指标 mfi = talib.MFI(stock_df['最高'], stock_df['最低'], stock_df['收盘'], stock_df['成交量'], timeperiod=14) # 计算HT_DCPERIOD指标 ht_dcperiod = talib.HT_DCPERIOD(stock_df['收盘']) # 计算AD指标 ad = talib.AD(stock_df['最高'], stock_df['最低'], stock_df['收盘'], stock_df['成交量']) # 获取最近一天的指标数据 last_index = stock_df.index[-1] result = { 'last_date': last_index.strftime('%Y-%m-%d'), 'BBANDS_upper': upper_band[-1], 'BBANDS_middle': middle_band[-1], 'BBANDS_lower': lower_band[-1], 'CCI': cci[-1], 'RSI': rsi[-1], 'OBV': obv[-1], 'ATR': atr[-1], 'WILLR': willr[-1], 'DEMA': dema[-1], 'MAMA': mama[-1], 'TRIMA': trima[-1], 'ADXR': adxr[-1], 'MACD': macd[-1], 'MFI': mfi[-1], 'HT_DCPERIOD': ht_dcperiod[-1], 'AD': ad[-1] } # 简单添加指标结果判断逻辑 analysis_result = {} # 对RSI指标进行简单判断 if rsi[-1] < 30: analysis_result['RSI_analysis'] = "RSI值较低,可能处于超卖状态,有一定反弹的可能性" elif rsi[-1] > 70: analysis_result['RSI_analysis'] = "RSI值较高,可能处于超买状态,股价有回调风险" else: analysis_result['RSI_analysis'] = "RSI处于正常区间,行情趋势相对稳定" # 对CCI指标进行简单判断 if cci[-1] < -100: analysis_result['CCI_analysis'] = "CCI值较低,股价可能处于超卖区间,关注反弹机会" elif cci[-1] > 100: analysis_result['CCI_analysis'] = "CCI值较高,股价可能处于超买区间,警惕回调风险" else: analysis_result['CCI_analysis'] = "CCI处于正常区间,市场行情暂无明显异动" # 对OBV指标进行简单判断(简单对比与前一天的大小,仅示例) if len(obv) > 1 and obv[-1] > obv[-2]: analysis_result['OBV_analysis'] = "OBV指标上升,说明近期成交量与股价配合较好,上涨动力可能增强" elif len(obv) > 1 and obv[-1] < obv[-2]: analysis_result['OBV_analysis'] = "OBV指标下降,可能成交量与股价配合不佳,上涨动力可能减弱" else: analysis_result['OBV_analysis'] = "OBV暂无明显变化,成交量与股价关系较平稳" # 对BBANDS指标进行简单判断 if stock_df['收盘'][-1] > upper_band[-1]: analysis_result['BBANDS_analysis'] = "股价位于布林带上轨之上,可能处于超买状态,有回调风险" elif stock_df['收盘'][-1] < lower_band[-1]: analysis_result['BBANDS_analysis'] = "股价位于布林带下轨之下,可能处于超卖状态,关注反弹机会" else: analysis_result['BBANDS_analysis'] = "股价在布林带通道内,行情相对平稳" # 对ATR指标进行简单判断(仅简单对比与历史均值,示例) atr_mean = atr.mean() if atr[-1] > atr_mean: analysis_result['ATR_analysis'] = "ATR值高于历史平均水平,近期股价波动幅度加大,市场活跃度较高" else: analysis_result['ATR_analysis'] = "ATR值低于或接近历史平均水平,近期股价波动幅度较小,市场相对平稳" # 对WILLR指标进行简单判断 if willr[-1] < 20: analysis_result['WILLR_analysis'] = "WILLR值较低,市场处于超卖状态,股价可能有反弹机会" elif willr[-1] > 80: analysis_result['WILLR_analysis'] = "WILLR值较高,市场处于超买状态,股价可能面临回调压力" else: analysis_result['WILLR_analysis'] = "WILLR处于正常区间,市场买卖力量相对平衡" # 新增指标分析逻辑部分 # 对DEMA指标进行简单判断(示例,对比与收盘价,简单判断趋势) if dema[-1] > stock_df['收盘'][-1]: analysis_result['DEMA_analysis'] = "DEMA值高于收盘价,短期价格趋势可能向上" elif dema[-1] < stock_df['收盘'][-1]: analysis_result['DEMA_analysis'] = "DEMA值低于收盘价,短期价格趋势可能向下" else: analysis_result['DEMA_analysis'] = "DEMA与收盘价接近,短期价格趋势较平稳" # 对MAMA指标进行简单判断(示例,对比与FAMA,简单看背离等情况,仅简单示意) if mama[-1] > fama[-1]: analysis_result['MAMA_analysis'] = "MAMA高于FAMA,可能价格趋势向上,且自适应移动平均显示趋势增强" elif mama[-1] < fama[-1]: analysis_result['MAMA_analysis'] = "MAMA低于FAMA,可能价格趋势向下,且自适应移动平均显示趋势减弱" else: analysis_result['MAMA_analysis'] = "MAMA与FAMA接近,价格趋势相对平稳,自适应调整不明显" # 对TRIMA指标进行简单判断(示例,对比与收盘价判断支撑阻力情况) if trima[-1] > stock_df['收盘'][-1]: analysis_result['TRIMA_analysis'] = "TRIMA高于收盘价,可能起到一定支撑作用" elif trima[-1] < stock_df['收盘'][-1]: analysis_result['TRIMA_analysis'] = "TRIMA低于收盘价,可能形成一定阻力" else: analysis_result['TRIMA_analysis'] = "TRIMA与收盘价接近,当前位置支撑阻力作用不明显" # 对ADXR指标进行简单判断(示例,对比与固定值判断趋势强度) if adxr[-1] > 50: analysis_result['ADXR_analysis'] = "ADXR值较高,说明价格长期趋势较强,市场方向性明显" elif adxr[-1] < 50: analysis_result['ADXR_analysis'] = "ADXR值较低,价格长期趋势相对较弱,市场方向性不明显" else: analysis_result['ADXR_analysis'] = "ADXR处于中间值附近,长期趋势强度一般" # 对MACD指标进行简单判断(示例,看MACD线与信号线位置关系) if macd[-1] > macdsignal[-1]: analysis_result['MACD_analysis'] = "MACD线在信号线之上,可能处于多头市场,上涨趋势有望延续" elif macd[-1] < macdsignal[-1]: analysis_result['MACD_analysis'] = "MACD线在信号线之下,可能处于空头市场,下跌趋势可能延续" else: analysis_result['MACD_analysis'] = "MACD线与信号线接近重合,市场趋势不明朗" # 对MFI指标进行简单判断(示例,对比与固定值判断资金流入流出情况) if mfi[-1] > 80: analysis_result['MFI_analysis'] = "MFI值较高,资金流入力量较强,市场处于超买状态,警惕资金流出风险" elif mfi[-1] < 20: analysis_result['MFI_analysis'] = "MFI值较低,资金流出力量较强,市场处于超卖状态,关注资金回流机会" else: analysis_result['MFI_analysis'] = "MFI处于正常区间,资金流入流出相对平衡,市场行情较平稳" # 对HT_DCPERIOD指标进行简单判断(示例,根据值大小判断周期长短情况) if ht_dcperiod[-1] > 20: analysis_result['HT_DCPERIOD_analysis'] = "HT_DCPERIOD值较大,资产价格周期较长,趋势变化相对缓慢" else: analysis_result['HT_DCPERIOD_analysis'] = "HT_DCPERIOD值较小,资产价格周期较短,趋势变化可能较频繁" # 对AD指标进行简单判断(示例,对比与前一天值判断趋势) if len(ad) > 1 and ad[-1] > ad[-2]: analysis_result['AD_analysis'] = "AD指标上升,说明资产累积情况增强,价格趋势向上的可能性增大" elif len(ad) > 1 and ad[-1] < ad[-2]: analysis_result['AD_analysis'] = "AD指标下降,资产分布情况增强,价格趋势向下的可能性增大" else: analysis_result['AD_analysis'] = "AD指标平稳,资产累积分布情况变化不大,价格趋势较稳定" result.update(analysis_result) return result except Exception as e: return {'error': str(e)} if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=20012)
-
自定义dify工具:将行情服务和指标分析服务作为dify平台自定义工具;
openapi: 3.1.0 info: title: AKTools API description: API for accessing financial data through AKTools, built on top of AKShare and FastAPI. version: "1.0.0" servers: - url: http://行情服务ip地址:8081 description: Local development server paths: /api/public/stock_zh_a_hist: get: summary: Get historical stock data for Chinese A-shares. description: This endpoint provides historical stock data for Chinese A-shares. It can be accessed with or without parameters. parameters: - in: query name: symbol schema: type: string description: The stock symbol.[600180] example: "600000" - in: query name: period schema: type: string enum: [daily, weekly, monthly] description: The period of the stock data. [daily, weekly, monthly] example: "daily" - in: query name: start_date schema: type: string format: date description: The start date for the data range.[20220101] example: "2022-01-01" - in: query name: end_date schema: type: string format: date description: The end date for the data range.[20221231] example: "2022-12-31" - in: query name: adjust schema: type: string enum: [qfq, hfq] description: The type of price adjustment.[qfq,hfq] example: "hfq" responses: '200': description: Successful response with historical stock data. content: application/json: schema: type: array items: $ref: '#/components/schemas/StockData' '400': description: Bad request, e.g., due to invalid parameters. '500': description: Internal server error. /api/public/stock_individual_info_em: get: summary: Get individual stock information. description: This endpoint is used to obtain information about a specific stock. parameters: - in: query name: symbol schema: type: string description: The stock code, e.g. symbol="603777". example: "603777" - in: query name: timeout schema: type: float description: Timeout parameter, default not set if None. example: null responses: '200': description: Successful response with stock individual information. content: application/json: schema: type: object properties: item: type: object value: type: object '400': description: Bad request, e.g., due to invalid parameters. '500': description: Internal server error. /api/public/stock_news_em: get: summary: Get stock-related news. description: This endpoint is used to obtain news related to a specific stock or other keywords. parameters: - in: query name: symbol schema: type: string description: The stock code or other keywords, e.g. symbol="300059". example: "300059" responses: '200': description: Successful response with stock news details. content: application/json: schema: type: object properties: 关键词: type: object 新闻标题: type: object 新闻内容: type: object 发布时间: type: object 文章来源: type: object 新闻链接: type: object '400': description: Bad request, e.g., due to invalid parameters. '500': description: Internal server error. /api/public/futures_news_shmet: get: summary: Get futures news from Shanghai Metals Market. description: This endpoint is used to obtain futures news from Shanghai Metals Market. parameters: - in: query name: symbol schema: type: string enum: ["全部", "要闻", "VIP", "财经", "铜", "铝", "铅", "锌", "镍", "锡", "贵金属", "小金属"] description: The category of news, e.g. symbol="铜". example: "铜" responses: '200': description: Successful response with futures news details. content: application/json: schema: type: object properties: 发布时间: type: object 内容: type: object '400': description: Bad request, e.g., due to invalid parameters. '500': description: Internal server error. components: schemas: StockData: type: object properties: date: type: string format: date open: type: number close: type: number high: type: number low: type: number volume: type: integer amount: type: number amplitude: type: number change_percent: type: number change: type: number turnover_rate: type: number security: - api_key: [] securityDefinitions: api_key: type: apiKey name: X-API-Key in: header description: For accessing the API, you need to provide your API key in the request header.
openapi: 3.0.0 info: title: Stock Indicators API version: 1.0.0 servers: - url: http://指标分析服务ip地址:20012 # 这里替换成实际的API基础URL description: Production server paths: /stock_indicators: post: summary: Calculate stock indicators and analysis results requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/StockIndicatorsRequest' responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/StockIndicatorsResponse' '500': description: Internal server error content: application/json: schema: type: object properties: error: type: string components: schemas: StockIndicatorsRequest: type: object properties: stock_code: type: string StockIndicatorsResponse: type: object properties: last_date: type: string format: date BBANDS_upper: type: number BBANDS_middle: type: number BBANDS_lower: type: number CCI: type: number RSI: type: number OBV: type: number ATR: type: number WILLR: type: number RSI_analysis: type: string CCI_analysis: type: string OBV_analysis: type: string BBANDS_analysis: type: string ATR_analysis: type: string WILLR_analysis: type: string
-
配置dify工作流:用户输入股票代码后,利用 Dify 时间工具获取相应时间戳,接着通过行情服务工具及指标分析工具获取指定股票的行情数据与指标分析内容,再借助大模型对行情数据和技术指标进行整合,最终输出为股评报告。
四、效果展示
同花顺综合分析报告(日期:2025-01-24)
一、行情分析
同花顺(300033)在近期的行情中呈现出波动上升的趋势。从2025年1月17日至1月24日的行情来看,股价在开盘价280.42元至299.23元之间波动,收盘价在288.30元至299.23元之间。整体来看,股价在经历了一段时间的震荡后,呈现上升态势。期间,成交量相对稳定,换手率在3.76%至10.40%之间。
二、技术分析
1. AD指标上升,表明资产累积情况增强,价格趋势向上的可能性增大。
2. ADXR值较低,价格长期趋势相对较弱,市场方向性不明显。
3. ATR值低于历史平均水平,近期股价波动幅度较小,市场相对平稳。
4. CCI处于正常区间,市场行情暂无明显异动。
5. MACD线在信号线之上,可能处于多头市场,上涨趋势有望延续。
6. MFI值较高,资金流入力量较强,市场处于超买状态,需警惕资金流出风险。
7. OBV指标上升,说明近期成交量与股价配合较好,上涨动力可能增强。
8. RSI处于正常区间,行情趋势相对稳定。
三、新闻影响评估
近期关于同花顺的新闻报道主要涉及融资净买入、行业关注、ETF表现等方面。例如,1月23日同花顺被提及为融资净买入金额排名前列的股票之一,显示市场对其有一定的关注。同时,同花顺所在行业软件开发受到关注,且相关ETF表现良好,这可能对同花顺股价产生积极影响。
四、市场情绪解读
综合行情走势和新闻报道,当前市场对同花顺的情绪较为乐观。股价的上涨和行业关注度提升表明投资者对其未来发展抱有信心。
五、投资建议
基于以上分析,对于同花顺给出以下投资建议:
短期投资:考虑到当前股价走势和市场情绪,建议短期投资者可考虑逢低吸纳,关注关键技术指标的变化和重要新闻事件的进展,以便及时调整投资策略。
长期投资:同花顺所在行业具有发展潜力,且公司基本面良好,建议长期投资者可持有,但需密切关注市场动态和公司业绩。
风险提示:股票市场具有较高的风险性和不确定性,投资决策应综合考虑个人的风险承受能力、投资目标和投资期限等因素,切勿盲目跟风投资。
同花顺最近重点新闻
1. 同花顺(300033)在1月23日融资客净买入金额排名中,涨跌幅为0.66%。
2. 同花顺(300033)在1月23日创业板指数强势上涨1.79%时,上涨6.12%。
3. 同花顺(300033)在1月23日创业板指数强势上涨1.54%时,上涨5.97%。
4. 同花顺(300033)的前十大权重股合计占比52.57%。
5. 同花顺(300033)在1月23日中证A500指数强势上涨1.69%时,上涨8.00%。
6. 同花顺(300033)在1月23日计算机行业资金流向日报中,涨跌幅为0.66%。
7. 同花顺(300033)在1月23日计算机行业资金流入榜中,涨跌幅为3.22%。
8. 同花顺(300033)在1月24日东方财富、同花顺等10股获融资净买入超1亿元时,融资净买入额居前三。
9. 同花顺(300033)在1月14日融资客净买入金额排名中,涨跌幅为14.68%。
10. 同花顺(300033)在1月15日融资客净买入金额排名中,涨跌幅为1.96%。
11. 同花顺(300033)在1月20日同花顺:约201.6万股限售股1月14日解禁。
12. 同花顺(300033)在1月17日创业板融资余额三连增时,最新融资余额为48.98亿元。
13. 同花顺(300033)在1月17日33股获杠杆资金净买入超亿元时,融资净买入额居首。
14. 同花顺(300033)在1月14日17股特大单净流入资金超2亿元时,特大单净流入资金超7.68亿元。
15. 同花顺(300033)在1月14日46股特大单净流入资金超2亿元时,特大单净流入资金超7.68亿元。
16. 同花顺(300033)在1月14日计算机行业1月14日资金流向日报中,涨跌幅为14.68%。
17. 同花顺(300033)在1月14日财政政策积极调控,助力新质生产力崛起时,上涨7.62%。
18. 同花顺(300033)在1月15日17股特大单净流入资金超2亿元时,特大单净流入资金超2亿元。
19. 同花顺(300033)在1月15日46股特大单净流入资金超2亿元时,特大单净流入资金超2亿元。
20. 同花顺(300033)在1月14日计算机行业1月14日资金流向日报中,涨跌幅为14.68%。
关注微信公众号【红岸解码室】,发送“股票分析师”,获取股票分析师DSL 文件!