量化数据进阶:多维实战篇(第 11 篇):历史涨跌停价:涨跌停序列与止损线测算

量化数据进阶:多维实战篇(第 11 篇):历史涨跌停价:涨跌停序列与止损线测算

一、前言

上一篇《板块轮动:行业资金流向与龙头股捕捉》我们把视角从「个股」抬到了「行业」,用资金流与龙头股回答了「哪条资金链在动」。但还有一类问题始终悬着:如果我看错了,最多会亏到哪里?

资金流告诉你往哪走,止损线告诉你走错了往哪退。前者关乎收益,后者关乎生存。而 A 股市场里,一条最硬、最不需要预测的天然防线,就是跌停价------它是交易所制度画出来的、当天价格允许下落的最低边界。

本篇进入「模块五·风控与止损」,用两个接口把这条边界量化出来:

  • hsstock/stopprice/history:历史涨跌停价,按日期区间返回每日的涨停价 h跌停价 l
  • hsstock/real/time:个股实时行情,用来补上「实际价格」------最新价 p、昨收 yc、振幅 zf

二者结合,我们自研「涨跌停绝对价差」「涨跌停幅度反推」「板块限制类型识别」「剩余下跌空间」「分层止损线」「波动率自适应止损」「波动利用率」七组指标,把「今天最多能跌到哪」翻译成「我该在哪条线上动手」。

衔接说明:本篇是「模块五·风控与止损」的开篇,也是本系列倒数第二篇。上一篇解决了「资金往哪走」,本篇解决「走错了怎么退」,下一篇(第 12 篇)将做全系列收官,把 11 篇的接口与因子串成一条生产级流水线。

郑重说明:本文所有幅度反推、板块识别、价差测算、剩余空间、三档止损、波动自适应逻辑全部是自研因子,不是必盈接口提供的功能stopprice/history 只返回 t / h / l 三个裸字段,所有衍生结论均由本文代码在本地算出。

二、接口字段解读

2.1 历史涨跌停价 hsstock/stopprice/history

复制代码
http://api.biyingapi.com/hsstock/stopprice/history/{代码.市场}/{LICENCE}?st={开始日期}&et={结束日期}

路径 / 查询参数:

参数 说明
代码.市场 带市场后缀的标的代码,如 600519.SH000001.SZ300750.SZ
LICENCE 授权码
st 开始日期,格式 YYYY-MM-DD
et 结束日期,格式 YYYY-MM-DD

返回字段(接口只暴露这三个):

字段 类型 含义
t string 交易日期
h number 当日涨停价(元)
l number 当日跌停价(元)

本篇最重要的技术前提 :该接口不返回收盘价、不返回昨收、不返回开盘价h / l 是「当日被允许的价格上界与下界」,它们由前一日收盘价乘以限制比例得出,但接口不会把这个前收价还给你。因此任何涉及「幅度」的计算,都必须引入第二个接口。

2.2 个股实时行情 hsstock/real/time

复制代码
http://api.biyingapi.com/hsstock/real/time/{代码.市场}/{LICENCE}
字段 类型 含义
p number 最新价(元)
o number 开盘价(元)
h number 最高价(元)
l number 最低价(元)
yc number 前收盘价(元)
v number 成交量
tv number 成交量
pv number 原始成交总量
cje number 成交额(元)
pc float 涨跌幅(%)
ud float 涨跌额(元)
zf float 振幅(%)
tr number 换手率(%)
pe number 市盈率
pb_ratio number 市净率
t string 更新时间

字段同名陷阱(务必注意) :两个接口都有 hl,但含义完全不同------

  • stopprice/history 里:h = 涨停价l = 跌停价
  • real/time 里:h = 当日最高价l = 当日最低价

一旦把两个接口的返回值塞进同一个字典或同一张宽表,字段会被静默覆盖,算出完全错误的结论。本文代码用独立的 up_limit / low_limit 变量承接涨跌停价,用 p_now / yc_now 承接实时价,永不混用

三、自研衍生指标 / 业务逻辑

接口只给裸字段,以下全部用 Python 手写:

  1. 涨跌停价序列(自研) :以 t 为轴,把 h / l 拉成时间序列。由于涨跌停价 = 前收盘 × (1 ± 限制比例),而前收盘逐日变动,所以 h / l 会随行情逐日漂移 ;观察 h.diff() 即可看出这条边界的移动节奏。
  2. 涨跌停绝对价差(自研)spread = h - l,即当日价格被允许波动的绝对区间宽度 (元)。价格越高、限制比例越大,spread 越宽------它直接决定了持仓的单日最大潜在损失金额。
  3. 隐含昨收反解(自研) :对涨跌停幅度对称的标的,h = yc × (1 + a)l = yc × (1 - a),两式相加得 yc = (h + l) / 2。这是只靠 t/h/l 三个字段就能还原昨收的技巧,用于给历史序列补上基准。
  4. 涨跌停幅度反推(自研)limit_up_pct = (h / yc - 1) × 100limit_down_pct = (1 - l / yc) × 100。这里必须用 real/timeyc(昨收),因为当日涨跌停价正是以它为基准计算的。
  5. 板块涨跌幅限制类型识别(自研) :取涨跌停幅度的均值,按数值区间加容差 归类------5% 对应 ST 股、10% 对应主板、20% 对应创业板 / 科创板、30% 对应北交所,落在区间外则标记为「非标准」。这一步让我们不依赖任何外部股票列表,纯用价格数据反推标的的交易制度属性
  6. 剩余下跌空间(自研,风控核心)room_down_pct = (p - l) / p × 100,即当前价距当日跌停价还有百分之多少的缓冲。它把「绝对价差」折算成「以现价为基准的百分比」,可直接跨标的比较。
  7. 分层止损线(自研) :以跌停价为极端防线,按剩余空间设三档------stop = l + (p - l) × ratio,ratio 取 50% / 25% / 10% 分别对应预警线 / 减仓线 / 清仓线。跌破预警线提示关注,跌破减仓线主动降仓,跌破清仓线不留余地。
  8. 日波动基准与波动率自适应止损(自研)日波动基准 = 近期 (h - l) / yc 的均值(回看窗口可配置),止损幅度 = k × 日波动基准自适应止损价 = p × (1 - 止损幅度 / 100)。波动大的标的自动放宽止损,避免在噪音里被扫出局。
  9. 波动利用率(自研)vol_util = zf / 日波动基准,用 real/time 的当日振幅除以制度允许的波动上限,衡量「今天实际用掉了多少额度」。利用率长期接近 1,说明标的已在制度边界上反复试探。
  10. 最终止损价取严(自研) :在「自适应止损价」与「清仓线」之间取更高者作为最终执行线------两者谁更严格就听谁的。

四、数据表设计

sql 复制代码
CREATE TABLE IF NOT EXISTS stop_price_history (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    code TEXT,
    t TEXT,
    h REAL,          -- 当日涨停价(接口原字段)
    l REAL,          -- 当日跌停价(接口原字段)
    collected_at TEXT,
    UNIQUE(code, t)
);

CREATE TABLE IF NOT EXISTS risk_stop_line (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    code TEXT,
    t TEXT,
    up_limit REAL,        -- 当日涨停价
    low_limit REAL,       -- 当日跌停价
    up_limit_pct REAL,    -- 自研:涨停幅度(%)
    down_limit_pct REAL,  -- 自研:跌停幅度(%)
    limit_type TEXT,      -- 自研:板块涨跌幅限制类型
    room_down_pct REAL,   -- 自研:剩余下跌空间(%)
    stop_warn REAL,       -- 自研:预警线(剩余空间 50%)
    stop_reduce REAL,     -- 自研:减仓线(剩余空间 25%)
    stop_clear REAL,      -- 自研:清仓线(剩余空间 10%)
    vol_base_pct REAL,    -- 自研:日波动基准(%)
    vol_stop_pct REAL,    -- 自研:自适应止损幅度(%)
    vol_stop_price REAL,  -- 自研:自适应止损价
    vol_util REAL,        -- 自研:波动利用率 = zf / 日波动基准
    final_stop REAL,      -- 自研:最终止损价(取严)
    collected_at TEXT,
    UNIQUE(code, t)
);

原样落库接口字段(h / l),自研结果单独进 risk_stop_line,保证「原始数据」与「衍生结论」可回溯、可对账。

五、完整可运行代码

python 复制代码
import requests
import logging
import time
import sqlite3
import pandas as pd
import numpy as np

# ========== 全局配置 ==========
LICENCE = "你的licence"
DB_PATH = "quant.db"
LOG_FILE = "quant_collect.log"
API_BASE = "http://api.biyingapi.com"

# ========== 自研参数(可配置常量) ==========
LIMIT_TOL = 0.30      # 涨跌停幅度归类容差(百分点)
WARN_RATIO = 0.50     # 预警线:保留剩余下跌空间的 50%
REDUCE_RATIO = 0.25   # 减仓线:保留剩余下跌空间的 25%
CLEAR_RATIO = 0.10    # 清仓线:保留剩余下跌空间的 10%
VOL_K = 0.80          # 波动率自适应止损系数 k
VOL_WINDOW = 20       # 日波动基准回看窗口(交易日)

# ---------- 日志初始化 ----------
logging.basicConfig(
    filename=LOG_FILE,
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
    filemode="a"
)
logger = logging.getLogger(__name__)


# ---------- 带重试 HTTP 请求(复用) ----------
def biying_api_get_retry(full_url, timeout=15, max_retry=3):
    for attempt in range(1, max_retry + 1):
        try:
            resp = requests.get(full_url, timeout=timeout)
            if resp.status_code == 200:
                return resp.json()
            logger.warning(f"HTTP状态码异常:{resp.status_code},第{attempt}次重试")
        except Exception as e:
            logger.warning(f"网络请求异常,第{attempt}次重试,错误信息:{str(e)}")
        time.sleep(2)
    logger.error("达到最大重试次数,接口请求失败")
    return []


# ---------- 代码补市场后缀 ----------
def with_exchange_suffix(code):
    code = str(code).strip().upper()
    if "." in code:
        return code
    if code.startswith(("60", "68", "5", "9")):
        return code + ".SH"
    if code.startswith(("00", "30", "1", "2")):
        return code + ".SZ"
    if code.startswith(("8", "4")):
        return code + ".BJ"
    return code + ".SH"


# ---------- 历史涨跌停价 ----------
def fetch_stopprice_history(code, st, et):
    dm = with_exchange_suffix(code)
    url = f"{API_BASE}/hsstock/stopprice/history/{dm}/{LICENCE}?st={st}&et={et}"
    data = biying_api_get_retry(url)
    if not data:
        logger.warning(f"{dm} 历史涨跌停价返回为空 st={st} et={et}")
        return pd.DataFrame(columns=["t", "h", "l"])
    if isinstance(data, dict):
        data = [data]
    df = pd.DataFrame(data)
    for col in ["t", "h", "l"]:
        if col not in df.columns:
            df[col] = np.nan
    df = df[["t", "h", "l"]].copy()
    df["t"] = df["t"].astype(str).str.slice(0, 10)
    df["h"] = pd.to_numeric(df["h"], errors="coerce")
    df["l"] = pd.to_numeric(df["l"], errors="coerce")
    df = df.dropna(subset=["t", "h", "l"])
    df = df[(df["h"] > 0) & (df["l"] > 0)]
    df = df.drop_duplicates(subset=["t"], keep="last")
    df = df.sort_values("t").reset_index(drop=True)
    return df


# ---------- 个股实时行情(补实际价格) ----------
def fetch_realtime(code):
    dm = with_exchange_suffix(code)
    url = f"{API_BASE}/hsstock/real/time/{dm}/{LICENCE}"
    data = biying_api_get_retry(url)
    if isinstance(data, list) and data:
        return data[0] if isinstance(data[0], dict) else {}
    if isinstance(data, dict):
        return data
    logger.warning(f"{dm} 实时行情返回异常")
    return {}


# ---------- 自研 1:涨跌停序列、绝对价差、隐含昨收 ----------
def build_stop_frame(df):
    if df.empty:
        return df
    df = df.copy()
    df["spread"] = (df["h"] - df["l"]).round(3)
    df["implied_yc"] = ((df["h"] + df["l"]) / 2).round(3)
    df["h_chg"] = df["h"].diff().round(3)
    df["spread_chg"] = df["spread"].diff().round(3)
    df["range_pct"] = ((df["h"] - df["l"]) / df["implied_yc"] * 100).round(3)
    return df


# ---------- 自研 2:涨跌停幅度反推(必须用 real/time 的 yc) ----------
def calc_limit_pct(h_val, l_val, yc_val):
    if yc_val is None or pd.isna(yc_val) or float(yc_val) <= 0:
        return None, None
    if h_val is None or l_val is None or pd.isna(h_val) or pd.isna(l_val):
        return None, None
    up_pct = (float(h_val) / float(yc_val) - 1) * 100
    down_pct = (1 - float(l_val) / float(yc_val)) * 100
    return round(up_pct, 3), round(down_pct, 3)


# ---------- 自研 3:板块涨跌幅限制类型识别 ----------
def classify_limit_type(up_pct, down_pct):
    if up_pct is None or down_pct is None:
        return "未知"
    avg = (up_pct + down_pct) / 2
    if abs(avg - 5) <= LIMIT_TOL:
        return "5%限制(ST股)"
    if abs(avg - 10) <= LIMIT_TOL:
        return "10%限制(主板)"
    if abs(avg - 20) <= LIMIT_TOL:
        return "20%限制(创业板/科创板)"
    if abs(avg - 30) <= LIMIT_TOL:
        return "30%限制(北交所)"
    return f"非标准({round(avg, 2)}%)"


# ---------- 自研 4:剩余下跌空间 + 分层止损线 ----------
def calc_room_and_stops(p_now, low_limit):
    if p_now is None or low_limit is None:
        return {}
    if pd.isna(p_now) or pd.isna(low_limit):
        return {}
    p_now = float(p_now)
    low_limit = float(low_limit)
    if p_now <= 0:
        return {}
    room_pct = (p_now - low_limit) / p_now * 100
    return {
        "room_down_pct": round(room_pct, 3),
        "stop_warn": round(low_limit + (p_now - low_limit) * WARN_RATIO, 3),
        "stop_reduce": round(low_limit + (p_now - low_limit) * REDUCE_RATIO, 3),
        "stop_clear": round(low_limit + (p_now - low_limit) * CLEAR_RATIO, 3),
    }


# ---------- 自研 5:日波动基准与波动率自适应止损 ----------
def calc_vol_base(df, window=VOL_WINDOW):
    if df.empty or "range_pct" not in df.columns:
        return None
    series = df["range_pct"].dropna()
    if series.empty:
        return None
    return round(float(series.tail(window).mean()), 3)


def calc_vol_stop(p_now, vol_base):
    if p_now is None or vol_base is None:
        return None, None
    if pd.isna(p_now) or pd.isna(vol_base) or float(p_now) <= 0:
        return None, None
    stop_pct = round(VOL_K * float(vol_base), 3)
    stop_price = round(float(p_now) * (1 - stop_pct / 100), 3)
    return stop_pct, stop_price


# ---------- 落库:历史涨跌停价 ----------
def save_stop_history(code, df):
    if df.empty:
        return
    conn = sqlite3.connect(DB_PATH)
    try:
        out = pd.DataFrame({
            "code": with_exchange_suffix(code),
            "t": df["t"].values,
            "h": df["h"].values,
            "l": df["l"].values,
            "collected_at": pd.Timestamp.now().strftime("%Y-%m-%d %H:%M:%S"),
        })
        out.to_sql("stop_price_history", conn, if_exists="append", index=False)
        conn.execute(
            "CREATE UNIQUE INDEX IF NOT EXISTS uk_sph ON stop_price_history(code, t)"
        )
        conn.commit()
    except Exception as e:
        logger.error(f"落库历史涨跌停价失败:{str(e)}")
    finally:
        conn.close()


# ---------- 落库:风控止损测算 ----------
def save_risk_stop_line(row):
    if not row:
        return
    conn = sqlite3.connect(DB_PATH)
    try:
        pd.DataFrame([row]).to_sql("risk_stop_line", conn, if_exists="append",
                                   index=False)
        conn.execute(
            "CREATE UNIQUE INDEX IF NOT EXISTS uk_rsl ON risk_stop_line(code, t)"
        )
        conn.commit()
    except Exception as e:
        logger.error(f"落库风控止损测算失败:{str(e)}")
    finally:
        conn.close()


# ---------- 单标的完整测算 ----------
def analyze(code, st, et):
    raw = fetch_stopprice_history(code, st, et)
    df = build_stop_frame(raw)
    if df.empty:
        logger.warning(f"{with_exchange_suffix(code)} 无有效涨跌停序列,跳过测算")
        return None
    save_stop_history(code, df)

    rt = fetch_realtime(code)
    p_now = pd.to_numeric(rt.get("p"), errors="coerce")
    yc_now = pd.to_numeric(rt.get("yc"), errors="coerce")
    zf_now = pd.to_numeric(rt.get("zf"), errors="coerce")

    last = df.iloc[-1]
    t_last = str(last["t"])
    up_limit = float(last["h"])
    low_limit = float(last["l"])

    # 停牌 / 无数据保护:yc 为 0 或缺失时不做幅度反推
    up_pct, down_pct = calc_limit_pct(up_limit, low_limit, yc_now)
    limit_type = classify_limit_type(up_pct, down_pct)
    stops = calc_room_and_stops(p_now, low_limit)
    vol_base = calc_vol_base(df)
    vol_stop_pct, vol_stop_price = calc_vol_stop(p_now, vol_base)

    vol_util = None
    if vol_base and not pd.isna(zf_now) and vol_base > 0:
        vol_util = round(float(zf_now) / vol_base, 3)

    final_stop = None
    candidates = []
    if vol_stop_price is not None:
        candidates.append(vol_stop_price)
    if stops.get("stop_clear") is not None:
        candidates.append(stops["stop_clear"])
    if candidates:
        final_stop = round(max(candidates), 3)

    row = {
        "code": with_exchange_suffix(code),
        "t": t_last,
        "up_limit": up_limit,
        "low_limit": low_limit,
        "up_limit_pct": up_pct,
        "down_limit_pct": down_pct,
        "limit_type": limit_type,
        "room_down_pct": stops.get("room_down_pct"),
        "stop_warn": stops.get("stop_warn"),
        "stop_reduce": stops.get("stop_reduce"),
        "stop_clear": stops.get("stop_clear"),
        "vol_base_pct": vol_base,
        "vol_stop_pct": vol_stop_pct,
        "vol_stop_price": vol_stop_price,
        "vol_util": vol_util,
        "final_stop": final_stop,
        "collected_at": pd.Timestamp.now().strftime("%Y-%m-%d %H:%M:%S"),
    }
    save_risk_stop_line(row)
    return df, row


# ---------- 演示入口 ----------
def demo(watchlist=None, st="2024-01-01", et="2024-12-31"):
    if watchlist is None:
        watchlist = ["600519", "000001", "300750", "688981"]
    for code in watchlist:
        result = analyze(code, st, et)
        if not result:
            print(f"\n=== {with_exchange_suffix(code)} === 无有效数据,已跳过")
            continue
        df, row = result
        print(f"\n=== {row['code']} ===")
        print(f"板块限制类型:{row['limit_type']}")
        print(f"涨停幅度 {row['up_limit_pct']}% | 跌停幅度 {row['down_limit_pct']}%")
        print(f"涨停价 {row['up_limit']} | 跌停价 {row['low_limit']}")
        print(f"剩余下跌空间 {row['room_down_pct']}%")
        print(f"预警线 {row['stop_warn']} | 减仓线 {row['stop_reduce']} | 清仓线 {row['stop_clear']}")
        print(f"日波动基准 {row['vol_base_pct']}% | 自适应止损 {row['vol_stop_pct']}% -> {row['vol_stop_price']}")
        print(f"波动利用率 {row['vol_util']} | 最终止损价 {row['final_stop']}")
        print("近 5 日涨跌停序列:")
        print(df[["t", "h", "l", "spread", "range_pct"]].tail(5).to_string(index=False))
    print("\n【仅为数据演示,不构成投资建议】已完成涨跌停序列与止损线测算")


if __name__ == "__main__":
    demo()

运行后控制台会打印每只标的的板块限制类型、涨跌停幅度、剩余下跌空间、三档止损线、自适应止损价与最近 5 个交易日的涨跌停价序列,同时把原始数据写入 stop_price_history、把测算结果写入 risk_stop_line。实际数值取决于你的 LICENCE 与查询区间,本文不做任何真实数字的假设。

六、业务关键点

  1. 单接口算不出幅度,必须借 ycstopprice/history 只给 t / h / l,涨跌停幅度是 h 与「昨收」之间的相对关系。缺了 real/timeyc,你只能看到两条边界的绝对数值,看不到这条边界有多宽。这是本篇最核心的数据约束。
  2. h / l 同名不同义 :两个接口的 h / l 含义完全不同(涨停价/跌停价 vs 最高价/最低价)。合并两个接口的返回值时,必须重命名为 up_limit / low_limit 等专属变量,否则会被静默覆盖。
  3. 停牌 / 无数据保护 :停牌、上市首日、退市整理期等场景下 yc 可能为 0 或缺失。所有除法前都要判 yc > 0,否则会出现除零或 inf。本文 calc_limit_pctcalc_room_and_stops 都做了防御,返回 None 而不是抛异常。
  4. 隐含昨收只对「对称限制」成立yc = (h + l) / 2 依赖涨跌停幅度相等。对绝大多数 A 股标的成立,但若遇到不对称情形(如特殊处理期的单边限制),该反解会偏差。此时应改用 real/timeyc 逐日补齐------但接口仅提供当日 yc,历史 yc 无法回溯,这是本接口的固有边界,需要接受。
  5. 日波动基准衡量的是「制度允许的上限」,不是实际波动range_pct = (h - l) / yc 在限制类型不变时近似恒等于 2 × 限制幅度(10% 股约 20%、20% 股约 40%)。它衡量的是「制度这条天花板有多高」,因此用 zf / vol_base 得到的波动利用率 ,才是刻画当日实际活跃度的补充指标。若标的限制类型发生变更(如 ST 摘帽从 5% 变 10%),range_pct 会跳变,回看窗口内应剔除类型切换点再做均值。
  6. 三档止损线的语义要说清stop = l + (p - l) × ratio 中,ratio = 50% 表示「保留一半剩余空间」,也就是吃掉 50% 的剩余缓冲 时触发预警;ratio = 10% 表示几乎逼近跌停。三档是递进的执行纪律(提示 → 降仓 → 离场),不是三个并列的候选值。
  7. 最终止损价取严:自适应止损价与清仓线谁更高就取谁,确保波动自适应不会把防线放得比制度底线还松。
  8. 落库唯一索引 (code, t) :两个表都以 (code, t) 建唯一索引,重复采集同一交易日会自动覆盖/去重,便于按日回溯「某天我本该在哪条线上离场」。

七、拓展练习

  1. 批量扫描自选股池,统计各 limit_type 的占比,验证你维护的股票池里「板块属性标注」是否与价格反推结果一致,找出标注错误的标的。
  2. room_down_pctreal/timepc(当日涨跌幅)结合:对「当日已大幅下跌、剩余下跌空间不足 2%」的标的打上「逼近跌停」标签,观察其次日表现。
  3. 调整 VOL_KVOL_WINDOW,回看不同参数下 final_stop 的松紧变化,体会「止损系数」对策略存活率的敏感度。

八、下篇预告

下一篇《综合实战流水线:多接口调度与指标整合收官》是本系列的收官之作,将把前面 11 篇的接口与自研因子全部串起来------用 APScheduler 做分时调度,按「板块分类 → 实时快照 → 盘口五档 → 分时逐笔 → 技术指标 → 资金轮动 → 风控止损」的顺序编排采集任务,统一入库 quant.db,并输出一份可复用的「多接口编排模板」,让整套进阶数据能力真正跑在生产节奏上。

九、免责申明

免责申明:文中所有数据处理逻辑仅为编程演示,仅为数据演示,不构成投资建议。市场有风险,投资需谨慎。

相关推荐
景熙55231 小时前
单体项目编写思路和落地形式
java·开发语言
Ivanqhz1 小时前
Slope One 算法详解:与矩阵分解、共现矩阵的异同
java·服务器·网络·人工智能·深度学习
ikun_文2 小时前
Django开启跨域请求
python·pycharm·django
外收内放2 小时前
Python与AI应用(项目开发实战:AI智能伴侣第三版)
python·学习·ai编程
别动我齐刘海2 小时前
ROS2 Jazzy + C++ 实战路线——进阶学习3
c++·人工智能·vscode·python·算法·机器学习·机器人
Bs_MoneyMagnet2 小时前
基于springboot+vue的非遗物质文化遗产系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·毕业设计·计算机毕业设计
万物智能2 小时前
波形发生AD9833模块配置—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
java
Logintern092 小时前
“以一致的顺序获取锁“是预防死锁最核心、最有效的手段
python·postgresql·锁机制
计算机毕设定制辅导-无忧学长2 小时前
《基于SpringBoot的未成年人健康知识科普平台的设计与实现》
java·开发语言·vue.js·spring boot·未成年人健康知识科普平台