sbd-npm 1.1.95 → 1.1.98

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.
@@ -0,0 +1,1320 @@
1
+ let Stock = {
2
+
3
+ code: "",
4
+ name: "",
5
+ price: 0,
6
+ tab_token: "basics_nav",
7
+ sort_type: "date",
8
+ sort_order: 0,
9
+ ttm_second: 0,
10
+ rzye_chart: false,
11
+ hkex_holding_chart: false,
12
+ hist_type: "",
13
+ hist_start_date: "",
14
+ hist_end_date: "",
15
+ profile: "",
16
+ data: {},
17
+ profit_data: [], // 盈利数据
18
+
19
+ fetch_data: function () {
20
+ let active_div = localStorage[Stock.tab_token];
21
+ if (Stock.data.hasOwnProperty(active_div)) {
22
+ return false;
23
+ }
24
+ Util.show_tips("Loading...");
25
+ switch (active_div) {
26
+ case "base":
27
+ Stock.fetch_base();
28
+ Util.init_metrics_statistics("amount", "成交额(单位:亿)", Stock.handle_metrics_statistics);
29
+ Util.init_metrics_statistics("volume", "成交量(单位:亿股)", Stock.handle_metrics_statistics);
30
+ Util.init_metrics_statistics("margin", "融资余额(单位:亿)", Stock.handle_metrics_statistics);
31
+ Util.init_metrics_statistics("hkex_holding", "港资持股量(单位:亿股)", Stock.handle_metrics_statistics);
32
+ Util.init_metrics_statistics("turnover", "换手率(百分比%)", Stock.handle_metrics_statistics);
33
+ Stock.fetch_bias_data();
34
+ break;
35
+ case "holder_top":
36
+ Stock.fetch_holder_top();
37
+ break;
38
+ case "holder_data":
39
+ Stock.fetch_holder_num_data();
40
+ break;
41
+ case "margin":
42
+ if (!Stock.rzye_chart) {
43
+ Util.init_range_date("margin_start_end_date", Stock, "fetch_margin");
44
+ }
45
+ $("#query_margin").click(function () {
46
+ Stock.fetch_margin();
47
+ });
48
+ $("#margin_date_type").change(function () {
49
+ Stock.fetch_margin();
50
+ });
51
+ Stock.fetch_margin();
52
+ break;
53
+ case "hkex_holding":
54
+ if (!Stock.hkex_holding_chart) {
55
+ Util.init_range_date("hkex_start_end_date", Stock, "fetch_hkex_holding");
56
+ }
57
+ $("#query_hkex_holding").click(function () {
58
+ Stock.fetch_hkex_holding();
59
+ });
60
+ $("#hkex_holding_date_type").change(function () {
61
+ Stock.fetch_hkex_holding();
62
+ });
63
+ Stock.fetch_hkex_holding();
64
+ break;
65
+ case "finance":
66
+ Stock.fetch_finance();
67
+ break;
68
+ case "notice":
69
+ Stock.fetch_notice();
70
+ break;
71
+ case "report_organization":
72
+ Stock.fetch_report_organization();
73
+ break;
74
+ case "public_fund":
75
+ Stock.fetch_public_fund();
76
+ break;
77
+ case "public_fund_change":
78
+ Stock.fetch_public_fund_change();
79
+ break;
80
+ case "big_deal":
81
+ Stock.fetch_big_deal();
82
+ break;
83
+ case "rps":
84
+ Stock.fetch_rps_data();
85
+ break;
86
+ case "hist_trade": // 个股历史交易记录
87
+ if (Stock.hist_start_date && Stock.hist_end_date) {
88
+ Util.init_range_date("hist_start_end_date", Stock, "fetch_hist_data", Stock.hist_start_date, Stock.hist_end_date);
89
+ } else {
90
+ Util.init_range_date("hist_start_end_date", Stock, "fetch_hist_data", 60);
91
+ }
92
+ if (Stock.hist_type) {
93
+ $("#hist_type").find("option[value='" + Stock.hist_type + "']").attr("selected", true);
94
+ }
95
+ Util.init_table_skeleton({
96
+ "element_id": "hist_table",
97
+ "caption": '<caption class="text-right" id="stock_hist_summary"></caption>',
98
+ "head_cols": [
99
+ {"name": "日期", "sort_type": "date"},
100
+ {"name": "开盘价"},
101
+ {"name": "最低价", "sort_type": "low"},
102
+ {"name": "最高价", "sort_type": "high"},
103
+ {"name": "收盘价", "sort_type": "close"},
104
+ {"name": "涨跌幅", "sort_type": "p_change"},
105
+ {"name": "成交均价"},
106
+ {"name": "成交量", "sort_type": "volume"},
107
+ {"name": "量比", "sort_type": "volume_ratio", "tooltip": "当日成交量与过去 5 日平均成交量的比"},
108
+ {"name": "量比30", "sort_type": "volume_ratio30", "tooltip": "当日成交量与过去 30 日平均成交量的比"},
109
+ {"name": "成交额", "sort_type": "amount"},
110
+ {"name": "换手率", "sort_type": "turnover"},
111
+ ]
112
+ });
113
+ $("#query_hist").click(function () {
114
+ Stock.fetch_hist_data();
115
+ return false;
116
+ });
117
+ $("#hist_type").change(function () {
118
+ Stock.fetch_hist_data();
119
+ });
120
+ Util.sort_table_column(Stock, Stock.fetch_hist_data);
121
+ Stock.fetch_hist_data();
122
+ break;
123
+ }
124
+ Stock["data"][active_div] = 1;
125
+ },
126
+
127
+ fetch_base: function () {
128
+ let _html = [];
129
+ let code_obj = $("#code");
130
+ code_obj.html(Util.snowball_url(code_obj.text()));
131
+
132
+ let ttm_obj = $("#time_to_market");
133
+ Stock.ttm_second = parseInt(ttm_obj.text());
134
+ ttm_obj.html(Stock.ttm_second > 0 ? Util.seconds_to_format(Stock.ttm_second, "%Y-%m-%d") : "--");
135
+
136
+ let concept_obj = $("#concept");
137
+ if (concept_obj.length > 0) {
138
+ let concept_arr = concept_obj.html().split(",");
139
+ _html = [];
140
+ concept_arr.forEach(function (item) {
141
+ _html.push('<a target="_blank" rel="noopener noreferrer nofollow" href="', Util.get_url("query_list"), '?concept=', item, '" class="btn btn-xs btn-warning">', item, '</a> ');
142
+ });
143
+ concept_obj.html(_html.join(""));
144
+ }
145
+
146
+ let location_obj = $("#location");
147
+ if (location_obj.length > 0) {
148
+ let location_arr = location_obj.text().split(",");
149
+ _html = [];
150
+ location_arr.forEach(function (location) {
151
+ _html.push(Util.map_url(location, location) + '&nbsp;&nbsp;');
152
+ });
153
+ location_obj.html(_html.join(""));
154
+ }
155
+ let cf_obj = $("#currency_funds");
156
+ cf_obj.html(Util.strip_html(Util.to_unit(cf_obj.attr("title"))));
157
+ //获取股票详情数据
158
+ Util.post("/stock/" + Stock["code"], {action: "code_detail"}, function (item) {
159
+ if (item["intro"]) {
160
+ // 简介
161
+ Util.init_modal_skeleton("profile_modal");
162
+ $("#profile_modal_title").html("简介");
163
+ Stock.profile = item["intro"];
164
+ let profile = Util.sub_str(Stock.profile, 250);
165
+ profile += "&nbsp;&nbsp;&nbsp;<a class='unfold text-info' data-toggle='modal' data-target='.profile_modal' href='#'>展开</a>";
166
+ $("#profile").html(profile);
167
+ $('#profile_modal').on('shown.bs.modal', function () {
168
+ let p_arr = Stock.profile.split("。");
169
+ let _html = [];
170
+ p_arr.forEach(function (p) {
171
+ if (p.length > 0) {
172
+ _html.push("<p>", p.replace(/,/g, ","), "。</p>");
173
+ }
174
+ });
175
+ Util.render_table_html("profile_modal_body", _html);
176
+ });
177
+ }
178
+ if (item["latest_date"] && !Stock.hist_end_date) {
179
+ Stock.hist_end_date = Util.seconds_to_format(item["latest_date"], "%Y-%m-%d");
180
+ Stock.hist_start_date = Util.seconds_to_format(item["latest_date"] - 60 * Util.one_day_second, "%Y-%m-%d");
181
+ }
182
+ item["price"] = (item["price"] && item["price"] > 0) ? item["price"] : parseFloat($("#price").html());
183
+ Stock.price = item["price"];
184
+ $("#price").html(Util.digit_compare_trend(item["price"], item["pre_close"]));
185
+ $("#year_price").html(Util.year_price_rate(item["price"], item["year_price"]));
186
+ let high_52week = $("#high_52week");
187
+ high_52week.html(Util.digit_compare_trend(high_52week.html(), item["price"]));
188
+ let low_52week = $("#low_52week");
189
+ low_52week.html(Util.digit_compare_trend(low_52week.html(), item["price"]));
190
+ if (item["high_history"]["close"]) {
191
+ let high_history = $("#high_history");
192
+ high_history.html(Util.digit_compare_trend(item["high_history"]["close"], item["price"]));
193
+ high_history.attr("title", Util.seconds_to_format(item["high_history"]["date"], "%Y-%m-%d"))
194
+ }
195
+ if (item["low_history"]["close"]) {
196
+ let low_history = $("#low_history");
197
+ low_history.html(Util.digit_compare_trend(item["low_history"]["close"], item["price"]));
198
+ low_history.attr("title", Util.seconds_to_format(item["low_history"]["date"], "%Y-%m-%d"))
199
+ }
200
+ // 备注
201
+ let remark_html = [];
202
+ if (item["down_day"] > 0) {
203
+ let down_ratio = "";
204
+ if (item["down_ratio"] > 0) {
205
+ down_ratio = "(" + item["down_ratio"] + "%)";
206
+ }
207
+ remark_html.push("<b class='text-success'>" + item["down_day"] + "天连跌" + down_ratio + "</b>");
208
+ }
209
+ if (item["is_down_macd"] === 1) {
210
+ remark_html.push("<b class='text-success'>MACD 下行</b>");
211
+ }
212
+ if (item["xsg_date"] > 0) {
213
+ let xsg_date = Util.seconds_to_format(item["xsg_date"], "%Y-%m-%d");
214
+ remark_html.push("<b class='text-success'>最近解禁<a href='" + Util.get_url("holder_restricted") + "?tab=xsg_list&date=" + xsg_date + "'>" + xsg_date + "</a></b>");
215
+ }
216
+ if (item["price"] > 0 && item["price"] < item["block_trade_price"]) {
217
+ remark_html.push("<b class='text-danger'>当前价小于最近<a href='" + Util.get_url("daily_block") + "?code=" + item["code"] + "'>大宗交易价(" + item["block_trade_price"] + ")</a></b>");
218
+ }
219
+ if (item["is_hkscc"] === 1) {
220
+ remark_html.push("<b class='text-danger'>港交所成份股</b>");
221
+ }
222
+ if (item["is_hs300s"] === 1) {
223
+ remark_html.push("<b class='text-danger'>沪深300成份股</b>");
224
+ }
225
+ if (item["desc"]) {
226
+ remark_html.push("<br><br><p>" + item["desc"] + "</p>");
227
+ }
228
+ remark_html = remark_html.join(", ");
229
+ if (item["industry_data"]) {
230
+ if (remark_html.length > 0) {
231
+ remark_html += "<br><br>";
232
+ }
233
+ remark_html += "&nbsp;&nbsp;<b>行业板块:</b> ";
234
+ item["industry_data"].forEach(function (i_d) {
235
+ let url = Util.get_url("summary_industry") + "?code=" + i_d["code"] + "&industry_type=" + i_d["industry_type"];
236
+ remark_html += " <a href='" + url + "' class='btn btn-xs btn-warning'>" + i_d["name"] + "</a>";
237
+ });
238
+ }
239
+ if (item["links"]) {
240
+ if (remark_html.length > 0) {
241
+ remark_html += "<br>";
242
+ }
243
+ remark_html += item["links"];
244
+ }
245
+ let remark_obj = $("#remark");
246
+ remark_obj.html(remark_html);
247
+ remark_obj.find("a").each(function () {
248
+ $(this).attr("target", "_blank");
249
+ $(this).attr("rel", "noopener noreferrer nofollow");
250
+ });
251
+ // 日均线抵扣价
252
+ if (item["price"] && item["ma_deduction"] && item["ma_deduction"].length > 0) {
253
+ let ma_deduction_html = [];
254
+ item["ma_deduction"].forEach(function (ma) {
255
+ if (ma["deduction_price"] > 0) {
256
+ let deduction_cls = Util.text_color(item["price"], ma["deduction_price"]);
257
+ let ma_cls = Util.text_color(item["price"], ma["ma"]);
258
+ ma_deduction_html.push(ma["day"] + "日均线:<b class='" + ma_cls + "'>" + ma["ma"] + "</b>(<b class='" + deduction_cls + "'>" + ma["deduction_price"] + "</b>)");
259
+ }
260
+ });
261
+ $("#ma_deduction").html(ma_deduction_html.join("、 "));
262
+ }
263
+ if (item["boll_up"] && item["boll_up"] > 0 && item["boll_down"] && item["boll_down"] > 0) {
264
+ $("#boll").html("<a title='当前上轨线 / 当前下轨线' target='_blank' rel='noopener noreferrer nofollow' href='" + Util.get_url("trend_boll") + "'><b class='text-danger'>" + Util.to_float(item["boll_up"], 2) + "</b> / <b class='text-success'>" + Util.to_float(item["boll_down"], 2) + "</b></a>");
265
+ }
266
+ if (item["usd_exchange_rate"] && item["usd_exchange_rate"] > 0) {
267
+ let market_capital = $("#market_capital").attr("data-val");
268
+ let usd_exchange_rate = Util.to_float((market_capital * 100) / item["usd_exchange_rate"], 2);
269
+ $("#usd_market_capital").html("($" + usd_exchange_rate + "亿)");
270
+ }
271
+
272
+ // 股东户数
273
+ let holder_num_url = Util.get_url("holder_num");
274
+ Util.post(holder_num_url, {action: "holder_num_info", code: Stock.code}, function (j) {
275
+ if (j["holder_num"] > 0 && j["pre_holder_num"]) {
276
+ let holder_num = Util.digit_compare_trend(j["holder_num"], j["pre_holder_num"]);
277
+ $("#holder_num").html(Util.pack_html_link(holder_num_url + "?code=" + Stock.code, holder_num));
278
+ }
279
+ });
280
+ Util.hide_tips();
281
+ });
282
+ },
283
+
284
+ fetch_hist_data: function () {
285
+ Util.show_tips("Loading...");
286
+ let hist_type = $("#hist_type").val();
287
+ let payload = {
288
+ sort_type: Stock.sort_type,
289
+ sort_order: Stock.sort_order,
290
+ start_date: $("#hist_start_date").val(),
291
+ end_date: $("#hist_end_date").val(),
292
+ hist_type: hist_type
293
+ };
294
+ Util.post("/stock/" + Stock["code"], payload, function (j) {
295
+ Stock.hist_type = "";
296
+ let _html = [];
297
+ let hist_low_price = 0;
298
+ let hist_high_price = 0;
299
+ let total_amount = 0;
300
+ let total_volume = 0;
301
+ j["data"].forEach(function (item) {
302
+ if (hist_low_price === 0 || hist_low_price > item["low"]) {
303
+ hist_low_price = item["low"];
304
+ }
305
+ hist_high_price = Math.max(hist_high_price, item["high"]);
306
+ if (hist_type === "week") {
307
+ item["date"] += Util.one_day_second * 5 - 1;
308
+ }
309
+ total_amount += item["amount"];
310
+ total_volume += item["volume"] * 100;
311
+ _html.push("<tr>");
312
+ let tick_time = Util.seconds_to_format(item["date"], "%Y%m%d");
313
+ let tick_url = "/tick?c=" + Stock.code + "&s=" + tick_time + "&e=" + tick_time;
314
+ _html.push("<td><a href='", tick_url, "'>", Util.seconds_to_format(item["date"], "%Y-%m-%d"), "</a></td>");
315
+ _html.push("<td>", item["open"], "</td>");
316
+ _html.push("<td class='price_low'>", item["low"], "</td>");
317
+ _html.push("<td class='price_high'>", item["high"], "</td>");
318
+ let cls = Util.text_color(item["p_change"]);
319
+ _html.push("<td><b class='", cls, "'>", item["close"], "</b></td>");
320
+ _html.push("<td><b class='", cls, "'>", item["p_change"], "%</b></td>");
321
+ _html.push("<td>", Util.to_float(item["amount"] / (item["volume"] * 100), 2), "</td>");
322
+ _html.push("<td class='volume-td'>", Util.to_float(item["volume"] / 10000, 2), "万手</td>");
323
+ _html.push("<td class='volume_ratio-td'>", item["volume_ratio"], "</td>");
324
+ _html.push("<td class='volume_ratio30-td'>", (item["volume_ratio30"] ? item["volume_ratio30"] : "--"), "</td>");
325
+ _html.push("<td class='amount-td'>", Util.to_hundred_million(item["amount"]), "亿</td>");
326
+ _html.push("<td>", (item["turnover"] > 0 ? (item["turnover"] + "%") : "--"), "</td>");
327
+ _html.push("</tr>");
328
+ });
329
+ Util.render_table_html("hist_table_body", _html);
330
+ $(".price_low").each(function () {
331
+ if (parseFloat($(this).text()) === hist_low_price) {
332
+ $(this).html("<span class='label label-success'>" + hist_low_price + "</span>");
333
+ }
334
+ });
335
+ $(".price_high").each(function () {
336
+ if (parseFloat($(this).text()) === hist_high_price) {
337
+ $(this).html("<span class='label label-danger'>" + hist_high_price + "</span>");
338
+ }
339
+ });
340
+ Util.parse_value_trend("volume-td");
341
+ Util.parse_value_trend("volume_ratio-td");
342
+ Util.parse_value_trend("volume_ratio30-td");
343
+ Util.parse_value_trend("amount-td");
344
+ Util.parse_value_trend("buy_amount-td");
345
+ Util.parse_value_trend("sell_amount-td");
346
+ Util.parse_value_trend("rzmre-td");
347
+ Util.parse_value_trend("rzye-td");
348
+ $("#stock_hist_summary").html("<b>时间区间内总成交额: <span class='label label-info'>" + Util.to_unit(total_amount) + "</span>, 总成交量: <span class='label label-info'>" + Util.to_unit(total_volume) + "</span> 股, 平均成交价: <span class='label label-warning'>" + Util.to_float(total_amount / total_volume, 2) + "</span></b>");
349
+ Util.hide_tips();
350
+ });
351
+ },
352
+
353
+ fetch_big_deal: function () {
354
+ if ($("#big_deal_table_body").length <= 0) {
355
+ Util.show_tips("Loading...");
356
+ Util.init_table_skeleton({
357
+ "element_id": "big_deal_summary_table",
358
+ "head_cols": [
359
+ {"name": "20日主力净流入"},
360
+ {"name": "10日主力净流入"},
361
+ {"name": "5日主力净流入"},
362
+ {"name": "3日主力净流入"},
363
+ ]
364
+ });
365
+ Util.init_table_skeleton({
366
+ "element_id": "big_deal_table",
367
+ "head_cols": [
368
+ {"name": "时间", "table_sort": 1},
369
+ {"name": "收盘价", "table_sort": 1},
370
+ {"name": "主力净流入", "table_sort": 1, "title": "超大单净流入 + 大单净流入"},
371
+ {"name": "超大单净流入", "table_sort": 1},
372
+ {"name": "大单净流入", "table_sort": 1},
373
+ {"name": "中单净流入", "table_sort": 1},
374
+ {"name": "小单净流入", "table_sort": 1},
375
+ ]
376
+ });
377
+ Util.post("/stock/" + Stock.code, {action: "big_deal"}, function (j) {
378
+ if (j["data"] && j["data"]["date"]) {
379
+ let date = j["data"]["date"];
380
+ //Stock.pack_big_deal("big_deal1", j["data"], "最近一天", date, date);
381
+ }
382
+ if (j["money_net_inflow"]) {
383
+ let _html = [];
384
+ let i = 0;
385
+ let day3_net_inflow = 0;
386
+ let day5_net_inflow = 0;
387
+ let day10_net_inflow = 0;
388
+ let day20_net_inflow = 0;
389
+ j["money_net_inflow"].forEach(function (item) {
390
+ i++;
391
+ if (i <= 3) {
392
+ day3_net_inflow += item["main_net_inflow"];
393
+ }
394
+ if (i <= 5) {
395
+ day5_net_inflow += item["main_net_inflow"];
396
+ }
397
+ if (i <= 10) {
398
+ day10_net_inflow += item["main_net_inflow"];
399
+ }
400
+ if (i <= 20) {
401
+ day20_net_inflow += item["main_net_inflow"];
402
+ }
403
+ _html.push("<tr>");
404
+ _html.push("<td>", Util.seconds_to_format(item["date"], "%Y-%m-%d"), "</td>");
405
+ _html.push("<td><b class='", Util.text_color(item["price_change"]), "'>", item["price"], "(", item["price_change"], "%)</b></td>");
406
+ _html.push("<td data-val='", item["main_net_inflow"], "'><b class='", Util.text_color(item["main_net_inflow"]), "'>", Util.to_unit(item["main_net_inflow"]), "</b></td>");
407
+ _html.push("<td data-val='", item["large_net_inflow"], "'><b class='", Util.text_color(item["large_net_inflow"]), "'>", Util.to_unit(item["large_net_inflow"]), "</b></td>");
408
+ _html.push("<td data-val='", item["big_net_inflow"], "'><b class='", Util.text_color(item["big_net_inflow"]), "'>", Util.to_unit(item["big_net_inflow"]), "</b></td>");
409
+ _html.push("<td data-val='", item["middle_net_inflow"], "'><b class='", Util.text_color(item["middle_net_inflow"]), "'>", Util.to_unit(item["middle_net_inflow"]), "</b></td>");
410
+ _html.push("<td data-val='", item["small_net_inflow"], "'><b class='", Util.text_color(item["small_net_inflow"]), "'>", Util.to_unit(item["small_net_inflow"]), "</b></td>");
411
+ _html.push("</tr>");
412
+ });
413
+ Util.render_table_html("big_deal_table_body", _html);
414
+ _html = [];
415
+ _html.push("<tr>");
416
+ _html.push("<td><b class='", Util.text_color(day20_net_inflow), "'>", Util.to_unit(day20_net_inflow), "</b></td>");
417
+ _html.push("<td><b class='", Util.text_color(day10_net_inflow), "'>", Util.to_unit(day10_net_inflow), "</b></td>");
418
+ _html.push("<td><b class='", Util.text_color(day5_net_inflow), "'>", Util.to_unit(day5_net_inflow), "</b></td>");
419
+ _html.push("<td><b class='", Util.text_color(day3_net_inflow), "'>", Util.to_unit(day3_net_inflow), "</b></td>");
420
+ _html.push("</tr>");
421
+ Util.render_table_html("big_deal_summary_table_body", _html);
422
+ }
423
+ Util.hide_tips();
424
+ });
425
+ }
426
+ },
427
+
428
+ // <div class="col-md-4 col-sm-4 col-xs-12" id="big_deal1"></div>
429
+ pack_big_deal: function (element_id, data, title, start_date, end_date) {
430
+ if (data[element_id]) {
431
+ let pie_element_id = element_id + "_pie";
432
+ title = "<a target='_blank' class='link_cls' href='" + Util.get_url("daily_big_deal") + "?code=" + Stock.code + "&start_date=" + start_date + "&end_date=" + end_date + "'>" + title + "<a>";
433
+ let tips = "<small id='" + pie_element_id + "_tips'></small>";
434
+ $('#' + element_id).html('<div class="x_panel"><div class="x_title"><h2>' + title + tips + '</h2><div class="clearfix"></div></div><div><div style="height: 350px;" id="' + pie_element_id + '"></div></div></div>');
435
+ Util.big_deal_pie(pie_element_id, data[element_id]);
436
+ }
437
+ },
438
+
439
+ fetch_rps_data: function () {
440
+ Util.show_tips("Loading...");
441
+ Util.post("/stock/" + Stock.code, {action: "rps"}, function (j) {
442
+ let _html = [];
443
+ j["data"].forEach(function (item) {
444
+ _html.push("<tr>");
445
+ _html.push("<td>", Util.seconds_to_format(item["date"], "%Y-%m-%d"), "</td>");
446
+ _html.push("<td style='background-color: ", item["rps20_color"], "'>", item["rps20"], "</td>");
447
+ _html.push("<td>", Util.parse_ratio(item["change_percent20"] * 100, 2), "</td>");
448
+ _html.push("<td style='background-color: ", item["rps60_color"], "'>", item["rps60"], "</td>");
449
+ _html.push("<td>", Util.parse_ratio(item["change_percent60"] * 100, 2), "</td>");
450
+ _html.push("<td style='background-color: ", item["rps120_color"], "'>", item["rps120"], "</td>");
451
+ _html.push("<td>", Util.parse_ratio(item["change_percent120"] * 100, 2), "</td>");
452
+ _html.push("</tr>");
453
+ });
454
+ if (_html.length > 0) {
455
+ Util.render_table_html("rps_data", _html);
456
+ } else {
457
+ let now = Util.now();
458
+ if ((now - Stock.ttm_second) < Util.one_year_second) {
459
+ let obj = $("#rps_data");
460
+ let td_num = obj.parent().find('thead td').length;
461
+ obj.html('<tr><td colspan="' + td_num + '">上市时间(' + Util.seconds_to_format(Stock.ttm_second, "%Y-%m-%d") + ')不足一年不做统计!</td></tr>');
462
+ } else {
463
+ Util.render_table_html("rps_data", []);
464
+ }
465
+ }
466
+ Util.hide_tips();
467
+ });
468
+ },
469
+
470
+ fetch_holder_top: function () {
471
+ Util.show_tips("Loading...");
472
+ Util.init_table_skeleton({
473
+ "element_id": "circulation_holder_table",
474
+ "head_cols": [
475
+ {"name": "排名", "table_sort": 1},
476
+ {"name": "股东名"},
477
+ {"name": "持股数"},
478
+ {"name": "持股市值"},
479
+ {"name": "持股比例"},
480
+ {"name": "变化"},
481
+ ]
482
+ });
483
+ Util.init_table_skeleton({
484
+ "element_id": "main_holder_table",
485
+ "head_cols": [
486
+ {"name": "排名", "table_sort": 1},
487
+ {"name": "股东名"},
488
+ {"name": "持股数"},
489
+ {"name": "持股市值"},
490
+ {"name": "持股比例"},
491
+ {"name": "变化"},
492
+ ]
493
+ });
494
+ let payload = {action: "top_holder"};
495
+ let date = $("#holder_top_date").val();
496
+ if (date) {
497
+ payload["date"] = date;
498
+ }
499
+ Util.post("/stock/" + Stock["code"], payload, function (j) {
500
+ let main_html = [];
501
+ let circulation_html = [];
502
+ let main_volume = 0;
503
+ let pre_main_volume = 0;
504
+ let circulation_volume = 0;
505
+ let pre_circulation_volume = 0;
506
+ j["data"].forEach(function (item) {
507
+ let change = item["change"];
508
+ if (change === "None") {
509
+ change = "新增";
510
+ } else if (parseInt(change) === 0) {
511
+ change = "不变";
512
+ } else if (parseFloat(change) > 0) {
513
+ change = "<b class='text-danger'>" + change + "%</b>";
514
+ } else if (parseFloat(change) < 0) {
515
+ change = "<b class='text-success'>" + change + "%</b>";
516
+ }
517
+ if (parseInt(item["type"]) === 1) {
518
+ main_volume += item["volume"];
519
+ main_html.push("<tr>");
520
+ main_html.push("<td>", item["rank"], "</td>");
521
+ main_html.push("<td>", item["holder_name"], "</td>");
522
+ main_html.push("<td>", Util.to_unit(item["volume"]), "</td>");
523
+ main_html.push("<td>", Util.to_unit(item["volume"] * Stock.price), "</td>");
524
+ main_html.push("<td>", item["holder_ratio"], "%</td>");
525
+ main_html.push("<td>", change, "</td>");
526
+ main_html.push("</tr>");
527
+ } else {
528
+ circulation_volume += item["volume"];
529
+ circulation_html.push("<tr>");
530
+ circulation_html.push("<td>", item["rank"], "</td>");
531
+ circulation_html.push("<td>", item["holder_name"], "</td>");
532
+ circulation_html.push("<td>", Util.to_unit(item["volume"]), "</td>");
533
+ circulation_html.push("<td>", Util.to_unit(item["volume"] * Stock.price), "</td>");
534
+ circulation_html.push("<td>", item["holder_ratio"], "%</td>");
535
+ circulation_html.push("<td>", change, "</td>");
536
+ circulation_html.push("</tr>");
537
+ }
538
+ });
539
+ j["pre_data"].forEach(function (item) {
540
+ if (parseInt(item["type"]) === 1) {
541
+ pre_main_volume += item["volume"];
542
+ } else {
543
+ pre_circulation_volume += item["volume"];
544
+ }
545
+ });
546
+ if (circulation_volume > 0 && pre_circulation_volume > 0) {
547
+ let price_tips = "";
548
+ if (j["date_price"]) {
549
+ price_tips = ", 当时价: " + Util.digit_compare_trend1(Stock["price"], j["date_price"]);
550
+ }
551
+ $("#circulation_holder_tips").html("(持股数环比: " + Util.year_price_rate(circulation_volume, pre_circulation_volume) + price_tips + ")");
552
+ } else {
553
+ $("#circulation_holder_tips").html("");
554
+ }
555
+ if (main_volume > 0 && pre_main_volume > 0) {
556
+ $("#main_holder_tips").html("(持股数环比: " + Util.year_price_rate(main_volume, pre_main_volume) + ")");
557
+ } else {
558
+ $("#main_holder_tips").html("");
559
+ }
560
+ let symbol = Util.code_to_symbol(Stock.code);
561
+ Util.render_table_html("circulation_holder_table_body", circulation_html);
562
+ $("#circulation_holder_url").attr("href", "https://xueqiu.com/snowman/S/" + symbol + "/detail#/LTGD");
563
+ Util.render_table_html("main_holder_table_body", main_html);
564
+ $("#main_holder_url").attr("href", "https://xueqiu.com/snowman/S/" + symbol + "/detail#/SDGD");
565
+ if (j["date_list"]) {
566
+ let date_html = [];
567
+ j["date_list"].forEach(function (date) {
568
+ date = Util.seconds_to_format(date, "%Y-%m-%d");
569
+ date_html.push("<option value='", date, "'>", date, "</option>");
570
+ });
571
+ let htd = $("#holder_top_date");
572
+ htd.html(date_html.join(""));
573
+ htd.change(function () {
574
+ Stock.fetch_holder_top();
575
+ });
576
+ }
577
+ Util.hide_tips();
578
+ });
579
+ },
580
+
581
+ fetch_finance: function () {
582
+ Util.show_tips("Loading...");
583
+ Util.init_table_skeleton({
584
+ "element_id": "cash_flow_table",
585
+ "head_cols": [
586
+ {"name": "年份"},
587
+ {"name": "经营活动现金流"},
588
+ {"name": "资本开支"},
589
+ {"name": "自由现金流", "tooltip": "自由现金流 = 经营活动现金流 - 资本开支"},
590
+ {
591
+ "name": "筹资现金净额",
592
+ "tooltip": "筹资活动现金流量,是企业现金流量的重要组成部分,其中包含了筹资活动现金流入和筹资活动现金流出两个小部分,筹资活动现金流入减去筹资活动现金流出,就是企业当期筹资活动产生的现金流量净额"
593
+ },
594
+ ]
595
+ });
596
+ Util.init_table_skeleton({
597
+ "element_id": "assets_liabilities_table",
598
+ "head_cols": [
599
+ {"name": "年份"},
600
+ {"name": "总资产"},
601
+ {"name": "总负债"},
602
+ {"name": "净资产", "tooltip": "净资产 = 总资产 - 总负债"},
603
+ {"name": "资产负债率", "tooltip": "资产负债率 = 总负债 / 总资产", "link": "https://baike.baidu.com/item/资产负债率/2429745"},
604
+ {
605
+ "name": "货币资金",
606
+ "tooltip": "货币资金(Money) 是指企业拥有的,以货币形式存在的资产,包括现金、银行存款和其他货币资金",
607
+ "link": "https://baike.baidu.com/item/货币资金/2408229"
608
+ },
609
+ {"name": "短期借款"},
610
+ {"name": "一年非流债", "tooltip": "一年内到期的非流动负债"},
611
+ {
612
+ "name": "短期还债比",
613
+ "tooltip": "货币资金 / (短期借款 + 一年内到期的非流动负债)",
614
+ "link": "https://mp.weixin.qq.com/s?__biz=MzAxMjEyOTYwMQ==&mid=2649823683&idx=1&sn=122617d91614ec7b78aa738ca4fdb4ed"
615
+ },
616
+ {"name": "商誉"},
617
+ {"name": "商誉占比"}
618
+ ]
619
+ });
620
+ Util.init_table_skeleton({
621
+ "element_id": "profit_table",
622
+ "head_cols": [
623
+ {"name": "年份季度"},
624
+ {"name": "净资产收益率(ROE)", "tooltip": "Return On Equity"},
625
+ {"name": "净利率(%)"},
626
+ {"name": "毛利率"},
627
+ {"name": "净利润"},
628
+ {"name": "每股收益(EPS)", "tooltip": "Earnings Per Share"},
629
+ {"name": "营业收入"},
630
+ {"name": "每股主营业务收入"},
631
+ ]
632
+ });
633
+ Util.post("/stock/" + Stock["code"], {action: "finance"}, function (j) {
634
+ // 现金流
635
+ let _html = [];
636
+ let total_ncf_from_oa = 0;
637
+ let total_cash_paid_for_assets = 0;
638
+ let total_free_cash_flow = 0;
639
+ let total_ncf_from_fa = 0;
640
+ j["cash_flow_data"].forEach(function (item) {
641
+ total_ncf_from_oa += item["ncf_from_oa"];
642
+ total_cash_paid_for_assets += item["cash_paid_for_assets"];
643
+ let free_cash_flow = item["ncf_from_oa"] - item["cash_paid_for_assets"];
644
+ total_free_cash_flow += free_cash_flow;
645
+ total_ncf_from_fa += item["ncf_from_fa"];
646
+ _html.push("<tr>");
647
+ _html.push("<td>", Util.seconds_to_format(item["date"], "%Y"), "</td>");
648
+ _html.push("<td>", Util.to_unit(item["ncf_from_oa"]), "</td>");
649
+ _html.push("<td>", Util.to_unit(item["cash_paid_for_assets"]), "</td>");
650
+ _html.push("<td>", Util.to_unit(free_cash_flow), "</td>");
651
+ _html.push("<td>", Util.to_unit(item["ncf_from_fa"]), "</td>");
652
+ _html.push("</tr>");
653
+ });
654
+ total_ncf_from_oa = total_ncf_from_oa >= 0 ? (Util.to_hundred_million(total_ncf_from_oa) + "亿") : ("<b class='text-danger'>" + Util.to_hundred_million(total_ncf_from_oa) + "亿</b>");
655
+ total_cash_paid_for_assets = total_cash_paid_for_assets >= 0 ? (Util.to_hundred_million(total_cash_paid_for_assets) + "亿") : ("<b class='text-danger'>" + Util.to_hundred_million(total_cash_paid_for_assets) + "亿</b>");
656
+ total_free_cash_flow = total_free_cash_flow >= 0 ? (Util.to_hundred_million(total_free_cash_flow) + "亿") : ("<b class='text-danger'>" + Util.to_hundred_million(total_free_cash_flow) + "亿</b>");
657
+ total_ncf_from_fa = total_ncf_from_fa >= 0 ? (Util.to_hundred_million(total_ncf_from_fa) + "亿") : ("<b class='text-danger'>" + Util.to_hundred_million(total_ncf_from_fa) + "亿</b>");
658
+ _html.push("<tr><td>总计</td><td>" + total_ncf_from_oa + "</td><td>" + total_cash_paid_for_assets + "</td><td>" + total_free_cash_flow + "</td><td>" + total_ncf_from_fa + "</td></tr>");
659
+ Util.render_table_html("cash_flow_table_body", _html);
660
+ // 资产负债
661
+ _html = [];
662
+ j["assets_liabilities_data"].forEach(function (item) {
663
+ let net_assets = item["total_assets"] - item["total_liabilities"];
664
+ let goodwill = "--";
665
+ let goodwill_rate = "--";
666
+ if (item["goodwill"] > 0) {
667
+ goodwill = Util.to_unit(item["goodwill"]);
668
+ goodwill_rate = Util.to_float((item["goodwill"] / net_assets) * 100, 2) + "%";
669
+ }
670
+ let debt_asset_ratio = "--";
671
+ if (item["debt_asset_ratio"] > 0) {
672
+ debt_asset_ratio = Util.to_float(item["debt_asset_ratio"], 2) + "%";
673
+ }
674
+ _html.push("<tr>");
675
+ _html.push("<td>", item["year"], "(", item["quarter"], ")</td>");
676
+ _html.push("<td>", Util.to_unit(item["total_assets"]), "</td>");
677
+ _html.push("<td>", Util.to_unit(item["total_liabilities"]), "</td>");
678
+ _html.push("<td>", Util.to_unit(net_assets), "</td>");
679
+ _html.push("<td>", debt_asset_ratio, "</td>");
680
+ _html.push("<td>", Util.to_unit(item["currency_funds"]), "</td>");
681
+ _html.push("<td>", Util.to_unit(item["short_term_loan"]), "</td>");
682
+ _html.push("<td>", Util.to_unit(item["noncurrent_liab_due_in1y"]), "</td>");
683
+ let flr = "--";
684
+ if (item["short_term_loan"] > 0 && item["noncurrent_liab_due_in1y"] > 0) {
685
+ flr = Util.to_float(item["currency_funds"] / (item["short_term_loan"] + item["noncurrent_liab_due_in1y"]), 2);
686
+ flr = flr >= 1 ? flr : ("<b class='text-danger'>" + flr + "</br>");
687
+ }
688
+ _html.push("<td>", flr, "</td>");
689
+ _html.push("<td>", goodwill, "</td>");
690
+ _html.push("<td>", goodwill_rate, "</td>");
691
+ _html.push("</tr>");
692
+ });
693
+ Util.render_table_html("assets_liabilities_table_body", _html);
694
+ Stock.profit_data = j["profit_data"];
695
+ Stock.render_profit_data();
696
+ $("#quarter").change(function () {
697
+ Stock.render_profit_data();
698
+ });
699
+ Util.hide_tips();
700
+ });
701
+ },
702
+
703
+ render_profit_data: function () {
704
+ let _html = [];
705
+ let quarter = parseInt($("#quarter").val());
706
+ Stock["profit_data"].forEach(function (item) {
707
+ if (quarter === 0 || quarter === item["quarter"]) {
708
+ let tr_cls = (quarter === 0 && item["quarter"] === 4) ? "success" : "";
709
+ _html.push("<tr class='", tr_cls, "'>");
710
+ _html.push("<td>", item["year"], "-", item["quarter"], "</td>");
711
+ _html.push("<td>", item["roe"], "</td>");
712
+ _html.push("<td>", item["net_profit_ratio"], "</td>");
713
+ _html.push("<td>", Util.to_float(item["gross_profit_rate"], 2), "%</td>");
714
+ _html.push("<td>", Util.to_unit(item["net_profits"] * 1000000), "</td>");
715
+ _html.push("<td>", Util.to_float(item["eps"], 3), "元</td>");
716
+ _html.push("<td>", Util.to_unit(item["business_income"] * 1000000), "</td>");
717
+ _html.push("<td>", Util.to_float(item["bips"], 2), "元</td>");
718
+ _html.push("</tr>");
719
+ }
720
+ });
721
+ Util.render_table_html("profit_table_body", _html);
722
+ },
723
+
724
+ fetch_holder_num_data: function () {
725
+ Stock["holder_chart"] = Util.show_chart_loading(Stock["holder_chart"], "holder_data_line_canvas");
726
+ Util.init_table_skeleton({
727
+ "element_id": "holder_data_table",
728
+ "head_cols": [
729
+ {"name": "时间", "table_sort": 1},
730
+ {"name": "人数", "title": "当前股东数", "table_sort": 1},
731
+ {"name": "股价变动", "title": "同期股价变动幅度", "table_sort": 1},
732
+ {"name": "人均持股", "table_sort": 1},
733
+ {"name": "人均持股市值", "table_sort": 1},
734
+ {"name": "流通持股", "title": "十大流通股东持股(万股)", "table_sort": 1},
735
+ {"name": "流通比例", "title": "十大流通股东占流通股本比例", "table_sort": 1},
736
+ {"name": "股东持股", "title": "十大股东持股(万股)", "table_sort": 1},
737
+ {"name": "股东比例", "title": "十大股东占流通股本比例", "table_sort": 1},
738
+ {"name": "基金持股", "title": "基金持股(万股)", "table_sort": 1},
739
+ {"name": "基金比例", "title": "基金占流通股本比例", "table_sort": 1},
740
+ ]
741
+ });
742
+ Util.post("/stock/" + Stock["code"], {action: "holder_num"}, function (j) {
743
+ Stock["holder_chart"].hideLoading();
744
+ let date_data = [];
745
+ let holder_data = [];
746
+ let price_data = [];
747
+ let _html = [];
748
+ let latest_date = 0;
749
+ let max_holder_num = 0;
750
+ let max_holder_num_date = 0;
751
+ let min_holder_num = Util.one_year_second;
752
+ let min_holder_num_date = 0;
753
+ j["data"].forEach(function (item) {
754
+ let date_format = Util.seconds_to_format(item["date"], "%Y-%m-%d");
755
+ latest_date = Math.max(latest_date, item["date"]);
756
+ if (item["holder_num"] > max_holder_num) {
757
+ max_holder_num = item["holder_num"];
758
+ max_holder_num_date = date_format;
759
+ }
760
+ if (item["holder_num"] < min_holder_num) {
761
+ min_holder_num = item["holder_num"];
762
+ min_holder_num_date = date_format;
763
+ }
764
+ date_data.push(date_format);
765
+ holder_data.push(item["holder_num"]);
766
+ price_data.push(item["price"]);
767
+ _html.push("<tr>");
768
+ _html.push("<td>", date_format, "</td>");
769
+ _html.push("<td>", Util.digit_compare_trend(item["holder_num"], item["pre_holder_num"]), "</td>");
770
+ _html.push("<td><b class='", Util.text_color(item["price_change"]), "'>", item["price"], "(", item["price_change"], "%)</b></td>");
771
+ _html.push("<td>", item["avg_num"], "</td>");
772
+ _html.push("<td>", Util.to_unit(item["avg_num"] * item["price"]), "</td>");
773
+ _html.push("<td>", item["circulation_stock"], "</td>");
774
+ _html.push("<td>", item["circulation_stock_ratio"], "%</td>");
775
+ _html.push("<td>", item["main_stock"], "</td>");
776
+ _html.push("<td>", item["main_stock_ratio"], "%</td>");
777
+ _html.push("<td>", item["fund_stock"], "</td>");
778
+ _html.push("<td>", item["fund_stock_ratio"], "%</td>");
779
+ _html.push("</tr>");
780
+ });
781
+ let holder_num_summary = "";
782
+ if (j["latest_date"]) {
783
+ if (j["previous_date"] > latest_date) {
784
+ date_data.unshift(Util.seconds_to_format(j["previous_date"], "%Y-%m-%d")); // 将新项添加到数组的开头
785
+ holder_data.unshift(j["previous_holder_num"]);
786
+ price_data.unshift(j["previous_day_price"]);
787
+ }
788
+ let latest_date_format = Util.seconds_to_format(j["latest_date"], "%Y-%m-%d");
789
+ if (j["latest_date"] > latest_date) {
790
+ latest_date = latest_date_format;
791
+ date_data.unshift(latest_date);
792
+ holder_data.unshift(j["latest_holder_num"]);
793
+ price_data.unshift(j["latest_day_price"]);
794
+ } else {
795
+ latest_date = Util.seconds_to_format(latest_date, "%Y-%m-%d");
796
+ }
797
+ if (j["latest_holder_num"] > max_holder_num) {
798
+ max_holder_num = j["latest_holder_num"];
799
+ max_holder_num_date = latest_date_format;
800
+ }
801
+ if (j["latest_holder_num"] < min_holder_num) {
802
+ min_holder_num = j["latest_holder_num"];
803
+ min_holder_num_date = latest_date_format;
804
+ }
805
+ max_holder_num = Math.max(max_holder_num, j["latest_holder_num"]);
806
+ min_holder_num = Math.min(min_holder_num, j["latest_holder_num"]);
807
+ holder_num_summary += "最新(" + latest_date + "):" + Util.digit_compare_trend(j["latest_holder_num"], j["previous_holder_num"]);
808
+ }
809
+ if (max_holder_num > 0) {
810
+ holder_num_summary += "&nbsp;&nbsp;历史最多(" + max_holder_num_date + "):<b class='text-success'>" + max_holder_num + "</b>&nbsp;&nbsp;历史最少(" + min_holder_num_date + "):<b class='text-danger'>" + min_holder_num + "<b>";
811
+ }
812
+ $("#holder_num_summary").html(holder_num_summary);
813
+ date_data = date_data.reverse();
814
+ holder_data = holder_data.reverse();
815
+ price_data = price_data.reverse();
816
+ Stock["holder_chart"] = Util.multi_axis_line(Stock["holder_chart"], "holder_data_line_canvas", date_data, '股东数', holder_data, '股价', price_data);
817
+ Util.render_table_html("holder_data_table_body", _html);
818
+ Util.hide_tips();
819
+ });
820
+ },
821
+
822
+ fetch_notice: function () {
823
+ Util.show_tips("Loading...");
824
+ Util.init_table_skeleton({
825
+ "element_id": "notice_table",
826
+ "head_cols": [
827
+ {"name": "序号"},
828
+ {"name": "标题"},
829
+ {"name": "日期", "table_sort": 1},
830
+ ]
831
+ });
832
+ let symbol = Util.code_to_symbol(Stock.code).toLowerCase();
833
+ $("#notice_url").attr("href", "https://vip.stock.finance.sina.com.cn/corp/view/vCB_BulletinGather.php?stock_str=" + symbol);
834
+ Util.post("/stock/" + Stock["code"], {action: "notice"}, function (j) {
835
+ let _html = [];
836
+ j["data"].forEach(function (item, i) {
837
+ _html.push("<tr title='", item["title"], "'>");
838
+ _html.push("<td>", i + 1, "</td>");
839
+ _html.push("<td><a target='_blank' rel='noopener noreferrer nofollow' href='", item["url"], "'>", Util.sub_str(item["title"], 70), "</a></td>");
840
+ _html.push("<td>", Util.seconds_to_format(item["date"], "%Y-%m-%d"), "</td>");
841
+ _html.push("</tr>");
842
+ });
843
+ Util.render_table_html("notice_table_body", _html);
844
+ //年报数据
845
+ let now = Util.now();
846
+ let dist_time = Util.one_day_second * 400;
847
+ if ((now - Stock.ttm_second) > dist_time) {
848
+ Util.post(Util.get_url("notice_report_annual"), {action: "report", code: Stock.code}, function (j) {
849
+ let _html = [];
850
+ _html.push("<option value=''>年度报告</option>");
851
+ j["data"].forEach(function (item) {
852
+ _html.push("<option value='", item["url"], "'>", item["year"], "年度报告</option>");
853
+ });
854
+ let report_obj = $("#report");
855
+ report_obj.html(_html.join(""));
856
+ report_obj.change(function () {
857
+ let url = $(this).val();
858
+ if (url) {
859
+ window.open(url, "_blank");
860
+ }
861
+ });
862
+ });
863
+ }
864
+ Util.hide_tips();
865
+ });
866
+ },
867
+
868
+ // 机构研究报告数据
869
+ fetch_report_organization: function () {
870
+ Util.show_tips("Loading...");
871
+ Util.init_table_skeleton({
872
+ "element_id": "report_organization_table",
873
+ "head_cols": [
874
+ {"name": "序号"},
875
+ {"name": "标题"},
876
+ {"name": "机构"},
877
+ {"name": "研究员"},
878
+ {"name": "日期", "table_sort": 1},
879
+ {"name": "价格变化", "table_sort": 1},
880
+ ]
881
+ });
882
+ Util.post("/stock/" + Stock["code"], {action: "report_organization"}, function (j) {
883
+ let _html = [];
884
+ j["data"].forEach(function (item, i) {
885
+ _html.push("<tr title='", item["title"], "'>");
886
+ _html.push("<td>", i + 1, "</td>");
887
+ _html.push("<td><a target='_blank' rel='noopener noreferrer nofollow' href='https://stock.finance.sina.com.cn/stock/go.php/vReport_Show/kind/search/rptid/", item["id"], "/index.phtml'>", Util.sub_str(item["title"], 70), "</a></td>");
888
+ _html.push("<td>", item["organization"], "</td>");
889
+ _html.push("<td>", item["analysts"], "</td>");
890
+ _html.push("<td>", Util.seconds_to_format(item["ctime"], "%Y-%m-%d"), "</td>");
891
+ _html.push("<td>", Util.digit_compare_trend1(Stock["price"], item["day_price"]), "</td>");
892
+ _html.push("</tr>");
893
+ });
894
+ Util.render_table_html("report_organization_table_body", _html);
895
+ Util.hide_tips();
896
+ });
897
+ },
898
+
899
+ // 公募持股
900
+ fetch_public_fund: function () {
901
+ Util.show_tips("Loading...");
902
+ Util.init_table_skeleton({
903
+ "element_id": "public_fund_table",
904
+ "head_cols": [
905
+ {"name": "序号"},
906
+ {"name": "基金代码"},
907
+ {"name": "基金名"},
908
+ {"name": "净值", "tooltip": "单位净值", "table_sort": 1},
909
+ {"name": "资产规模", "table_sort": 1},
910
+ {"name": "基金类型"},
911
+ {"name": "投资类型"},
912
+ {"name": "基金管理公司"},
913
+ {"name": "成立日期", "table_sort": 1},
914
+ {"name": "持有量", "table_sort": 1},
915
+ {"name": "持仓市值", "table_sort": 1},
916
+ {"name": ""},
917
+ ]
918
+ });
919
+ Util.post("/stock/" + Stock["code"], {
920
+ action: "public_fund",
921
+ public_fund_date: $("#public_fund_date").val()
922
+ }, function (j) {
923
+ let _html = [];
924
+ let total_public_fund = 0;
925
+ let total_stock_num = 0;
926
+ let total_market_capital = 0;
927
+ j["data"].forEach(function (item) {
928
+ total_public_fund++;
929
+ total_stock_num += item["stock_num"];
930
+ total_market_capital += item["market_capital"];
931
+ let public_date = "--";
932
+ if (item["public_date"] > 0) {
933
+ public_date = Util.seconds_to_format(item["public_date"], "%Y-%m-%d");
934
+ }
935
+ let net = item["net"];
936
+ let cls = Util.text_color(item["change_percent"])
937
+ if (cls !== "") {
938
+ net = "<b class='" + cls + "'>" + net + "(" + Util.to_float(item["change_percent"], 2) + "%)</b>";
939
+ }
940
+ _html.push("<tr class='", (($.inArray(item["fund_code"], j["etf_code_list"]) > -1) ? "danger" : ""), "'>");
941
+ _html.push("<td>", total_public_fund, "</td>");
942
+ _html.push("<td>", Util.pack_html_link('https://fund.eastmoney.com/' + item["fund_code"] + '.html', item["fund_code"]), "</td>");
943
+ _html.push("<td title='基金概况'>", Util.pack_html_link('https://fundf10.eastmoney.com/jbgk_' + item["fund_code"] + '.html', item["fund_name"]), "</td>");
944
+ _html.push("<td>", net, "</td>");
945
+ _html.push("<td>", item["assets"], "亿</td>");
946
+ _html.push("<td>", item["fund_type"], "</td>");
947
+ _html.push("<td>", item["invest_type"], "</td>");
948
+ _html.push("<td>", item["administrator"], "</td>");
949
+ _html.push("<td>", public_date, "</td>");
950
+ _html.push("<td>", Util.to_ten_thousand(item["stock_num"], 3), "万</td>");
951
+ _html.push("<td>", Util.to_hundred_million(item["market_capital"], 4), "亿</td>");
952
+ _html.push("<td><a class='link_cls' data-toggle='modal' data-target='.public_fund_modal' data-val='", item["fund_code"], "'>详细</a></td>");
953
+ _html.push("</tr>");
954
+ });
955
+ Util.render_table_html("public_fund_table_body", _html);
956
+ $("#public_fund_tips").html('共 <span class="label label-info">' + total_public_fund + '</span> 家, <span class="label label-info">' + Util.to_hundred_million(total_stock_num, 3) + '</span> 亿股,<span class="label label-info">' + Util.to_hundred_million(total_market_capital, 3) + '</span>亿市值');
957
+ if ($("#public_fund_date").length === 0) {
958
+ Util.post("/stock/" + Stock["code"], {action: "public_fund_date"}, function (j) {
959
+ let _html = [];
960
+ _html.push('<select id="public_fund_date">');
961
+ j["data"].forEach(function (item) {
962
+ _html.push('<option value="', item["date"], '">', item["date"], '</option>');
963
+ });
964
+ _html.push('</select>');
965
+ $("#public_fund_date_zone").html(_html.join(""));
966
+ $("#public_fund_date").change(function () {
967
+ Stock.fetch_public_fund();
968
+ });
969
+ });
970
+ }
971
+ Util.hide_tips();
972
+ });
973
+ },
974
+
975
+ fetch_public_fund_change: function () {
976
+ Stock["pfc_stock_chart"] = Util.show_chart_loading(Stock["pfc_stock_chart"], "pfc_stock_line_canvas");
977
+ Util.init_table_skeleton({
978
+ "element_id": "pfc_fund_table",
979
+ "head_cols": [
980
+ {"name": "时间", "table_sort": 1},
981
+ {"name": "股价", "table_sort": 1},
982
+ {"name": "总持股数(万股)", "table_sort": 1},
983
+ {"name": "持仓家数", "table_sort": 1},
984
+ ]
985
+ });
986
+ Util.post("/stock/" + Stock["code"], {action: "public_fund_change"}, function (j) {
987
+ Stock["pfc_stock_chart"].hideLoading();
988
+ let date_data = [];
989
+ let fund_num_data = [];
990
+ let stock_num_data = [];
991
+ let price_data = [];
992
+ let _html = [];
993
+ j["data"].forEach(function (item) {
994
+ let date_format = Util.seconds_to_format(item["date"], "%Y-%m-%d");
995
+ date_data.push(date_format);
996
+ fund_num_data.push(item["fund_num"]);
997
+ stock_num_data.push(item["stock_num"]);
998
+ price_data.push(item["price"]);
999
+ _html.push("<tr>");
1000
+ _html.push("<td>", date_format, "</td>");
1001
+ _html.push("<td>", item["price"], "</td>");
1002
+ _html.push("<td>", item["stock_num"], "</td>");
1003
+ _html.push("<td>", item["fund_num"], "</td>");
1004
+ _html.push("</tr>");
1005
+ });
1006
+ date_data = date_data.reverse();
1007
+ fund_num_data = fund_num_data.reverse();
1008
+ stock_num_data = stock_num_data.reverse();
1009
+ price_data = price_data.reverse();
1010
+ Stock["pfc_stock_chart"] = Util.multi_axis_line(Stock["pfc_stock_chart"], "pfc_stock_line_canvas", date_data, '总持股数(万股)', stock_num_data, '股价', price_data);
1011
+ Stock["pfc_fund_chart"] = Util.multi_axis_line(Stock["pfc_fund_chart"], "pfc_fund_line_canvas", date_data, '持仓家数', fund_num_data, '股价', price_data);
1012
+ if (j["cur_stock_num"] && j["cur_stock_num"] > 0 && j["pre_stock_num"] && j["pre_stock_num"] > 0) {
1013
+ $("#pfc_stock_tips").html("(当前持股数: <b class='text-info'>" + Util.to_unit(j["cur_stock_num"] * 10000, 3) + "</b>, 环比: " + Util.year_price_rate(j["cur_stock_num"], j["pre_stock_num"]) + ")");
1014
+ }
1015
+ if (j["cur_fund_num"] && j["cur_fund_num"] > 0 && j["pre_fund_num"] && j["pre_fund_num"] > 0) {
1016
+ $("#pfc_fund_tips").html("(当前基金数: <b class='text-info'>" + Util.to_unit(j["cur_fund_num"]) + "</b>, 环比: " + Util.year_price_rate(j["cur_fund_num"], j["pre_fund_num"]) + ")");
1017
+ }
1018
+ if (j["cfi_id"]) {
1019
+ $("#pfc_stock_tips").parent().find("a").each(function () {
1020
+ let url = $(this).attr("href");
1021
+ if (url && url.indexOf("cfi") !== -1) {
1022
+ $(this).attr("href", "https://quote.cfi.cn/jjccbd/" + j["cfi_id"] + "/" + Stock["code"] + ".html");
1023
+ }
1024
+ });
1025
+ }
1026
+ Util.render_table_html("pfc_fund_table_body", _html);
1027
+ Util.hide_tips();
1028
+ });
1029
+ },
1030
+
1031
+ handle_metrics_statistics: function (metrics, date_type) {
1032
+ Stock[metrics + "_bar_chart"] = Util.startup_metrics_statistics(Stock[metrics + "_bar_chart"], metrics, date_type);
1033
+ if (metrics === "margin" || metrics === "hkex_holding") {
1034
+ let t_obj = $("#" + metrics + "_title");
1035
+ if (!t_obj.hasClass("link_cls")) {
1036
+ t_obj.addClass("link_cls");
1037
+ t_obj.click(function () {
1038
+ Util.eventFire(metrics, 'click');
1039
+ });
1040
+ }
1041
+ }
1042
+ let metrics_drop_down_btn_id = metrics + "_btn_" + date_type;
1043
+ let interval = parseInt($("#" + metrics_drop_down_btn_id).text());
1044
+ Util.post("/stock/" + Stock["code"], {
1045
+ action: "metrics_statistics",
1046
+ metrics: metrics,
1047
+ date_type: date_type,
1048
+ interval: interval
1049
+ }, function (j) {
1050
+ Stock[metrics + "_bar_chart"].hideLoading();
1051
+ let date_data = [];
1052
+ let value_data = [];
1053
+ let price_data = [];
1054
+ let color_data = [];
1055
+ j["data"].forEach(function (item) {
1056
+ date_data.push(item["date"]);
1057
+ value_data.push(item["value"]);
1058
+ price_data.push(item["price"]);
1059
+ color_data.push("#E74C3C");
1060
+ });
1061
+ if (j["current"] && j["current"]["value"] && j["current"]["value"] > 0) {
1062
+ date_data.push(j["current"]["date"]);
1063
+ value_data.push(j["current"]["value"]);
1064
+ price_data.push(j["current"]["price"]);
1065
+ color_data.push("#C9CBCF");
1066
+ }
1067
+ let title = Util.strip_bracket_string($("#" + metrics + "_title").text());
1068
+ Stock[metrics + "_bar_chart"] = Util.chart_bar_line(Stock[metrics + "_bar_chart"], metrics + "_bar_canvas", date_data, value_data, title, color_data, price_data, "价格");
1069
+ if (Stock[metrics + "_bar_chart"]) {
1070
+ Stock[metrics + "_bar_chart"].on('click', function (params) {
1071
+ if (params["componentSubType"] === "bar" && (metrics === "amount" || metrics === "volume")) {
1072
+ let date_type = "week";
1073
+ $("." + metrics + "_bar_btn").each(function () {
1074
+ if ($(this).hasClass("btn-info")) {
1075
+ date_type = $(this).attr("data-val");
1076
+ }
1077
+ });
1078
+ let date = params["name"];
1079
+ if (date_type === "week") {
1080
+ date = Util.format_to_second(date);
1081
+ date = date - 4 * Util.one_day_second;
1082
+ Stock.hist_start_date = Util.seconds_to_format(date, "%Y-%m-%d");
1083
+ Stock.hist_end_date = Util.seconds_to_format(date - 1 + 7 * Util.one_day_second, "%Y-%m-%d");
1084
+ } else if (date_type === "month") {
1085
+ Stock.hist_start_date = date;
1086
+ let d_arr = date.split("-");
1087
+ let year = parseInt(d_arr[0]);
1088
+ let month = parseInt(d_arr[1]);
1089
+ if (month === 12) {
1090
+ month = 1;
1091
+ year += 1;
1092
+ } else {
1093
+ month += 1;
1094
+ }
1095
+ date = Util.format_to_second(year + "-" + month + "-01");
1096
+ Stock.hist_end_date = Util.seconds_to_format(date - 1, "%Y-%m-%d");
1097
+ } else if (date_type === "season") {
1098
+ let d_arr = date.split("-");
1099
+ let year = parseInt(d_arr[0]);
1100
+ let season = d_arr[1];
1101
+ if (season === "S1") {
1102
+ Stock.hist_start_date = year + "-01-01";
1103
+ date = year + "-04-01";
1104
+ } else if (season === "S2") {
1105
+ Stock.hist_start_date = year + "-04-01";
1106
+ date = year + "-07-01";
1107
+ } else if (season === "S3") {
1108
+ Stock.hist_start_date = year + "-07-01";
1109
+ date = year + "-10-01";
1110
+ } else {
1111
+ Stock.hist_start_date = year + "-10-01";
1112
+ date = (year + 1) + "-01-01";
1113
+ }
1114
+ date = Util.format_to_second(date);
1115
+ Stock.hist_end_date = Util.seconds_to_format(date - 1, "%Y-%m-%d");
1116
+ }
1117
+ Stock.hist_type = date_type;
1118
+ delete Stock.data["hist_trade"];
1119
+ Util.eventFire("hist_trade", 'click');
1120
+ }
1121
+ });
1122
+ }
1123
+ if (j["interval_week"]) {
1124
+ $("#" + metrics + "_tips").html("<b class='text-success'>(创连续" + j["interval_week"] + "周成交额最低)<b>");
1125
+ }
1126
+ Util.hide_tips();
1127
+ });
1128
+ },
1129
+
1130
+ fetch_bias_data: function () {
1131
+ Util.show_tips("Loading...");
1132
+ Util.post("/stock/" + Stock["code"], {action: "bias"}, function (j) {
1133
+ let date_data = [];
1134
+ let bias20_data = [];
1135
+ let bias60_data = [];
1136
+ let bias120_data = [];
1137
+ let price_data = [];
1138
+ let color_data = [];
1139
+ let current_date = 0;
1140
+ let current_bias20 = 0;
1141
+ let current_bias60 = 0;
1142
+ let current_bias120 = 0;
1143
+ j["data"].forEach(function (item) {
1144
+ if (item["date"] > current_date) {
1145
+ current_date = item["date"];
1146
+ current_bias20 = item["bias20"];
1147
+ current_bias60 = item["bias60"];
1148
+ current_bias120 = item["bias120"];
1149
+ }
1150
+ date_data.push(Util.seconds_to_format(item["date"], "%Y-%m-%d"));
1151
+ bias20_data.push(item["bias20"]);
1152
+ bias60_data.push(item["bias60"]);
1153
+ bias120_data.push(item["bias120"]);
1154
+ price_data.push(item["price"]);
1155
+ color_data.push("#C9CBCF");
1156
+ });
1157
+ Stock["bias_chart"] = Util.bias_bar_line(Stock["bias_chart"], "bias_line_chart", date_data, bias120_data, color_data, bias20_data, bias60_data, price_data);
1158
+ $("#bias_summary").html("当前120日乖离率:" + Util.label_text_color(current_bias120) + ", 60日乖离率:" + Util.label_text_color(current_bias60) + ", 20日乖离率:" + Util.label_text_color(current_bias20) + ",20日最高乖离率:" + Util.label_text_color(j["max_bias20"]) + "(" + Util.seconds_to_format(j["max_bias20_date"], "%Y-%m-%d") + "),20日最低乖离率:" + Util.label_text_color(j["min_bias20"]) + "(" + Util.seconds_to_format(j["min_bias20_date"], "%Y-%m-%d") + ")");
1159
+ Util.hide_tips();
1160
+ });
1161
+ },
1162
+
1163
+ fetch_margin: function () {
1164
+ Stock["rzye_chart"] = Util.show_chart_loading(Stock["rzye_chart"], "rzye_line_canvas");
1165
+ let is_summary = 0;
1166
+ if (!Stock.rzye_chart) {
1167
+ is_summary = 1;
1168
+ }
1169
+ let payload = {
1170
+ action: "margin",
1171
+ is_summary: is_summary,
1172
+ date_type: $("#margin_date_type").val(),
1173
+ start_date: $("#margin_start_date").val(),
1174
+ end_date: $("#margin_end_date").val()
1175
+ };
1176
+ Util.post("/stock/" + Stock["code"], payload, function (j) {
1177
+ Stock["rzye_chart"].hideLoading();
1178
+ let date_data = [];
1179
+ let rzye_data = [];
1180
+ let rqye_data = [];
1181
+ let price_data = [];
1182
+ let rzye_low = 0;
1183
+ let rzye_high = 0;
1184
+ j["data"].forEach(function (item) {
1185
+ if (rzye_low === 0 || item["rzye"] < rzye_low) {
1186
+ rzye_low = item["rzye"];
1187
+ }
1188
+ rzye_high = Math.max(rzye_high, item["rzye"]);
1189
+ date_data.push(Util.seconds_to_format(item["date"], "%Y-%m-%d"));
1190
+ rzye_data.push(Util.to_hundred_million(item["rzye"]));
1191
+ rqye_data.push(Util.to_float(item["rqye"] / 10000, 2));
1192
+ price_data.push(item["price"]);
1193
+ });
1194
+ let margin_summary = "";
1195
+ if (!Stock.rzye_chart && j["latest"].length > 0) {
1196
+ if (j["latest"].length === 1) {
1197
+ margin_summary = "最新(" + Util.seconds_to_format(j["latest"][0]["date"], "%Y-%m-%d") + "): " + Util.to_unit(j["latest"][0]["rzye"]);
1198
+ } else if (j["latest"].length === 2) {
1199
+ let d1 = j["latest"][0];
1200
+ let d2 = j["latest"][1];
1201
+ let difference = d1["rzye"] - d2["rzye"];
1202
+ let dist_tips = "";
1203
+ if (difference > 0) {
1204
+ dist_tips = "(<b title='" + Util.strip_html(Util.to_unit(d2["rzye"])) + "' style='color: #a94442;'>+" + Util.strip_html(Util.to_unit(difference)) + "</b>)";
1205
+ } else if (difference < 0) {
1206
+ dist_tips = "(<b title='" + Util.strip_html(Util.to_unit(d2["rzye"])) + "' style='color: #3c763d;'>" + Util.strip_html(Util.to_unit(difference)) + "</b>)";
1207
+ }
1208
+ margin_summary = "最新(" + Util.seconds_to_format(d1["date"], "%Y-%m-%d") + "): " + Util.to_unit(d1["rzye"]) + dist_tips;
1209
+ }
1210
+ }
1211
+ margin_summary = '[' + Util.pack_html_link(j["url"], Stock.name) + ']融资余额(单位:亿)' + margin_summary + ' 最高: ' + Util.to_unit(rzye_high) + ' 最低: ' + Util.to_unit(rzye_low);
1212
+ if (j["high"] && j["high"]["date"] && j["high"]["date"] > 0) {
1213
+ margin_summary += ' 历史最高: ' + Util.to_unit(j["high"]["rzye"]) + '(' + Util.seconds_to_format(j["high"]["date"], "%Y-%m-%d") + ')';
1214
+ }
1215
+ if (j["low"] && j["low"]["date"] && j["low"]["date"] > 0) {
1216
+ margin_summary += ' 历史最低: ' + Util.to_unit(j["low"]["rzye"]) + '(' + Util.seconds_to_format(j["low"]["date"], "%Y-%m-%d") + ')';
1217
+ }
1218
+ $("#margin_summary").html(margin_summary);
1219
+ Stock["rzye_chart"] = Util.multi_axis_line(Stock["rzye_chart"], "rzye_line_canvas", date_data, '融资余额', rzye_data, '股价', price_data);
1220
+ let flow_data = [];
1221
+ date_data = [];
1222
+ let color_data = [];
1223
+ j["flow_data"].forEach(function (item) {
1224
+ if (item["value"] !== 0) {
1225
+ date_data.push(item["date"]);
1226
+ flow_data.push(item["value"]);
1227
+ color_data.push(item["value"] > 0 ? "#E74C3C" : "#1ABB9C");
1228
+ }
1229
+ });
1230
+ Stock["margin_month_flow_chart"] = Util.chart_basic_bar(Stock["margin_month_flow_chart"], "margin_month_flow_bar_chart", date_data, flow_data, "增幅", color_data);
1231
+ Stock["rqye_chart"] = Util.multi_axis_line(Stock["rqye_chart"], "rqye_line_canvas", date_data, '融券余额', rqye_data, '股价', price_data);
1232
+ Util.hide_tips();
1233
+ });
1234
+ },
1235
+
1236
+ fetch_hkex_holding: function () {
1237
+ Stock["hkex_holding_chart"] = Util.show_chart_loading(Stock["hkex_holding_chart"], "hkex_holding_line_canvas");
1238
+ let is_summary = 0;
1239
+ if (!Stock.hkex_holding_chart) {
1240
+ is_summary = 1;
1241
+ }
1242
+ let payload = {
1243
+ action: "hkex_holding",
1244
+ is_summary: is_summary,
1245
+ date_type: $("#hkex_holding_date_type").val(),
1246
+ start_date: $("#hkex_start_date").val(),
1247
+ end_date: $("#hkex_end_date").val()
1248
+ };
1249
+ Util.post("/stock/" + Stock["code"], payload, function (j) {
1250
+ Stock["hkex_holding_chart"].hideLoading();
1251
+ let date_data = [];
1252
+ let volume_data = [];
1253
+ let price_data = [];
1254
+ j["data"].forEach(function (item) {
1255
+ date_data.push(Util.seconds_to_format(item["date"], "%Y-%m-%d"));
1256
+ volume_data.push(item["volume"]);
1257
+ price_data.push(item["price"]);
1258
+ });
1259
+ if (!Stock.hkex_holding_chart && j["latest"].length > 0) {
1260
+ let circulation_stock = $("#circulation_stock").attr("data-val");
1261
+ let latest_html = "";
1262
+ if (j["latest"].length === 1) {
1263
+ let holding_num = Util.to_hundred_million(j["latest"][0]["volume"]);
1264
+ let holding_rate = Math.round((holding_num / circulation_stock) * 10000) / 100;
1265
+ latest_html = "最新(" + Util.seconds_to_format(j["latest"][0]["date"], "%Y-%m-%d") + "): " + holding_num + "亿股, 占 <b>" + holding_rate + "%</b> 流通股, ";
1266
+ } else if (j["latest"].length === 2) {
1267
+ let d1 = j["latest"][0];
1268
+ let d2 = j["latest"][1];
1269
+ let difference = d1["volume"] - d2["volume"];
1270
+ let dist_tips = "";
1271
+ if (difference > 0) {
1272
+ dist_tips = "(<b title='" + Util.strip_html(Util.to_unit(d2["volume"])) + "股' style='color: #a94442;'>+" + Util.strip_html(Util.to_unit(difference)) + "股</b>)";
1273
+ } else if (difference < 0) {
1274
+ dist_tips = "(<b title='" + Util.strip_html(Util.to_unit(d2["volume"])) + "股' style='color: #3c763d;'>" + Util.strip_html(Util.to_unit(difference)) + "股</b>)";
1275
+ }
1276
+ let holding_num = Util.to_hundred_million(d1["volume"]);
1277
+ let holding_rate = Math.round((holding_num / circulation_stock) * 10000) / 100;
1278
+ latest_html = "最新(" + Util.seconds_to_format(d1["date"], "%Y-%m-%d") + "): " + holding_num + "亿股" + dist_tips + ", 占 <b>" + holding_rate + "%</b> 流通股, ";
1279
+ }
1280
+ let hhs_obj = $("#hkex_holding_summary");
1281
+ let hkex_holding_summary = hhs_obj.text();
1282
+ hkex_holding_summary = '[<a target="_blank" rel="noopener noreferrer nofollow" class="link_cls" href="' + j["url"] + '">' +
1283
+ hkex_holding_summary + "</a>]" + latest_html + ' 最高: ' + Util.to_unit(j["high"]["volume"]) +
1284
+ '股(' + Util.seconds_to_format(j["high"]["date"], "%Y-%m-%d") +
1285
+ ') 最低: ' + Util.to_unit(j["low"]["volume"]) + '股(' + Util.seconds_to_format(j["low"]["date"], "%Y-%m-%d") + ')';
1286
+ hhs_obj.html(hkex_holding_summary);
1287
+ }
1288
+ Stock["hkex_holding_chart"] = Util.multi_axis_line(Stock["hkex_holding_chart"], "hkex_holding_line_canvas", date_data, '持股数', volume_data, '股价', price_data);
1289
+ let flow_data = [];
1290
+ date_data = [];
1291
+ let color_data = [];
1292
+ j["flow_data"].forEach(function (item) {
1293
+ date_data.push(item["date"]);
1294
+ flow_data.push(item["value"]);
1295
+ color_data.push(item["value"] > 0 ? "#E74C3C" : "#1ABB9C");
1296
+ });
1297
+ Stock["hkex_holding_month_flow_chart"] = Util.chart_basic_bar(Stock["hkex_holding_month_flow_chart"], "hkex_holding_month_flow_chart", date_data, flow_data, "增幅", color_data);
1298
+ Util.hide_tips();
1299
+ });
1300
+ },
1301
+
1302
+ init: function (code, name, price) {
1303
+ Stock.code = code;
1304
+ Stock.name = name;
1305
+ Stock.price = Util.to_float(price, 2);
1306
+ Util.init_hsgt_stock_detail_component("hsgt_stock_detail_modal");
1307
+ Util.init_public_fund_component("public_fund_modal");
1308
+
1309
+ let request_arguments = Util.request_arguments();
1310
+ localStorage[Stock.tab_token] = request_arguments["tab"] ? request_arguments["tab"] : "base";
1311
+ Util.tab_switch(Stock.tab_token, Stock.fetch_data);
1312
+ Stock.fetch_data();
1313
+
1314
+ let circulation_stock = $("#circulation_stock").attr("data-val");
1315
+ let total_stock = $("#total_stock").attr("data-val");
1316
+ let stock_rate = Util.to_float(((circulation_stock / total_stock) * 10000) / 100, 2);
1317
+ $("#stock_rate").html("(" + stock_rate + "%)");
1318
+ }
1319
+
1320
+ };