st-comp 0.0.43 → 0.0.45

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.
@@ -7,7 +7,14 @@ import isSameOrAfter from "dayjs/plugin/isSameOrAfter";
7
7
  import { ElMessage } from "element-plus";
8
8
  import "element-plus/dist/index.css";
9
9
  import { formatValue } from "../../../../packages/Kline/utils";
10
- import { getSingleCycleSingleVariety, getDict, getNetPositionData, queryPairedRecordByVariety } from "../api.ts";
10
+ import {
11
+ getDiffKLine,
12
+ queryDiffLineRevelance,
13
+ getDiffSubKLine,
14
+ getDict,
15
+ getNetPositionData,
16
+ queryPairedRecordByVariety,
17
+ } from "../api.ts";
11
18
  import { mainIndicatorList } from "st-func";
12
19
 
13
20
  dayjs.extend(isSameOrAfter);
@@ -51,9 +58,16 @@ const sellBuyTypeOptions = ref<any>([
51
58
  { label: "买卖", value: 2 },
52
59
  ]);
53
60
 
61
+ const otherChart = ref("价差分布图");
62
+ const otherChartOptions = ["二腿价格走势图", "二腿价格走势百分比图", "二腿相关度", "价差周期性", "价差分布图"];
63
+
54
64
  // 接口原生-点位数据
55
65
  const originPointData = ref<any>([]);
56
-
66
+ // 接口原生-二腿相关度数据
67
+ const relevanceOriginData = ref<any>([]);
68
+ // 接口原生-二腿价格趋势数据
69
+ const priceTrendOriginData = ref<any>([]);
70
+ const priceTrendPercentOriginData = ref<any>([]);
57
71
  // K线组件入参
58
72
  const isSelect = ref(false);
59
73
  const klineData = ref<any>([]);
@@ -67,9 +81,47 @@ const defaultMenuData = ref([
67
81
  callBack: (echartsInstance: any, cursorPenVisible: any) => createWarning(echartsInstance, cursorPenVisible),
68
82
  },
69
83
  ]);
84
+ const relevanceData = computed(() => {
85
+ let result = [];
86
+ result = relevanceOriginData.value.reduce((res: any[], item: any) => {
87
+ res.push([
88
+ dayjs(item.genTime).format(cycle.value === "6" ? "YYYY-MM-DDT00:00:00" : "YYYY-MM-DDT15:00:00"),
89
+ item.rel,
90
+ ]);
91
+ return res;
92
+ }, []);
93
+ return result;
94
+ });
95
+ const priceTrendData = computed(() => {
96
+ let result = [];
97
+ result = priceTrendOriginData.value.reduce((res: any[], item: any) => {
98
+ res.push({
99
+ name: item.name,
100
+ data: item.infos.map((i) => {
101
+ return [dayjs(i.genTime).format("YYYY-MM-DDTHH:mm:ss"), i.close];
102
+ }),
103
+ });
104
+ return res;
105
+ }, []);
106
+ return result;
107
+ });
108
+ const priceTrendPercentData = computed(() => {
109
+ let result = [];
110
+ result = priceTrendPercentOriginData.value.reduce((res: any[], item: any) => {
111
+ res.push({
112
+ name: item.name,
113
+ data: item.infos.map((i) => {
114
+ return [dayjs(i.genTime).format("YYYY-MM-DDTHH:mm:ss"), i.close];
115
+ }),
116
+ });
117
+ return res;
118
+ }, []);
119
+ return result;
120
+ });
70
121
  const config = ref({
71
- totalBarCount: 2000,
72
- preBarCount: 100,
122
+ totalBarCount: 2000, // 会被渲染的K线条数
123
+ preBarCount: 100, // 预加载K线条数
124
+ // 左上角Tips配置
73
125
  tipsConfig: {
74
126
  open: true,
75
127
  heigh: true,
@@ -79,77 +131,76 @@ const config = ref({
79
131
  riseAndFall: true,
80
132
  netPosition: true,
81
133
  },
134
+ // 动态数据加载配置
82
135
  dynamicLoadConfig: {
83
136
  historyVisible: true,
84
137
  historyLoadCallBack: async (historyIsAllLoad: any) => {
85
138
  const { totalBarCount, preBarCount } = config.value;
86
- // 1.如果当前K线数据量就小于API希望得到的数量,说明已经没有数据了,将API得到的数据作全部展示
87
- // 并且打上标记,此K线数据已无更多
139
+ // 前置判断: 如果 [K线数据量 < 期望总渲染条数 + 预请求数] ,则标记完毕
88
140
  if (klineData.value.length < totalBarCount + preBarCount) {
89
141
  config.value.totalBarCount = klineData.value.length;
90
- console.log("K线数据已无更多-1");
91
142
  historyIsAllLoad.value = true;
92
143
  return;
93
144
  }
94
- // 2.已当前存储的K线数据第一条时间作为结束时间,往前再次请求
95
- const params = {
96
- right: 1, // 复权方式
97
- variety: "au8888", // 品种
98
- cycle: cycle.value, // 周期
99
- endTime: klineData.value[0][0], // 结束时间
100
- limit: 2000, // 总条数
101
- queryType: 1, // 0-按时间,1-按结束时间,2-按开始时间
102
- };
103
- const res = await getSingleCycleSingleVariety(params);
145
+ // 运算过程:
146
+ // 1.计算出当前K线数据中,第一根K线时间点
147
+ // 2.请求接口,获取历史K线数据,并拼接
148
+ // 3.如果请求到的数据量小于期望获得的条数,或当前数据总根数大于限制的10000条数, 则标记完毕
149
+ const endTime = dayjs(klineData.value[0][0]).format("YYYY-MM-DD HH:mm:ss");
150
+ const params = { diffId: 1481, cycle: cycle.value, limit: 2800, endTime, queryType: 1 };
151
+ const res = await getDiffKLine(params);
104
152
  const apiData = res.data.body.slice(0, res.data.body.length - 1);
105
153
  klineData.value = [...apiData, ...klineData.value];
106
- config.value.totalBarCount = config.value.totalBarCount + apiData.length;
107
- // 3.如果请求到的数据量小于期望的条数,或者当前数据总根数大于限制的10000条数
108
- // 也打上标记,此K线数据已无更多
109
- if (apiData.length < 2000 - 1 || config.value.totalBarCount > 6000) {
110
- console.log("K线数据已无更多-2");
154
+ config.value.totalBarCount = klineData.value.length;
155
+ if (apiData.length < 2800 - 1 || config.value.totalBarCount > 10000) {
111
156
  historyIsAllLoad.value = true;
112
157
  }
113
158
  },
114
- futureVisible: true,
115
- futureLoadCallBack: async (futureIsAllLoad: any) => {
116
- const { totalBarCount, preBarCount } = config.value;
117
- // 1.如果当前K线数据量就小于API希望得到的数量,说明已经没有数据了,将API得到的数据作全部展示
118
- // 并且打上标记,此K线数据已无更多
119
- // if (klineData.value.length < totalBarCount + preBarCount) {
120
- // config.value.totalBarCount = klineData.value.length;
121
- // console.log("K线数据已无更多-1");
122
- // futureIsAllLoad.value = true;
123
- // return;
124
- // }
125
- // 2.已当前存储的K线数据最后一条时间作为开始时间,往后再次请求
126
- const params = {
127
- contractType: 0,
128
- right: 0, // 复权方式
129
- variety: "FU", // 品种
130
- cycle: cycle.value, // 周期
131
- startTime: klineData.value[klineData.value.length - 1][0], // 开始
132
- limit: 20, // 总条数
133
- queryType: 2, // 0-按时间,1-按结束时间,2-按开始时间
134
- };
135
- const res = await getSingleCycleSingleVariety(params);
136
- const apiData = res.data.body.slice(1); // 取掉重复数据
137
- klineData.value = [...klineData.value, ...apiData];
138
- config.value.totalBarCount = config.value.totalBarCount + apiData.length;
139
- // 3.如果请求到的数据量小于期望的条数,或者当前数据总根数大于限制的10000条数
140
- // 也打上标记,此K线数据已无更多
141
- if (apiData.length < 20 - 1 || config.value.totalBarCount > 6000) {
142
- console.log("K线数据已无更多-2");
143
- futureIsAllLoad.value = true;
144
- }
145
- },
146
159
  },
147
- zoomLock: true,
160
+ isOpenDS: false,
148
161
  });
149
162
 
150
- onMounted(() => {
151
- console.log("---------单品种单周期组件: onMounted挂载成功---------");
152
- });
163
+ watch(
164
+ otherChart,
165
+ (newValue: string) => {
166
+ config.value.isOpenDS = false;
167
+ relevanceOriginData.value = [];
168
+ priceTrendOriginData.value = [];
169
+ priceTrendPercentOriginData.value = [];
170
+ const callBackMap = new Map([
171
+ [
172
+ "二腿价格走势图",
173
+ async () => {
174
+ await getPriceTrendData("value");
175
+ },
176
+ ],
177
+ [
178
+ "二腿价格走势百分比图",
179
+ async () => {
180
+ await getPriceTrendData("percent");
181
+ },
182
+ ],
183
+ [
184
+ "二腿相关度",
185
+ async () => {
186
+ await getRelevanceData();
187
+ },
188
+ ],
189
+ ["价差周期性", async () => {}],
190
+ [
191
+ "价差分布图",
192
+ async () => {
193
+ config.value.isOpenDS = true;
194
+ },
195
+ ],
196
+ ]);
197
+ const callBack = callBackMap.get(newValue);
198
+ callBack instanceof Function && callBack();
199
+ },
200
+ {
201
+ immediate: true,
202
+ }
203
+ );
153
204
 
154
205
  // 初始化
155
206
  const componentInit = async () => {
@@ -157,8 +208,8 @@ const componentInit = async () => {
157
208
  loading.value = true;
158
209
  await getDictCycle();
159
210
  await getKlineData();
160
- await getKlinePointData();
161
- await getKlineNetPositionData();
211
+ // await getKlinePointData();
212
+ // await getKlineNetPositionData();
162
213
  loading.value = false;
163
214
  await getKlineExtendData();
164
215
  } catch (error) {
@@ -185,20 +236,11 @@ const getDictCycle = async () => {
185
236
  });
186
237
  };
187
238
  /**
188
- * @description: 获取K线数据
239
+ * @description: 获取K线数据(价差)
189
240
  */
190
241
  const getKlineData = async () => {
191
- const params = {
192
- contractType: 0,
193
- cycle: cycle.value,
194
- endTime: "2024-03-28 15:00:00",
195
- preLimit: 800,
196
- queryType: 0,
197
- right: 0,
198
- startTime: "2024-01-28 15:00:00",
199
- variety: "RU",
200
- };
201
- const res = await getSingleCycleSingleVariety(params);
242
+ const params = { diffId: 1481, cycle: cycle.value, limit: 2800, endTime: "2024-04-08 17:02:19", queryType: 1 };
243
+ const res = await getDiffKLine(params);
202
244
  klineData.value = res.data.body;
203
245
  };
204
246
  /**
@@ -251,18 +293,18 @@ const getKlinePointData = async () => {
251
293
  part: null, // 份数
252
294
  profitAndLoss: item.profitAndLoss,
253
295
  time: openTime, // 匹配到X轴的时间
254
- markLineTarget: []
296
+ markLineTarget: [],
255
297
  };
256
298
  // 连线逻辑,当天的不连
257
299
  if (openTime !== closeTime) {
258
300
  openItem.markLineTarget = [
259
- {
301
+ {
260
302
  time: closeTime,
261
303
  name: `平${item.tradeDirection ? "空" : "多"}`,
262
304
  lineStyle: {
263
- color: item.profitAndLoss >= 0 ? '#FF0000' : '#389e0d'
264
- }
265
- }
305
+ color: item.profitAndLoss >= 0 ? "#FF0000" : "#389e0d",
306
+ },
307
+ },
266
308
  ];
267
309
  }
268
310
  const closeItem = {
@@ -515,6 +557,30 @@ const getKlineNetPositionData = async () => {
515
557
  }
516
558
  netPositionData.value = klineData.value.map((item: any) => netPositionMap.get(item[0]) ?? null);
517
559
  };
560
+ /**
561
+ * @description: 获取二腿相关度数据
562
+ */
563
+ const getRelevanceData = async () => {
564
+ const params = {
565
+ diffId: 1481,
566
+ };
567
+ const res = await queryDiffLineRevelance(params);
568
+ const { body } = res.data;
569
+ relevanceOriginData.value = body;
570
+ };
571
+ /**
572
+ * @description: 获取二腿价格走势数据
573
+ */
574
+ const getPriceTrendData = async (type: string) => {
575
+ const params = { diffId: 1481, cycle: cycle.value, limit: 2800, endTime: "2024-04-08 17:02:19", queryType: 1 };
576
+ const res = await getDiffSubKLine(params);
577
+ const { body } = res.data;
578
+ if (type === "value") {
579
+ priceTrendOriginData.value = body;
580
+ } else {
581
+ priceTrendPercentOriginData.value = body;
582
+ }
583
+ };
518
584
 
519
585
  /**
520
586
  * @description: 周期切换
@@ -524,7 +590,8 @@ const cycleChange = async () => {
524
590
  loading.value = true;
525
591
  config.value.totalBarCount = 2000;
526
592
  await getKlineData();
527
- await getKlinePointData();
593
+ // await getPriceTrendData();
594
+ // await getKlinePointData();
528
595
  loading.value = false;
529
596
  } catch (error) {
530
597
  console.log(error);
@@ -713,6 +780,13 @@ const reFresh = () => {
713
780
  />
714
781
  </el-select>
715
782
  </div>
783
+ <!-- 价差额外图表展示 + 选择 -->
784
+ <div class="kline-header-item sellBuySelect">
785
+ <span>{{ otherChart }}</span>
786
+ <el-select v-model="otherChart" popper-class="element-dark" @change="sellBuyTypeChange">
787
+ <el-option v-for="item in otherChartOptions" :key="item" :label="item" :value="item" />
788
+ </el-select>
789
+ </div>
716
790
  </div>
717
791
  <!-- K线本体 -->
718
792
  <st-kline
@@ -724,6 +798,9 @@ const reFresh = () => {
724
798
  :lineData="lineData"
725
799
  :brushRange="brushRange"
726
800
  :netPositionData="netPositionData"
801
+ :relevanceData="relevanceData"
802
+ :priceTrendData="priceTrendData"
803
+ :priceTrendPercentData="priceTrendPercentData"
727
804
  :defaultMenuData="defaultMenuData"
728
805
  :isSelect="isSelect"
729
806
  :config="config"
@@ -1,10 +1,50 @@
1
1
  <template>
2
- <div style="width: 100%; height: 100%;">
3
- <st-klineNew />
2
+ <div style="width: 100%; height: 42px;">
3
+ <el-select v-model="freqId" :style="{ width: '120px', marginRight: '12px' }">
4
+ <el-option
5
+ v-for="item in freqOption"
6
+ :key="item.value"
7
+ :label="item.label"
8
+ :value="item.value"
9
+ />
10
+ </el-select>
11
+ <el-select v-model="mainIndicator" :style="{ width: '120px', marginRight: '12px' }">
12
+ <el-option
13
+ v-for="item in mainIndicatorList"
14
+ :key="item.value"
15
+ :label="item.label"
16
+ :value="item.value"
17
+ />
18
+ </el-select>
19
+ </div>
20
+ <div style="width: 100%; height: calc(100% - 42px);">
21
+ <st-klineNew
22
+ :code="'RU'"
23
+ :freqId="freqId"
24
+ :freqDict="freqOption"
25
+ :mainIndicator="mainIndicator"
26
+ :mainIndicatorList="mainIndicatorList"
27
+ :subIndicatorList="subIndicatorList"
28
+ />
4
29
  </div>
5
30
  </template>
6
31
 
7
32
  <script setup lang="ts">
33
+ import { ref } from 'vue'
34
+ import { mainIndicatorList, subIndicatorList } from "st-func"
35
+
36
+ const freqOption = [
37
+ { value: "1", label: "1m" },
38
+ { value: "2", label: "5m" },
39
+ { value: "3", label: "15m" },
40
+ { value: "4", label: "30m" },
41
+ { value: "5", label: "60m" },
42
+ { value: "6", label: "1d" },
43
+ { value: "7", label: "1w" },
44
+ { value: "8", label: "1mon" }
45
+ ]
46
+ const freqId = ref('5')
47
+ const mainIndicator = ref('DKX_EMA')
8
48
  </script>
9
49
 
10
50
  <style lang="scss" scoped>