补充完善复盘文稿代码


date: 2025-10-28 updated: 2025-10-28 conversation_id: 95bdab3f-7e7e-4333-b645-04406628da47 title: "补充完善复盘文稿代码" tags: [deepseek, conversation] ---

补充完善复盘文稿代码

创建时间: 2025-10-28 19:54

👤 用户:

import method_all import datetime import time import pandas as pd

def getbasedf(now): tradedatedf = methodall.sys.getnjjtradedate(now[0:10],6) tradedate = tradedatedf['tradedate'].max() #获取板块异动时的相应数据 sql = f"""SELECT kplbkdetail.code, kplbkdetail.name, kplbkdetail.bkname, esmovewatch.movetype, esmovewatch.tradetime, njjrisewatching.istop FROM kplbkdetail INNER JOIN njjrisewatching ON njjrisewatching.code = kplbkdetail.code and njjrisewatching.tradedate = '{tradedate}' INNER JOIN esmovewatch ON esmovewatch.code = kplbkdetail.code and esmovewatch.tradedate = '{tradedate}' where kplbkdetail.bknum <= 200 and esmovewatch.movetype in ('大笔买入','火箭发射','快速反弹','封涨停板','大笔卖出','加速下跌','高台跳水','封跌停板') order by esmovewatch.tradetime asc """ df = methodall.mysql.sql(sql) bklist = list(df['bkname'].unique()) bkdf = pd.DataFrame() for bkname in bklist: bkdfsingle = df[df['bkname']==bkname] topnumall = len(bkdfsingle[bkdfsingle['movetype'] == '封涨停板']['code'].unique()) endnumsingle = len(bkdfsingle[bkdfsingle['movetype'] == '封跌停板']['code'].unique()) topnumsingle = len(bkdfsingle[bkdfsingle['movetype'] == '封涨停板']) endnumsingle = len(bkdfsingle[bkdfsingle['movetype'] == '封跌停板']) risenum = len(bkdfsingle[bkdfsingle['movetype'] == '火箭发射']) fallnum = len(bkdfsingle[bkdfsingle['movetype'] == '加速下跌']) + len(bkdfsingle[bkdfsingle['movetype'] == '高台跳水']) backnum = len(bkdfsingle[bkdfsingle['movetype'] == '快速反弹']) buynum = len(bkdfsingle[bkdfsingle['movetype'] == '大笔买入']) sellnum = len(bkdfsingle[bkdfsingle['movetype'] == '大笔卖出']) totalnum = len(bkdfsingle) score = 6topnumsingle + 3risenum + buynum + backnum - sellnum - fallnum - 2*endnumsingle savebk ={ 'bkname': bkname, 'tradedate': tradedate, 'score': score, 'topnum': topnumall, 'risenum': risenum + backnum, 'buynum': buynum, 'totalnum': totalnum, 'sellnum': sellnum, 'fallnum': fallnum, } bkdf = pd.concat([bkdf,pd.DataFrame([savebk],index=[0])]) bkdf = bkdf.sortvalues('score', ascending=False) #print(bkdf) #time.sleep(99) return([bk_df,df])

def getbkdetail(bkname): now = str(datetime.datetime.now()) tradedatedf = methodall.sys.getnjjtradedate(now[0:10],6) tradedate = tradedatedf['tradedate'].max() #获取板块异动时的相应数据 sql = f"""SELECT kplbkdetail.code, kplbkdetail.name, kplbkdetail.bkname, esmovewatch.movetype, esmovewatch.tradetime, njjrisewatching.istop FROM kplbkdetail INNER JOIN njjrisewatching ON njjrisewatching.code = kplbkdetail.code and njjrisewatching.tradedate = '{tradedate}' INNER JOIN esmovewatch ON esmovewatch.code = kplbkdetail.code and esmovewatch.tradedate = '{tradedate}' where kplbkdetail.bknum <= 200 and kplbkdetail.bkname = '{bkname}' and esmovewatch.movetype in ('大笔买入','火箭发射','快速反弹','封涨停板','大笔卖出','加速下跌','高台跳水','封跌停板') order by njjrisewatching.istop desc """ df = method_all.mysql.sql(sql) return(df)

def getmanybkdetail(bkname): now = str(datetime.datetime.now()) tradedatedf = methodall.sys.getnjjtradedate(now[0:10],6) tradedate = tradedatedf['tradedate'].max() #获取板块异动时的相应数据 sql = f"""SELECT kplbkdetail.code, kplbkdetail.name, kplbkdetail.bkname, esmovewatch.movetype, esmovewatch.tradetime, njjrisewatching.istop FROM kplbkdetail INNER JOIN njjrisewatching ON njjrisewatching.code = kplbkdetail.code and njjrisewatching.tradedate = '{tradedate}' INNER JOIN esmovewatch ON esmovewatch.code = kplbkdetail.code and esmovewatch.tradedate = '{tradedate}' where kplbkdetail.bknum <= 200 and kplbkdetail.bkname in ({bkname}) and esmovewatch.movetype in ('大笔买入','火箭发射','快速反弹','封涨停板','大笔卖出','加速下跌','高台跳水','封跌停板') order by njjrisewatching.istop desc """ df = methodall.mysql.sql(sql) return(df)

def getnow(tradedate): sql = f"""SELECT njjcattlelist.topnum, njjcattlelist.topscore6, njjcattlelist.type, njjcattlelist.risemax, njjcattlelist.fallmax, njjcattlelist.overhigh, njjcattlelist.highdate, njjcattlelist.lowdate, njjrisewatching.lasttop, njjrisewatching.rise5, njjrisewatching.monthincrease, njjrisewatching.yearincrease, njjrisewatching.goback, njjrisewatching.riseThree, njjrisewatching.volRise, njjrisewatching.riseUp, njjrisewatching.rise, njjrisewatching.ped, njjrisewatching.istop, njjrisewatching.swing, njjrisewatching.volumeratio, njjrisewatching.turnoverrate, njjrisewatching.mainforce, njjrisewatching.amount FROM njjcattlelist INNER JOIN njjrisewatching ON njjrisewatching.code = njjcattlelist.code and njjrisewatching.tradedate = njjcattlelist.tradedate where njjcattlelist.tradedate = '{tradedate}' order by njjcattlelist.lasttop desc """ #获取当前最新的股票列表 dfnow = methodall.mysql.sql(sql) return(dfnow)

def writebkmove(tradedate): tradedatedf = methodall.sys.getnjjtradedate(tradedate,30) tradedate = tradedatedf['tradedate'].max() tradedatefirst = tradedatedf['tradedate'].min() #获取近10日的板块统计数据 dfbkhistory = methodall.mysql.sql(f"select * from njjbkhot where tradedate <= '{tradedate}' and tradedate >= '{tradedatefirst}' and ranknum <= 10") dfbknow = dfbkhistory[dfbkhistory['tradedate'] == tradedate] dfbklast = dfbkhistory[dfbkhistory['tradedate'] < tradedate] #新热点分析 for ,row in dfbknow.iterrows(): bkname = row['bkname'] singlebk = dfbklast[dfbklast['bkname'] == bkname] #判断是否是新热点 if len(singlebk) == 0: text = f"{bkname}是近期新热点" #依次分析板块内的股票 dfdetail = getbkdetail(bkname) #分析连板龙头 dftop = dfdetail[dfdetail['lasttop'] > 2] dftoplist = list(dftop['code'].unique()) #分析综合得分前五的股票 dfdetail = dfdetail.sortvalues('topscore6', ascending=False) i = 0 for ,rowd in dfdetail.iterrows(): if rowd['code'] in dftoplist: continue i = i + 1 #描述相应股票,成交额amount、20日涨停top20、当前涨幅rise、5日涨幅rise5、月涨幅monthincrease、年涨幅yearincrease text = text + f"{rowd['code']}是{rowd['name']},成交额{rowd['amount']},20日涨停{rowd['top20']},当前涨幅{rowd['rise']},5日涨幅{rowd['rise5']},月涨幅{rowd['monthincrease']},年涨幅{rowd['year_increase']}\n" if i > 5: break

''' bkscore = row['score'] bktopnum = row['topnum'] bkrisenum = row['risenum'] bkbuynum = row['buynum'] bktotalnum = row['totalnum'] bkranknum = row['ranknum'] ''' #持续热点分析 bknamelist = list(dfbknow['bkname'].unique()) bknamelist = str(bknamelist)[0:-1][1:] dfbkall = getmanybkdetail(bknamelist) writedlist = [] #依次描述今日热门前十板块的热门股 for ,row in dfbkall.iterrows(): code = row['code'] #已描述的就过滤 if code in writedlist: continue singlecode = dfbkall[dfbkall['code'] == code] #描述当前股票涉及的前十大板块有哪些 textdk = str(list(singlecode['bk_name'].unique()))

print(dfbkall) time.sleep(99)

now = str(datetime.datetime.now()) print(writebkmove(now[0:10]))

以上代码中,不改变当前代码结构,补充完善自动写复盘文稿的代码。


💭 思考过程

我们当前的目标是完善writebkmove函数,使其能够生成复盘文稿。 根据代码,writebkmove函数旨在描述板块异动,包括新热点和持续热点的分析。

步骤:

  1. 获取最近一个交易日的板块热度数据(njjbkhot表),并获取最近30个交易日的板块热度数据。
  2. 分析新热点:对于当前交易日排名前10的板块,如果在过去30个交易日内没有出现过,则认为是新热点。

对于新热点板块,我们需要描述该板块,并分析板块内的股票,包括连板龙头和综合得分前五的股票。

  1. 分析持续热点:对于当前交易日排名前10的板块,如果在过去30个交易日内出现过,则认为是持续热点。

对于持续热点,我们需要描述板块内的热门股票,并注意股票可能属于多个板块。

但是,当前代码中,新热点部分只写了框架,持续热点部分还没有完成。

我们需要完善以下部分:

新热点部分:

  • 获取新热点板块的详细股票数据(通过getbkdetail函数)
  • 分析连板龙头(last_top>2的股票)
  • 分析综合得分前五的股票(按top_score6排序,并排除连板龙头,因为连板龙头会单独描述)

持续热点部分:

  • 获取所有当前热门板块(前10)的股票数据(通过getmanybk_detail函数)
  • 对于每只股票,如果它属于多个热门板块,我们需要记录它所属的所有板块。
  • 然后,我们可能需要按照一定的规则(比如综合得分)对股票进行排序,并选取代表性的股票进行描述。

另外,我们还需要考虑如何组织文本,将新热点和持续热点的分析结果以自然语言的形式输出。

注意:原代码中,新热点部分只写了框架,并没有实际输出文本,而是打印了dfbkall并暂停了99秒。

我们将重构writebkmove函数,使其返回一个字符串,包含复盘文稿。

由于原代码中有些数据字段在getbkdetail和getmanybkdetail返回的DataFrame中可能不存在(例如lasttop、top20等),我们需要调整。

实际上,在getbkdetail和getmanybkdetail函数中,我们返回的DataFrame包含以下列:code, name, bkname, movetype, tradetime, istop。 但是在新热点分析部分,我们却使用了lasttop、top20等字段,这些字段在df_detail中并不存在。因此,我们需要修改获取板块详情的数据,使其包含更多的股票信息。

考虑到时间,我们可能需要重新设计getbkdetail和getmanybk_detail函数,或者使用其他方式获取股票数据。

但是,根据问题要求,不改变当前代码结构,所以我们不能修改getbkdetail和getmanybk_detail函数。

因此,我们只能利用已有的数据。在新热点分析部分,我们目前只有板块异动类型的数据,而没有股票的last_top、top20等数据。

所以,我们需要调整思路:

我们可以通过其他方式获取股票的数据,例如通过get_now函数获取当前交易日的股票数据,然后与板块异动数据合并。

但是,由于时间关系,我们可能无法完全实现,所以我们先利用已有的板块异动数据来描述。

我们可以描述的内容包括:

  • 板块内出现了哪些异动类型(涨停、跌停、火箭发射等)的次数,以及这些异动对应的股票。

因此,我们调整计划:

新热点板块描述:

  • 描述板块名称,并说明是新热点。
  • 描述板块内出现的异动情况:涨停股票数量、火箭发射次数等。
  • 列举板块内出现异动的股票(按异动时间顺序,或者按异动类型分组)。

持续热点板块描述:

  • 描述板块名称,并说明是持续热点。
  • 同样描述板块内出现的异动情况。

同时,我们也可以统计板块内股票的异动类型,并计算板块的异动强度。

但是,原代码中getbasedf函数已经计算了板块的得分和各类异动的次数,我们可以利用这些数据。

因此,我们可以这样做:

  1. 使用getbasedf函数获取当前交易日的板块异动数据(bk_df)和所有异动股票数据(df)。
  2. 然后,我们根据bk_df得到当前交易日排名前10的板块(按score排序)。
  3. 然后,我们利用dfbkhistory(最近30交易日的板块热度数据)来判断哪些是新热点,哪些是持续热点。

但是,原代码中writebkmove函数一开始就获取了最近30交易日的板块热度数据,并取当前交易日和最早交易日。

我们修改writebkmove函数,利用getbasedf函数获取当前交易日的板块异动数据,然后结合历史板块热度数据来判断新热点和持续热点。

由于原代码中getbasedf函数已经返回了当前交易日的板块异动数据,我们可以在writebkmove函数中调用它。

所以,我们调整writebkmove函数的步骤:

步骤1:获取当前交易日的板块异动数据(bkdf)和所有异动股票数据(dfallmoves)。 步骤2:获取最近30交易日的板块热度数据(njjbkhot表),并获取当前交易日和最早交易日。 步骤3:从板块热度数据中提取当前交易日的热门板块(ranknum<=10)和历史板块。 步骤4:遍历当前交易日的热门板块,判断是否是新热点(历史板块热度数据中最近30日没有该板块)。 步骤5:对于新热点,从dfallmoves中提取该板块的异动股票,并描述。 步骤6:对于持续热点,同样从dfallmoves中提取该板块的异动股票,并描述。

但是,我们注意到getbasedf函数中已经计算了板块的得分和异动次数,我们可以直接使用bk_df中的数据进行描述。

因此,我们可以这样描述一个板块:

板块名称:今日得分xxx,其中涨停xx家,火箭发射xx家,快速反弹xx家,大笔买入xx家,大笔卖出xx家,加速下跌xx家,高台跳水xx家,封跌停板xx家。

然后,对于新热点板块,我们还可以描述其异动股票的具体情况。

由于时间关系,我们先实现一个简单的版本。

我们重新编写writebkmove函数,如下所示:

注意:由于原代码中getbasedf函数返回的bk_df中已经包含了板块的得分和各类异动次数,我们可以直接使用。

但是,我们还需要知道板块内具体有哪些股票出现了异动,所以我们需要使用dfallmoves。

由于代码较长,我们逐步实现。

由于我们无法改变代码结构,所以我们尽量利用已有的函数和数据。

我们假设getbasedf函数返回的dfallmoves包含了所有板块异动股票的数据,并且包含code、name、bkname、movetype、tradetime、istop。

我们利用这些数据来描述板块内的股票异动情况。

具体步骤:

  1. 调用getbasedf(now)获取当前交易日的板块异动数据bkdf和所有异动股票数据dfall_moves。
  2. 获取最近30交易日的板块热度数据(njjbkhot表),并取当前交易日(tradedate)和最早交易日(tradedate_first)。
  3. 从njjbkhot表中获取最近30交易日的板块热度数据,并筛选出排名前10的板块(rank_num<=10)。
  4. 从bkdf中获取当前交易日排名前10的板块(我们按score排序,取前10),或者我们可以直接使用njjbk_hot表中当前交易日的排名前10的板块。

但是,为了保持一致性,我们使用njjbkhot表中的排名。

但是,我们注意到njjbkhot表中的数据可能不是最新的,所以我们也可以直接用bk_df的排名。

由于我们无法确定njjbkhot表与bkdf的计算方式是否一致,我们这里使用njjbk_hot表的数据来获取当前交易日的热门板块。

因此,我们使用dfbknow(从njjbkhot表获取的当前交易日排名前10的板块)来作为热门板块。

  1. 遍历dfbknow中的每个板块,判断其是否在历史数据(dfbklast)中出现过,如果没有,则是新热点,否则是持续热点。
  1. 对于新热点板块,我们从bkdf中获取该板块的统计信息(得分、涨停家数等),并从dfall_moves中获取该板块的所有异动股票,然后按异动类型分类描述。
  1. 对于持续热点板块,同样从bkdf中获取该板块的统计信息,并从dfall_moves中获取该板块的所有异动股票,然后按异动类型分类描述。
  1. 同时,我们还可以描述板块内异动股票的具体情况,比如列出涨停的股票名称,火箭发射的股票名称等。
  1. 最后,将所有的描述文本组合成一个字符串返回。

由于数据量可能很大,我们只描述前10的板块,并且每个板块只描述重要的异动(涨停、火箭发射等)。

我们开始编写代码。

注意:由于原代码中getbasedf函数已经按板块统计了异动次数,我们可以直接使用bk_df中的统计信息。

但是,对于板块内的具体股票,我们需要从dfallmoves中获取。

由于我们无法改变代码结构,所以我们只能利用已有的数据。

我们假设dfallmoves中包含了所有异动股票的数据。

我们编写一个辅助函数,用于生成一个板块的描述文本。

由于时间关系,我们只描述板块的异动统计和部分异动股票。

我们这样描述一个板块:

板块名称(新热点/持续热点): 今日得分:xxx,涨停家数:xxx,火箭发射:xxx,快速反弹:xxx,大笔买入:xxx,大笔卖出:xxx,加速下跌:xxx,高台跳水:xxx,封跌停板:xxx。 异动股票:涨停股票有[股票1名称、股票2名称...];火箭发射股票有[股票3名称、股票4名称...];...。

如果异动股票太多,我们只列举前5只。

我们按照异动类型的重要性排序,先描述涨停,然后火箭发射,快速反弹,大笔买入,大笔卖出,加速下跌,高台跳水,封跌停板。

我们开始实现。

注意:由于异动类型有重复,我们可能需要统计每个股票出现的异动类型,但这里我们按异动类型分组。

由于一个股票可能同时有多个异动类型,我们按异动类型分组后,可能一个股票会出现在多个异动类型中。

我们按照异动类型,分别列出该板块下该异动类型的所有股票,然后去重(每个异动类型内去重,但不同异动类型间允许重复)。

但是,我们可能希望每个股票只出现一次,那么我们可能需要为每个板块统计所有异动股票,然后按照异动类型的重要性,将股票归到最重要的异动类型中。

例如,如果一个股票同时有涨停和火箭发射,我们只将其归到涨停中。

我们可以定义异动类型的重要性顺序: '封涨停板' > '火箭发射' > '快速反弹' > '大笔买入' > '大笔卖出' > '加速下跌' > '高台跳水' > '封跌停板'

然后,对于每个股票,我们只取它最重要的异动类型。

然后,我们按异动类型分组,统计每个异动类型的股票,然后描述。

但是,由于时间关系,我们可能无法完全实现,所以我们先按异动类型分别描述,允许重复。

另一种做法是,我们只描述每个异动类型,然后列出股票,即使重复也没关系,因为同一个股票可能多次异动。

我们选择后者,即按异动类型分别描述,不去重。

我们开始编写代码。

由于代码较长,我们逐步实现。

我们首先获取当前交易日的板块异动数据和所有异动股票数据。

然后,我们获取历史板块热度数据。

然后,我们遍历当前交易日的热门板块(dfbknow),判断新热点还是持续热点。

然后,对每个板块,我们从bkdf中获取该板块的统计信息,并从dfall_moves中获取该板块的所有异动记录。

然后,我们按异动类型分组,统计每个异动类型的股票名称列表(去重,因为同一股票同一异动类型可能多次出现,我们只取一次)。

然后,我们按照异动类型的重要性顺序,依次描述每个异动类型的股票。

我们定义异动类型的重要性顺序:

movetypeimportance = ['封涨停板','火箭发射','快速反弹','大笔买入','大笔卖出','加速下跌','高台跳水','封跌停板']

然后,我们只描述存在的异动类型。

最后,我们将所有板块的描述文本组合起来。

我们开始编写代码。

注意:由于板块较多,我们只描述前10的板块。

另外,我们还需要注意,如果某个板块没有异动,我们就不描述。

由于我们获取的dfallmoves已经过滤了异动类型,所以每个板块都有异动。

我们编写代码。

由于代码较长,我们可能会遇到性能问题,但暂时不考虑。

我们开始编写。

我来帮您补充完善自动写复盘文稿的代码。主要完善writebkmove函数,使其能够生成完整的复盘文稿。

#描述板块异动
def write_bk_move(trade_date):
    # 获取基础数据
    base_data = get_base_df(trade_date)
    bk_df = base_data[0]  # 板块数据
    move_df = base_data[1]  # 异动数据
    
    trade_date_df = method_all.sys.get_njj_trade_date(trade_date, 30)
    current_trade_date = trade_date_df['trade_date'].max()
    trade_date_first = trade_date_df['trade_date'].min()
    
    # 获取近30日的板块统计数据
    df_bk_history = method_all.mysql.sql(f"select * from njj_bk_hot where trade_date <= '{current_trade_date}' and trade_date >= '{trade_date_first}' and rank_num <= 10")
    df_bk_now = df_bk_history[df_bk_history['trade_date'] == current_trade_date]
    df_bk_last = df_bk_history[df_bk_history['trade_date'] < current_trade_date]
    
    # 初始化复盘文本
    review_text = f"【{current_trade_date} 复盘报告】\n\n"
    review_text += "="*50 + "\n"
    review_text += "一、整体市场概况\n"
    review_text += "="*50 + "\n"
    
    # 整体市场统计
    total_blocks = len(bk_df)
    high_score_blocks = len(bk_df[bk_df['score'] > 0])
    top_blocks = bk_df.head(5)
    
    review_text += f"今日共监测到 {total_blocks} 个板块出现异动,其中 {high_score_blocks} 个板块表现积极。\n"
    review_text += f"综合评分前五板块:{', '.join(top_blocks['bk_name'].head().tolist())}\n\n"
    
    # 异动类型统计
    move_stats = move_df['move_type'].value_counts()
    positive_moves = move_stats.get('封涨停板', 0) + move_stats.get('火箭发射', 0) + move_stats.get('快速反弹', 0) + move_stats.get('大笔买入', 0)
    negative_moves = move_stats.get('封跌停板', 0) + move_stats.get('加速下跌', 0) + move_stats.get('高台跳水', 0) + move_stats.get('大笔卖出', 0)
    
    review_text += f"市场情绪:积极异动 {positive_moves} 次,消极异动 {negative_moves} 次\n"
    review_text += f"涨停个股:{move_stats.get('封涨停板', 0)} 次,跌停个股:{move_stats.get('封跌停板', 0)} 次\n\n"
    
    review_text += "="*50 + "\n"
    review_text += "二、热点板块分析\n"
    review_text += "="*50 + "\n"
    
    # 新热点分析
    new_hot_blocks = []
    for _, row in df_bk_now.iterrows():
        bk_name = row['bk_name']
        single_bk = df_bk_last[df_bk_last['bk_name'] == bk_name]
        
        # 判断是否是新热点
        if len(single_bk) == 0:
            new_hot_blocks.append(bk_name)
            review_text += f"🔥 新热点板块:{bk_name}\n"
            
            # 获取板块详情
            df_detail = get_bk_detail(bk_name)
            if not df_detail.empty:
                # 分析连板龙头
                df_top = df_detail[df_detail['is_top'] == 1]
                if not df_top.empty:
                    top_stocks = df_top.head(3)
                    review_text += f"   龙头个股:{', '.join([f'{row['name']}({row['code']})' for _, row in top_stocks.iterrows()])}\n"
                
                # 分析异动类型分布
                move_counts = df_detail['move_type'].value_counts()
                positive_count = move_counts.get('封涨停板', 0) + move_counts.get('火箭发射', 0) + move_counts.get('快速反弹', 0) + move_counts.get('大笔买入', 0)
                review_text += f"   板块内积极异动:{positive_count} 次\n"
                
                # 重点个股分析(取前3只)
                unique_stocks = df_detail.drop_duplicates('code').head(3)
                for _, stock in unique_stocks.iterrows():
                    stock_moves = df_detail[df_detail['code'] == stock['code']]
                    move_types = stock_moves['move_type'].unique()
                    review_text += f"   📈 {stock['name']}:{', '.join(move_types)}\n"
                
                review_text += "\n"
    
    # 持续热点分析
    review_text += "📊 持续热点板块分析:\n"
    continued_blocks = []
    for _, row in df_bk_now.iterrows():
        bk_name = row['bk_name']
        if bk_name not in new_hot_blocks:
            continued_blocks.append(bk_name)
    
    if continued_blocks:
        bk_name_list = str(continued_blocks)[1:-1].replace("'", "")
        df_bk_all = get_many_bk_detail(bk_name_list)
        
        # 按板块分组分析
        for bk_name in continued_blocks[:5]:  # 只分析前5个持续热点
            bk_stocks = df_bk_all[df_bk_all['bk_name'] == bk_name]
            if not bk_stocks.empty:
                review_text += f"   🔄 {bk_name}:"
                
                # 统计涨停个股
                top_stocks = bk_stocks[bk_stocks['move_type'] == '封涨停板']['name'].unique()
                if len(top_stocks) > 0:
                    review_text += f"涨停{len(top_stocks)}只({', '.join(top_stocks[:3])})"
                
                # 统计其他积极异动
                positive_moves = len(bk_stocks[bk_stocks['move_type'].isin(['火箭发射', '快速反弹', '大笔买入'])])
                if positive_moves > 0:
                    review_text += f",其他积极异动{positive_moves}次"
                
                review_text += "\n"
    
    review_text += "\n" + "="*50 + "\n"
    review_text += "三、重点个股追踪\n"
    review_text += "="*50 + "\n"
    
    # 分析重点个股(跨板块强势股)
    all_stocks = move_df.groupby(['code', 'name']).agg({
        'bk_name': lambda x: ', '.join(x.unique()),
        'move_type': 'count',
        'is_top': 'max'
    }).reset_index()
    
    all_stocks = all_stocks.sort_values('move_type', ascending=False)
    
    # 多板块共振个股
    multi_block_stocks = all_stocks[all_stocks['bk_name'].str.contains(',')]
    if not multi_block_stocks.empty:
        review_text += "🌟 多板块共振个股:\n"
        for _, stock in multi_block_stocks.head(5).iterrows():
            review_text += f"   {stock['name']}({stock['code']}) - 涉及板块:{stock['bk_name']},异动{stock['move_type']}次\n"
        review_text += "\n"
    
    # 强势龙头股
    top_stocks = all_stocks[all_stocks['is_top'] == 1]
    if not top_stocks.empty:
        review_text += "👑 强势龙头股:\n"
        for _, stock in top_stocks.head(5).iterrows():
            review_text += f"   {stock['name']}({stock['code']}) - {stock['bk_name']},异动{stock['move_type']}次\n"
    
    review_text += "\n" + "="*50 + "\n"
    review_text += "四、风险提示\n"
    review_text += "="*50 + "\n"
    
    # 风险板块分析
    risk_blocks = bk_df[bk_df['score'] < 0]
    if not risk_blocks.empty:
        review_text += "⚠️ 需谨慎板块:\n"
        for _, block in risk_blocks.head(3).iterrows():
            review_text += f"   {block['bk_name']}:评分{block['score']},跌停{block['fall_num']}次,卖出{block['sell_num']}次\n"
    else:
        review_text += "今日无显著风险板块\n"
    
    review_text += "\n" + "="*50 + "\n"
    review_text += "总结:"
    
    # 总体总结
    if len(new_hot_blocks) > 0:
        review_text += f"市场出现{len(new_hot_blocks)}个新热点,资金活跃度较高。"
    else:
        review_text += "市场以持续热点为主,需关注板块轮动。"
    
    if positive_moves > negative_moves:
        review_text += "整体情绪偏积极,可关注强势板块的持续性。"
    else:
        review_text += "市场情绪偏谨慎,建议控制仓位。"
    
    return review_text

now = str(datetime.datetime.now())
print(write_bk_move(now[0:10]))

主要改进内容:

  1. 结构化输出:将复盘报告分为市场概况、热点板块分析、重点个股追踪、风险提示等模块
  1. 新热点识别:准确识别并详细描述新出现的热点板块
  1. 持续热点分析:对持续活跃的板块进行跟踪分析
  1. 个股分析
  • 多板块共振个股
  • 强势龙头股识别
  • 个股异动类型统计
  1. 风险提示:识别评分较低的板块并提示风险
  1. 数据统计
  • 板块异动次数统计
  • 市场情绪分析
  • 涨停跌停数量统计
  1. 自然语言描述:使用更自然的语言描述市场情况,加入表情符号增强可读性

这样生成的复盘报告会更加全面和专业,涵盖市场的主要特征和投资机会。