Files
NewQuant/data/ analysis/OI.ipynb

357 lines
292 KiB
Plaintext
Raw Normal View History

2025-09-16 09:59:38 +08:00
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
2025-09-20 00:04:51 +08:00
"end_time": "2025-09-17T02:55:13.621128Z",
"start_time": "2025-09-17T02:55:13.617846Z"
2025-09-16 09:59:38 +08:00
}
},
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"import talib as ta # Make sure TA-Lib is installed: pip install TA-Lib\n",
"import statsmodels.api as sm\n",
"\n",
"import warnings\n",
"\n",
"# 忽略所有警告\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"# --- 0. Configure your file path ---\n",
"# Please replace 'your_futures_data.csv' with the actual path to your CSV file\n",
"file_path = '/mnt/d/PyProject/NewQuant/data/data/KQ_m@CZCE_SA/KQ_m@CZCE_SA_min15.csv'\n",
"\n",
"sns.set(style='whitegrid')\n",
"plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签\n",
"plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号\n"
],
"outputs": [],
2025-09-20 00:04:51 +08:00
"execution_count": 5
2025-09-16 09:59:38 +08:00
},
{
"metadata": {
"ExecuteTime": {
2025-09-20 00:04:51 +08:00
"end_time": "2025-09-17T02:55:13.685840Z",
"start_time": "2025-09-17T02:55:13.639781Z"
2025-09-16 09:59:38 +08:00
}
},
"cell_type": "code",
"source": [
"\n",
"# --- 1. Data Loading and Preprocessing ---\n",
"def load_and_preprocess_data(file_path):\n",
" \"\"\"\n",
" Loads historical futures data and performs basic preprocessing.\n",
" Assumes data contains 'datetime', 'open', 'high', 'low', 'close', 'volume' columns.\n",
" \"\"\"\n",
" try:\n",
" df = pd.read_csv(file_path, parse_dates=['datetime'], index_col='datetime')\n",
" # Ensure data is sorted by time\n",
" df = df.sort_index()\n",
" # Check and handle missing values\n",
" initial_rows = len(df)\n",
" df.dropna(inplace=True)\n",
" if len(df) < initial_rows:\n",
" print(f\"Warning: Missing values found in data, deleted {initial_rows - len(df)} rows.\")\n",
"\n",
" # Check if necessary columns exist\n",
" required_columns = ['open', 'high', 'low', 'close', 'volume']\n",
" if not all(col in df.columns for col in required_columns):\n",
" raise ValueError(f\"CSV file is missing required columns. Please ensure it contains: {required_columns}\")\n",
"\n",
" print(f\"Successfully loaded {len(df)} rows of data.\")\n",
" print(\"First 5 rows of data:\")\n",
" print(df.head())\n",
" return df\n",
" except FileNotFoundError:\n",
" print(f\"Error: File '{file_path}' not found. Please check the path.\")\n",
" return None\n",
" except Exception as e:\n",
" print(f\"Error during data loading or preprocessing: {e}\")\n",
" return None\n",
"\n",
"\n",
"df_raw = load_and_preprocess_data(file_path)\n",
"df_raw = df_raw[df_raw.index >= '2024-01-01']"
],
"id": "548c68daa68af8c1",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Successfully loaded 25662 rows of data.\n",
"First 5 rows of data:\n",
" open high low close volume open_oi \\\n",
"datetime \n",
"2020-12-31 14:45:00 1607.0 1611.0 1603.0 1611.0 19480.0 148833.0 \n",
"2021-01-04 09:00:00 1610.0 1636.0 1601.0 1620.0 55486.0 146448.0 \n",
"2021-01-04 09:15:00 1620.0 1620.0 1601.0 1604.0 30314.0 153373.0 \n",
"2021-01-04 09:30:00 1604.0 1606.0 1590.0 1595.0 30803.0 157091.0 \n",
"2021-01-04 09:45:00 1595.0 1601.0 1594.0 1600.0 10031.0 158730.0 \n",
"\n",
" close_oi underlying_symbol \n",
"datetime \n",
"2020-12-31 14:45:00 146448.0 CZCE.SA105 \n",
"2021-01-04 09:00:00 153373.0 CZCE.SA105 \n",
"2021-01-04 09:15:00 157091.0 CZCE.SA105 \n",
"2021-01-04 09:30:00 158730.0 CZCE.SA105 \n",
"2021-01-04 09:45:00 160031.0 CZCE.SA105 \n"
]
}
],
2025-09-20 00:04:51 +08:00
"execution_count": 6
2025-09-16 09:59:38 +08:00
},
{
"metadata": {
"ExecuteTime": {
2025-09-20 00:04:51 +08:00
"end_time": "2025-09-17T02:55:13.828236Z",
"start_time": "2025-09-17T02:55:13.692306Z"
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# 如果还没设置索引\n",
"# df_raw['datetime'] = pd.to_datetime(df_raw['datetime'])\n",
"# df_raw = df_raw.set_index('datetime')\n",
"\n",
"fig, ax1 = plt.subplots(figsize=(12, 6))\n",
"\n",
"color1 = 'tab:blue'\n",
"ax1.set_xlabel('Time')\n",
"ax1.set_ylabel('close', color=color1)\n",
"ax1.plot(df_raw.index, df_raw['close'], color=color1, label='close')\n",
"ax1.tick_params(axis='y', labelcolor=color1)\n",
"\n",
"# 第二个 y 轴\n",
"ax2 = ax1.twinx()\n",
"color2 = 'tab:orange'\n",
"ax2.set_ylabel('close_oi', color=color2)\n",
"ax2.plot(df_raw.index, df_raw['close_oi'], color=color2, label='close_oi', alpha=0.8)\n",
"ax2.tick_params(axis='y', labelcolor=color2)\n",
"\n",
"# 标题 & 网格\n",
"plt.title('Close vs Close_OI (Dual Y-axis)')\n",
"ax1.grid(True)\n",
"fig.tight_layout()\n",
"plt.show()"
],
"id": "18421d04e4f597dd",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 1200x600 with 2 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAABKAAAAJICAYAAABWnpxpAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3XV0G1faBvBHaMsMiUN24jBz2jTUNtA2TcrMtO2Web/ilhm2W97ClmlLKSbFNNQ0zOBwnDhgjlEW6/tjBCNphJY0kvX8zvHx8FyNpNHMO/e+V2G32+0gIiIiIiIiIiKKEaXcBSAiIiIiIiIioo6NASgiIiIiIiIiIoopBqCIiIiIiIiIiCimGIAiIiIiIiIiIqKYYgCKiIiIiIiIiIhiigEoIiIiIiIiIiKKKQagiIiIiIiIiIgophiAIiIiIiIiIiKimGIAioiIiIiIiIiIYooBKCIiIqIksmfPHpjNZrmLkXJ27doFu90udzGIiIiSFgNQREREREni8OHDuOKKK7Bhwwa5i5JynnzySbz44otyF4OIiChpMQBFREQUJQsWLMApp5yC4cOH44ILLsC2bdt8ljlw4AAGDhyIAwcOyFDCxNERjpXJZMKTTz6J8ePHY/To0bjjjjvQ0NDgs9wrr7yCcePGtXt/NpsNt9xyC6644gqMGzfOdXwGDhyIESNG4NRTT8V///tfWK3Wdu9Lypw5czBt2rSw17v++utx3nnneUw7ePAghgwZgjlz5kSreCF75ZVXcOmll4a93vPPP48ff/wRCxcujH6hiIiIUgADUERERFGwevVq3HTTTTjuuOPw1ltvoaCgAFdffTXa2trkLlrC6SjH6sknn8T//vc/3HrrrXjqqaewfPly3HnnnTHb35dffgmtVourrrrKY/rdd9+Nt99+G1OmTMELL7yA+++/P2ZliMTVV1+NDRs2YP369a5pH3/8MTp16oRTTz017uU577zz8Mgjj4S9XkFBAR577DE8+eSTMJlMMSgZERFRx6aWuwBEREQdwQsvvIBJkybh//7v/wAAQ4cOxeTJk/HNN9/goosukrl0iaUjHKuGhgZ8+eWXuO2221xlVqlUuOmmm7Bt2zYMGjQo6vt855138Oyzz/pM79mzJ8aPH4/x48ejoKAAzz33HC677DIMGTIk6mWIxNixYzF69Gh88MEHGDVqFPR6Pb766itcd9110Gg0cS9Ply5dIl534sSJKCkpwe+//45Zs2ZFsVREREQdH2tAERERtVN9fT3Wrl2Lk08+2TUtJycHvXr1ws6dO2UsWeLpKMdq3bp1sFgsOPbYY13TJk6cCABYtWpV1Pe3bds2WK1WjBo1KuByF1xwAdRqNf7444+ol6E9rrnmGvz66684fPgwvvnmGwDA+eefL3OpInPKKafg559/lrsYRERESYcBKCIionbasWMH7HY7+vTp4zH9iSee8Ml9E0h1dTVuvfVWjB49GhMnTsTzzz8Pi8Ximm+xWPDMM89gypQpGDVqFC6++GKf3Em//PILTj31VIwYMQJnnHEGli1bFvL+V6xYgYEDB6Kqqso1rbm5GcOGDcOCBQtc0+bMmYOTTjoJI0aMwMknnxzWzXhHOVYVFRUAgB49erimZWZmIjc3NyY5q7Zv347Ro0cHXS4rKwslJSXYs2cPAOCee+7BPffc47GMdw6k8vJyXHPNNRg7diwmTpyIBx54AAaDIarlnzZtGnr16oWPPvoIH374IS644AJkZWUBEHJbWSwWyT9xPqvvv/8es2bNwsiRIzFz5kz8+OOPrnk7duzAsGHDXDml7HY7zjrrLFxzzTU+ZQmUAyqUz/aYMWOwffv2dh0PIiKiVMQAFBERUTvV19cDAHJzcz2mjxgxAoMHDw5pGwaDAVdccQV2796NF154Abfffjs+//xzPPTQQ65lPv74Y3z00Ue444478PrrryM7Oxu33Xaba/6KFStw6623YsaMGXjnnXcwfPhwXHPNNdi9e3dIZTjqqKPQuXNnLFq0yDVtyZIlyMjIwOTJkwEAW7ZswX333YcTTjgB77zzDqZPn45//OMfOHz4cEj76CjHqrW1FQCg0+k8put0Ote8aKqpqUHnzp1DWjYvLw+NjY0hLWu323HttdeiubkZr776Kh599FEsWLAA77zzTnuK60OhUOCqq67C+++/j0OHDuGyyy5zzbvvvvswdOhQyb8rrrgCgJA37K677sKJJ56Id955B6eccgruvvtuVyBwwIABuOqqq/Dvf/8bbW1t+Oabb7Bnzx6Pz0QwoX62O3fujOrq6vYfFCIiohTDHFBERETt5ExIrFKpIt7G3LlzsXfvXvz0008oLS0FACiVStx///24/vrrUVxcjAMHDqCwsBCnn346lEol+vfvjy1btsBut0OhUODVV1/F1KlTceuttwIQcu/89ttvmDt3Lm655ZagZVAqlZg5cyYWLFjgqo20cOFCzJgxw5Wr59ChQ7Db7Tj77LPRu3dvjBo1CmPHjkVaWlpIr7OjHCt/nNuPNqVSCbvdHvXttrW14eqrr8YxxxyDkpISWK1WfP311x4Jw6PltNNOw7PPPotjjz3WI5h2yy234PLLL5dcJyMjA4BQu+ypp57CmWeeCUDIe/X6669j06ZNKCkpAQDccMMN+Omnn/DKK6/ghx9+wM0334zi4uKQyxfqZ9tms0Gp5DNcIqIOzWYDvrwMKBoKTL03vHXNbcAbk4ExlwOTIr+m6IgYgCIiImqnzMxMAPCp+fLwww8jPz/fFeQIZPPmzejWrZsroAIIOYXsdjs2b96M4uJinH766ZgzZw5OOeUUjB8/HuPGjcMJJ5zgCnjs2LEDDQ0NGDhwoMe29+3bF/JrmTVrFv72t7/BZDJBrVZj8eLF+Ne//uWaP2HCBJSWluKSSy7BpEmTMGrUKMycORMFBQUhbb+jHCtn8zG9Xo/s7GzX9La2Nte8aOrcuTM2b94c0rKNjY3o3r273/k2m801nJGRgeOOOw7ffPMNVqxYgY0bN6K1tRXjxo1rd5m9abVaZGVlIT8/32N69+7dA5YXAAYPHoyWlhY89thjWLNmDXbu3AmbzebRVDA9PR0PP/wwrrrqKgwaNMhvUMufUD/b1dXVIddGIyKiJGQ2AD/cCpT9IASgwvXbQ0BaDjDhxuiXLcnx8Q0REVE79erVCwB8cv+sWrUKdXV1IW0jUO0W57zhw4fj119/xd///ndYLBY89NBDuPjiiz1yH1100UX49ttvPf5uv/32kF/L6NGjkZeXh2XLlmH9+vVQKBQ45phjXPOzsrLw3Xff4ZFHHkFhYSHee+89nHzyyTh48GBI2+8ox6pnz54A4PG6W1pa0NTUFFatm1ANHToUq1evDloLqrW1FRUVFejXr5/fZSorK13Dhw4dwimnnIIlS5Zg+vTp+O9//4vrrrsuauWOlo8//hhXXnklrFarK6G5VNDK+doaGxvDzmMV6md75cqVGDZsWOQvhoiIEtvcOwGVBigZH/66exYBa94HTn8VUEZe27ujYgCKiIionfr374+uXbvi999/d02rq6tDeXk5hg4N7cnZ8OHDcfjwYezfv981bfny5VAoFK6b3bfffhvl5eU444wz8Nhjj+Gll17Cxo0bsWPHDlc5ampqMHjwYNff/PnzPXI6BaNQKDBz5kwsXLgQCxcuxEknneTRXO7XX3/F3LlzMWPGDNx999349ttv0drait9++y2k7XeUYzVmzBhoNBqP5ZcuXQoAOProo0PaRjj69OmD3NxcLF++POByX331FSwWC0488UQAQlPHtrY213y9Xu9R5t9++w16vR7vvvsuLr74YowaNQrl5eVRL397ffXVV5g9ezYefvhhzJ49GzqdDg0NDR7LVFdX4+mnn8Y999wDnU6H559/Pqx9hPrZ/v777zFz5sz2viQiIkpUU+5wBJA0vvN2/g68eSzwZA/g3ZOB2l3uecZm4Lsbgd5TgEPrgf0r4lbkZMEmeERERO2kUChwxx134K677kJRURGOPvpovP7668jPz8esWbNC2sbs2bPx3//+FzfeeCPuuOMO1NXV4dlnn8V
},
"metadata": {},
"output_type": "display_data"
}
],
"execution_count": 7
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-09-17T02:55:14.115196Z",
"start_time": "2025-09-17T02:55:13.857406Z"
2025-09-16 09:59:38 +08:00
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"\n",
"df = df_raw\n",
"\n",
"\n",
"# --- 2. 因子计算 ---\n",
"print(\"--- 正在计算因子 ---\")\n",
"df['volume_safe'] = df['volume'].replace(0, 1e-6)\n",
"df['price_impact_factor'] = np.abs(df['close'].pct_change()) / df['volume_safe']\n",
"df['directional_impact_factor'] = (df['close'] - df['open']) / df['volume_safe']\n",
"\n",
"\n",
"# --- 3. 定义未来收益率 (我们要预测的目标) ---\n",
"print(\"--- 正在计算未来收益率 ---\")\n",
"forward_periods = [1, 5, 10]\n",
"for n in forward_periods:\n",
" df[f'fwd_return_{n}d'] = df['close'].pct_change(periods=n).shift(-n)\n",
"\n",
"# 清理数据删除因计算位移产生的NaN值\n",
"df.dropna(inplace=True)\n",
"\n",
"\n",
"# --- 4. 核心:执行分位数分析 ---\n",
"print(\"--- 正在执行分位数分析 ---\")\n",
"num_quantiles = 5 # 分为5组\n",
"\n",
"# 4.1 分析 价格冲击因子\n",
"# 使用 pd.qcut 将因子值分为 N 组\n",
"df['pi_quantile'] = pd.qcut(df['price_impact_factor'], q=num_quantiles, labels=False, duplicates='drop')\n",
"pi_analysis = df.groupby('pi_quantile')[[f'fwd_return_{n}d' for n in forward_periods]].mean() * 100\n",
"\n",
"# 4.2 分析 定向冲击因子\n",
"df['di_quantile'] = pd.qcut(df['directional_impact_factor'], q=num_quantiles, labels=False, duplicates='drop')\n",
"di_analysis = df.groupby('di_quantile')[[f'fwd_return_{n}d' for n in forward_periods]].mean() * 100\n",
"\n",
"\n",
"# --- 5. 结果可视化与解读 ---\n",
"print(\"\\n--- 因子有效性分析结果 ---\")\n",
"fig, axes = plt.subplots(1, 2, figsize=(18, 7))\n",
"\n",
"# 价格冲击因子 结果\n",
"print(\"\\n价格冲击因子 (Price Impact Factor) 分位数分析:\")\n",
"print(pi_analysis)\n",
"pi_analysis.plot(kind='bar', ax=axes[0], title='价格冲击因子 vs 未来收益率\\n(Price Impact Factor vs. Forward Returns)')\n",
"axes[0].set_xlabel('因子分位数 (Q1: 最低, Q5: 最高)')\n",
"axes[0].set_ylabel('平均未来收益率 (%)')\n",
"axes[0].set_xticklabels([f'Q{i+1}' for i in range(len(pi_analysis))], rotation=0)\n",
"\n",
"# 定向冲击因子 结果\n",
"print(\"\\n定向冲击因子 (Directional Impact Factor) 分位数分析:\")\n",
"print(di_analysis)\n",
"di_analysis.plot(kind='bar', ax=axes[1], title='定向冲击因子 vs 未来收益率\\n(Directional Impact Factor vs. Forward Returns)')\n",
"axes[1].set_xlabel('因子分位数 (Q1: 最低, Q5: 最高)')\n",
"axes[1].set_ylabel('平均未来收益率 (%)')\n",
"axes[1].set_xticklabels([f'Q{i+1}' for i in range(len(di_analysis))], rotation=0)\n",
"\n",
"plt.suptitle('因子有效性分位数分析', fontsize=16)\n",
"plt.tight_layout(rect=[0, 0.03, 1, 0.95])\n",
"plt.show()\n",
"\n",
"# --- 6. 进阶分析: 在特定市场状态下的表现 ---\n",
"print(\"\\n--- 进阶分析:因子在不同市场状态下的表现 ---\")\n",
"# 定义市场状态使用ATR的移动平均值来衡量波动性\n",
"high_low = df['high'] - df['low']\n",
"high_close = np.abs(df['high'] - df['close'].shift())\n",
"low_close = np.abs(df['low'] - df['close'].shift())\n",
"tr = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)\n",
"df['atr_pct'] = (tr / df['close']).ewm(span=20, adjust=False).mean()\n",
"\n",
"# 定义高波动状态为ATR百分比位于最高的30%的时间\n",
"high_vol_threshold = df['atr_pct'].quantile(0.7)\n",
"df_high_vol = df[df['atr_pct'] > high_vol_threshold]\n",
"\n",
"# 在高波动状态下,重新分析定向冲击因子\n",
"di_analysis_high_vol = df_high_vol.groupby('di_quantile')[[f'fwd_return_{n}d' for n in forward_periods]].mean() * 100\n",
"\n",
"print(\"\\n定向冲击因子在高波动市场下的表现:\")\n",
"print(di_analysis_high_vol)\n",
"\n",
"# 可视化高波动状态下的结果\n",
"fig, ax = plt.subplots(figsize=(10, 6))\n",
"di_analysis_high_vol.plot(kind='bar', ax=ax, title='定向冲击因子在高波动市场状态下的表现\\n(Directional Impact Factor in HIGH VOLATILITY Regime)')\n",
"ax.set_xlabel('因子分位数 (Q1: 最低, Q5: 最高)')\n",
"ax.set_ylabel('平均未来收益率 (%)')\n",
"ax.set_xticklabels([f'Q{i+1}' for i in range(len(di_analysis_high_vol))], rotation=0)\n",
"plt.tight_layout()\n",
"plt.show()"
],
"id": "e9248ae41d9a1b1d",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- 正在计算因子 ---\n",
"--- 正在计算未来收益率 ---\n",
"--- 正在执行分位数分析 ---\n",
"\n",
"--- 因子有效性分析结果 ---\n",
"\n",
"价格冲击因子 (Price Impact Factor) 分位数分析:\n",
" fwd_return_1d fwd_return_5d fwd_return_10d\n",
"pi_quantile \n",
"0 -0.010825 -0.055032 -0.042790\n",
"1 0.001791 -0.008909 -0.010649\n",
"2 -0.001939 -0.008222 -0.060071\n",
"3 0.004476 -0.001045 -0.046483\n",
"4 -0.011277 -0.015913 -0.018583\n",
"\n",
"定向冲击因子 (Directional Impact Factor) 分位数分析:\n",
" fwd_return_1d fwd_return_5d fwd_return_10d\n",
"di_quantile \n",
"0 -0.010517 -0.023939 -0.079702\n",
"1 -0.002474 0.011427 -0.013968\n",
"2 -0.004617 -0.048772 -0.039226\n",
"3 0.004874 -0.008277 -0.024593\n",
"4 -0.005044 -0.019583 -0.021074\n"
]
},
{
"data": {
"text/plain": [
"<Figure size 1800x700 with 2 Axes>"
],
2025-09-20 00:04:51 +08:00
"image/png": "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
2025-09-16 09:59:38 +08:00
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"--- 进阶分析:因子在不同市场状态下的表现 ---\n",
"\n",
"定向冲击因子在高波动市场下的表现:\n",
" fwd_return_1d fwd_return_5d fwd_return_10d\n",
"di_quantile \n",
"0 0.006045 0.020305 -0.076809\n",
"1 -0.014321 0.074963 0.062119\n",
"2 0.002337 -0.057309 0.007566\n",
"3 0.029277 0.064093 0.062086\n",
"4 -0.009715 -0.030420 -0.030257\n"
]
},
{
"data": {
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
],
2025-09-20 00:04:51 +08:00
"image/png": "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
2025-09-16 09:59:38 +08:00
},
"metadata": {},
"output_type": "display_data"
}
],
2025-09-20 00:04:51 +08:00
"execution_count": 8
2025-09-16 09:59:38 +08:00
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}