8.29day49

121. 买卖股票的最佳时机 - 力扣(LeetCode)

知识点:1.dp数组含义 dp[i][0] 表示 持有该i个股票的最大值 dp[i][1] 表示不持有的最大值

              2.递推公式:1.持有股票 dp[i][0]=Max(dp[i-1][0](上一个状态),-price[i](买入股票))(买亏了就不买入 取最大);2.不持有股票 dp[i][1]=Max(dp[i-1][1],dp[i-1][0]+price[i](加上上一状态的卖出价格就是该状态))

              3.初始化:dp[0][0]持有所以是-prices[i] dp[0][1] 不持有就是0

              4.循环公式

122. 买卖股票的最佳时机 II - 力扣(LeetCode)

知识点:相比于1 我们要处理当天重复买卖股票问题:

              买卖股票1 是不能当天买第二天卖 

              持有股票时身上有的钱只能是初始购买股票身上的值

              买卖股票2

              持有股票的钱可以是上一股票卖出后自身身上所拥有的钱

               

总结:改题就是对dp[i][0]和dp[i][1]的推导

import tushare as ts import pandas as pd import numpy as np from datetime import datetime, timedelta warnings.filterwarnings("ignore") # 初始化(替换个人Tushare Token) ts.set_token("你的Tushare Token") pro = ts.pro_api() # 核心参数(8.20-8.29,三次优化版) START_DATE = "20250820" END_DATE = "20250829" # 止盈止损与分时参数 BIG_CANDLE_3PCT = 3 # 3%减仓(含分时) BIG_CANDLE_5PCT = 5 # 5%清仓(含分时) STOP_LOSS_DAYS = 2 # 2日内止损 INTRADAY_HOLD_THRESHOLD = 2 # 分时冲高≥2%且收盘≥1%视为有效 # 资金参数(新增北向资金) INSTITUTION_THRESHOLD = 5 # 机构持股≥5% FINANCE_INFLOW_2D = 4000 # 连续2日游资净流入≥4000万 NORTH_FUND_INFLOW = 500 # 北向资金当日净流入≥500万元 # 量能与大盘参数 VOL_MULTIPLE = 1.2 # 成交量≥近5日均值1.2倍 HS300_DROP_LIMIT = -1.5 # 沪深300跌幅≤-1.5%暂停买入 # 情绪与热点参数 MARKET_SENTIMENT_THRESHOLD = 50 # 大盘情绪≥50 STOCK_SENTIMENT_THRESHOLD = 60 # 个股舆情≥60 HOT_SECTORS = ["人工智能", "新能源", "半导体"] # 8月核心板块 # 1. 工具函数:动态热点阈值(复用前序逻辑) def get_dynamic_sector_threshold(industry): sector_stocks = pro.stock_basic(industry=industry, list_status="L")["ts_code"].head(3) one_day_pcts = [] for code in sector_stocks: df = pro.daily(ts_code=code, start_date=END_DATE, end_date=END_DATE) if not df.empty: one_day_pcts.append(df["pct_change"].iloc[0]) if not one_day_pcts: return 5 avg_one_day_pct = np.mean(one_day_pcts) return 4 if avg_one_day_pct >= 3 else 6 if avg_one_day_pct <= 1 else 5 # 2. 工具函数:个股舆情(复用前序逻辑) def get_stock_sentiment(ts_code): try: sentiment_df = pro.stock_news_sentiment(ts_code=ts_code, start_date=START_DATE, end_date=END_DATE) return sentiment_df["sentiment_score"].mean() if not sentiment_df.empty else 50 except: announcements = pro.anns(ts_code=ts_code, start_date=START_DATE, end_date=END_DATE, ann_type="利好") return 65 if not announcements.empty else 50 # 3. 新增工具函数:分时最高涨幅计算 def get_intraday_high_pct(ts_code, trade_date): try: # 获取当日分时数据(按分钟级取最高) intraday = pro.minute(ts_code=ts_code, date=trade_date.strftime("%Y%m%d"), freq="15min") if not intraday.empty: open_price = intraday["open"].iloc[0] high_price = intraday["high"].max() return ((high_price - open_price) / open_price) * 100 return 0 except: # 无分时数据时用日线高低点估算 daily = pro.daily(ts_code=ts_code, start_date=trade_date.strftime("%Y%m%d"), end_date=trade_date.strftime("%Y%m%d")) if not daily.empty: return ((daily["high"].iloc[0] - daily["open"].iloc[0]) / daily["open"].iloc[0]) * 100 return 0 # 4. 新增工具函数:北向资金当日净流入 def get_north_fund_inflow(ts_code, trade_date): try: north_df = pro.moneyflow_hsgt(trade_date=trade_date.strftime("%Y%m%d"), ts_code=ts_code) return north_df["north_money"].iloc[0] if not north_df.empty else 0 except: return 0 # 无北向数据默认0 # 5. 工具函数:板块3日涨幅(复用前序逻辑) def get_sector_3d_pct(industry): try: sector_stocks = pro.stock_basic(industry=industry, list_status="L")["ts_code"].head(5) pct_sum = 0 count = 0 for code in sector_stocks: df = pro.daily(ts_code=code, start_date=START_DATE, end_date=END_DATE) if not df.empty: pct_sum += df["pct_change"].sum() count += 1 return pct_sum / count if count > 0 else 0 except: return 0 # 6. 获取三次优化后个股数据 def get_triple_optimized_data(ts_code, name, industry): # 基础日线与均线 daily = pro.daily(ts_code=ts_code, start_date=START_DATE, end_date=END_DATE) if len(daily) < 5: return None daily = daily.sort_values("trade_date").reset_index(drop=True) daily["trade_date"] = pd.to_datetime(daily["trade_date"]) daily["ma5"] = daily["close"].rolling(5).mean() daily["ma10"] = daily["close"].rolling(10).mean().fillna(daily["close"]) daily["ma20"] = daily["close"].rolling(20).mean().fillna(daily["close"]) daily["daily_pct"] = daily["close"].pct_change() * 100 daily["vol_avg_5d"] = daily["vol"].rolling(5).mean() # 资金数据(游资+机构+北向) money = pro.moneyflow_daily(ts_code=ts_code, start_date=START_DATE, end_date=END_DATE) money["trade_date"] = pd.to_datetime(money["trade_date"]) daily = pd.merge(daily, money[["trade_date", "net_inflow"]], on="trade_date", how="left") daily["net_inflow"] = daily["net_inflow"].fillna(0) daily["net_inflow_2d"] = daily["net_inflow"].rolling(2).sum() # 机构持股 inst = pro.inst_hold(ts_code=ts_code, start_date="20250801", end_date=END_DATE) daily["inst_hold_ratio"] = inst.sort_values("end_date").iloc[-1]["hold_ratio"] if not inst.empty else 0 # 北向资金(当日净流入) daily["north_inflow"] = daily.apply(lambda x: get_north_fund_inflow(ts_code, x["trade_date"]), axis=1) # 热点与情绪(动态热点+个股舆情) dynamic_thresh = get_dynamic_sector_threshold(industry) sector_3d_pct = get_sector_3d_pct(industry) daily["is_hot"] = 1 if (industry in HOT_SECTORS) and (sector_3d_pct >= dynamic_thresh) else 0 daily["stock_sentiment"] = get_stock_sentiment(ts_code) # 大盘与分时关联(分时最高涨幅) hs300 = pro.index_daily(ts_code="000300.SH", start_date=START_DATE, end_date=END_DATE) hs300["trade_date"] = pd.to_datetime(hs300["trade_date"]) daily = pd.merge(daily, hs300[["trade_date", "pct_change"]], on="trade_date", how="left", suffixes=("", "_hs300")) daily["hs300_pct"] = daily["pct_change_hs300"].fillna(0) # 分时最高涨幅(用于后续止盈判断) daily["intraday_high_pct"] = daily.apply(lambda x: get_intraday_high_pct(ts_code, x["trade_date"]), axis=1) # 个股标签 daily["name"] = name daily["industry"] = industry return daily # 7. 生成三次优化买卖信号(分时过滤+北向资金) def generate_triple_optimized_signals(df): if df.empty: return pd.DataFrame() # 买入条件(新增北向资金+保留前序优化条件) df["buy_cond"] = ( # 基础均线 (df["close"] > df["ma5"]) & (df["close"] > df["ma20"]) & (np.abs((df["close"] - df["ma10"])/df["ma10"]) <= 0.02) & # 资金三要素(游资+机构+北向) (df["net_inflow_2d"] >= FINANCE_INFLOW_2D) & (df["inst_hold_ratio"] >= INSTITUTION_THRESHOLD) & (df["north_inflow"] >= NORTH_FUND_INFLOW) & # 量能与大盘 (df["vol"] >= df["vol_avg_5d"] * VOL_MULTIPLE) & (df["hs300_pct"] >= HS300_DROP_LIMIT) & # 热点与情绪 (df["is_hot"] == 1) & (df["market_sentiment"] >= MARKET_SENTIMENT_THRESHOLD) & (df["stock_sentiment"] >= STOCK_SENTIMENT_THRESHOLD) ) # 持有周期与分时止盈逻辑 df["buy_date"] = df["trade_date"].where(df["buy_cond"] == 1).fillna(method="ffill") df["days_since_buy"] = (df["trade_date"] - df["buy_date"]).dt.days df["valid_hold"] = (df["days_since_buy"] >= 1) & (df["days_since_buy"] <= 5) # 止盈条件(分时+日线结合) # 5%清仓:日线达5% 或 分时达5%且收盘≥3% df["full_sell_cond"] = df["valid_hold"] & ( (df["daily_pct"] >= BIG_CANDLE_5PCT) | (df["intraday_high_pct"] >= BIG_CANDLE_5PCT) & (df["daily_pct"] >= 3) ) # 3%减仓:日线达3% 或 分时达3%且收盘≥1%(排除冲高回落) df["partial_sell_cond"] = df["valid_hold"] & ( (df["daily_pct"] >= BIG_CANDLE_3PCT) | (df["intraday_high_pct"] >= BIG_CANDLE_3PCT) & (df["daily_pct"] >= INTRADAY_HOLD_THRESHOLD) ) # 止损条件(保留快速止损) df["stop_loss_cond"] = df["valid_hold"] & (df["days_since_buy"] <= STOP_LOSS_DAYS) & (df["daily_pct"] <= 0) & (df["close"] < df["ma10"]) # 提取信号(优先级:止损→清仓→减仓) buy_dates = df[df["buy_cond"]]["trade_date"].unique() signals = [] for bd in buy_dates: buy_row = df[df["trade_date"] == bd].iloc[0] hold_window = df[(df["trade_date"] > bd) & (df["trade_date"] <= bd + timedelta(days=5))] if hold_window.empty: continue # 止损信号 if not hold_window[hold_window["stop_loss_cond"]].empty: sell_row = hold_window[hold_window["stop_loss_cond"]].iloc[0] signals.append(build_signal("止损", buy_row, sell_row)) # 清仓信号 elif not hold_window[hold_window["full_sell_cond"]].empty: sell_row = hold_window[hold_window["full_sell_cond"]].iloc[0] signals.append(build_signal("5%清仓", buy_row, sell_row)) # 减仓信号 elif not hold_window[hold_window["partial_sell_cond"]].empty: sell_row = hold_window[hold_window["partial_sell_cond"]].iloc[0] # 分时减仓按60%仓位计算(比日线减仓高10%,补偿冲高收益) avg_return = ((sell_row["close"]/buy_row["close"] - 1) * 0.6) signals.append(build_signal("3%减仓", buy_row, sell_row, avg_return)) return pd.DataFrame(signals) # 辅助函数:构建信号字典 def build_signal(op_type, buy_row, sell_row, avg_return=None): base = { "操作类型": op_type, "买入日": buy_row["trade_date"].strftime("%Y-%m-%d"), "代码": buy_row["ts_code"], "名称": buy_row["name"], "行业": buy_row["industry"], "买入价": round(buy_row["close"], 2), "卖出日": sell_row["trade_date"].strftime("%Y-%m-%d"), "卖出价": round(sell_row["close"], 2) } if avg_return is None: base["收益率"] = round((sell_row["close"]/buy_row["close"] - 1)*100, 2) else: base["收益率"] = round(avg_return*100, 2) return base # 8. 执行三次优化回测 def run_triple_optimized_backtest(): # 个股池(排除ST、新股) stock_pool = pro.stock_basic( list_status="L", fields="ts_code,name,industry,list_date" ) stock_pool = stock_pool[ (~stock_pool["name"].str.contains("ST")) & (pd.to_datetime(stock_pool["list_date"]) <= pd.to_datetime("20240820")) ] print(f"8.20-8.29三次优化回测:共{len(stock_pool)}只个股") all_signals = [] for _, row in stock_pool.iterrows(): df = get_triple_optimized_data(row["ts_code"], row["name"], row["industry"]) if df is None: continue sig = generate_triple_optimized_signals(df) if not sig.empty: all_signals.append(sig) return pd.concat(all_signals, ignore_index=True) if all_signals else pd.DataFrame() # 9. 输出回测结果 if __name__ == "__main__": result = run_triple_optimized_backtest() if result.empty: print("三次优化策略无符合条件信号") else: total = len(result) win_count = len(result[result["收益率"] > 0]) win_rate = (win_count / total) * 100 avg_return = result["收益率"].mean() loss_return = result[result["收益率"] <= 0]["收益率"].mean() high_return_count = len(result[result["收益率"] >= 5]) # 高收益(≥5%)信号占比 print(f"\n8.20-8.29三次优化回测结果:") print(f"- 有效信号数:{total}个") print(f"- 胜率:{win_rate:.2f}%") print(f"- 平均收益率:{avg_return:.2f}%") print(f"- 平均亏损幅度:{loss_return:.2f}%") print(f"- 高收益信号(≥5%)占比:{round(high_return_count/total*100, 2)}%") print(f"\n操作类型分布:\n{result['操作类型'].value_counts().to_string()}") print(f"\n前5个信号详情:") print(result[["操作类型", "买入日", "代码", "名称", "收益率"]].head().to_string(index=False))
09-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值