pandaai-cli 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
template.py ADDED
@@ -0,0 +1,578 @@
1
+ """
2
+ 因子分析模板(从 factor_analysis_template.py 拷贝并参数化)
3
+
4
+ 分析链路:
5
+ CodeControl → FactorBuildProControl → FactorAnalysisControl → FactorAnalysisChartControl
6
+ (代码/公式) (因子构建) (因子分析) (结果展示)
7
+ → DataDownloadControl (数据下载)
8
+ """
9
+
10
+ import copy
11
+ import uuid
12
+ from datetime import datetime, timedelta
13
+ from typing import Literal
14
+
15
+ # ─── 原始模板(常量,不可变) ───
16
+
17
+ FACTOR_ANALYSIS_TEMPLATE = {
18
+ "format_version": "V1.0",
19
+ "name": "因子分析",
20
+ "description": "",
21
+ "owner": "",
22
+ "feature_tag": {
23
+ "factor": [{"node_id": "300e12f5-4814-44c2-9810-c95a4567283c", "node_title": "因子分析"}]
24
+ },
25
+ "last_run_id": None,
26
+ "category": "4",
27
+ "display_tag": ["1"],
28
+ "chat_status": 0,
29
+ "chat_info": {},
30
+ "publish_status": 0,
31
+ "subscription_id": None,
32
+ "checkpoint_content_hash": "a771c52773c36e0279687ff1340e6de0",
33
+ "litegraph": {
34
+ "id": "00000000-0000-0000-0000-000000000000",
35
+ "revision": 0,
36
+ "last_node_id": 5,
37
+ "last_link_id": 4,
38
+ "nodes": [
39
+ {
40
+ "id": 1,
41
+ "type": "CodeControl",
42
+ "pos": [-691.1473999023438, -219.1048583984375],
43
+ "size": [210, 63],
44
+ "flags": {
45
+ "uuid": "9434feb5-7745-41b1-a6bb-61148ce21777",
46
+ "plugin_source": "official",
47
+ "type": "",
48
+ },
49
+ "order": 1003,
50
+ "mode": 0,
51
+ "inputs": [
52
+ {
53
+ "name": "策略代码",
54
+ "type": "string",
55
+ "boundingRect": [-10010, -10010, 20, 20],
56
+ "pos": [10, 36],
57
+ "link": None,
58
+ "hide": True,
59
+ "fieldName": "code",
60
+ }
61
+ ],
62
+ "outputs": [
63
+ {
64
+ "name": "策略代码",
65
+ "type": "string",
66
+ "boundingRect": [-500.14739990234375, -215.1048583984375, 20, 20],
67
+ "links": [2],
68
+ "hide": False,
69
+ "fieldName": "code",
70
+ }
71
+ ],
72
+ "title": "Python代码输入",
73
+ "properties": {"title": "Python代码输入", "策略代码": ""},
74
+ "color": "#232",
75
+ "bgcolor": "#353",
76
+ "_fullTitle": "",
77
+ },
78
+ {
79
+ "id": 4,
80
+ "type": "FactorBuildProControl",
81
+ "pos": [-391.46734619140625, -218.9175567626953],
82
+ "size": [210, 150],
83
+ "flags": {
84
+ "uuid": "7735ed8d-80b0-4fd4-9fee-05f3aac16ca4",
85
+ "plugin_source": "official",
86
+ "type": "",
87
+ },
88
+ "order": 2003,
89
+ "mode": 0,
90
+ "inputs": [
91
+ {
92
+ "name": "开始时间",
93
+ "type": "string",
94
+ "widget": {"name": "开始时间"},
95
+ "boundingRect": [-10010, -10010, 15, 20],
96
+ "pos": [10, 36],
97
+ "link": None,
98
+ "hide": True,
99
+ "fieldName": "start_date",
100
+ },
101
+ {
102
+ "name": "结束时间",
103
+ "type": "string",
104
+ "widget": {"name": "结束时间"},
105
+ "boundingRect": [-10010, -10010, 15, 20],
106
+ "pos": [10, 65],
107
+ "link": None,
108
+ "hide": True,
109
+ "fieldName": "end_date",
110
+ },
111
+ {
112
+ "name": "因子代码",
113
+ "type": "string",
114
+ "widget": None,
115
+ "boundingRect": [-391.46734619140625, -214.9175567626953, 20, 20],
116
+ "link": 2,
117
+ "hide": False,
118
+ "fieldName": "code",
119
+ },
120
+ {
121
+ "name": "因子类型",
122
+ "type": "string",
123
+ "widget": {"name": "因子类型"},
124
+ "boundingRect": [-10010, -10010, 15, 20],
125
+ "pos": [10, 94],
126
+ "link": None,
127
+ "hide": True,
128
+ "fieldName": "market",
129
+ },
130
+ {
131
+ "name": "编码方式",
132
+ "type": "string",
133
+ "widget": {"name": "编码方式"},
134
+ "boundingRect": [-10010, -10010, 15, 20],
135
+ "pos": [10, 123],
136
+ "link": None,
137
+ "hide": True,
138
+ "fieldName": "type",
139
+ },
140
+ ],
141
+ "outputs": [
142
+ {
143
+ "name": "因子值",
144
+ "type": "dataframe",
145
+ "boundingRect": [-200.46734619140625, -214.9175567626953, 20, 20],
146
+ "links": [3, 4],
147
+ "hide": False,
148
+ "fieldName": "factor",
149
+ }
150
+ ],
151
+ "title": "线性因子构建",
152
+ "properties": {
153
+ "title": "线性因子构建",
154
+ "开始时间": "20250101",
155
+ "结束时间": "20250301",
156
+ "因子代码": "",
157
+ "因子类型": "股票",
158
+ "编码方式": "Python",
159
+ },
160
+ "color": "#223",
161
+ "bgcolor": "#335",
162
+ "_fullTitle": "",
163
+ },
164
+ {
165
+ "id": 2,
166
+ "type": "FactorAnalysisControl",
167
+ "pos": [-83.86952209472656, -218.59759521484375],
168
+ "size": [210, 150],
169
+ "flags": {
170
+ "uuid": "300e12f5-4814-44c2-9810-c95a4567283c",
171
+ "plugin_source": "official",
172
+ "type": "",
173
+ },
174
+ "order": 3003,
175
+ "mode": 0,
176
+ "inputs": [
177
+ {
178
+ "name": "因子值",
179
+ "type": 0,
180
+ "widget": None,
181
+ "boundingRect": [-83.86952209472656, -214.59759521484375, 20, 20],
182
+ "link": 3,
183
+ "hide": False,
184
+ "fieldName": "df_factor",
185
+ },
186
+ {
187
+ "name": "调仓周期",
188
+ "type": "string",
189
+ "widget": {"name": "调仓周期"},
190
+ "boundingRect": [-10010, -10010, 15, 20],
191
+ "pos": [10, 36],
192
+ "link": None,
193
+ "hide": True,
194
+ "fieldName": "adjustment_cycle",
195
+ },
196
+ {
197
+ "name": "分组数量",
198
+ "type": "string",
199
+ "widget": {"name": "分组数量"},
200
+ "boundingRect": [-10010, -10010, 15, 20],
201
+ "pos": [10, 65],
202
+ "link": None,
203
+ "hide": True,
204
+ "fieldName": "group_number",
205
+ },
206
+ {
207
+ "name": "因子方向(0:负向,1:正向)",
208
+ "type": "string",
209
+ "widget": {"name": "因子方向(0:负向,1:正向)"},
210
+ "boundingRect": [-10010, -10010, 15, 20],
211
+ "pos": [10, 94],
212
+ "link": None,
213
+ "hide": True,
214
+ "fieldName": "factor_direction",
215
+ },
216
+ {
217
+ "name": "股票池",
218
+ "type": "string",
219
+ "widget": {"name": "股票池"},
220
+ "boundingRect": [-83.86952209472656, -105.59759521484375, 15, 20],
221
+ "pos": [10, 123],
222
+ "link": None,
223
+ "hide": False,
224
+ "fieldName": "stock_pool",
225
+ },
226
+ ],
227
+ "outputs": [
228
+ {
229
+ "name": "分析结果",
230
+ "type": "string",
231
+ "boundingRect": [107.13047790527344, -214.59759521484375, 20, 20],
232
+ "links": [1],
233
+ "hide": False,
234
+ "fieldName": "task_id",
235
+ }
236
+ ],
237
+ "title": "因子分析",
238
+ "properties": {
239
+ "title": "因子分析",
240
+ "调仓周期": "1",
241
+ "分组数量": "5",
242
+ "因子方向(0:负向,1:正向)": "1",
243
+ "股票池": "沪深全A",
244
+ },
245
+ "color": "#223",
246
+ "bgcolor": "#335",
247
+ "_fullTitle": "",
248
+ },
249
+ {
250
+ "id": 3,
251
+ "type": "FactorAnalysisChartControl",
252
+ "pos": [217.6486053466797, -218.7091522216797],
253
+ "size": [210, 63],
254
+ "flags": {
255
+ "uuid": "25c44d05-55f2-450a-a696-3fd21f080754",
256
+ "plugin_source": "official",
257
+ "type": "",
258
+ },
259
+ "order": 4003,
260
+ "mode": 0,
261
+ "inputs": [
262
+ {
263
+ "name": "分析结果",
264
+ "type": "string",
265
+ "widget": None,
266
+ "boundingRect": [217.6486053466797, -214.7091522216797, 20, 20],
267
+ "link": 1,
268
+ "hide": False,
269
+ "fieldName": "task_id",
270
+ }
271
+ ],
272
+ "outputs": [
273
+ {
274
+ "name": "结果JSON",
275
+ "type": "string",
276
+ "boundingRect": [408.6486053466797, -214.7091522216797, 20, 20],
277
+ "links": None,
278
+ "hide": False,
279
+ "fieldName": "result_json",
280
+ }
281
+ ],
282
+ "title": "因子分析结果",
283
+ "properties": {"title": "因子分析结果", "分析结果": "error"},
284
+ "color": "#323",
285
+ "bgcolor": "#535",
286
+ "_fullTitle": "",
287
+ },
288
+ {
289
+ "id": 5,
290
+ "type": "DataDownloadControl",
291
+ "pos": [-83.86952209472656, 49.40240478515625],
292
+ "size": [210, 63],
293
+ "flags": {
294
+ "uuid": "b8d8661c-5704-4b1d-9c96-ffe1c5da8259",
295
+ "plugin_source": "official",
296
+ "type": "",
297
+ },
298
+ "order": 5003,
299
+ "mode": 0,
300
+ "inputs": [
301
+ {
302
+ "name": "因子值",
303
+ "type": 0,
304
+ "widget": None,
305
+ "boundingRect": [-83.86952209472656, 53.40240478515625, 20, 20],
306
+ "link": 4,
307
+ "hide": False,
308
+ "fieldName": "df_factor",
309
+ }
310
+ ],
311
+ "outputs": [
312
+ {
313
+ "name": "点击下载",
314
+ "type": "string",
315
+ "boundingRect": [107.13047790527344, 53.40240478515625, 20, 20],
316
+ "links": None,
317
+ "hide": False,
318
+ "fieldName": "url",
319
+ }
320
+ ],
321
+ "title": "数据下载",
322
+ "properties": {"title": "数据下载"},
323
+ "color": "#223",
324
+ "bgcolor": "#335",
325
+ "_fullTitle": "",
326
+ },
327
+ ],
328
+ "links": [
329
+ [1, 2, 0, 3, 0, "string"],
330
+ [2, 1, 0, 4, 2, "string"],
331
+ [3, 4, 0, 2, 0, "dataframe"],
332
+ [4, 4, 0, 5, 0, "dataframe"],
333
+ ],
334
+ "groups": [],
335
+ "config": {},
336
+ "extra": {"ds": {"scale": 0.8807086125833189, "offset": [208.58126780560525, 553.654858823258]}},
337
+ "version": 0.4,
338
+ },
339
+ "nodes": [
340
+ {
341
+ "uuid": "9434feb5-7745-41b1-a6bb-61148ce21777",
342
+ "name": "CodeControl",
343
+ "title": "Python代码输入",
344
+ "type": "CodeControl",
345
+ "litegraph_id": 1,
346
+ "positionX": -691.1473999023438,
347
+ "positionY": -219.1048583984375,
348
+ "width": 210.0,
349
+ "height": 63.0,
350
+ "static_input_data": {"code": ""},
351
+ "output_db_id": None,
352
+ "custom_code": None,
353
+ "custom_code_modified_at": None,
354
+ "original_node_name": None,
355
+ },
356
+ {
357
+ "uuid": "7735ed8d-80b0-4fd4-9fee-05f3aac16ca4",
358
+ "name": "FactorBuildProControl",
359
+ "title": "线性因子构建",
360
+ "type": "FactorBuildProControl",
361
+ "litegraph_id": 4,
362
+ "positionX": -391.46734619140625,
363
+ "positionY": -218.9175567626953,
364
+ "width": 210.0,
365
+ "height": 150.0,
366
+ "static_input_data": {
367
+ "start_date": "20250101",
368
+ "end_date": "20250301",
369
+ "code": "",
370
+ "market": "股票",
371
+ "type": "Python",
372
+ },
373
+ "output_db_id": None,
374
+ "custom_code": None,
375
+ "custom_code_modified_at": None,
376
+ "original_node_name": None,
377
+ },
378
+ {
379
+ "uuid": "300e12f5-4814-44c2-9810-c95a4567283c",
380
+ "name": "FactorAnalysisControl",
381
+ "title": "因子分析",
382
+ "type": "FactorAnalysisControl",
383
+ "litegraph_id": 2,
384
+ "positionX": -83.86952209472656,
385
+ "positionY": -218.59759521484375,
386
+ "width": 210.0,
387
+ "height": 150.0,
388
+ "static_input_data": {
389
+ "adjustment_cycle": "1",
390
+ "group_number": "5",
391
+ "factor_direction": "1",
392
+ "stock_pool": "沪深全A",
393
+ },
394
+ "output_db_id": None,
395
+ "custom_code": None,
396
+ "custom_code_modified_at": None,
397
+ "original_node_name": None,
398
+ },
399
+ {
400
+ "uuid": "25c44d05-55f2-450a-a696-3fd21f080754",
401
+ "name": "FactorAnalysisChartControl",
402
+ "title": "因子分析结果",
403
+ "type": "FactorAnalysisChartControl",
404
+ "litegraph_id": 3,
405
+ "positionX": 217.6486053466797,
406
+ "positionY": -218.7091522216797,
407
+ "width": 210.0,
408
+ "height": 63.0,
409
+ "static_input_data": {"task_id": "error"},
410
+ "output_db_id": None,
411
+ "custom_code": None,
412
+ "custom_code_modified_at": None,
413
+ "original_node_name": None,
414
+ },
415
+ {
416
+ "uuid": "b8d8661c-5704-4b1d-9c96-ffe1c5da8259",
417
+ "name": "DataDownloadControl",
418
+ "title": "数据下载",
419
+ "type": "DataDownloadControl",
420
+ "litegraph_id": 5,
421
+ "positionX": -83.86952209472656,
422
+ "positionY": 49.40240478515625,
423
+ "width": 210.0,
424
+ "height": 63.0,
425
+ "static_input_data": {},
426
+ "output_db_id": None,
427
+ "custom_code": None,
428
+ "custom_code_modified_at": None,
429
+ "original_node_name": None,
430
+ },
431
+ ],
432
+ "links": [
433
+ {
434
+ "uuid": "5641f65c-8d92-4cb4-9810-08b5b688387e",
435
+ "litegraph_id": 1,
436
+ "status": 1,
437
+ "previous_node_uuid": "300e12f5-4814-44c2-9810-c95a4567283c",
438
+ "input_field_name": "task_id",
439
+ "next_node_uuid": "25c44d05-55f2-450a-a696-3fd21f080754",
440
+ "output_field_name": "task_id",
441
+ },
442
+ {
443
+ "uuid": "abca1145-d244-438e-a3eb-360592c2c33a",
444
+ "litegraph_id": 2,
445
+ "status": 1,
446
+ "previous_node_uuid": "9434feb5-7745-41b1-a6bb-61148ce21777",
447
+ "input_field_name": "code",
448
+ "next_node_uuid": "7735ed8d-80b0-4fd4-9fee-05f3aac16ca4",
449
+ "output_field_name": "code",
450
+ },
451
+ {
452
+ "uuid": "2b093b36-1ff3-4de9-9b44-c449346628cd",
453
+ "litegraph_id": 3,
454
+ "status": 1,
455
+ "previous_node_uuid": "7735ed8d-80b0-4fd4-9fee-05f3aac16ca4",
456
+ "input_field_name": "df_factor",
457
+ "next_node_uuid": "300e12f5-4814-44c2-9810-c95a4567283c",
458
+ "output_field_name": "factor",
459
+ },
460
+ {
461
+ "uuid": "3163578a-acfe-4456-be9a-4d7963db423d",
462
+ "litegraph_id": 4,
463
+ "status": 1,
464
+ "previous_node_uuid": "7735ed8d-80b0-4fd4-9fee-05f3aac16ca4",
465
+ "input_field_name": "df_factor",
466
+ "next_node_uuid": "b8d8661c-5704-4b1d-9c96-ffe1c5da8259",
467
+ "output_field_name": "factor",
468
+ },
469
+ ],
470
+ }
471
+
472
+ # 节点 UUID 常量
473
+ CODE_CONTROL_UUID = "9434feb5-7745-41b1-a6bb-61148ce21777"
474
+ FACTOR_BUILD_PRO_UUID = "7735ed8d-80b0-4fd4-9fee-05f3aac16ca4"
475
+ FACTOR_ANALYSIS_UUID = "300e12f5-4814-44c2-9810-c95a4567283c"
476
+
477
+
478
+ def _default_date_range():
479
+ """默认日期范围:昨天往前60天 ~ 昨天"""
480
+ today = datetime.now().date()
481
+ yesterday = today - timedelta(days=1)
482
+ start = yesterday - timedelta(days=60)
483
+ return start.strftime("%Y%m%d"), yesterday.strftime("%Y%m%d")
484
+
485
+
486
+ def build_factor_json(
487
+ content: str,
488
+ mode: Literal["code", "formula"],
489
+ name: str = "AI生成因子",
490
+ start_date: str = None,
491
+ end_date: str = None,
492
+ market: str = "股票",
493
+ adjustment_cycle: str = "1",
494
+ factor_direction: str = "1",
495
+ ) -> dict:
496
+ """
497
+ 构建因子分析 JSON(可用于 SaveWorkflowRequest)。
498
+
499
+ 分组数量固定为 10,股票池固定为沪深全A,不可修改。
500
+
501
+ Args:
502
+ content: Python 代码 或 因子公式字符串
503
+ mode: "code" = Python 代码; "formula" = 因子公式
504
+ name: 因子分析名称
505
+ start_date: 因子构建开始日期 YYYYMMDD,默认昨天-60天
506
+ end_date: 因子构建结束日期 YYYYMMDD,默认昨天
507
+ market: 市场,固定"股票"
508
+ adjustment_cycle: 调仓周期,默认 1,范围 1-10
509
+ factor_direction: 因子方向 0=负向 1=正向,默认 1
510
+
511
+ Returns:
512
+ 完整因子分析 dict
513
+ """
514
+ factor = copy.deepcopy(FACTOR_ANALYSIS_TEMPLATE)
515
+
516
+ if start_date is None or end_date is None:
517
+ sd, ed = _default_date_range()
518
+ start_date = start_date or sd
519
+ end_date = end_date or ed
520
+
521
+ factor["name"] = name
522
+
523
+ # 生成新的链路 UUID(避免跟已有模板冲突)
524
+ # 替换 nodes 中的 UUID
525
+ code_uuid = str(uuid.uuid4())
526
+ factor_uuid = str(uuid.uuid4())
527
+
528
+ # ── 替换 CodeControl 节点 ──
529
+ for node in factor["nodes"]:
530
+ if node["uuid"] == CODE_CONTROL_UUID:
531
+ node["uuid"] = code_uuid
532
+ if mode == "code":
533
+ node["static_input_data"]["code"] = content
534
+ elif mode == "formula":
535
+ # 公式模式:CodeControl 存公式文本
536
+ node["static_input_data"]["code"] = content
537
+
538
+ # ── 替换 FactorBuildPro 节点 ──
539
+ for node in factor["nodes"]:
540
+ if node["uuid"] == FACTOR_BUILD_PRO_UUID:
541
+ node["uuid"] = factor_uuid
542
+ node["static_input_data"]["start_date"] = start_date
543
+ node["static_input_data"]["end_date"] = end_date
544
+ node["static_input_data"]["market"] = market
545
+ node["static_input_data"]["type"] = "Python" if mode == "code" else "公式"
546
+
547
+ # ── 设置 FactorAnalysis 节点参数 ──
548
+ for node in factor["nodes"]:
549
+ if node["uuid"] == FACTOR_ANALYSIS_UUID:
550
+ node["static_input_data"]["adjustment_cycle"] = adjustment_cycle
551
+ node["static_input_data"]["group_number"] = "10"
552
+ node["static_input_data"]["factor_direction"] = factor_direction
553
+ node["static_input_data"]["stock_pool"] = "沪深全A"
554
+
555
+ # ── 替换 links 中的 UUID 引用 ──
556
+ for link in factor["links"]:
557
+ if link["previous_node_uuid"] == CODE_CONTROL_UUID:
558
+ link["previous_node_uuid"] = code_uuid
559
+ if link["previous_node_uuid"] == FACTOR_BUILD_PRO_UUID:
560
+ link["previous_node_uuid"] = factor_uuid
561
+ if link["next_node_uuid"] == FACTOR_BUILD_PRO_UUID:
562
+ link["next_node_uuid"] = factor_uuid
563
+
564
+ # ── 更新 feature_tag ──
565
+ if "feature_tag" in factor and "factor" in factor["feature_tag"]:
566
+ for ft in factor["feature_tag"]["factor"]:
567
+ if ft["node_id"] == "300e12f5-4814-44c2-9810-c95a4567283c":
568
+ # 因子分析节点的 UUID 保持不变(不改它),但可以不改
569
+ pass
570
+
571
+ # 移除 SaveWorkflowRequest 不接受的多余字段
572
+ factor.pop("owner", None)
573
+ factor.pop("feature_tag", None)
574
+ factor.pop("last_run_id", None)
575
+ factor.pop("publish_status", None)
576
+ factor.pop("subscription_id", None)
577
+
578
+ return factor