股票之声

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: alexrr

记录一下26年的操作情况

[复制链接]
 楼主| 发表于 2026-6-20 23:10 | 显示全部楼层
不行 还是有好多要修改的 明天再继续吧

感觉改成一个评分系统是不是会更好一些?? 满足多少训练条件得一个分数
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-21 13:57 | 显示全部楼层
强者恒强 选择大于努力

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-21 14:04 | 显示全部楼层
import pandas as pd
import numpy as np

# ---------- 辅助函数 ----------
def MA(series, n):
    return series.rolling(n).mean()

def REF(series, n):
    return series.shift(n)

# ---------- 主选股函数 ----------
def check_stock(df_stock, df_index, df_sector, params, current_date=None,
                roe=None, cash_flow=None, shareholder_cnt=None, north_hold=None):
    """
    判断股票在指定日期是否属于四种训练形态之一
    参数:
        df_stock : DataFrame, 必须含 open, high, low, close, volume, capital
        df_index : DataFrame, 必须含 close (大盘指数)
        df_sector: DataFrame, 必须含 close (板块指数)
        params   : dict, 包含所有参数 N1~N22
        current_date : 日期, 默认最新
        roe : list, 最近3年ROE(%),如 [12, 13, 14]
        cash_flow : float, 经营现金流/净利润,如 1.2
        shareholder_cnt : list, 最近3期股东户数,如 [50000, 48000, 46000]
        north_hold : list, 最近3期北向持股比例(%),如 [3.2, 3.8, 4.5]
    返回:
        dict: {"match": True/False, "type1": True/False, ...}
    """
    if current_date is None:
        current_date = df_stock.index[-1]

    df = df_stock.loc[:current_date].copy()
    if len(df) < 250:
        return {"match": False, "type1": False, "type2": False, "type3": False, "type4": False,
                "score": 0, "level": "D"}

    # ========== 提取参数 ==========
    N1  = params['N1']; N2  = params['N2']; N3  = params['N3']; N4  = params['N4']; N5  = params['N5']
    N6  = params['N6']; N7  = params['N7']; N8  = params['N8'];
    N10 = params['N10']
    N11 = params['N11']; N12 = params['N12']; N13 = params['N13']; N14 = params['N14'];
    N15 = params.get('N15', 25)
    N17 = params.get('N17', 0.4)
    N18 = params.get('N18', 1.5)
    N19 = params.get('N19', 1)
    N20 = params.get('N20', 1.5)
    N22 = params.get('N22', 100)

    # Volume单位:share 或 hand,必须显式指定,不自动猜测
    VOLUME_UNIT = params.get('volume_unit', 'share')  # 默认share

    # ========== 分类型参数 ==========
    N9_1 = params.get('N9_1', 40); N16_1 = params.get('N16_1', 1.5); N21_1 = params.get('N21_1', 8)
    CHIP_1 = params.get('CHIP_1', 0.85); LEAD_1 = params.get('LEAD_1', 0.15)
    N9_2 = params.get('N9_2', 60); N16_2 = params.get('N16_2', 1.5); N21_2 = params.get('N21_2', 5)
    CHIP_2 = params.get('CHIP_2', 0.90)
    N9_3 = params.get('N9_3', 30); N16_3 = params.get('N16_3', 1.0); N21_3 = params.get('N21_3', 5)
    CHIP_3 = params.get('CHIP_3', 0.80); LEAD_3 = params.get('LEAD_3', 0.10)
    CHIP_4 = params.get('CHIP_4', 0.75)

    # ========== 计算常用均线 ==========
    df['MA5']   = MA(df['close'], 5)
    df['MA10']  = MA(df['close'], 10)
    df['MA20']  = MA(df['close'], 20)
    df['MA60']  = MA(df['close'], 60)
    df['MA120'] = MA(df['close'], 120)
    df['MA250'] = MA(df['close'], 250)

    # 最新日数据
    o = df['open'].iloc[-1]
    c = df['close'].iloc[-1]
    h = df['high'].iloc[-1]
    l = df['low'].iloc[-1]
    v = df['volume'].iloc[-1]
    capital = df['capital'].iloc[-1] if 'capital' in df else 1e8

    # ========== 1. 前期拉高建仓 ==========
    # 固定区间(45~25天前)
    vol5_end = df['volume'].rolling(5).mean().iloc[-25]
    vol30_start = df['volume'].rolling(30).mean().iloc[-45]
    lift_vol = vol5_end > vol30_start * N4

    seg = df.iloc[-45:-25]
    seg_high = seg['high'].max()
    seg_low = seg['low'].min()
    lift_amp = (seg_high - seg_low) / seg_low * 100 if seg_low != 0 else 0

    end_price = df['close'].iloc[-25]
    ma250_end = df['MA250'].iloc[-25]
    lift_over_ma = end_price > ma250_end * 1.1
    fixed_build_1 = (lift_amp > N9_1) & lift_vol & lift_over_ma
    fixed_build_2 = (lift_amp > N9_2) & lift_vol & lift_over_ma
    fixed_build_3 = (lift_amp > N9_3) & lift_vol & lift_over_ma

    # 动态区间(最近30天)
    vol5_now = df['volume'].rolling(5).mean().iloc[-1]
    vol20_10_ago = df['volume'].rolling(20).mean().iloc[-10]
    dyn_vol = vol5_now > vol20_10_ago * N4

    dyn_low = df['low'].iloc[-30:].min()
    dyn_high = df['high'].iloc[-30:].max()
    dyn_amp = (dyn_high - dyn_low) / dyn_low * 100 if dyn_low != 0 else 0
    dyn_over_ma = dyn_high > df['MA250'].iloc[-1] * 1.1
    dyn_build_1 = (dyn_amp > N9_1) & dyn_vol & dyn_over_ma
    dyn_build_2 = (dyn_amp > N9_2) & dyn_vol & dyn_over_ma
    dyn_build_3 = (dyn_amp > N9_3) & dyn_vol & dyn_over_ma

    if N10 == 1:
        has_build_1, has_build_2, has_build_3 = fixed_build_1, fixed_build_2, fixed_build_3
    elif N10 == 0:
        has_build_1, has_build_2, has_build_3 = dyn_build_1, dyn_build_2, dyn_build_3
    else:
        has_build_1 = fixed_build_1 or dyn_build_1
        has_build_2 = fixed_build_2 or dyn_build_2
        has_build_3 = fixed_build_3 or dyn_build_3

    # ========== 2. 高位横盘 ==========
    seg25 = df.iloc[-25:]
    hh25 = seg25['high'].max()
    ll25 = seg25['low'].min()
    amp25 = (hh25 - ll25) / ll25 * 100 if ll25 != 0 else 0
    amp_cond = amp25 < N1

    mid_neg = ((seg25['close'] < seg25['open']) & ((seg25['open'] - seg25['close']) / seg25['open'] > 0.02)).sum()
    no_mid = (mid_neg == 0)

    upper_shadow = (seg25['high'] - seg25[['close','open']].max(axis=1)) / REF(seg25['close'], 1) * 100
    lower_shadow = (seg25[['close','open']].min(axis=1) - seg25['low']) / REF(seg25['close'], 1) * 100
    long_shadow_cnt = ((upper_shadow > 2.5) | (lower_shadow > 2.5)).sum()
    no_long_shadow = long_shadow_cnt <= N2

    ma5_series = df['volume'].rolling(5).mean()
    max_ma5_30 = ma5_series.iloc[-31:-1].max()
    vol_shrink = df['volume'].iloc[-10:].mean() < max_ma5_30 * N3

    prev_high = df['close'].iloc[-60:-30].max()
    not_break = ll25 > prev_high * 0.96

    horiz_cond = amp_cond & no_mid & no_long_shadow & vol_shrink & not_break

    # ========== 3. 今日突破 ==========
    below_ma = (o < df['MA5'].iloc[-1]) + (o < df['MA10'].iloc[-1]) + (o < df['MA20'].iloc[-1])
    break_cond = (c > o) and (c > df['MA5'].iloc[-1]) and (c > df['MA10'].iloc[-1]) and (c > df['MA20'].iloc[-1]) and (c > df['MA60'].iloc[-1]) and (c > df['MA120'].iloc[-1]) and (below_ma >= 2)

    vol_ma10_yest = df['volume'].rolling(10).mean().iloc[-2]
    vol_break = v > vol_ma10_yest * N5

    ma250_now = df['MA250'].iloc[-1]
    on_year = (c > ma250_now) and ((c - ma250_now) / ma250_now < 0.4)

    # ========== 4. 均线多头排列 ==========
    multi = (df['MA5'].iloc[-1] > df['MA10'].iloc[-1] > df['MA20'].iloc[-1] > df['MA60'].iloc[-1] > df['MA120'].iloc[-1])
    multi_ok = True if N11 == 0 else multi

    # ========== 5. 创30日新高 ==========
    new_high_cond = (c >= df['close'].iloc[-30:].max() * 0.995)
    new_high_ok = True if N12 == 0 else new_high_cond

    # ========== 6. 实体占比 ==========
    body = abs(c - o); range_ = h - l
    body_pct = 100 if range_ == 0 else body / range_ * 100
    body_ok = True if N13 == 0 else (body_pct >= N13)

    # ========== 7. 强势突破 ==========
    high60 = df['high'].iloc[-60:-1].max()
    break_strength = (c - high60) / high60 * 100 if high60 != 0 else 0
    strong_break = break_strength > N18

    # ========== 8. 竞价与换手 ==========
    open_pct = (o / df['close'].iloc[-2] - 1) * 100
    gap_up = o > df['high'].iloc[-2]
    bid_ok = True if N14 == 0 else (open_pct > 1.0 or gap_up)

    # 换手率:显式指定单位,不自动猜测
    if VOLUME_UNIT == 'hand':
        turn = (v * 100) / capital * 100
    else:  # 'share'
        turn = v / capital * 100
    turn_ok = True if N15 == 0 else ((turn >= N20) and (turn <= N15))

    # ========== 9. 大盘过滤 ==========
    index_close = df_index.loc[:current_date]['close']
    index_ma = MA(index_close, N8).iloc[-1]
    index_ok = True if N6 == 0 else (index_close.iloc[-1] > index_ma)

    # ========== 10. 板块共振 ==========
    sector_close = df_sector.loc[:current_date]['close']
    sector_ma = MA(sector_close, N8).iloc[-1]
    sector_ok = True if N7 == 0 else (sector_close.iloc[-1] > sector_ma)

    # ========== 核心条件 ==========
    # ① 年线60日斜率
    ma250_60 = df['MA250'].iloc[-60]
    year_slope = (ma250_now - ma250_60) / ma250_60 * 100 if ma250_60 != 0 else 0
    year_angle_ok_1 = year_slope > N16_1
    year_angle_ok_2 = year_slope > N16_2
    year_angle_ok_3 = year_slope > N16_3

    # ② 底部抬高
    low1 = df['low'].iloc[-180:-120].min()
    low2 = df['low'].iloc[-120:-60].min()
    low3 = df['low'].iloc[-60:].min()
    higher_low_1 = (low3 > low2 * (1 + N21_1/100)) and (low2 > low1 * (1 + N21_1/100))
    higher_low_2 = (low3 > low2 * (1 + N21_2/100)) and (low2 > low1 * (1 + N21_2/100))
    higher_low_3 = (low3 > low2 * (1 + N21_3/100)) and (low2 > low1 * (1 + N21_3/100))

    # ③ 回踩年线不破
    touch_year = (abs(df['low'] - df['MA250']) / df['MA250']) < 0.03
    touch_cnt = touch_year.iloc[-180:].sum()
    break_days = (df['close'].iloc[-180:] < df['MA250'].iloc[-180:] * 0.97).sum()
    not_real_break = (break_days <= 3)
    year_retest_ok = (touch_cnt >= N19) and not_real_break

    # ④ 提前大盘见底
    stock_return = c / df['close'].iloc[-120] - 1 if len(df) >= 120 else 0
    index_return = index_close.iloc[-1] / index_close.iloc[-120] - 1 if len(index_close) >= 120 else 0
    lead_market_1 = stock_return > index_return + LEAD_1
    lead_market_3 = stock_return > index_return + LEAD_3

    # ⑤ 控盘度(放宽到5%)
    daily_amp = (df['high'] - df['low']) / df['close']
    control_ok = daily_amp.iloc[-25:].mean() < 0.05

    # ⑥ 量能**稳
    vol_ma20 = df['volume'].rolling(20).mean()
    vol_ratio = df['volume'] / vol_ma20
    vol_ratio_std = vol_ratio.iloc[-25:].std()
    vol_control_ok = vol_ratio_std < N17

    # ⑦ 围绕年线震荡
    around_year = (abs(df['close'] - df['MA250']) / df['MA250']).iloc[-120:].mean() < 0.12

    # ⑧ 年线60日震荡
    year_pre = df['MA250'].iloc[-60:-30].mean()
    year_post = df['MA250'].iloc[-30:].mean()
    year_slope60 = (year_post - year_pre) / year_pre * 100 if year_pre != 0 else 0
    year_wavy = abs(year_slope60) < 2

    # ⑨ 筹码解放率
    high_250 = df['high'].iloc[-250:].max()
    release_rate = c / high_250 if high_250 != 0 else 0
    chip_release_1 = release_rate > CHIP_1
    chip_release_2 = release_rate > CHIP_2
    chip_release_3 = release_rate > CHIP_3
    chip_release_4 = release_rate > CHIP_4

    # ⑩ 年线上方时间占比
    above_year_days = (df['close'].iloc[-120:] > df['MA250'].iloc[-120:]).sum()
    year_hold_ok = above_year_days >= N22

    # ⑪ 机构吸筹(量缩价稳:价格60日均线向上 + 成交量60日均线向下)
    price_ma60_slope = (df['close'].iloc[-1] / df['close'].iloc[-60] - 1) * 100 if df['close'].iloc[-60] != 0 else 0
    vol_ma60_slope = (df['volume'].iloc[-1] / df['volume'].iloc[-60] - 1) * 100 if df['volume'].iloc[-60] != 0 else 0
    institution_ok = (price_ma60_slope > 0) and (vol_ma60_slope < 0)

    # ========== 财务质量条件 ==========
    fundamental_ok = True
    # ROE连续3年 > 12%
    if roe is not None and isinstance(roe, list) and len(roe) >= 3:
        fundamental_ok = fundamental_ok and all(r > 12 for r in roe)
    # 经营现金流 > 净利润
    if cash_flow is not None:
        fundamental_ok = fundamental_ok and (cash_flow > 1.0)
    # 股东户数连续下降
    if shareholder_cnt is not None and isinstance(shareholder_cnt, list) and len(shareholder_cnt) >= 3:
        fundamental_ok = fundamental_ok and (shareholder_cnt[0] > shareholder_cnt[1] > shareholder_cnt[2])
    # 北向持股连续增加
    if north_hold is not None and isinstance(north_hold, list) and len(north_hold) >= 3:
        fundamental_ok = fundamental_ok and (north_hold[0] < north_hold[1] < north_hold[2])

    # ========== 四种形态定义 ==========
    type1 = (
        has_build_1
        and year_angle_ok_1
        and higher_low_1
        and year_retest_ok
        and lead_market_1
        and control_ok
        and vol_control_ok
        and on_year
        and chip_release_1
        and year_hold_ok
        and institution_ok
        and fundamental_ok
    )

    type2 = (
        has_build_2
        and horiz_cond
        and break_cond
        and vol_break
        and multi_ok
        and control_ok
        and vol_control_ok
        and on_year
        and new_high_ok
        and body_ok
        and strong_break
        and chip_release_2
        and institution_ok
        and fundamental_ok
    )

    type3 = (
        has_build_3
        and year_angle_ok_3
        and higher_low_3
        and year_retest_ok
        and lead_market_3
        and control_ok
        and vol_control_ok
        and on_year
        and not break_cond
        and chip_release_3
        and year_hold_ok
        and institution_ok
        and fundamental_ok
    )

    type4 = (
        around_year
        and year_wavy
        and year_retest_ok
        and chip_release_4
        and year_hold_ok
        and institution_ok
        and control_ok          # 新增
        and vol_control_ok      # 新增
        and fundamental_ok
    )

    # ========== 最终结果 ==========
    final = (
        (type1 or type2 or type3 or type4)
        and index_ok
        and sector_ok
        and turn_ok
        and bid_ok
    )

    # ========== 评分系统(满分130分)==========
    score = 0
    score += 20 if has_build_1 or has_build_2 or has_build_3 else 0
    score += 10 if vol_break else 0
    score += 10 if horiz_cond else 0      # 从15降到10
    score += 10 if control_ok else 0
    score += 5 if vol_control_ok else 0
    score += 10 if (higher_low_1 or higher_low_2 or higher_low_3) else 0
    score += 10 if (year_angle_ok_1 or year_angle_ok_2 or year_angle_ok_3) else 0
    score += 10 if year_retest_ok else 0
    score += 5 if (lead_market_1 or lead_market_3) else 0
    score += 5 if index_ok else 0
    score += 5 if chip_release_1 or chip_release_2 or chip_release_3 or chip_release_4 else 0
    score += 5 if fundamental_ok else 0
    score += 10 if institution_ok else 0   # 从5升到10
    score += 10 if year_hold_ok else 0     # 从5升到10
    score += 5 if control_ok and vol_control_ok else 0  # 控盘组合加分

    # 等级评定
    if score >= 100:
        level = "S"
    elif score >= 85:
        level = "A"
    elif score >= 75:
        level = "B"
    elif score >= 65:
        level = "C"
    else:
        level = "D"

    return {
        "match": final,
        "type1": type1,
        "type2": type2,
        "type3": type3,
        "type4": type4,
        "score": score,
        "level": level,
        "release_rate": release_rate,
        "year_slope": year_slope,
        "control_rate": daily_amp.iloc[-25:].mean(),
        "above_year_days": above_year_days,
        "turn": turn
    }

回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-21 14:05 | 显示全部楼层
params = {
    # 全局参数
    'N1': 12,
    'N2': 2,
    'N3': 0.6,
    'N4': 1.8,
    'N5': 1.3,
    'N6': 1,
    'N7': 1,
    'N8': 20,
    'N10': 2,
    'N11': 1,
    'N12': 1,
    'N13': 60,
    'N14': 0,
    'N15': 25,
    'N17': 0.4,
    'N18': 1.5,
    'N19': 1,
    'N20': 1.5,
    'N22': 100,
    'volume_unit': 'share',  # 强制指定:'share' 或 'hand'

    # 类型1: V型转势
    'N9_1': 40,
    'N16_1': 1.5,
    'N21_1': 8,
    'CHIP_1': 0.85,
    'LEAD_1': 0.15,

    # 类型2: 厂字突破
    'N9_2': 60,
    'N16_2': 1.5,
    'N21_2': 5,
    'CHIP_2': 0.90,

    # 类型3: 稳健中高级
    'N9_3': 30,
    'N16_3': 1.0,
    'N21_3': 5,
    'CHIP_3': 0.80,
    'LEAD_3': 0.10,

    # 类型4: 围绕年线震荡
    'CHIP_4': 0.75,
}

回复 支持 反对

使用道具 举报

发表于 2026-6-21 14:14 来自手机 | 显示全部楼层
优秀
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-21 14:27 | 显示全部楼层
还是有很多问题 慢慢补充修改
回复 支持 反对

使用道具 举报

发表于 2026-6-21 15:34 | 显示全部楼层
感谢楼主的无私共享。
回复 支持 反对

使用道具 举报

发表于 2026-6-21 16:05 来自手机 | 显示全部楼层
骨王接班人出现了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-21 21:06 | 显示全部楼层

夸张了 我只是一个普通的学**者


回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-21 21:10 | 显示全部楼层
我发现有一种股票不是无脑的情绪疯涨票,也不是连扳的打板票。
如果6板 7板的票是打出高度的    那这种我把他称为中坚力量

举几个例子301319 002980 002655 605389
你会发现他们的周线 月线多么漂亮。永远不s
在关键的位置 一定会有涨停。 能拿一个这样的股票真的太爽了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2026-6-21 21:51 来自手机 | 显示全部楼层
好票!不停涨涨不停
回复 支持 反对

使用道具 举报

发表于 2026-6-21 21:51 来自手机 | 显示全部楼层
干就完了
回复 支持 反对

使用道具 举报

发表于 2026-6-22 08:48 来自手机 | 显示全部楼层
很喜欢楼主的风格,我也喜欢干这种票,希望楼主能拉个群
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-22 10:55 | 显示全部楼层
300319先出掉了哈 仓位太大20多个点到手
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-22 11:16 | 显示全部楼层
又倒闭了 4400多下跌 但大盘影响不了短线操作,努力一下这个月能不能收益率破百啊? 目前持有的只剩中钨了

600226 300398考虑干不干。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-22 12:28 | 显示全部楼层
楼主下午期末考试去了 看不了盘

中午复盘结束 说下我的观点 大盘跌4000还是跌5000家我都不在意。我需要关注前100的股票就可以了。
当前100名都表现弱势的时候 空仓就行

一个股票开始走弱了 不要幻想 立马出局。跌破10日线 安慰自己30日有支撑 等跌破30日 下一个支撑在哪呢??

上上周我开始关注钨 重新回到视野 买卖点也都说了
同样的我继续关注最强的 中钨 其次600397 600549 000657等

好股太多了再分享下  我认为可以追踪关注的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-6-22 12:29 | 显示全部楼层
绿色的不要看
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

【2024年5月31日最新敬告:文明发帖】

Archiver|手机版|小黑屋|股票之声 ( 京ICP备09051785号 )

GMT+8, 2026-7-28 06:13 , Processed in 0.084382 second(s), 4 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表