一、关于k线数据
极智的4小时行情和文华财经一样。但是k线上显示的时间不一样。
比如:7.31 21:00-21:01这一根k线,在文华财经上显示为07312100
在极智显示为07312101
1小时k线也是这样。
和快期行情k线是不相同的。
以甲醇为例,交易时间是这样的:
夜盘:21:00—23:00
日盘:09:00—10:15、10:30—11:30、13:30—15:00(10:15—10:30 为午休休市)
全天交易时间为5小时45分钟。
现在是2026.Aug.01,极智量化4小时图最后一根k显示时间为:2026.8.3 11:15,得知k线显示的时间是结束时间。
前1根显示:7.31 15:00 即:11点15分钟+下午1.5小时,所以这个4h不足4小时,只有1小时45分。(通过文华财经核对,的确是这样,极知这根k线的高低点就是文华11:15-15:00时间段的高低点。)
再前1根显示:7.31 11:15 即晚上2小时+9:00-10:00+10点的45分钟+11点的15分钟。
二、关于SetBarInterval(context.contract, 'D', 1, 'A', isTrigger=False)
isTrigger 设置非基准合约是否触发,基准合约设置该参数无效,默认值为 False
由于 isTrigger 对基准合约((即策略主图显示的合约))无效,无论设置为 True 还是 False,日线数据都会正常触发 handle_data()。
所以这个参数主要在多合约策略中有意义。
三、关于多周期
SetBarInterval设定的第一个周期就是handledate的调用周期。
比如下面的代码,显示的结果是:
[2026\7\31 7.34.52] [INFO][15]: 当前触发时间:20260729 150000
[2026\7\31 7.34.52] [INFO][15]: 240分钟线 - 时间: 20260729 0.150000 开盘: 3071.00 收盘: 3062.00
[2026\7\31 7.34.52] [INFO][15]: 日线 - 时间: 20260729 0.000000 开盘: 3060.00 收盘: 3062.00
[2026\7\31 7.34.52] [INFO][15]: 当前触发时间:20260730 111500
[2026\7\31 7.34.52] [INFO][15]: 240分钟线 - 时间: 20260730 0.111500 开盘: 3061.00 收盘: 3021.00
[2026\7\31 7.34.52] [INFO][15]: 日线 - 时间: 20260730 0.000000 开盘: 3061.00 收盘: 3014.00
[2026\7\31 7.34.52] [INFO][15]: 当前触发时间:20260730 150000
[2026\7\31 7.34.52] [INFO][15]: 240分钟线 - 时间: 20260730 0.150000 开盘: 3021.00 收盘: 3014.00
[2026\7\31 7.34.52] [INFO][15]: 日线 - 时间: 20260730 0.000000 开盘: 3061.00 收盘: 3014.00
[2026\7\31 7.34.52] [INFO][15]: 当前触发时间:20260731 111500
[2026\7\31 7.34.52] [INFO][15]: 240分钟线 - 时间: 20260731 0.111500 开盘: 3014.00 收盘: 3010.00
[2026\7\31 7.34.52] [INFO][15]: 日线 - 时间: 20260731 0.000000 开盘: 3014.00 收盘: 3010.00
即每4小时调用一次,但同时会更新日线的k线数据。
测试代码:
import talib
def initialize(context):
context.contract = Symbol()
SetBarInterval(context.contract, 'M', 240, 'A')
SetBarInterval(context.contract, 'D', 1, 'A')
def handle_data(context):
contract = context.contract
# 打印当前触发时间(来自 context)
ts = context.dateTimeStamp()
ts_str = str(ts)
date_str = ts_str[:8]
time_str = ts_str[8:14]
LogInfo("当前触发时间:%s %s" % (date_str, time_str))
# 240分钟线数据
open_240 = Open(contract, 'M', 240)[-1]
close_240 = Close(contract, 'M', 240)[-1]
date_240 = Date(contract, 'M', 240) # 整数,如 20260731
time_240 = Time(contract, 'M', 240) # 浮点数,如 0.093400
LogInfo("240分钟线 - 时间: %d %.6f 开盘: %.2f 收盘: %.2f" % (date_240, time_240, open_240, close_240))
# 日线数据
open_D = Open(contract, 'D', 1)[-1]
close_D = Close(contract, 'D', 1)[-1]
date_D = Date(contract, 'D', 1)
time_D = Time(contract, 'D', 1)
LogInfo("日线 - 时间: %d %.6f 开盘: %.2f 收盘: %.2f" % (date_D, time_D, open_D, close_D))
如果调换SetBarInterval顺序,则结果就是:
[2026\7\31 8.0.10] [INFO][20]: 当前触发时间:20260729 000000
[2026\7\31 8.0.10] [INFO][20]: 240分钟线 - 时间: 20260728 0.150000 开盘: 3059.00 收盘: 3060.00
[2026\7\31 8.0.10] [INFO][20]: 日线 - 时间: 20260729 0.000000 开盘: 3060.00 收盘: 3062.00
[2026\7\31 8.0.10] [INFO][20]: 当前触发时间:20260730 000000
[2026\7\31 8.0.10] [INFO][20]: 240分钟线 - 时间: 20260729 0.150000 开盘: 3071.00 收盘: 3062.00
[2026\7\31 8.0.10] [INFO][20]: 日线 - 时间: 20260730 0.000000 开盘: 3061.00 收盘: 3014.00
[2026\7\31 8.0.10] [INFO][20]: 当前触发时间:20260731 000000
[2026\7\31 8.0.10] [INFO][20]: 240分钟线 - 时间: 20260730 0.150000 开盘: 3021.00 收盘: 3014.00
[2026\7\31 8.0.10] [INFO][20]: 日线 - 时间: 20260731 0.000000 开盘: 3014.00 收盘: 3010.00
四、关于回测与成交。
极智量化在回测时使用主连合约,但成交(下单)时使用的是该主连当前映射到的具体合约。
五、关于ema
def calc_ema(price, period):
"""计算指数移动平均(EMA)"""
if len(price) < period:
return np.array([])
ema = np.zeros(len(price))
alpha = 2.0 / (period + 1)
ema[0] = price[0]
for i in range(1, len(price)):
ema[i] = alpha * price[i] + (1 - alpha) * ema[i-1]
return ema
alpha 的值只和period有关。


简单移动平均(SMA)和指数移动平均(EMA)在算法本质上的核心区别。
简单来说:
MA5(简单移动平均):是“近视眼”,只看最近5天,第6天的数据直接扔掉,没有任何影响。
EMA5(指数移动平均):是“记忆体”,理论上会用到从第1天到今天的全部数据,但每一天的权重不同。
因为 EMA 的公式是递归的(今天的值依赖于昨天的值,昨天的值依赖于前天的值……)。
继续往前推,你会发现第1天的价格(P(第1天))虽然系数已经变得非常非常小(0.667^100),但它永远不等于零,会一直以极微弱的权重存在于今天的EMA值中。
目前市场上主流的趋势跟踪系统(如海龟交易法则的变种、双均线系统)大多采用 EMA 或加权均线,因为它能更好地体现“当前价格热度”。既然你的策略逻辑是基于“趋势证伪”(价格跌破EMA5离场),那么离场触发价格用 EMA 会比 MA 更早一步反映资金出逃的迹象,帮你保住更多利润。除非你在实盘中明显感觉到 EMA 让止损过于频繁(噪音过大),否则不建议换回 MA。
六、ParabolicSAR
根据提供的文档(“极智量化API手册.pdf”第120-121页):
语法:ParabolicSAR(numpy.array high, numpy.array low, float afstep, float aflimit)
参数:高、低、加速因子步长、加速因子限制。
返回值:四个值,均为数值型numpy.array。
第一个值:oParClose - 当前bar的停损值。
第二个值:oParOpen - 下一Bar的停损值。
第三个值:oPosition - 输出建议的持仓状态,1 - 买仓,-1 - 卖仓。
第四个值:oTransition - 输出当前Bar的状态是否发生反转,1或-1为反转,0为保持不变。
另外,回想一下标准SAR(抛物线转向)指标在技术分析中的工作原理:它跟踪趋势,停损点随价格移动(加速因子增加),当价格穿越SAR值时趋势反转。