st-comp 0.0.172 → 0.0.174

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.
Files changed (82) hide show
  1. package/es/ChartLayout.js +3 -3
  2. package/es/Dialog.js +14 -14
  3. package/es/FactorWarning.cjs +1 -1
  4. package/es/FactorWarning.js +337 -817
  5. package/es/Kline.js +16 -16
  6. package/es/KlineBasic.js +26 -26
  7. package/es/KlineConfig.cjs +1 -1
  8. package/es/KlineConfig.js +41 -40
  9. package/es/KlineNew.js +14 -14
  10. package/es/KlinePlus.cjs +3 -3
  11. package/es/KlinePlus.js +458 -465
  12. package/es/Pagination.js +19 -19
  13. package/es/PasswordPrompt.js +3 -3
  14. package/es/Table.js +21 -21
  15. package/es/User.js +39 -39
  16. package/es/VarSelectDialog.cjs +2 -2
  17. package/es/VarSelectDialog.js +146 -144
  18. package/es/VarietySearch.cjs +16 -1
  19. package/es/VarietySearch.js +4283 -1144
  20. package/es/VirtualTable.js +494 -494
  21. package/es/{_initCloneObject-a9305c1e.js → _initCloneObject-da90eef0.js} +3 -3
  22. package/es/{base-4bcd2756.js → base-d9284bf0.js} +23 -23
  23. package/es/{castArray-681d750b.js → castArray-b0ab0165.js} +1 -1
  24. package/es/{config-provider-93846ae3.js → config-provider-f0151e9f.js} +10 -10
  25. package/es/{debounce-51046b06.js → debounce-3cec4646.js} +1 -1
  26. package/es/{dropdown-65e74de8.js → dropdown-82b80e8b.js} +6 -6
  27. package/es/{el-button-d39472d3.js → el-button-34665425.js} +9 -9
  28. package/es/{el-dialog-f45ec2a1.js → el-dialog-a412484e.js} +17 -17
  29. package/es/{el-divider-7cf13678.js → el-divider-fd2b4e2e.js} +4 -4
  30. package/es/{el-empty-64b2ea8a.js → el-empty-412fc297.js} +2 -2
  31. package/es/{el-form-item-b31e7a98.js → el-form-item-668ba024.js} +65 -65
  32. package/es/{el-input-42315ac4.js → el-input-22e66e37.js} +22 -22
  33. package/es/{el-input-number-ebd64e22.js → el-input-number-481e21c5.js} +26 -26
  34. package/es/{el-loading-5d29f26d.js → el-loading-d4e403ab.js} +5 -5
  35. package/es/{el-menu-item-d62e0a3f.js → el-menu-item-404c10e5.js} +8 -8
  36. package/es/el-message-box-41f39f6d.js +558 -0
  37. package/es/el-message-box-6694f827.cjs +1 -0
  38. package/es/{el-message-bd1d2c82.js → el-message-ef506caa.js} +24 -24
  39. package/es/{el-overlay-690b50aa.js → el-overlay-4a9fa4e1.js} +30 -30
  40. package/es/{el-popconfirm-88bbd066.js → el-popconfirm-7b9183aa.js} +6 -6
  41. package/es/{el-popper-85365d5b.js → el-popper-e73466eb.js} +5 -5
  42. package/es/{el-scrollbar-bcf29780.js → el-scrollbar-45318df0.js} +8 -8
  43. package/es/el-segmented-3ba6d664.cjs +1 -0
  44. package/es/el-segmented-41820018.js +135 -0
  45. package/es/{el-select-d3bce4d1.js → el-select-d7a00294.js} +13 -13
  46. package/es/{el-table-column-9691b26d.js → el-table-column-a2d0c635.js} +122 -122
  47. package/es/{el-tag-6036f51c.js → el-tag-7f391090.js} +32 -32
  48. package/es/{index-d3c37134.js → index-1c41bd56.js} +3 -3
  49. package/es/index-3120be08.js +14 -0
  50. package/es/{index-fbe85773.js → index-85a32a00.js} +15 -15
  51. package/es/{index-21fb27eb.js → index-94f38460.js} +19 -19
  52. package/es/{index-ef7c4392.js → index-a8e9ec0f.js} +23 -23
  53. package/es/{index-cb8157f2.js → index-d577b81b.js} +2 -2
  54. package/es/{index-8ee89b40.js → index-d99fdc6d.js} +8 -8
  55. package/es/{index-3425f2f0.js → index-ee1cebbc.js} +5 -5
  56. package/es/{raf-36faa519.js → raf-bfbf42e4.js} +1 -1
  57. package/es/{scroll-0277d145.js → scroll-e3cb691f.js} +2 -2
  58. package/es/style.css +1 -1
  59. package/es/{use-form-common-props-54c31983.js → use-form-common-props-cc347a83.js} +36 -36
  60. package/es/{use-global-config-946f61a4.js → use-global-config-c7f0a7e3.js} +3 -3
  61. package/es/validator-10fa54fe.js +5 -0
  62. package/es/validator-af488a9a.cjs +1 -0
  63. package/es/{vnode-dfc92f20.js → vnode-6be33bb1.js} +1 -1
  64. package/es/{zh-cn-5066f5e9.js → zh-cn-d883afa8.js} +2 -2
  65. package/lib/bundle.js +1 -1
  66. package/lib/bundle.umd.cjs +234 -219
  67. package/lib/{index-d9f6d2bc.js → index-c5c93747.js} +32971 -29838
  68. package/lib/{python-e8bc0c16.js → python-1b054f75.js} +1 -1
  69. package/lib/style.css +1 -1
  70. package/package.json +2 -1
  71. package/packages/KlinePlus/index.vue +1 -2
  72. package/packages/KlinePlus/utils.js +22 -49
  73. package/packages/VarSelectDialog/index.vue +3 -1
  74. package/packages/VarietySearch/components/FactorScreen/FactorDescription.vue +54 -20
  75. package/packages/VarietySearch/components/FactorScreen/index.vue +79 -54
  76. package/src/pages/KlinePlus/index.vue +20 -4
  77. package/src/pages/KlinePlus/tradeLogMock.js +1927 -0
  78. package/es/el-checkbox-group-020b49f5.cjs +0 -1
  79. package/es/el-checkbox-group-779f353a.js +0 -67
  80. package/es/el-segmented-84707138.js +0 -136
  81. package/es/el-segmented-bccd9f2a.cjs +0 -1
  82. package/es/index-c45ac024.js +0 -14
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "st-comp",
3
3
  "public": true,
4
- "version": "0.0.172",
4
+ "version": "0.0.174",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
@@ -19,6 +19,7 @@
19
19
  "echarts": "^5.4.3",
20
20
  "element-plus": "^2.9.4",
21
21
  "interactjs": "^1.10.27",
22
+ "markdown-it": "^14.1.0",
22
23
  "monaco-editor": "0.47.0",
23
24
  "pinia": "^2.1.6",
24
25
  "st-func": "^0.0.59",
@@ -12,7 +12,6 @@ import {
12
12
  handleMarkPointTradeLog,
13
13
  handleNetPositionLine,
14
14
  handleTradeIncomeRateLine,
15
- handleMarkPointOffset,
16
15
  normalizeToKlineTimeByMatch,
17
16
  } from "./utils.js";
18
17
  import Tips from "./components/Tips.vue";
@@ -513,7 +512,7 @@ const draw = (params = { startValue: 0, endValue: 0 }) => {
513
512
  {
514
513
  type: "candlestick",
515
514
  data,
516
- markPoint: { data: handleMarkPointOffset([...tradePointData]) },
515
+ markPoint: { data: [...tradePointData] },
517
516
  markLine: { data: [...tradeLineData] },
518
517
  itemStyle: {
519
518
  color: "transparent",
@@ -489,28 +489,6 @@ export const normalizeToKlineTimeByMatch = (klineTimeArray, timeRange, cycle) =>
489
489
  return [klineStart, klineEnd];
490
490
  };
491
491
 
492
- // 统一处理markPoint标记点的偏移量
493
- export const handleMarkPointOffset = (markPointData) => {
494
- const data = [];
495
- markPointData.reduce((result, item) => {
496
- // 1. 找到当前标记的位置
497
- const key = `${item.coord[0]}+${item.label.position}`;
498
- const baseOffset = item.label.position === "top" ? -16 : 16;
499
- // 2. 找到先前处于相同位置 [key] 标记的数量
500
- const sameNum = result.get(key);
501
- if (sameNum) {
502
- result.set(key, sameNum + 1);
503
- item.symbolOffset[1] = baseOffset * (sameNum + 1);
504
- } else {
505
- result.set(key, 1);
506
- item.symbolOffset[1] = item.label.position === "top" ? -7 : 7;
507
- }
508
- data.push(item);
509
- return result;
510
- }, new Map());
511
- return data;
512
- };
513
-
514
492
  // 生成图表配置所需数据: 成交点位, 成交点位连线
515
493
  export const handleMarkPointTradeLog = (tradeLog, cycle, sellBuy, klineTimeArray, klineDataArray) => {
516
494
  // 获取交易类型
@@ -588,8 +566,7 @@ export const handleMarkPointTradeLog = (tradeLog, cycle, sellBuy, klineTimeArray
588
566
  // 2.图标位置 [开在K线上方,平在K线下方]
589
567
  const position = ["开多", "开空"].includes(tradeType) ? "top" : "bottom";
590
568
  // 3.获取对应Y轴值
591
- const klineIndex = binarySearch(klineTimeAry, next.klineTime);
592
- const yAxisValue = position === "top" ? klineDataAry[klineIndex]?.[3] : klineDataAry[klineIndex]?.[2];
569
+ const yAxisValue = position === "top" ? (next.openPriceAll / next.amount)?.toFixed(2) : (next.closePriceAll / next.amount)?.toFixed(2);
593
570
  // 4.将Y轴值存到连线的数据中, 提供给连线配置使用
594
571
  baseLineData.forEach((item) => {
595
572
  const rangeTime = position === "top" ? item.range[0] : item.range[1];
@@ -624,50 +601,45 @@ export const handleMarkPointTradeLog = (tradeLog, cycle, sellBuy, klineTimeArray
624
601
  };
625
602
  // 交易点: 生成基础点位, 连线数据
626
603
  const handleTradePointLineData = (tradeLog, cycle, klineTimeArray) => {
627
- /**
628
- * @description: 点位, 连线
629
- * 1.生成点位, 连线基础数据
630
- * 2.点位处理: 合并同一根K线上的数据, 整体按照时间排序
631
- * 3.连线处理: 过滤相同范围的连线
632
- */
604
+ // 1. 生成基础数据 { 点位数据, 连线数据 }
633
605
  const { basePointData, baseLineData } = tradeLog.reduce(
634
606
  (result, item) => {
635
- // 开仓点位的数据
607
+ // 开仓点
636
608
  const startPoint = {
637
- pointTime: item.openTime, // 交易点位的真实时间
638
- klineTime: normalizeToKlineTime(klineTimeArray, item.openTime, cycle), // 交易点位的K线时间
639
-
609
+ pointTime: item.openTime, // 交易时间
640
610
  tradeAction: "开", // 交易行为
641
611
  tradeDirection: item.tradeDirection ? "空" : "多", // 交易方向 1:空, 0:多
642
612
  tradeType: `开${item.tradeDirection ? "空" : "多"}`,
643
-
644
613
  part: null, // 份数,
645
614
  amount: item.tradeVolume, // 手数
646
615
  profitAndLoss: item.profitAndLoss, // 盈亏
647
- openPriceAll: item.openPrice * item.tradeVolume, // 开仓价格
648
- closePriceAll: item.closePrice * item.tradeVolume, // 平仓价格
616
+ openPriceAll: item.openPrice * item.tradeVolume, // 开仓总价
617
+ closePriceAll: item.closePrice * item.tradeVolume, // 平仓总价
618
+
619
+ klineTime: normalizeToKlineTime(klineTimeArray, item.openTime, cycle), // K线时间
649
620
  };
650
- // 平仓点位的数据
621
+ // 平仓点
651
622
  const endPoint = {
652
- pointTime: item.closeTime, // 交易点位的真实时间
653
- klineTime: normalizeToKlineTime(klineTimeArray, item.closeTime, cycle), // 交易点位的K线时间
654
-
623
+ pointTime: item.closeTime, // 交易时间
655
624
  tradeAction: "平", // 交易行为
656
625
  tradeDirection: item.tradeDirection ? "空" : "多", // 交易方向 1:空, 0:多
657
626
  tradeType: `平${item.tradeDirection ? "空" : "多"}`,
658
-
659
627
  part: null, // 份数,
660
628
  amount: item.tradeVolume, // 手数
661
629
  profitAndLoss: item.profitAndLoss, // 盈亏
662
- openPriceAll: item.openPrice * item.tradeVolume, // 开仓价格
663
- closePriceAll: item.closePrice * item.tradeVolume, // 平仓价格
630
+ openPriceAll: item.openPrice * item.tradeVolume, // 开仓总价
631
+ closePriceAll: item.closePrice * item.tradeVolume, // 平仓总价
632
+
633
+ klineTime: normalizeToKlineTime(klineTimeArray, item.closeTime, cycle), // K线时间
664
634
  };
665
- result.basePointData.push(startPoint, endPoint);
666
- result.baseLineData.push({
635
+ // 连线
636
+ const line = {
667
637
  range: [startPoint.klineTime, endPoint.klineTime],
668
638
  rangeValue: [null, null],
669
639
  color: endPoint.profitAndLoss > 0 ? "#FF0000" : "#389e0d",
670
- });
640
+ };
641
+ result.basePointData.push(startPoint, endPoint);
642
+ result.baseLineData.push(line);
671
643
  return result;
672
644
  },
673
645
  {
@@ -675,12 +647,12 @@ export const handleMarkPointTradeLog = (tradeLog, cycle, sellBuy, klineTimeArray
675
647
  baseLineData: [], // 连线数据
676
648
  }
677
649
  );
650
+ // 2. 合并同一根K线上的数据, 整体按照时间排序
678
651
  const basePointDataMergeMap = basePointData.reduce((result, item) => {
679
652
  const newItem = JSON.parse(JSON.stringify(item));
653
+ // 判断这个节点是否已存在数据, 若存在说明重复, 进行数据合并
680
654
  const key = newItem.klineTime + newItem.tradeType;
681
- // 判断这个节点是否已存在数据
682
655
  if (result.has(key)) {
683
- // 已存在,说明节点重复,进行数据合并
684
656
  const oldItem = result.get(key);
685
657
  newItem.amount += oldItem.amount;
686
658
  newItem.part += oldItem.part;
@@ -692,6 +664,7 @@ export const handleMarkPointTradeLog = (tradeLog, cycle, sellBuy, klineTimeArray
692
664
  return result;
693
665
  }, new Map([]));
694
666
  const pointData = [...basePointDataMergeMap.values()].sort((a, b) => new Date(a.klineTime) - new Date(b.klineTime));
667
+ // 3. 过滤掉开始和结束都在一根K线上的连线
695
668
  const lineData = baseLineData.filter(({ range }) => range[0] !== range[1]);
696
669
  return { pointData, lineData };
697
670
  };
@@ -239,9 +239,11 @@ defineExpose({
239
239
  <!-- Tip示例 -->
240
240
  <el-tooltip
241
241
  effect="dark"
242
- :content="formatItem.tip"
243
242
  placement="top-start"
244
243
  >
244
+ <template #content>
245
+ <span style="white-space: pre-line">{{ formatItem.tip }}</span>
246
+ </template>
245
247
  <el-icon><InfoFilled /></el-icon>
246
248
  </el-tooltip>
247
249
  </div>
@@ -1,37 +1,71 @@
1
1
  <!-- 因子说明 -->
2
2
  <script setup name="FactorDescription">
3
+ import { ref, onMounted, inject } from "vue";
4
+ import MarkdownIt from "markdown-it";
5
+
6
+ const { env } = inject("stConfig"); // 组件库全局配置
7
+
8
+ // 选股变量说明文档
9
+ const md = new MarkdownIt();
10
+ const markdownContent = ref("");
11
+
3
12
  const props = defineProps({
13
+ factorType: { type: String, default: "模版" },
4
14
  data: { type: Array, default: [] },
5
15
  });
6
16
  const visible = defineModel("visible", { default: false });
17
+
18
+ onMounted(async () => {
19
+ let res = "";
20
+ if (env.MODE === "production") {
21
+ res = await fetch("//47.99.165.133/factor_select.md");
22
+ } else {
23
+ res = await fetch("//192.168.12.38/factor_select.md");
24
+ }
25
+ const markdownText = await res.text();
26
+ markdownContent.value = md.render(markdownText);
27
+ });
7
28
  </script>
8
29
 
9
30
  <template>
10
31
  <el-dialog
11
32
  v-model="visible"
12
- title="因子使用说明"
33
+ :title="factorType === '模版' ? '因子说明' : '脚本编写说明'"
13
34
  width="1000"
14
35
  align-center
36
+ draggable
37
+ overflow
38
+ append-to-body
15
39
  destroy-on-close
16
40
  >
17
- <el-table
18
- :data="data"
19
- border
20
- height="500"
21
- >
22
- <el-table-column
23
- prop="factorName"
24
- label="因子名称"
25
- width="200"
26
- />
27
- <el-table-column
28
- prop="factorDesc"
29
- label="因子说明"
30
- />
31
- <el-table-column
32
- prop="factorScoreDefine"
33
- label="分值定义"
34
- />
35
- </el-table>
41
+ <el-scrollbar height="500px">
42
+ <template v-if="factorType === '模版'">
43
+ <el-table
44
+ :data="data"
45
+ border
46
+ height="500"
47
+ >
48
+ <el-table-column
49
+ prop="factorName"
50
+ label="因子名称"
51
+ width="200"
52
+ />
53
+ <el-table-column
54
+ prop="factorDesc"
55
+ label="因子说明"
56
+ />
57
+ <el-table-column
58
+ prop="factorScoreDefine"
59
+ label="分值定义"
60
+ />
61
+ </el-table>
62
+ </template>
63
+ <template v-if="factorType === '脚本'">
64
+ <div
65
+ class="markdown-body"
66
+ v-html="markdownContent"
67
+ />
68
+ </template>
69
+ </el-scrollbar>
36
70
  </el-dialog>
37
71
  </template>
@@ -1,10 +1,10 @@
1
1
  <!-- 因子筛选组件 -->
2
2
  <script setup name="FactorScreen">
3
3
  import { nextTick, ref, watch } from "vue";
4
- import { Plus, CircleCloseFilled, InfoFilled } from "@element-plus/icons-vue";
4
+ import { Close, Plus, CircleCloseFilled, InfoFilled } from "@element-plus/icons-vue";
5
5
  import { handleVerifyScore, extractConditionDetails } from "./tools.js";
6
6
  import FactorDescription from "./FactorDescription.vue";
7
- import MonacoEditor from "../../../MonacoEditor/index.vue"
7
+ import MonacoEditor from "../../../MonacoEditor/index.vue";
8
8
 
9
9
  const props = defineProps({
10
10
  config: {
@@ -49,14 +49,18 @@ const dialogForm = ref({
49
49
  // SQL语句
50
50
  sqlValue: null,
51
51
  // 脚本语句
52
- factorSelectExpr: '',
52
+ factorSelectExpr: "",
53
53
  });
54
54
 
55
- watch(() => [factorType.value, visible.value], () => {
56
- if (factorType.value === '模版' || visible.value === false) {
57
- stVarSelectDialogRef.value.close();
58
- }
59
- }, { deep: true })
55
+ watch(
56
+ () => [factorType.value, visible.value],
57
+ () => {
58
+ if (factorType.value === "模版" || visible.value === false) {
59
+ stVarSelectDialogRef.value.close();
60
+ }
61
+ },
62
+ { deep: true }
63
+ );
60
64
 
61
65
  // 打开
62
66
  const handleOpenDialog = () => {
@@ -73,15 +77,15 @@ const handleOpenDialog = () => {
73
77
  // 解决初次访问样式错乱问题
74
78
  nextTick(() => {
75
79
  if (factorSelectExpr) {
76
- factorType.value = '脚本'
80
+ factorType.value = "脚本";
77
81
  monacoEditorRef.value.setValue(factorSelectExpr);
78
- } else factorType.value = '模版';
82
+ } else factorType.value = "模版";
79
83
  monacoEditorRef.value.resize();
80
- })
84
+ });
81
85
  };
82
86
  // 确定
83
87
  const handleSubmit = () => {
84
- if (factorType.value === '模版') {
88
+ if (factorType.value === "模版") {
85
89
  dialogFormRef.value.validate((valid) => {
86
90
  const { list, sqlEnable, sqlValue } = dialogForm.value;
87
91
  if (!valid) return;
@@ -100,7 +104,7 @@ const handleSubmit = () => {
100
104
  list: JSON.parse(JSON.stringify(list)),
101
105
  sqlEnable,
102
106
  sqlValue,
103
- factorSelectExpr: '',
107
+ factorSelectExpr: "",
104
108
  };
105
109
  visible.value = false;
106
110
  });
@@ -220,12 +224,18 @@ const handleDeleteTag = (aciton, index) => {
220
224
  break;
221
225
  }
222
226
  case "scriptTag": {
223
- data.value = {
224
- list: [],
225
- sqlEnable: 0,
226
- sqlValue: null,
227
- factorSelectExpr: '',
228
- };
227
+ ElMessageBox.confirm("是否确认删除因子筛选: 脚本模式", "删除操作", {
228
+ confirmButtonText: "确认",
229
+ cancelButtonText: "取消",
230
+ type: "warning",
231
+ }).then(() => {
232
+ data.value = {
233
+ list: [],
234
+ sqlEnable: 0,
235
+ sqlValue: null,
236
+ factorSelectExpr: "",
237
+ };
238
+ });
229
239
  break;
230
240
  }
231
241
  }
@@ -233,10 +243,10 @@ const handleDeleteTag = (aciton, index) => {
233
243
 
234
244
  // 打开变量选择器
235
245
  const open = () => {
236
- const zIndex = document.getElementsByClassName('factor-dialog')?.[0]?.style?.zIndex;
237
- console.log(zIndex)
246
+ const zIndex = document.getElementsByClassName("factor-dialog")?.[0]?.style?.zIndex;
247
+ console.log(zIndex);
238
248
  stVarSelectDialogRef.value.open(monacoEditorRef.value, zIndex);
239
- }
249
+ };
240
250
  </script>
241
251
 
242
252
  <template>
@@ -277,7 +287,7 @@ const open = () => {
277
287
  width="500"
278
288
  placement="bottom-start"
279
289
  >
280
- <div style="white-space: pre-line;">
290
+ <div style="white-space: pre-line">
281
291
  {{ data.factorSelectExpr }}
282
292
  </div>
283
293
  <template #reference>
@@ -309,38 +319,49 @@ const open = () => {
309
319
  width="1000"
310
320
  align-center
311
321
  destroy-on-close
322
+ :show-close="false"
312
323
  >
313
324
  <template #header="{ titleId, titleClass }">
314
325
  <div class="custom-header">
315
- <span
316
- :id="titleId"
317
- :class="titleClass"
318
- >
319
- 因子筛选
320
- </span>
321
- <el-tooltip
322
- effect="dark"
323
- content="点击查看: 因子使用说明"
324
- placement="right"
325
- >
326
- <el-icon @click="visibleDescriptions = true"><InfoFilled /></el-icon>
327
- </el-tooltip>
328
- <el-radio-group
329
- v-model="factorType"
330
- size="small"
331
- style="margin-left: 12px;"
332
- >
333
- <el-radio-button label="模版" value="模版" />
334
- <el-radio-button label="脚本" value="脚本" />
335
- </el-radio-group>
336
- <!-- 变量选择器 -->
337
- <div style="flex: 1; text-align: right;" v-if="factorType === '脚本'">
326
+ <div class="left">
327
+ <span
328
+ :id="titleId"
329
+ :class="titleClass"
330
+ >
331
+ 因子筛选
332
+ </span>
333
+ <el-tooltip
334
+ effect="dark"
335
+ content="点击查看: 因子使用说明"
336
+ placement="right"
337
+ >
338
+ <el-icon @click="visibleDescriptions = true"><InfoFilled /></el-icon>
339
+ </el-tooltip>
340
+ <el-radio-group
341
+ v-model="factorType"
342
+ size="small"
343
+ >
344
+ <el-radio-button
345
+ label="模版"
346
+ value="模版"
347
+ />
348
+ <el-radio-button
349
+ label="脚本"
350
+ value="脚本"
351
+ />
352
+ </el-radio-group>
353
+ </div>
354
+ <!-- 变量选择器 + 关闭 -->
355
+ <div class="right">
338
356
  <el-button
357
+ v-if="factorType === '脚本'"
339
358
  size="small"
340
359
  type="primary"
341
360
  @click="open"
342
- >变量选择器</el-button>
343
- </div>
361
+ >变量选择器</el-button
362
+ >
363
+ <el-icon @click="visible = false"><Close /></el-icon>
364
+ </div>
344
365
  </div>
345
366
  </template>
346
367
  <!-- 模版模式 -->
@@ -348,6 +369,7 @@ const open = () => {
348
369
  v-if="factorType === '模版'"
349
370
  ref="dialogFormRef"
350
371
  :model="dialogForm"
372
+ style="height: 400px"
351
373
  >
352
374
  <!-- 因子筛选表格 -->
353
375
  <div
@@ -576,11 +598,7 @@ const open = () => {
576
598
  <!-- 脚本模式 -->
577
599
  <div
578
600
  style="width: 968px; height: 400px"
579
- :style="
580
- factorType === '脚本' ?
581
- null :
582
- { position: 'fixed', top: '-400px', zIndex: -1 }
583
- "
601
+ :style="factorType === '脚本' ? null : { position: 'fixed', top: '-400px', zIndex: -1 }"
584
602
  >
585
603
  <MonacoEditor
586
604
  ref="monacoEditorRef"
@@ -601,6 +619,7 @@ const open = () => {
601
619
  <!-- 因子说明: 机器打分, 人工打分因子 -->
602
620
  <FactorDescription
603
621
  v-model:visible="visibleDescriptions"
622
+ :factorType="factorType"
604
623
  :data="config.factorDescriptions?.filter((item) => [1, 3].includes(item.type))"
605
624
  />
606
625
  <!-- 变量选择器 -->
@@ -615,8 +634,14 @@ const open = () => {
615
634
  .custom-header {
616
635
  display: flex;
617
636
  align-items: center;
637
+ justify-content: space-between;
638
+ .left,
639
+ .right {
640
+ display: flex;
641
+ align-items: center;
642
+ gap: 10px;
643
+ }
618
644
  .el-icon {
619
- margin-left: 4px;
620
645
  cursor: pointer;
621
646
  }
622
647
  }
@@ -2,6 +2,20 @@
2
2
  <div>
3
3
  <div style="display: flex; align-items: center; gap: 10px">
4
4
  <el-button @click="stKlineConfigRef?.open">打开K线自定义配置</el-button>
5
+ <el-select
6
+ v-model="sellBuy"
7
+ style="width: 100px"
8
+ >
9
+ <el-option
10
+ v-for="item in [
11
+ { label: '买卖', value: 0 },
12
+ { label: '开平', value: 1 },
13
+ ]"
14
+ :key="item.value"
15
+ :value="item.value"
16
+ :label="item.label"
17
+ />
18
+ </el-select>
5
19
  <el-select
6
20
  v-model="cycle"
7
21
  style="width: 100px"
@@ -43,6 +57,7 @@
43
57
 
44
58
  <script setup>
45
59
  import dayjs from "dayjs";
60
+ import tradeLogMock from "./tradeLogMock";
46
61
  import { onMounted, ref, reactive, provide, inject, nextTick } from "vue";
47
62
 
48
63
  const { request } = inject("stConfig"); // 组件库全局配置
@@ -54,14 +69,15 @@ provide("userKlineConfig", userKlineConfig);
54
69
 
55
70
  const cycleOptions = [
56
71
  { label: "1m", value: "1" },
72
+ { label: "60m", value: "5" },
57
73
  { label: "1d", value: "6" },
58
74
  { label: "1mon", value: "8" },
59
75
  ];
60
76
 
61
- const varietyName = ref(null);
62
- const varietyCode = ref("000016");
63
- const varietyStock = ref(1); // 0: 期货, 1: 股票, 2: 期权
64
- const tradeLog = ref([]);
77
+ const varietyName = ref("棉花");
78
+ const varietyCode = ref("CF");
79
+ const varietyStock = ref(0); // 0: 期货, 1: 股票, 2: 期权
80
+ const tradeLog = ref(tradeLogMock);
65
81
  const netPositionData = ref([]);
66
82
  const cycle = ref("6");
67
83
  const sellBuy = ref(1);