TD Ameritrade ThinkScript循环代码转Python遇输出格式问题
问题解决:ThinkScript Fold循环转Python一维数组实现
首先明确原ThinkScript的核心逻辑:
对于每个位置的收盘价ca[i],与前lengtha(如10)个开盘价oa[i-1], oa[i-2], ..., oa[i-lengtha]逐一比较:
ca[i] > oa[j]时累加+1ca[i] < oa[j]时累加-1- 相等则加0
初始值为0,最终输出与ca/oa同维度的一维序列,结果范围随有效比较次数在[-lengtha, lengtha]内。
你之前遇到的多维数组、值超范围问题,本质是广播逻辑错误和边界未处理导致的,以下是两种正确实现方案:
方案1:Numpy向量化实现(高效适合大数据)
利用滑动窗口获取每个ca对应的历史oa,再批量计算得分:
import numpy as np lengtha = 10 # 替换为你的真实ca、oa一维数组 ca = np.random.rand(100) * 100 oa = np.random.rand(100) * 100 # 给oa前补lengtha-1个nan,保证每个ca位置都能取到lengtha个窗口(不足的用nan填充) padded_oa = np.concatenate([np.full(lengtha-1, np.nan), oa]) # 生成每个ca对应的前lengtha个oa的滑动窗口 window_oa = np.lib.stride_tricks.sliding_window_view(padded_oa, window_shape=lengtha)[:-lengtha+1] # 批量比较计算得分 comparison = np.where(ca[:, None] > window_oa, 1, np.where(ca[:, None] < window_oa, -1, 0)) # 忽略nan(无历史数据的位置),按行求和得到一维结果 result = np.nansum(comparison, axis=1) # 验证结果 print(result.shape) # 输出与ca/oa一致的一维数组形状 print(result.min(), result.max()) # 结果范围符合预期
方案2:纯Python循环(直观易调试)
适合小数据量或需要明确控制边界逻辑的场景:
lengtha = 10 # 替换为你的真实ca、oa列表/数组 ca = [x * 100 for x in np.random.rand(100)] oa = [x * 100 for x in np.random.rand(100)] result = [] for i in range(len(ca)): score = 0 # 遍历前lengtha个开盘价,超出数组范围则停止 for j in range(1, lengtha+1): prev_idx = i - j if prev_idx < 0: break if ca[i] > oa[prev_idx]: score += 1 elif ca[i] < oa[prev_idx]: score -= 1 result.append(score) result = np.array(result) # 验证结果 print(result.shape) print(result.min(), result.max())
错误原因说明
- 多维数组问题:你之前可能直接用
ca[:, None] > oa做广播,生成的是N×N的二维数组(每个ca[i]和所有oa[j]比较),完全不符合原逻辑中"只比较前lengtha个历史值"的要求。 - 超范围值(如-11):未处理边界,当
i < lengtha时错误地访问了数组负索引(对应数组末尾元素),导致累加了额外的错误值,超出预期范围。
内容的提问来源于stack exchange,提问作者thetadecay
相关产品推荐
相关产品推荐

