3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 PTrade 量化交易平台中,KDJ(随机指标)是极常用的技术分析工具。虽然 PTrade 提供了内置的 get_KDJ 函数,但手动编写 KDJ 计算逻辑有助于您深度定制策略(例如修改平滑权重或引入动态周期)。\n\n以下是使用 get_history 获取历史价格并手动计算 KDJ 指标的完整实现指南。\n\n### 一、 KDJ 指标计算原理\nKDJ 的计算主要分为三个步骤(以经典的 9 天周期为例):\n1. 计算未成熟随机值 RSV (Raw Stochastic Value):\n $$RSV_t = \frac{Close_t - L_{9}}{H_{9} - L_{9}} \times 100$$\n 其中,$Close_t$ 为当日收盘价,$L_{9}$ 为过去 9 天内的最低价,$H_{9}$ 为过去 9 天内的最高价。\n2. 计算 K 值与 D 值(通常初始值设为 50):\n $$K_t = \frac{2}{3} \times K_{t-1} + \frac{1}{3} \times RSV_t$$\n $$D_t = \frac{2}{3} \times D_{t-1} + \frac{1}{3} \times K_t$$\n3. 计算 J 值:\n $$J_t = 3 \times K_t - 2 \times D_t$$\n\n---\n\n### 二、 PTrade 策略实现代码\n\n您可以在 PTrade 的 handle_data 周期函数中,通过 get_history 获取高开低收数据,并使用以下 Python 代码手动计算 KDJ:\n\npython\nimport numpy as np\nimport pandas as pd\n\ndef initialize(context):\n # 设置操作的股票池\n g.security = '600570.SS' # 恒生电子\n set_universe(g.security)\n\ndef handle_data(context, data):\n # 1. 获取过去 50 天的日线高、开、低、收历史行情\n # 注意:计算 KDJ 需要至少 N 天以上的数据进行平滑递推\n h = get_history(50, '1d', ['close', 'high', 'low'], security_list=g.security)\n \n # 提取 numpy 数组\n high_arr = h['high'].values\n low_arr = h['low'].values\n close_arr = h['close'].values\n \n # 2. 手动计算 KDJ (参数 N=9, M1=3, M2=3)\n k_val, d_val, j_val = calculate_manual_kdj(high_arr, low_arr, close_arr, n=9, m1=3, m2=3)\n \n # 3. 获取最新的 KDJ 值\n current_k = k_val[-1]\n current_d = d_val[-1]\n current_j = j_val[-1]\n \n log.info(f\"手动计算 KDJ -> K: {current_k:.2f}, D: {current_d:.2f}, J: {current_j:.2f}\")\n \n # 4. 验证:对比 PTrade 内置的 get_KDJ 函数\n k_built, d_built, j_built = get_KDJ(high_arr, low_arr, close_arr, n=9, m1=3, m2=3)\n log.info(f\"内置函数 KDJ -> K: {k_built[-1]:.2f}, D: {d_built[-1]:.2f}, J: {j_built[-1]:.2f}\")\n\ndef calculate_manual_kdj(high, low, close, n=9, m1=3, m2=3):\n \"\"\"\n 手动计算 KDJ 指标函数\n \"\"\"\n length = len(close)\n k = np.zeros(length)\n d = np.zeros(length)\n j = np.zeros(length)\n \n # 初始值通常设为 50\n k[0:n-1] = 50.0\n d[0:n-1] = 50.0\n \n for i in range(n - 1, length):\n # 获取过去 N 天的最高价和最低价\n hn = np.max(high[i - n + 1 : i + 1])\n ln = np.min(low[i - n + 1 : i + 1])\n \n # 计算 RSV\n if hn == ln:\n rsv = 50.0 # 防止分母为 0\n else:\n rsv = (close[i] - ln) / (hn - ln) * 100\n \n # 递推计算 K 值和 D 值\n k[i] = (m1 - 1) / m1 * k[i - 1] + 1 / m1 * rsv\n d[i] = (m2 - 1) / m2 * d[i - 1] + 1 / m2 * k[i]\n \n # 计算 J 值\n j[i] = 3 * k[i] - 2 * d[i]\n \n return k, d, j\n\n\n---\n\n### 三、 开发注意事项\n1. 数据长度选择:由于 KDJ 是一个递推平滑指标,前期的 K、D 值会影响后期的计算结果。建议使用 get_history 获取至少 50 条以上的历史 K 线,以确保递推到最新一天时,KDJ 的数值已经收敛并趋于精准。\n2. 极值处理:在涨跌停或一字板时,可能会出现 $H_n = L_n$ 的情况。在手动编写算法时,必须加入 if hn == ln 的异常保护逻辑,防止程序因除以 0 而崩溃。