st-comp 0.0.247 → 0.0.248
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.
- package/es/ChartLayout.js +4 -4
- package/es/CustomFunction.js +42 -42
- package/es/FactorWarning.js +33 -33
- package/es/Kline.js +17 -17
- package/es/KlineBasic.js +26 -26
- package/es/KlineConfig.js +61 -61
- package/es/KlineNew.js +16 -16
- package/es/KlinePlus.cjs +4 -4
- package/es/KlinePlus.js +589 -575
- package/es/LinearLegend.cjs +1 -1
- package/es/LinearLegend.js +1 -63
- package/es/MonacoEditor.js +24 -24
- package/es/Pagination.js +73 -73
- package/es/PasswordPrompt.js +3 -3
- package/es/Table.js +38 -38
- package/es/User.js +44 -44
- package/es/VarSelectDialog.js +25 -25
- package/es/VarietyAutoComplete.js +10 -10
- package/es/VarietySearch.js +38 -38
- package/es/{VarietySelect-5a9dd50b.js → VarietySelect-b9fe3000.js} +4 -4
- package/es/VarietyTextCopy.js +12 -12
- package/es/VirtualTable.js +14 -14
- package/es/{_initCloneObject-c34c65bc.js → _initCloneObject-382335b2.js} +7 -7
- package/es/{base-a5af3db3.js → base-ff0e366f.js} +40 -40
- package/es/{castArray-7741a212.js → castArray-15070be9.js} +1 -1
- package/es/{config-provider-06a63185.js → config-provider-2e85eee8.js} +6 -6
- package/es/{debounce-8d53f4dd.js → debounce-e9e47f9a.js} +1 -1
- package/es/{dropdown-302f71e7.js → dropdown-2b35a683.js} +13 -13
- package/es/{el-autocomplete-ed75a659.js → el-autocomplete-18be2c5a.js} +16 -16
- package/es/{el-button-d09ff85f.js → el-button-f08c0639.js} +39 -39
- package/es/{el-checkbox-64648e02.js → el-checkbox-058dba2d.js} +31 -31
- package/es/{el-dialog-6a80e3d8.js → el-dialog-d328e0d8.js} +15 -15
- package/es/{el-divider-4e059794.js → el-divider-4fe55ebe.js} +1 -1
- package/es/{el-empty-33cb66f1.js → el-empty-ceecb81c.js} +5 -5
- package/es/{el-form-item-4eca95be.js → el-form-item-cb328886.js} +36 -36
- package/es/{el-input-cae60510.js → el-input-0f6ead19.js} +50 -50
- package/es/{el-input-number-c2499410.js → el-input-number-66e68609.js} +36 -36
- package/es/{el-loading-c738468d.js → el-loading-412370c7.js} +5 -5
- package/es/{el-menu-item-f904f685.js → el-menu-item-0ee8ad18.js} +22 -22
- package/es/{el-message-box-05d8cf39.js → el-message-box-6db52b29.js} +11 -11
- package/es/{el-message-0df23ae7.js → el-message-e6c755df.js} +23 -23
- package/es/{el-overlay-cc9bc792.js → el-overlay-981f8d49.js} +56 -56
- package/es/{el-popconfirm-a6f66a0e.js → el-popconfirm-005013fa.js} +20 -20
- package/es/{el-popper-a38874f4.js → el-popper-fdc7c793.js} +109 -109
- package/es/{el-segmented-51b1c797.js → el-segmented-050d0090.js} +8 -8
- package/es/{el-select-1b149fab.js → el-select-23a1f302.js} +64 -64
- package/es/{el-table-column-3e30ebae.js → el-table-column-d0c374cf.js} +15 -15
- package/es/{el-tag-0a25efdf.js → el-tag-f13f463b.js} +15 -15
- package/es/{el-text-73d899ff.js → el-text-27cef2be.js} +2 -2
- package/es/{index-42e59bf5.js → index-09bd2621.js} +43 -43
- package/es/{index-94e43e0d.js → index-15b9603e.js} +3 -3
- package/es/{index-960806da.js → index-269b8a8c.js} +36 -36
- package/es/{index-54d289d1.js → index-4a3f30c5.js} +12 -12
- package/es/{index-6e967429.js → index-80a7ad32.js} +17 -17
- package/es/{index-d77a7336.js → index-93a8960e.js} +1 -1
- package/es/{index-4194c942.js → index-b937ea22.js} +2 -2
- package/es/{index-ac98a4d8.js → index-c266c23a.js} +10 -10
- package/es/{index-6806997d.js → index-e0901394.js} +34 -34
- package/es/{index-87b4bf61.js → index-ec7ad93f.js} +31 -31
- package/es/{python-a914569a.js → python-823b276b.js} +24 -24
- package/es/raf-8e05a7f4.js +6 -0
- package/es/{scroll-679bd6bf.js → scroll-41b4f625.js} +5 -5
- package/es/style.css +1 -1
- package/es/{use-form-common-props-47e50c10.js → use-form-common-props-631cacae.js} +65 -65
- package/es/{use-global-config-f52caea0.js → use-global-config-5d001623.js} +14 -14
- package/es/{validator-94c04152.js → validator-4160d9e7.js} +1 -1
- package/es/{vnode-5ddb7ed1.js → vnode-06571d5b.js} +1 -1
- package/es/{zh-cn-4921961d.js → zh-cn-5df98ac2.js} +2 -2
- package/lib/bundle.js +1 -1
- package/lib/bundle.umd.cjs +79 -79
- package/lib/{index-750ede1b.js → index-f00d1e1f.js} +4912 -4898
- package/lib/{python-e34a2958.js → python-0f34e2e6.js} +1 -1
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/KlinePlus/index.vue +88 -62
- package/src/App.vue +15 -4
- package/src/pages/KlineNew/components/KlineAction/mockApi/index.js +1 -1
- package/src/pages/KlineNew/components/KlineBasic/utils.js +1 -1
- package/src/pages/KlineNew/components/KlineSlide/utils.js +1 -1
- package/src/pages/KlinePlus/KlineDialog/MultiCycle.vue +312 -0
- package/src/pages/KlinePlus/KlineDialog/api.js +108 -0
- package/src/pages/KlinePlus/KlineDialog/index.vue +582 -0
- package/src/pages/KlinePlus/KlineDialog/indicator.js +109 -0
- package/src/pages/KlinePlus/KlineDialog/tools.js +86 -0
- package/src/pages/KlinePlus/index.vue +23 -209
- package/es/raf-80ef0c0a.js +0 -6
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
|
|
3
|
+
// 测试环境
|
|
4
|
+
// const userid = 103;
|
|
5
|
+
// const token = "490cebe77872589fc6f670d30983b268";
|
|
6
|
+
// export const host = "http://192.168.12.38:5173";
|
|
7
|
+
|
|
8
|
+
// 线上环境
|
|
9
|
+
const userid = 200;
|
|
10
|
+
const token = "02e233681c5cecaf788525e70c380ed5";
|
|
11
|
+
export const host = "//investapi.hzyotoy.com";
|
|
12
|
+
|
|
13
|
+
// 获取数据: 指标列表
|
|
14
|
+
export const getIndicator = async (data) => {
|
|
15
|
+
const res = await axios({
|
|
16
|
+
method: "post",
|
|
17
|
+
headers: { token, userid },
|
|
18
|
+
url: `${host}/middleLayer/kline/getIndicator`,
|
|
19
|
+
data,
|
|
20
|
+
});
|
|
21
|
+
return res.data;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// 获取周期列表
|
|
25
|
+
export const getCycleList = async () => {
|
|
26
|
+
const res = await axios({
|
|
27
|
+
method: "post",
|
|
28
|
+
headers: { token, userid },
|
|
29
|
+
url: `${host}/middleLayer/post/common/qt/getDict`,
|
|
30
|
+
data: { dictIds: [1002] },
|
|
31
|
+
});
|
|
32
|
+
return res.data;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// 查询品种是否股票
|
|
36
|
+
export const queryContractType = async (data) => {
|
|
37
|
+
const res = await axios({
|
|
38
|
+
method: "post",
|
|
39
|
+
headers: { token, userid },
|
|
40
|
+
url: `${host}/middleLayer/bjpost/invest/analysis/queryContractType`,
|
|
41
|
+
data,
|
|
42
|
+
});
|
|
43
|
+
return res.data;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// 获取净值曲线数据
|
|
47
|
+
export const queryVarietyNetPositionValue = async (data) => {
|
|
48
|
+
const res = await axios({
|
|
49
|
+
method: "post",
|
|
50
|
+
headers: { token, userid },
|
|
51
|
+
url: `${host}/middleLayer/bjpost/invest/analysis/queryVarietyNetPositionValue`,
|
|
52
|
+
data,
|
|
53
|
+
});
|
|
54
|
+
return res.data;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// 获取交易订单数据
|
|
58
|
+
export const queryPairedRecordByVariety = async (data) => {
|
|
59
|
+
const res = await axios({
|
|
60
|
+
method: "post",
|
|
61
|
+
headers: { token, userid },
|
|
62
|
+
url: `${host}/middleLayer/bjpost/invest/analysis/queryPairedRecordByVariety`,
|
|
63
|
+
data,
|
|
64
|
+
});
|
|
65
|
+
return res.data;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// 获取篮子品种对应的价差指数
|
|
69
|
+
export const queryJCVariety = async (data) => {
|
|
70
|
+
const res = await axios({
|
|
71
|
+
method: "post",
|
|
72
|
+
headers: { token, userid },
|
|
73
|
+
url: `${host}/middleLayer/bjpost/invest/analysis/queryJCVariety`,
|
|
74
|
+
data,
|
|
75
|
+
});
|
|
76
|
+
return res.data;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const getUserConfig = async (data) => {
|
|
80
|
+
const res = await axios({
|
|
81
|
+
method: "post",
|
|
82
|
+
headers: { token, userid },
|
|
83
|
+
url: `${host}/middleLayer/bjpost/common/qt/getUserConfig`,
|
|
84
|
+
data,
|
|
85
|
+
});
|
|
86
|
+
return res.data;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// 获取配置
|
|
90
|
+
export const getConfig = async () => {
|
|
91
|
+
const res = await axios({
|
|
92
|
+
method: "get",
|
|
93
|
+
headers: { token, userid },
|
|
94
|
+
url: `${host}/middleLayer/get/invest/sys/frontconfig/info`,
|
|
95
|
+
});
|
|
96
|
+
return res.data;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// 设置配置
|
|
100
|
+
export const setConfig = async (data) => {
|
|
101
|
+
const res = await axios({
|
|
102
|
+
method: "post",
|
|
103
|
+
headers: { token, userid },
|
|
104
|
+
url: `${host}/middleLayer/post/invest/sys/frontconfig/save`,
|
|
105
|
+
data,
|
|
106
|
+
});
|
|
107
|
+
return res.data;
|
|
108
|
+
};
|
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { actionStat } from "st-func";
|
|
3
|
+
import { ref, reactive, onMounted, provide, nextTick, watch } from "vue";
|
|
4
|
+
import { ArrowLeftBold, ArrowRightBold, RefreshRight, CloseBold, Setting } from "@element-plus/icons-vue";
|
|
5
|
+
import { sellBuyOptions, rightTypeOptions, klineTypeOptions, formatLabel, getTimeRange } from "./tools.js";
|
|
6
|
+
import useIndicatorStore from "./indicator.js";
|
|
7
|
+
import { queryContractType, queryVarietyNetPositionValue, queryPairedRecordByVariety, queryJCVariety, getUserConfig, getCycleList } from "./api.js";
|
|
8
|
+
import MultiCycle from "./MultiCycle.vue";
|
|
9
|
+
|
|
10
|
+
const actionParams = ref({ pageName: null, other: null }); // 数据埋点
|
|
11
|
+
|
|
12
|
+
const stKlineConfigRef = ref(null);
|
|
13
|
+
const userKlineConfig = reactive({});
|
|
14
|
+
provide("userKlineConfig", userKlineConfig);
|
|
15
|
+
|
|
16
|
+
const indicatorStore = useIndicatorStore();
|
|
17
|
+
const cycleOptions = ref([]);
|
|
18
|
+
|
|
19
|
+
const visible = ref(false);
|
|
20
|
+
const loading = ref(false); // 初始数据载入, 参数变动等
|
|
21
|
+
const MultiCycleRef = ref(null);
|
|
22
|
+
|
|
23
|
+
const pageType = ref(1);
|
|
24
|
+
const analyseId = ref(null);
|
|
25
|
+
const varietyList = ref([]);
|
|
26
|
+
const varietyIndex = ref(0);
|
|
27
|
+
|
|
28
|
+
const varietyName = ref(null);
|
|
29
|
+
const varietyCode = ref(null);
|
|
30
|
+
const jcVarietyOptions = ref([]); // 价差品种数据源
|
|
31
|
+
const ifBasket = ref(0); // 1: 是篮子, 0: 不是篮子
|
|
32
|
+
|
|
33
|
+
// 品种参数
|
|
34
|
+
const varietyStock = ref(1); // 0: 期货, 1: 股票, 2: 期权
|
|
35
|
+
const tradeLog = ref([]);
|
|
36
|
+
const netPositionData = ref([]);
|
|
37
|
+
|
|
38
|
+
// 交互参数
|
|
39
|
+
const cycle = ref("6");
|
|
40
|
+
const sellBuy = ref(1);
|
|
41
|
+
const rightType = ref(1);
|
|
42
|
+
const klineType = ref(0);
|
|
43
|
+
const mainIndicator = ref("DKX_EMA");
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @description: 首屏时间
|
|
47
|
+
* 1. 默认按照交易第一笔开仓 ~ 最后一笔平仓时间 (前后拓展200根)
|
|
48
|
+
* 2. 如果参数positionTime, 则以此时间为准 (前后拓展200根)
|
|
49
|
+
*/
|
|
50
|
+
const initTimeRange = ref([]);
|
|
51
|
+
const positionTime = ref(null);
|
|
52
|
+
|
|
53
|
+
// 获取主品种类型
|
|
54
|
+
const getVarietyStock = async () => {
|
|
55
|
+
const params = { condition: varietyCode.value, conditionName: varietyName.value };
|
|
56
|
+
const { body } = await queryContractType(params);
|
|
57
|
+
varietyStock.value = body;
|
|
58
|
+
};
|
|
59
|
+
// 获取价差品种数据
|
|
60
|
+
const getJcVarietyOptions = async () => {
|
|
61
|
+
if (varietyStock.value === 1) {
|
|
62
|
+
const params = { condition: varietyCode.value, conditionName: varietyName.value };
|
|
63
|
+
const { body } = await queryJCVariety(params);
|
|
64
|
+
jcVarietyOptions.value = body ?? [];
|
|
65
|
+
} else {
|
|
66
|
+
jcVarietyOptions.value = [{ varietyName: varietyName.value, varietyCode: varietyCode.value }];
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// 获取品种交易数据
|
|
71
|
+
const getTradeLog = async () => {
|
|
72
|
+
// 如果已经自带了交易数据, 说明是要聚焦这一笔明细的, 就不用拉取全部数据
|
|
73
|
+
if (tradeLog.value.length !== 0) return;
|
|
74
|
+
const params = {
|
|
75
|
+
analyseId: analyseId.value,
|
|
76
|
+
varietyName: varietyName.value,
|
|
77
|
+
varietyCode: varietyCode.value,
|
|
78
|
+
ifBasket: ifBasket.value, // 是否篮子
|
|
79
|
+
cycle: cycle.value,
|
|
80
|
+
};
|
|
81
|
+
const { body } = await queryPairedRecordByVariety(params);
|
|
82
|
+
tradeLog.value = body ?? [];
|
|
83
|
+
};
|
|
84
|
+
// 获取品种净值数据
|
|
85
|
+
const getNetPositionData = async () => {
|
|
86
|
+
// 如果没有交易数据, 就不用请求净值数据了
|
|
87
|
+
if (tradeLog.value.length === 0) return;
|
|
88
|
+
if (ifBasket.value === 1) return;
|
|
89
|
+
const params = {
|
|
90
|
+
analyseId: analyseId.value,
|
|
91
|
+
varietyCode: varietyCode.value,
|
|
92
|
+
startTime: tradeLog.value[0].openTime,
|
|
93
|
+
endTime: tradeLog.value.at(-1).closeTime,
|
|
94
|
+
};
|
|
95
|
+
const { body } = await queryVarietyNetPositionValue(params);
|
|
96
|
+
netPositionData.value = body;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// 顶栏: 时间控制
|
|
100
|
+
const handleTimeRange = async (type) => {
|
|
101
|
+
// 单周期
|
|
102
|
+
if (pageType.value === 1) {
|
|
103
|
+
const params = {
|
|
104
|
+
type,
|
|
105
|
+
cycle: cycle.value,
|
|
106
|
+
startTime: tradeLog.value[0]?.openTime,
|
|
107
|
+
endTime: positionTime.value ? positionTime.value : tradeLog.value.at(-1)?.closeTime,
|
|
108
|
+
};
|
|
109
|
+
initTimeRange.value = getTimeRange(params);
|
|
110
|
+
}
|
|
111
|
+
// 多周期
|
|
112
|
+
else if (pageType.value === 2) MultiCycleRef.value?.changeTimeRange(type);
|
|
113
|
+
};
|
|
114
|
+
// 顶栏: 主品种切换
|
|
115
|
+
const handleChangeVariety = async (type) => {
|
|
116
|
+
const oldIndex = varietyIndex.value;
|
|
117
|
+
const maxIndex = varietyList.value.length - 1;
|
|
118
|
+
switch (type) {
|
|
119
|
+
// 上一个品种
|
|
120
|
+
case "pre": {
|
|
121
|
+
if (oldIndex === 0) return ElMessage.warning("已是本页第一个品种");
|
|
122
|
+
varietyIndex.value -= 1;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
// 下一个品种
|
|
126
|
+
case "next": {
|
|
127
|
+
if (oldIndex === maxIndex) return ElMessage.warning("已是本页最后一个品种");
|
|
128
|
+
varietyIndex.value += 1;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (oldIndex !== varietyIndex.value) {
|
|
133
|
+
loading.value = true;
|
|
134
|
+
const varietyInfo = varietyList.value[varietyIndex.value];
|
|
135
|
+
varietyName.value = varietyInfo.varietyName;
|
|
136
|
+
varietyCode.value = varietyInfo.varietyCode;
|
|
137
|
+
ifBasket.value = varietyInfo.ifBasket;
|
|
138
|
+
tradeLog.value = varietyInfo.tradeLog ?? [];
|
|
139
|
+
netPositionData.value = [];
|
|
140
|
+
await getVarietyStock();
|
|
141
|
+
await getJcVarietyOptions();
|
|
142
|
+
await getTradeLog();
|
|
143
|
+
await getNetPositionData();
|
|
144
|
+
handleTimeRange("reset");
|
|
145
|
+
loading.value = false;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
// 顶栏: 价差品种切换
|
|
149
|
+
const handleChangeJcVariety = (varietyCode) => {
|
|
150
|
+
const item = jcVarietyOptions.value.find((i) => i.varietyCode === varietyCode);
|
|
151
|
+
// 由于这里要修改其它响应式数据, select组件内部原因, 自动关闭下拉框这一行为会受到影响, 所以使用nextTick
|
|
152
|
+
nextTick(() => {
|
|
153
|
+
varietyName.value = item.varietyName;
|
|
154
|
+
handleTimeRange("reset");
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// 多周期双击切到单周期
|
|
159
|
+
const goToSingleCycle = (item) => {
|
|
160
|
+
if (!userKlineConfig.enable_dbClickOpenSingel) return;
|
|
161
|
+
cycle.value = item.cycle;
|
|
162
|
+
pageType.value = 1;
|
|
163
|
+
};
|
|
164
|
+
// 用户自定义K线配置(获取, 更新)
|
|
165
|
+
const handleUserKlineConfig = async (action, formJson) => {
|
|
166
|
+
switch (action) {
|
|
167
|
+
case "get": {
|
|
168
|
+
const { body } = await getUserConfig({ appId: 1 });
|
|
169
|
+
Object.assign(userKlineConfig, stKlineConfigRef.value?.getDefaultUserKlineConfig(), body ? JSON.parse(body) : {});
|
|
170
|
+
console.log(userKlineConfig)
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case "update": {
|
|
174
|
+
loading.value = true;
|
|
175
|
+
// 更新配置数据
|
|
176
|
+
Object.assign(userKlineConfig, JSON.parse(formJson));
|
|
177
|
+
// 默认值 [自定义配置]
|
|
178
|
+
pageType.value = userKlineConfig.pageType;
|
|
179
|
+
cycle.value = userKlineConfig.singelCycle;
|
|
180
|
+
sellBuy.value = userKlineConfig.sellBuy;
|
|
181
|
+
mainIndicator.value = userKlineConfig.mainIndicator;
|
|
182
|
+
nextTick(() => (loading.value = false));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
onMounted(async () => {
|
|
188
|
+
await indicatorStore.init();
|
|
189
|
+
handleUserKlineConfig("get");
|
|
190
|
+
cycleOptions.value = (await getCycleList()).body[1002].map((item) => ({ label: item.dictName, value: item.dictCode }));
|
|
191
|
+
});
|
|
192
|
+
watch(
|
|
193
|
+
() => pageType.value,
|
|
194
|
+
(newValue) => {
|
|
195
|
+
// 当切换到单周期的时候, 需要重置初始时间, 多周期业务组件内部自带了重置触发逻辑
|
|
196
|
+
if (newValue === 1) handleTimeRange("reset");
|
|
197
|
+
actionParams.value?.pageName && actionStat(actionParams.value?.pageName, "查看K线", pageType.value === 1 ? "单周期" : "多周期");
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
defineExpose({
|
|
201
|
+
/**
|
|
202
|
+
* @description: 打开K线弹窗组件
|
|
203
|
+
* @param {Object} params - 入参
|
|
204
|
+
* params.analyseId - 绩效记录id
|
|
205
|
+
* params.varietyInfo - 品种信息 { index, varietyName, varietyCode, ifBasket, positionTime, tradeLog }
|
|
206
|
+
* params.varietyList - 当页品种列表 <varietyInfo>
|
|
207
|
+
* params.actionParams - 行为埋点参数
|
|
208
|
+
*/
|
|
209
|
+
open: async (params) => {
|
|
210
|
+
try {
|
|
211
|
+
loading.value = true;
|
|
212
|
+
visible.value = true;
|
|
213
|
+
|
|
214
|
+
// 外部传入
|
|
215
|
+
analyseId.value = params.analyseId;
|
|
216
|
+
varietyList.value = params.varietyList ?? [];
|
|
217
|
+
varietyIndex.value = params.varietyInfo.index ?? 0;
|
|
218
|
+
varietyName.value = params.varietyInfo.varietyName;
|
|
219
|
+
varietyCode.value = params.varietyInfo.varietyCode;
|
|
220
|
+
ifBasket.value = params.varietyInfo.ifBasket;
|
|
221
|
+
positionTime.value = params.varietyInfo.positionTime;
|
|
222
|
+
tradeLog.value = params.varietyInfo.tradeLog ?? [];
|
|
223
|
+
|
|
224
|
+
// 默认值 [内部固定]
|
|
225
|
+
varietyStock.value = 1;
|
|
226
|
+
rightType.value = 1;
|
|
227
|
+
klineType.value = 0;
|
|
228
|
+
initTimeRange.value = [];
|
|
229
|
+
netPositionData.value = [];
|
|
230
|
+
|
|
231
|
+
// 默认值 [自定义配置]
|
|
232
|
+
pageType.value = userKlineConfig.pageType;
|
|
233
|
+
cycle.value = userKlineConfig.singelCycle;
|
|
234
|
+
sellBuy.value = userKlineConfig.sellBuy;
|
|
235
|
+
mainIndicator.value = userKlineConfig.mainIndicator;
|
|
236
|
+
|
|
237
|
+
await getVarietyStock();
|
|
238
|
+
await getJcVarietyOptions();
|
|
239
|
+
await getTradeLog();
|
|
240
|
+
await getNetPositionData();
|
|
241
|
+
handleTimeRange("reset");
|
|
242
|
+
} catch (error) {
|
|
243
|
+
throw new Error(`打开K线弹窗异常: ${error}`);
|
|
244
|
+
} finally {
|
|
245
|
+
loading.value = false;
|
|
246
|
+
// 埋点
|
|
247
|
+
actionParams.value = params.actionParams;
|
|
248
|
+
actionParams.value?.pageName && actionStat(actionParams.value?.pageName, "查看K线", pageType.value === 1 ? "单周期" : "多周期");
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
</script>
|
|
253
|
+
|
|
254
|
+
<template>
|
|
255
|
+
<el-dialog
|
|
256
|
+
class="kline-dialog"
|
|
257
|
+
v-model="visible"
|
|
258
|
+
:fullscreen="true"
|
|
259
|
+
:show-close="false"
|
|
260
|
+
:destroy-on-close="true"
|
|
261
|
+
:z-index="2000"
|
|
262
|
+
>
|
|
263
|
+
<div class="main element-dark">
|
|
264
|
+
<template v-if="!loading">
|
|
265
|
+
<!-- 功能栏 -->
|
|
266
|
+
<div class="kline-header">
|
|
267
|
+
<!-- 标题 -->
|
|
268
|
+
<div class="kline-header-item kline-header-item-select">
|
|
269
|
+
<span> {{ varietyName }} {{ varietyCode }} </span>
|
|
270
|
+
<el-select
|
|
271
|
+
v-model="varietyCode"
|
|
272
|
+
popper-class="element-dark"
|
|
273
|
+
@change="handleChangeJcVariety"
|
|
274
|
+
>
|
|
275
|
+
<el-option
|
|
276
|
+
v-for="(item, index) in jcVarietyOptions"
|
|
277
|
+
:key="item.varietyCode"
|
|
278
|
+
:label="`${item.varietyName} ${item.varietyCode}`"
|
|
279
|
+
:value="item.varietyCode"
|
|
280
|
+
/>
|
|
281
|
+
</el-select>
|
|
282
|
+
</div>
|
|
283
|
+
<!-- 周期 -->
|
|
284
|
+
<template v-if="pageType === 1">
|
|
285
|
+
<div class="kline-header-item kline-header-item-select">
|
|
286
|
+
<span>{{ formatLabel(cycle, cycleOptions) }}</span>
|
|
287
|
+
<el-select
|
|
288
|
+
v-model="cycle"
|
|
289
|
+
popper-class="element-dark"
|
|
290
|
+
>
|
|
291
|
+
<el-option
|
|
292
|
+
v-for="(item, index) in cycleOptions"
|
|
293
|
+
:key="index"
|
|
294
|
+
:label="item.label"
|
|
295
|
+
:value="item.value"
|
|
296
|
+
/>
|
|
297
|
+
</el-select>
|
|
298
|
+
</div>
|
|
299
|
+
</template>
|
|
300
|
+
<!-- 指标 -->
|
|
301
|
+
<div class="kline-header-item kline-header-item-select">
|
|
302
|
+
<span>{{ mainIndicator }}</span>
|
|
303
|
+
<el-select
|
|
304
|
+
v-model="mainIndicator"
|
|
305
|
+
popper-class="element-dark"
|
|
306
|
+
>
|
|
307
|
+
<el-option
|
|
308
|
+
v-for="(item, index) in indicatorStore.mainIndicatorList"
|
|
309
|
+
:key="index"
|
|
310
|
+
:label="item.label"
|
|
311
|
+
:value="item.value"
|
|
312
|
+
/>
|
|
313
|
+
<template #footer>
|
|
314
|
+
<el-button
|
|
315
|
+
text
|
|
316
|
+
:icon="Setting"
|
|
317
|
+
@click="indicatorStore.config"
|
|
318
|
+
>
|
|
319
|
+
指标配置
|
|
320
|
+
</el-button>
|
|
321
|
+
</template>
|
|
322
|
+
</el-select>
|
|
323
|
+
</div>
|
|
324
|
+
<!-- 买卖 -->
|
|
325
|
+
<div class="kline-header-item kline-header-item-select">
|
|
326
|
+
<span>{{ formatLabel(sellBuy, sellBuyOptions) }}</span>
|
|
327
|
+
<el-select
|
|
328
|
+
v-model="sellBuy"
|
|
329
|
+
popper-class="element-dark"
|
|
330
|
+
>
|
|
331
|
+
<el-option
|
|
332
|
+
v-for="(item, index) in sellBuyOptions"
|
|
333
|
+
:key="index"
|
|
334
|
+
:label="item.label"
|
|
335
|
+
:value="item.value"
|
|
336
|
+
/>
|
|
337
|
+
</el-select>
|
|
338
|
+
</div>
|
|
339
|
+
<!-- 复权选项 [股票] -->
|
|
340
|
+
<template v-if="varietyStock === 1">
|
|
341
|
+
<div class="kline-header-item kline-header-item-select">
|
|
342
|
+
<span>{{ formatLabel(rightType, rightTypeOptions) }}</span>
|
|
343
|
+
<el-select
|
|
344
|
+
v-model="rightType"
|
|
345
|
+
popper-class="element-dark"
|
|
346
|
+
>
|
|
347
|
+
<el-option
|
|
348
|
+
v-for="(item, index) in rightTypeOptions"
|
|
349
|
+
:key="index"
|
|
350
|
+
:label="item.label"
|
|
351
|
+
:value="item.value"
|
|
352
|
+
/>
|
|
353
|
+
</el-select>
|
|
354
|
+
</div>
|
|
355
|
+
</template>
|
|
356
|
+
<!-- 常用选项 [期货] -->
|
|
357
|
+
<template v-if="varietyStock === 0">
|
|
358
|
+
<div class="kline-header-item kline-header-item-select">
|
|
359
|
+
<span>{{ formatLabel(klineType, klineTypeOptions) }}</span>
|
|
360
|
+
<el-select
|
|
361
|
+
v-model="klineType"
|
|
362
|
+
popper-class="element-dark"
|
|
363
|
+
>
|
|
364
|
+
<el-option
|
|
365
|
+
v-for="(item, index) in klineTypeOptions"
|
|
366
|
+
:key="index"
|
|
367
|
+
:label="item.label"
|
|
368
|
+
:value="item.value"
|
|
369
|
+
/>
|
|
370
|
+
</el-select>
|
|
371
|
+
</div>
|
|
372
|
+
</template>
|
|
373
|
+
<!-- 品种切换 -->
|
|
374
|
+
<template v-if="varietyList.length">
|
|
375
|
+
<div class="kline-header-item">
|
|
376
|
+
<el-button
|
|
377
|
+
size="small"
|
|
378
|
+
:icon="ArrowLeftBold"
|
|
379
|
+
@click="handleChangeVariety('pre')"
|
|
380
|
+
>
|
|
381
|
+
上一品种
|
|
382
|
+
</el-button>
|
|
383
|
+
<el-button
|
|
384
|
+
size="small"
|
|
385
|
+
@click="handleChangeVariety('next')"
|
|
386
|
+
>
|
|
387
|
+
下一品种
|
|
388
|
+
<el-icon class="el-icon--right"><ArrowRightBold /></el-icon>
|
|
389
|
+
</el-button>
|
|
390
|
+
</div>
|
|
391
|
+
</template>
|
|
392
|
+
<!-- 时间控制 -->
|
|
393
|
+
<div class="kline-header-item">
|
|
394
|
+
<el-button
|
|
395
|
+
link
|
|
396
|
+
size="small"
|
|
397
|
+
@click="handleTimeRange('week')"
|
|
398
|
+
>本周</el-button
|
|
399
|
+
>
|
|
400
|
+
<el-button
|
|
401
|
+
link
|
|
402
|
+
size="small"
|
|
403
|
+
@click="handleTimeRange('month')"
|
|
404
|
+
>本月</el-button
|
|
405
|
+
>
|
|
406
|
+
<el-button
|
|
407
|
+
size="small"
|
|
408
|
+
:icon="RefreshRight"
|
|
409
|
+
@click="handleTimeRange('reset')"
|
|
410
|
+
>重置</el-button
|
|
411
|
+
>
|
|
412
|
+
</div>
|
|
413
|
+
<!-- 关闭 -->
|
|
414
|
+
<div class="kline-header-item-right">
|
|
415
|
+
<el-radio-group
|
|
416
|
+
size="small"
|
|
417
|
+
v-model="pageType"
|
|
418
|
+
>
|
|
419
|
+
<el-radio-button :value="1">单周期</el-radio-button>
|
|
420
|
+
<el-radio-button :value="2">多周期</el-radio-button>
|
|
421
|
+
</el-radio-group>
|
|
422
|
+
<el-icon
|
|
423
|
+
class="setting-icon"
|
|
424
|
+
title="K线自定义配置"
|
|
425
|
+
:size="20"
|
|
426
|
+
@click="stKlineConfigRef?.open"
|
|
427
|
+
>
|
|
428
|
+
<Setting />
|
|
429
|
+
</el-icon>
|
|
430
|
+
<el-button
|
|
431
|
+
size="small"
|
|
432
|
+
@click="() => (visible = false)"
|
|
433
|
+
>
|
|
434
|
+
关闭窗口
|
|
435
|
+
<el-icon class="close-icon">
|
|
436
|
+
<CloseBold />
|
|
437
|
+
</el-icon>
|
|
438
|
+
</el-button>
|
|
439
|
+
</div>
|
|
440
|
+
</div>
|
|
441
|
+
<!-- 内容 -->
|
|
442
|
+
<div class="kline-body">
|
|
443
|
+
<!-- K线组件 [单周期] -->
|
|
444
|
+
<template v-if="pageType === 1">
|
|
445
|
+
<st-klinePlus
|
|
446
|
+
:varietyCode="varietyCode"
|
|
447
|
+
:varietyStock="varietyStock"
|
|
448
|
+
:indicatorStore="indicatorStore"
|
|
449
|
+
:userKlineConfig="userKlineConfig"
|
|
450
|
+
:cycle="cycle"
|
|
451
|
+
:sellBuy="sellBuy"
|
|
452
|
+
:rightType="rightType"
|
|
453
|
+
:klineType="klineType"
|
|
454
|
+
:initTimeRange="initTimeRange"
|
|
455
|
+
:mainIndicator="mainIndicator"
|
|
456
|
+
:tradeLog="tradeLog"
|
|
457
|
+
:netPositionData="netPositionData"
|
|
458
|
+
:positionTime="positionTime"
|
|
459
|
+
/>
|
|
460
|
+
</template>
|
|
461
|
+
<!-- K线组件 [多周期] -->
|
|
462
|
+
<template v-else>
|
|
463
|
+
<MultiCycle
|
|
464
|
+
ref="MultiCycleRef"
|
|
465
|
+
:varietyCode="varietyCode"
|
|
466
|
+
:varietyStock="varietyStock"
|
|
467
|
+
:indicatorStore="indicatorStore"
|
|
468
|
+
:userKlineConfig="userKlineConfig"
|
|
469
|
+
:sellBuy="sellBuy"
|
|
470
|
+
:rightType="rightType"
|
|
471
|
+
:klineType="klineType"
|
|
472
|
+
:initTimeRange="initTimeRange"
|
|
473
|
+
:mainIndicator="mainIndicator"
|
|
474
|
+
:tradeLog="tradeLog"
|
|
475
|
+
:netPositionData="netPositionData"
|
|
476
|
+
:positionTime="positionTime"
|
|
477
|
+
@goToSingleCycle="goToSingleCycle"
|
|
478
|
+
/>
|
|
479
|
+
</template>
|
|
480
|
+
</div>
|
|
481
|
+
</template>
|
|
482
|
+
<template v-else>
|
|
483
|
+
<div
|
|
484
|
+
class="user-kline-config-loading"
|
|
485
|
+
v-loading="loading"
|
|
486
|
+
/>
|
|
487
|
+
</template>
|
|
488
|
+
</div>
|
|
489
|
+
</el-dialog>
|
|
490
|
+
<st-klineConfig
|
|
491
|
+
ref="stKlineConfigRef"
|
|
492
|
+
:indicatorStore="indicatorStore"
|
|
493
|
+
@callBack="(formJson) => handleUserKlineConfig('update', formJson)"
|
|
494
|
+
/>
|
|
495
|
+
</template>
|
|
496
|
+
|
|
497
|
+
<style lang="scss">
|
|
498
|
+
.kline-dialog {
|
|
499
|
+
padding: 0;
|
|
500
|
+
background-color: black;
|
|
501
|
+
.el-dialog__header {
|
|
502
|
+
display: none !important;
|
|
503
|
+
}
|
|
504
|
+
.el-dialog__body {
|
|
505
|
+
padding: 0;
|
|
506
|
+
border: none;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
</style>
|
|
510
|
+
<style lang="scss" scoped>
|
|
511
|
+
.kline-dialog {
|
|
512
|
+
.main {
|
|
513
|
+
width: 100vw;
|
|
514
|
+
height: 100vh;
|
|
515
|
+
color-scheme: dark;
|
|
516
|
+
background-color: black;
|
|
517
|
+
overflow: hidden;
|
|
518
|
+
position: relative;
|
|
519
|
+
.kline-header {
|
|
520
|
+
color: white;
|
|
521
|
+
font-size: 14px;
|
|
522
|
+
display: flex;
|
|
523
|
+
align-items: center;
|
|
524
|
+
border-bottom: 1px solid rgb(100, 100, 100);
|
|
525
|
+
position: relative;
|
|
526
|
+
.kline-header-item {
|
|
527
|
+
height: 32px;
|
|
528
|
+
line-height: 32px;
|
|
529
|
+
display: flex;
|
|
530
|
+
align-items: center;
|
|
531
|
+
border-right: 1px solid rgb(100, 100, 100);
|
|
532
|
+
padding: 0 6px;
|
|
533
|
+
box-sizing: border-box;
|
|
534
|
+
}
|
|
535
|
+
.kline-header-item-select {
|
|
536
|
+
:deep(.el-select) {
|
|
537
|
+
margin-left: 4px;
|
|
538
|
+
width: 16px;
|
|
539
|
+
.el-select__icon {
|
|
540
|
+
margin-left: 0;
|
|
541
|
+
color: black;
|
|
542
|
+
width: 16px;
|
|
543
|
+
height: 16px;
|
|
544
|
+
}
|
|
545
|
+
.el-select__wrapper {
|
|
546
|
+
border-radius: 50%;
|
|
547
|
+
background: #ccc;
|
|
548
|
+
padding: 0;
|
|
549
|
+
gap: 0;
|
|
550
|
+
min-height: 12px;
|
|
551
|
+
line-height: 12px;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
.kline-header-item-right {
|
|
556
|
+
height: 100%;
|
|
557
|
+
position: absolute;
|
|
558
|
+
top: 0px;
|
|
559
|
+
right: 6px;
|
|
560
|
+
display: flex;
|
|
561
|
+
align-items: center;
|
|
562
|
+
gap: 10px;
|
|
563
|
+
.el-icon {
|
|
564
|
+
font-size: 18px;
|
|
565
|
+
cursor: pointer;
|
|
566
|
+
&:hover {
|
|
567
|
+
color: var(--el-color-primary);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
.kline-body {
|
|
573
|
+
width: 100vw;
|
|
574
|
+
height: calc(100vh - 39px);
|
|
575
|
+
}
|
|
576
|
+
.user-kline-config-loading {
|
|
577
|
+
width: 100%;
|
|
578
|
+
height: 100%;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
</style>
|