# 原生指标函数
Lambda提供了大量原生指标函数。用户策略里可以直接使用这些指标,不需要自己用pandas重写 MA / MACD / CROSS。
常用写法:
def handle_bar(context, bar_dict):
ma5 = MA(CLOSE, 5)
ma10 = MA(CLOSE(), 10)
buy_signal = CROSS(ma5, ma10)
price_filter = CLOSE > ma5
# 需要读取 MACD 三个结果序列时,先绑定 KData,再按结果序号访问。
stock = sm[to_internal_code(context.stock)]
kdata = stock.get_kdata(Query(Datetime(202606100000), Datetime(202607090000), Query.DAY))
macd = MACD(CLOSE, 12, 26, 9)(kdata)
dif = macd.get_result(0)
dea = macd.get_result(1)
bar = macd.get_result(2)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
常用原生指标包括:
| 类别 | 函数 |
|---|---|
| 行情源指标 | KDATA、OPEN、HIGH、LOW、CLOSE、AMO、VOL |
| 均线和趋势 | MA、EMA、SMA、WMA、MACD |
| 交叉和引用 | CROSS、LONGCROSS、REF、BARSLAST、BARSCOUNT |
| 区间统计 | HHV、LLV、COUNT、SUM |
| 基础运算 | ABS、MAX、MIN、IF |
说明:
- 这些函数底层复用原生
Indicator,不是 Python 层重新计算。 CLOSE这类源指标既支持CLOSE(),也支持作为参数直接写入MA(CLOSE, 5)。
注意
下面这段代码获取k线数据get_kdata获取的是所有当前股票最近的200根k,不管当前运行到哪个bar都是你运行这个策略真实时间的最近N根k。
def init(context):
context.stock = "000001.SZ"
set_benchmark("000300.SH")
def handle_bar(context, bar_dict):
s = sm[context.stock]
k = s.get_kdata(Query(-200))
1
2
3
4
5
6
7
2
3
4
5
6
7
Query 参数与枚举速查:
Query(start=0, end=None, ktype=Query.DAY, recover_type=Query.NO_RECOVER)
1
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
start | int 或 Datetime | 0 | 起始索引或起始日期。Query(-200) 表示最近 200 根 K 线;Query(Datetime(...), Datetime(...)) 表示按日期区间取数。 |
end | int、Datetime 或 None | None | 结束索引或结束日期;应与 start 同类型。省略时按 start 的查询方式使用默认结束点。 |
ktype | Query 周期枚举 | Query.DAY | K 线周期。 |
常用写法:
| 写法 | 含义 |
|---|---|
Query(-200) | 最近 200 根K线 |
Query(-200, ktype=Query.DAY) | 最近 200 根日线 |
Query(-200, ktype=Query.MIN5) | 最近 200 根 5 分钟线 |
Query(Datetime(202607010000), Datetime(202607200000), Query.DAY) | 取 2026-07-01 到 2026-07-20 的日线区间。 |
K 线周期枚举:
| 枚举 | 说明 |
|---|---|
Query.DAY | 日线 |
Query.WEEK | 周线 |
Query.MONTH | 月线 |
Query.QUARTER | 季线 |
Query.HALFYEAR | 半年线 |
Query.YEAR | 年线 |
Query.MIN | 1 分钟线 |
Query.MIN5 | 5 分钟线 |
Query.MIN15 | 15 分钟线 |
Query.MIN30 | 30 分钟线 |
Query.MIN60 | 60 分钟线 |
Query.HOUR2 | 2 小时线 |
Query.HOUR4 | 4 小时线 |
Query.HOUR6 | 6 小时线 |
Query.HOUR12 | 12 小时线 |
滚动计算ma金叉死叉策略
def init(context):
set_benchmark("000300.SH")
context.stock = "000001.SZ"
def handle_bar(context, bar_dict):
hist = attribute_history(context.stock, 25, "1d", ["close"])
if len(hist) < 25:
return
ma5 = hist["close"].rolling(5).mean()
ma20 = hist["close"].rolling(20).mean()
# 金叉
buy = ma5.iloc[-2] <= ma20.iloc[-2] and ma5.iloc[-1] > ma20.iloc[-1]
# 死叉
sell = ma5.iloc[-2] >= ma20.iloc[-2] and ma5.iloc[-1] < ma20.iloc[-1]
if buy:
order_target_percent(context.stock, 1.0)
elif sell:
order_target_percent(context.stock, 0)
def after_trading(context):
log.info("盘后运行结束")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ma原生指标回测策略
def init(context):
context.stock = "000001.SZ"
set_benchmark("000300.SH")
def handle_bar(context, bar_dict):
sym = context.stock
# 必须先取 kdata
kdata = sm[context.stock].get_kdata(Query(Datetime(202001010000), Datetime(202612310000), Query.DAY))
if len(kdata) < 30:
return
# 第1步:定义指标
ma5_ind = MA(CLOSE, 5)
ma20_ind = MA(CLOSE, 20)
# 第2步:用 kdata 计算
ma5 = ma5_ind(kdata)
ma20 = ma20_ind(kdata)
# 金叉
buy = CROSS(ma5_ind, ma20_ind)(kdata)
# 死叉
sell = CROSS(ma20_ind, ma5_ind)(kdata)
dt = get_datetime()
current_date = str(dt)[:10]
i = -1
for j in range(len(kdata)):
kdate = str(kdata[j].datetime)[:10]
if kdate <= current_date:
i = j
if i < 1:
return
buy_value = int(float(buy[i]) > 0)
sell_value = int(float(sell[i]) > 0)
pos = get_position(sym)
amount = pos.amount if pos else 0
if amount <= 0 and buy_value > 0:
order_target_percent(sym, 0.8)
log.info("MA金叉,买入满仓")
elif amount > 0 and sell_value > 0:
order_target_percent(sym, 0)
log.info("MA死叉,卖出清仓")
record(
buy=buy_value,
sell=sell_value,
)
def after_trading(context):
log.info("盘后运行结束")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
macd指标回测策略
def init(context):
context.stock = "000001.SZ"
set_benchmark("000300.SH")
set_execution("close")
def handle_bar(context, bar_dict):
sym = context.stock
dt = get_datetime()
stock = sm[to_internal_code(sym)]
kdata = stock.get_kdata(
Query(
Datetime(202001010000),
Datetime(202612310000),
Query.DAY
)
)
if len(kdata) < 35:
return
dif_ind = EMA(CLOSE, 12) - EMA(CLOSE, 26)
dea_ind = EMA(dif_ind, 9)
macd_ind = 2 * (dif_ind - dea_ind)
dif = dif_ind(kdata)
dea = dea_ind(kdata)
macd = macd_ind(kdata)
buy = CROSS(dif_ind, dea_ind)(kdata)
sell = CROSS(dea_ind, dif_ind)(kdata)
dt = get_datetime()
current_date = str(dt)[:10]
i = -1
for j in range(len(kdata)):
kdate = str(kdata[j].datetime)[:10]
if kdate <= current_date:
i = j
if i < 1:
return
dif_value = float(dif[i])
dea_value = float(dea[i])
macd_value = float(macd[i])
buy_value = int(float(buy[i]) > 0)
sell_value = int(float(sell[i]) > 0)
log.info(
"当前日期=%s 信号日期=%s kdata_last=%s dif=%.4f dea=%.4f buy=%d sell=%d",
dt,
kdata[i].datetime,
kdata[-1].datetime,
dif_value,
dea_value,
buy_value,
sell_value,
)
pos = get_position(sym)
amount = pos.amount if pos else 0
if amount <= 0 and buy_value > 0:
order_target_percent(sym, 0.8)
log.info("MACD金叉,买入满仓")
elif amount > 0 and sell_value > 0:
order_target_percent(sym, 0)
log.info("MACD死叉,卖出清仓")
record(
dif=dif_value,
dea=dea_value,
macd=macd_value,
buy=buy_value,
sell=sell_value,
)
def after_trading(context):
log.info("盘后运行结束")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
原生指标ma金叉死叉版按当前bar取k,这用起来才更像指标原生写法,取k线技巧
def init(context):
context.stock = "000001.SZ"
set_benchmark("000300.SH")
def handle_bar(context, bar_dict):
sym = context.stock
# 必须先取 kdata
# kdata = sm[context.stock].get_kdata(Query(-200))
current_dt = get_datetime()
end_dt = Datetime(current_dt.year, current_dt.month, current_dt.day,
current_dt.hour, current_dt.minute, current_dt.second, 0, 0)
kdata = sm[context.stock].get_kdata(Query(Datetime(202001010000), end_dt, Query.DAY))
if len(kdata) < 30:
return
# 第1步:定义指标
ma5_ind = MA(CLOSE, 5)
ma20_ind = MA(CLOSE, 20)
# 第2步:用 kdata 计算
ma5 = ma5_ind(kdata)
ma20 = ma20_ind(kdata)
# 金叉
buy = CROSS(ma5_ind, ma20_ind)(kdata)
# 死叉
sell = CROSS(ma20_ind, ma5_ind)(kdata)
# 只判断当前bar
if buy[-1] > 0 :
order_target_percent(context.stock, 1.0)
elif sell[-1] > 0 :
order_target_percent(context.stock, 0)
def after_trading(context):
log.info("盘后运行结束")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
直接用cross构建金叉指标
def init(context):
context.stock = "000001.SZ"
set_benchmark("000300.SH")
def handle_bar(context, bar_dict):
sym = context.stock
# 必须先取 kdata
# kdata = sm[context.stock].get_kdata(Query(-200))
current_dt = get_datetime()
end_dt = Datetime(current_dt.year, current_dt.month, current_dt.day,
current_dt.hour, current_dt.minute, current_dt.second, 0, 0)
kdata = sm[context.stock].get_kdata(Query(Datetime(202001010000), end_dt, Query.DAY))
if len(kdata) < 30:
return
# # 第1步:定义指标
# ma5_ind = MA(CLOSE, 5)
# ma20_ind = MA(CLOSE, 20)
# # 第2步:用 kdata 计算
# ma5 = ma5_ind(kdata)
# ma20 = ma20_ind(kdata)
# 金叉
buy = CROSS(MA(CLOSE, 5), MA(CLOSE, 20))(kdata)
# 死叉
sell = CROSS( MA(CLOSE, 20), MA(CLOSE, 5))(kdata)
# 只判断当前bar
if buy[-1] > 0 :
order_target_percent(context.stock, 1.0)
elif sell[-1] > 0 :
order_target_percent(context.stock, 0)
def after_trading(context):
log.info("盘后运行结束")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40