index.html 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title></title>
  8. <link rel="stylesheet" href="css/common.css">
  9. </head>
  10. <style>
  11. [v-cloak]{
  12. display: none !important;
  13. }
  14. </style>
  15. <body>
  16. <!-- <div class="h20 bgHeader"></div> -->
  17. <div id="app" v-cloak>
  18. <div class="header plr15 flex alcenter bgHeader white fixed pt30">
  19. <img src="../../static/image/return.png" class="h15 wt15 mr20" @click="goback">
  20. <div class="white ft18 bold ">{{symbol}}</div>
  21. </div>
  22. <div>
  23. <div class="pt60 pb10 plr20 bgHeader" style="min-height: 50px;">
  24. <div class="flex alcenter between pt5">
  25. <div class="tc" :class="[updown.substring(0,1) == '-'?'red':'green']">
  26. <p class="bold ft24">{{newprice || '0.00'}}</p>
  27. <p class="mt10">{{updown ||'0.00'}}%</p>
  28. </div>
  29. <div class="w50">
  30. <div class="flex between mb5">
  31. <span class="blue">{{translatedInfo.high || '--'}}</span>
  32. <span class="blue white">{{maxprice || '0.00'}}</span>
  33. </div>
  34. <div class="flex between mb5">
  35. <span class="blue">{{translatedInfo.low || '--'}}</span>
  36. <span class="blue white">{{minprice ||'0.00'}}</span>
  37. </div>
  38. <div class="flex between">
  39. <span class="blue">{{translatedInfo.volume || '--'}}</span>
  40. <span class="blue white">{{dayvom ||'0.00'}}</span>
  41. </div>
  42. </div>
  43. </div>
  44. </div>
  45. <div id="tv_chart_container" style="width:100%;height:60vh;margin-top: 5px;"></div>
  46. <div class="mt5 pb100 bgHeader">
  47. <div class="plr10">
  48. <div class="flex alcenter ptb5 ft12">
  49. <div class="flex1 ">{{translatedInfo.num || '--'}}</div>
  50. <div class="flex1 tc">{{translatedInfo.price || '--'}}</div>
  51. <div class="flex1 tr">{{translatedInfo.time || '--'}}</div>
  52. </div>
  53. <div class="">
  54. <div class="flex alcenter ptb5" :class="[item.way==1?'red':'green']" v-for="(item,i) in complete" :key="i">
  55. <div class="flex1">{{item.number |fixed4}}</div>
  56. <div class="flex1 tc">{{item.price}}</div>
  57. <div class="flex1 tr">{{item.time.substr(11)}}</div>
  58. </div>
  59. </div>
  60. </div>
  61. </div>
  62. <div class="flex between plr20 alcenter plr20 bgHeader fixed w100 pos_l0b0" style="height: 80px;">
  63. <!-- <span>添加自选</span>
  64. <img src="./images/collect.png" style="width: 20px;" id="noCollct" v-if="!hasCollcet" @click="triggerCollcet(true)">
  65. <img src="./images/collect_active.png" style="width: 20px;" id="hasCollct" @click="triggerCollcet(false)" v-else > -->
  66. <button class="goTranbuy bgRed flex1 ptb10 mr20 white radius4" @click="goTrade('buy')">{{translatedInfo.buy || '--'}}</button>
  67. <button class="goTransell bgGreen flex1 ptb10 white radius4" @click="goTrade('sell')">{{translatedInfo.sell || '--'}}</button>
  68. </div>
  69. </div>
  70. </div>
  71. <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
  72. <script src="lib/vue.min.js"></script>
  73. <script src="lib/jquery.js"></script>
  74. <!-- <script src="javascripts/jquery.cookie.js"></script> -->
  75. <script src="lib/layer_mobile/layer.js"></script>
  76. <script src="javascripts/main.js"></script>
  77. <script src="javascripts/socket.io.js"></script>
  78. <script src="tradeview/charting_library/charting_library.min.js"></script>
  79. <script>
  80. document.addEventListener('UniAppJSBridgeReady', function() {
  81. // document.querySelector('.btn-list').addEventListener('click', function(evt) {
  82. // uni.navigateBack({
  83. // delta: 1
  84. // });
  85. // });
  86. var vm = new Vue({
  87. el: '#app',
  88. data: {
  89. widget: null,
  90. symbolInfo: null,
  91. feed: null,
  92. wsEx: null,
  93. ws: null,
  94. lists: [],
  95. newData: '',
  96. symbol: '',
  97. priceScale: 100000,
  98. histime: '',
  99. newprice: '0.00',
  100. updown: '0.00',
  101. maxprice: '0.00',
  102. minprice: '0.00',
  103. dayvom: '0.00',
  104. currencyList: [],
  105. couponSelected: '',
  106. legal_id: '',
  107. currency_id: '',
  108. legal_name: '',
  109. currency_name: '',
  110. hasCollcet: '',
  111. myid: '',
  112. balance: '',
  113. rates: '',
  114. // websockUrl: 'wss://www.hsfuture.net/ws',
  115. // url: 'http://www.hsfuture.net/',
  116. websockUrl: 'wss://'+_HOST+'/ws',
  117. url: _DOMAIN+'/',
  118. complete: [],
  119. transwords: {
  120. zh: {
  121. high: '高',
  122. low: '低',
  123. volume: '24H量',
  124. num: '数量',
  125. price: '价格',
  126. time: '时间',
  127. buy: '买入',
  128. sell: '卖出',
  129. },
  130. en: {
  131. high: 'high',
  132. low: 'low',
  133. volume: '24H volume',
  134. num: 'number',
  135. price: 'price',
  136. time: 'time',
  137. buy: 'buy',
  138. sell: 'sell',
  139. },
  140. hk: {
  141. high: '高',
  142. low: '低',
  143. volume: '24H量',
  144. num: '數量',
  145. price: '價格',
  146. time: '時間',
  147. buy: '買入',
  148. sell: '賣出',
  149. },
  150. jp: {
  151. high: '高さ',
  152. low: '低い',
  153. volume: '24 h量',
  154. num: '数',
  155. price: '価格',
  156. time: '時間',
  157. buy: '購入',
  158. sell: '売却',
  159. },
  160. kor:{
  161. high : '높음',
  162. low : '낮음',
  163. volume : '24H 볼륨',
  164. num : '숫자',
  165. price : '가격',
  166. time : '시간',
  167. buy : '구매',
  168. sell : '매도',
  169. },
  170. th:{
  171. high:"โด่ง",
  172. low:"หดหู่ใจ",
  173. volume:"ปริมาณ",
  174. num:"จำนวนรวม",
  175. price:"ราคา",
  176. time:"กาละ",
  177. buy:"ซื้อ",
  178. sell:"ขาย"
  179. },
  180. de:{
  181. high:"hoch",
  182. low:"niedrig",
  183. volume:"24h Volumen",
  184. num:"Anzahl",
  185. price:"Preis",
  186. time:"Zeit",
  187. buy:"Kauf",
  188. sell:"Verkauf aus"
  189. },
  190. fra:{
  191. high:"Élevé",
  192. low:"Faible",
  193. volume:"Quantité 24h",
  194. num:"Nombre",
  195. price:"Prix",
  196. time:"Temps",
  197. buy:"Acheter",
  198. sell:"Vendre"
  199. },
  200. hi:{
  201. high:"उच्च",
  202. low:"कम",
  203. volume:"24H मात्रा",
  204. num:"मात्रा",
  205. price:"कीमत",
  206. time:"समय",
  207. buy:"खरीदना",
  208. sell:"बेचना"
  209. },
  210. id:{
  211. high:"tinggi",
  212. low:"rendah",
  213. volume:"Volume 24 jam",
  214. num:"Kuantitas",
  215. price:"harga",
  216. time:"waktu",
  217. buy:"Membeli di",
  218. sell:"Menjual"
  219. },
  220. pt:{
  221. high:"Alto",
  222. low:"Baixo",
  223. volume:"24h volume",
  224. num:"Número",
  225. price:"Preço",
  226. time:"Tempo",
  227. buy:"Compra",
  228. sell:"Vender fora"
  229. },
  230. ru:{
  231. high:"высота",
  232. low:"низкий",
  233. volume:"24H количество",
  234. num:"количество",
  235. price:"цена",
  236. time:"время",
  237. buy:"покупать",
  238. sell:"продать"
  239. },
  240. spa:{
  241. high:"Alto",
  242. low:"Baja",
  243. volume:"Cantidad de 24h",
  244. num:"Cantidad",
  245. price:"Precio",
  246. time:"Tiempo",
  247. buy:"Comprar",
  248. sell:"Vender"
  249. }
  250. },
  251. translatedInfo: {},
  252. lang: ''
  253. },
  254. filters:{
  255. fixed4:function(vals){
  256. var values = iTofixed(vals,4);
  257. return values;
  258. }
  259. },
  260. created() {
  261. var that = this;
  262. if(window.plus){
  263. setTimeout(()=>{
  264. plus.navigator.setStatusBarStyle('light');
  265. },300)
  266. that.lang = plus.storage.getItem('lang') || 'en';
  267. }else{
  268. // that.lang = JSON.parse(localStorage.getItem('lang')).data;
  269. that.lang = localStorage.getItem('lang') || 'en';
  270. }
  271. var paramsed = get_all_params();
  272. that.symbol = paramsed.symbol;
  273. let c_name = paramsed.symbol.split('/')
  274. that.legal_name = c_name[1];
  275. that.currency_name = c_name[0];
  276. that.legal_id = paramsed.legal_id;
  277. that.currency_id = paramsed.currency_id;
  278. // console.log(that.$t('market.volume'));
  279. that.translatedInfo = that.transwords[that.lang];
  280. // document.getElementById('mytitle').innerText='123';
  281. // document.title = '123' ;
  282. document.title = that.symbol;
  283. if(window.plus){
  284. if (!plus.storage.getItem('token')) {
  285. uni.navigateTo({
  286. url: '/pages/mine/login',
  287. });
  288. }
  289. }else{
  290. if (localStorage.getItem('token') == null || localStorage.getItem('token') == '') {
  291. uni.navigateTo({
  292. url: '/pages/mine/login',
  293. });
  294. }
  295. }
  296. // uni.setNavigationBarColor({
  297. // frontColor: '#ffffff',
  298. // backgroundColor: '#ff0000',})
  299. // plus.navigator.setStatusBarStyle('black');
  300. // plus.navigator.setStatusBarBackground('#102030');
  301. },
  302. computed: {
  303. listenState() { //监听交易对
  304. return this.symbol;
  305. }
  306. },
  307. watch: {
  308. listenState: function(a, b) { //监听交易对
  309. if (a != b && b != '') {
  310. this.widget.setSymbol(a, localStorage.getItem('tim'), function onReadyCallback() {}) //切换币种
  311. }
  312. }
  313. },
  314. mounted() {
  315. this.createWidget();
  316. this.getComplete();
  317. },
  318. destroyed() {
  319. this.removeWidget();
  320. },
  321. beforeDestroy() {
  322. },
  323. methods: {
  324. goback() {
  325. if(window.plus){
  326. uni.navigateBack({
  327. delta: 1
  328. });
  329. }else{
  330. history.back(-1);
  331. }
  332. },
  333. goTrade(mytype) {
  334. let localData = {
  335. legal_name: this.legal_name,
  336. legal_id: this.legal_id,
  337. currency_name: this.currency_name,
  338. currency_id: this.currency_id,
  339. }
  340. if(window.plus){
  341. plus.storage.setItem('tradeData', JSON.stringify(localData));
  342. plus.storage.setItem('tradeType', mytype);
  343. }else{
  344. localStorage.setItem('tradeData', JSON.stringify(localData));
  345. localStorage.setItem('tradeType', mytype);
  346. }
  347. uni.switchTab({
  348. url: '/pages/trade/trade'
  349. })
  350. },
  351. getComplete() {
  352. initDataToken({
  353. url: 'transaction/deal',
  354. type: 'POST',
  355. data: {
  356. legal_id: this.legal_id,
  357. currency_id: this.currency_id,
  358. }
  359. }, res => {
  360. this.complete = res.complete;
  361. this.completeSocket();
  362. })
  363. },
  364. // 收藏
  365. triggerCollcet(e) {
  366. // if(e){
  367. // this.initDataToken({url:'quotation/collect',data:{match_id:this.myid},type:'POST'},(res)=>{
  368. // alert(res);
  369. // this.hasCollcet=true;
  370. // })
  371. // }else{
  372. // this.initDataToken({url:'quotation/remove',data:{match_id:this.myid}},(res,msg)=>{
  373. // this.hasCollcet=false;
  374. // })
  375. // }
  376. },
  377. timestampToTime(timestamp) {
  378. // var time=''
  379. // if(timestamp.length>11){
  380. // time=timestamp
  381. // }else{
  382. // time=timestamp*1000
  383. // }
  384. // var now = new Date(time),
  385. //    y = now.getFullYear(),
  386. //    m = now.getMonth() + 1,
  387. //    d = now.getDate();
  388. //    return y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d) + " " + now.toTimeString().substr(0, 8);
  389. var time=''
  390. if(timestamp.toString().length>11){
  391. time=timestamp
  392. }else{
  393. time=timestamp*1000
  394. }
  395. var date = new Date(time); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
  396. var Y = date.getFullYear() + '-';
  397. var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
  398. var D = date.getDate() >= 10 ? date.getDate() + ' ' : ('0' + date.getDate()) + ' ';
  399. var h = date.getHours() >= 10 ? date.getHours() + ':' : ('0' + date.getHours()) + ':';
  400. var m = date.getMinutes() >= 10 ? date.getMinutes() + ':' : ('0' + date.getMinutes()) + ':';
  401. var s = date.getSeconds() >= 10 ? date.getSeconds() : ('0' + date.getSeconds());
  402. return Y + M + D + h + m + s;
  403. },
  404. // 默认
  405. connect(real) { //封装推送数据
  406. var that = this, tokens='';
  407. if(window.plus){
  408. if (plus.storage.getItem('uid')) {
  409. tokens=JSON.parse(plus.storage.getItem('uid')).data
  410. }
  411. }else{
  412. if(localStorage.getItem('uid')){
  413. tokens = JSON.parse(localStorage.getItem('uid')).data;
  414. }
  415. }
  416. var socket = io(socket_api);
  417. socket.emit('login',tokens);
  418. // 后端推送来消息时
  419. socket.on('kline', msg=> {
  420. if (msg.type == 'kline') {
  421. let obj = {}
  422. var types = localStorage.getItem('type');
  423. if (that.symbol == msg.symbol&&types==msg.period) {
  424. obj.open = Number(msg.open)
  425. obj.low = Number(msg.low)
  426. obj.high = Number(msg.high)
  427. obj.close = Number(msg.close)
  428. obj.volume = Number(msg.volume)
  429. obj.time = Number(msg.time)
  430. that.newprice = msg.close;
  431. real(obj)
  432. }
  433. }
  434. });
  435. socket.on('daymarket', msg=> {
  436. if (msg.type == 'daymarket') {
  437. if (that.symbol == msg.symbol) {
  438. that.maxprice = msg.high;
  439. that.minprice = msg.low;
  440. that.dayvom = Number(msg.volume).toFixed(4);
  441. that.updown = msg.change;
  442. }
  443. }
  444. });
  445. },
  446. // 币币交易全站交易WebSocket
  447. completeSocket() { //封装推送数据
  448. var that = this,tokens='';
  449. if(window.plus){
  450. if (plus.storage.getItem('uid')) {
  451. tokens=JSON.parse(plus.storage.getItem('uid')).data
  452. }
  453. }else{
  454. if(localStorage.getItem('uid')){
  455. tokens = JSON.parse(localStorage.getItem('uid')).data;
  456. }
  457. }
  458. var socket = io(socket_api);
  459. socket.emit("login",tokens);
  460. socket.on("match_trade", msg=> {
  461. if (msg.type == "match_trade") {
  462. if(that.legal_id == msg.legal_id && that.currency_id == msg.currency_id){
  463. var times = that.timestampToTime(msg.data[0].ts)
  464. var way;
  465. msg.data[0].direction == 'buy' ? way=1 : way=2;
  466. var data ={
  467. price: msg.data[0].price,
  468. time: times,
  469. number: msg.data[0].amount,
  470. way: way
  471. }
  472. that.complete.unshift(data)
  473. if(that.complete.length >20){
  474. that.complete.pop()
  475. }
  476. }
  477. }
  478. });
  479. },
  480. createWidget() {
  481. let _this = this;
  482. this.$nextTick(function() {
  483. let widget = _this.widget = new TradingView.widget({
  484. symbol: _this.symbol,
  485. interval: 1,
  486. debug: true,
  487. fullscreen: false,
  488. autosize: true,
  489. container_id: "tv_chart_container",
  490. // datafeed: new Datafeeds.UDFCompatibleDatafeed("http://demo_feed.tradingview.com"),
  491. datafeed: _this.createFeed(),
  492. library_path: "tradeview/charting_library/",
  493. custom_css_url: 'bundles/new.css',
  494. locale: _this.lang,
  495. width: "100%",
  496. height: 516,
  497. drawings_access: {
  498. type: 'black',
  499. tools: [{
  500. name: "Regression Trend"
  501. }]
  502. },
  503. disabled_features: [ // 禁用的功能
  504. 'left_toolbar', 'widget_logo', 'header_saveload', 'compare_symbol', 'display_market_status',
  505. 'go_to_date', 'header_chart_type', 'header_compare', 'header_interval_dialog_button',
  506. 'header_resolutions', 'header_screenshot', 'header_symbol_search', 'header_undo_redo',
  507. 'legend_context_menu', 'show_hide_button_in_legend', 'show_interval_dialog_on_key_press',
  508. 'snapshot_trading_drawings', 'symbol_info', 'timeframes_toolbar', 'use_localstorage_for_settings',
  509. 'volume_force_overlay'
  510. ],
  511. enabled_features: [ // 启用的功能(备注:disable_resolution_rebuild 功能用于控制当时间范围为1个月时,日期刻度是否都是每个月1号
  512. 'dont_show_boolean_study_arguments', 'hide_last_na_study_output', 'move_logo_to_main_pane',
  513. 'same_data_requery', 'side_toolbar_in_fullscreen_mode', 'disable_resolution_rebuild'
  514. ],
  515. charts_storage_url: 'http://saveload.tradingview.com',
  516. charts_storage_api_version: "1.1",
  517. toolbar_bg: "transparent",
  518. timezone: "Asia/Shanghai",
  519. studies_overrides: {
  520. 'volume.precision': '1000'
  521. },
  522. overrides: _this.overrides()
  523. });
  524. widget.MAStudies = [];
  525. widget.selectedIntervalButton = null;
  526. // widget.setLanguage('en')
  527. widget.onChartReady(function() { //图表方法
  528. // document.getElementById('trade-view').childNodes[0].setAttribute('style', 'display:block;width:100%;height:100%;');
  529. //let that =this
  530. widget.chart().createStudy('Moving Average', false, true, [15, 'close', 0], null, {
  531. 'Plot.color': '#e843da'
  532. });
  533. widget.chart().createStudy("MA Cross", false, false, [10, 20]);
  534. let buttonArr = [{
  535. value: "1min",
  536. period: "1",
  537. text: "Time",
  538. chartType: 3,
  539. type: "1min"
  540. },
  541. {
  542. value: "1",
  543. period: "1m",
  544. text: "1min",
  545. chartType: 1,
  546. type: "1min"
  547. },
  548. {
  549. value: "5",
  550. period: "5m",
  551. text: "5min",
  552. chartType: 1,
  553. type: "5min"
  554. },
  555. {
  556. value: "30",
  557. period: "30m",
  558. text: "30min",
  559. chartType: 1,
  560. type: "30min"
  561. },
  562. {
  563. value: "60",
  564. period: "60分钟",
  565. text: "1hour",
  566. chartType: 1,
  567. type: "60min"
  568. },
  569. {
  570. value: "1D",
  571. period: "1D",
  572. text: "1day",
  573. chartType: 1,
  574. type: "1day"
  575. },
  576. {
  577. value: "1W",
  578. period: "1W",
  579. text: "1week",
  580. chartType: 1,
  581. type: "1week"
  582. },
  583. {
  584. value: "1M",
  585. period: "1M",
  586. text: "1mon",
  587. chartType: 1,
  588. type: "1mon"
  589. }
  590. ];
  591. let btn = {};
  592. let nowTime = '';
  593. buttonArr.forEach((v, i) => {
  594. let button = widget.createButton()
  595. button.attr('title', v.text)
  596. .addClass("my2")
  597. .text(v.text)
  598. if (v.text == '1min') {
  599. button.css({
  600. 'color': '#218bde',
  601. 'border-bottom': '1px solid #218bde'
  602. })
  603. localStorage.setItem('tim', '1min') //默认为1分钟
  604. localStorage.setItem('type', '1min') //默认为1分钟
  605. }
  606. btn = button.on("click", function(e) {
  607. $(this).parents(".left").children().find(".my2").removeAttr("style"); //去掉1分钟的
  608. handleClick(e, v.value, v.type);
  609. widget.chart().setChartType(v.chartType); //改变K线类型
  610. });
  611. });
  612. if (localStorage.getItem('tim') == '1min') {
  613. widget.chart().setChartType(1);
  614. }
  615. let handleClick = (e, value, type) => {
  616. _this.setSymbol = function(symbol, value) {
  617. gh.chart().setSymbol(symbol, value);
  618. };
  619. localStorage.setItem('tim', value);
  620. localStorage.setItem('type', type) //默认为1分钟
  621. widget.chart().setResolution(value, function onReadyCallback() {}); //改变分辨率
  622. $(e.target)
  623. .addClass("mydate")
  624. .closest("div.space-single")
  625. .siblings("div.space-single")
  626. .find("div.button")
  627. .removeClass("mydate")
  628. };
  629. });
  630. _this.widget = widget;
  631. })
  632. },
  633. createFeed() {
  634. let this_vue = this;
  635. let Datafeed = {};
  636. Datafeed.DataPulseUpdater = function(datafeed, updateFrequency) {
  637. this._datafeed = datafeed;
  638. this._subscribers = {};
  639. this._requestsPending = 0;
  640. var that = this;
  641. var update = function() {
  642. if (that._requestsPending > 0) {
  643. return;
  644. }
  645. for (var listenerGUID in that._subscribers) {
  646. var subscriptionRecord = that._subscribers[listenerGUID];
  647. var resolution = subscriptionRecord.resolution;
  648. var datesRangeRight = parseInt((new Date().valueOf()) / 1000);
  649. // BEWARE: please note we really need 2 bars, not the only last one
  650. // see the explanation below. `10` is the `large enough` value to work around holidays
  651. var datesRangeLeft = datesRangeRight - that.periodLengthSeconds(resolution, 10);
  652. that._requestsPending++;
  653. (function(_subscriptionRecord) { // eslint-disable-line
  654. that._datafeed.getBars(_subscriptionRecord.symbolInfo, resolution, datesRangeLeft, datesRangeRight,
  655. function(bars) {
  656. that._requestsPending--;
  657. // means the subscription was cancelled while waiting for data
  658. if (!that._subscribers.hasOwnProperty(listenerGUID)) {
  659. return;
  660. }
  661. if (bars.length === 0) {
  662. return;
  663. }
  664. var lastBar = bars[bars.length - 1];
  665. if (!isNaN(_subscriptionRecord.lastBarTime) && lastBar.time < _subscriptionRecord.lastBarTime) {
  666. return;
  667. }
  668. var subscribers = _subscriptionRecord.listeners;
  669. // BEWARE: this one isn't working when first update comes and this update makes a new bar. In this case
  670. // _subscriptionRecord.lastBarTime = NaN
  671. var isNewBar = !isNaN(_subscriptionRecord.lastBarTime) && lastBar.time > _subscriptionRecord.lastBarTime;
  672. // Pulse updating may miss some trades data (ie, if pulse period = 10 secods and new bar is started 5 seconds later after the last update, the
  673. // old bar's last 5 seconds trades will be lost). Thus, at fist we should broadcast old bar updates when it's ready.
  674. if (isNewBar) {
  675. if (bars.length < 2) {
  676. throw new Error('Not enough bars in history for proper pulse update. Need at least 2.');
  677. }
  678. var previousBar = bars[bars.length - 2];
  679. for (var i = 0; i < subscribers.length; ++i) {
  680. subscribers[i](previousBar);
  681. }
  682. }
  683. _subscriptionRecord.lastBarTime = lastBar.time;
  684. for (var i = 0; i < subscribers.length; ++i) {
  685. subscribers[i](lastBar);
  686. }
  687. },
  688. // on error
  689. function() {
  690. that._requestsPending--;
  691. });
  692. })(subscriptionRecord);
  693. }
  694. };
  695. if (typeof updateFrequency != 'undefined' && updateFrequency > 0) {
  696. setInterval(update, updateFrequency);
  697. }
  698. };
  699. Datafeed.DataPulseUpdater.prototype.periodLengthSeconds = function(resolution, requiredPeriodsCount) {
  700. var daysCount = 0;
  701. if (resolution === 'D') {
  702. daysCount = requiredPeriodsCount;
  703. } else if (resolution === 'M') {
  704. daysCount = 31 * requiredPeriodsCount;
  705. } else if (resolution === 'W') {
  706. daysCount = 7 * requiredPeriodsCount;
  707. } else {
  708. daysCount = requiredPeriodsCount * resolution / (24 * 60);
  709. }
  710. return daysCount * 24 * 60 * 60;
  711. };
  712. Datafeed.DataPulseUpdater.prototype.subscribeDataListener = function(symbolInfo, resolution, newDataCallback,
  713. listenerGUID) {
  714. this._datafeed._logMessage('Subscribing ' + listenerGUID);
  715. if (!this._subscribers.hasOwnProperty(listenerGUID)) {
  716. this._subscribers[listenerGUID] = {
  717. symbolInfo: symbolInfo,
  718. resolution: resolution,
  719. lastBarTime: NaN,
  720. listeners: []
  721. };
  722. }
  723. this._subscribers[listenerGUID].listeners.push(newDataCallback);
  724. };
  725. Datafeed.DataPulseUpdater.prototype.unsubscribeDataListener = function(listenerGUID) {
  726. this._datafeed._logMessage('Unsubscribing ' + listenerGUID);
  727. delete this._subscribers[listenerGUID];
  728. };
  729. Datafeed.Container = function(updateFrequency) {
  730. this._configuration = {
  731. supports_search: false,
  732. supports_group_request: false,
  733. supported_resolutions: ['1', '3', '5', '15', '30', '60', '120', '240', '360', '720', '1D', '3D', '1W',
  734. '1M'
  735. ],
  736. supports_marks: true,
  737. supports_timescale_marks: true,
  738. exchanges: ['gh']
  739. };
  740. this._barsPulseUpdater = new Datafeed.DataPulseUpdater(this, updateFrequency || 10 * 1000);
  741. // this._quotesPulseUpdater = new Datafeed.QuotesPulseUpdater(this);
  742. this._enableLogging = true;
  743. this._callbacks = {};
  744. this._initializationFinished = true;
  745. this._fireEvent('initialized');
  746. this._fireEvent('configuration_ready');
  747. };
  748. Datafeed.Container.prototype._fireEvent = function(event, argument) {
  749. if (this._callbacks.hasOwnProperty(event)) {
  750. var callbacksChain = this._callbacks[event];
  751. for (var i = 0; i < callbacksChain.length; ++i) {
  752. callbacksChain[i](argument);
  753. }
  754. this._callbacks[event] = [];
  755. }
  756. };
  757. Datafeed.Container.prototype._logMessage = function(message) {
  758. if (this._enableLogging) {
  759. var now = new Date();
  760. }
  761. };
  762. Datafeed.Container.prototype.on = function(event, callback) {
  763. if (!this._callbacks.hasOwnProperty(event)) {
  764. this._callbacks[event] = [];
  765. }
  766. this._callbacks[event].push(callback);
  767. return this;
  768. };
  769. Datafeed.Container.prototype.onReady = function(callback) {
  770. let that = this;
  771. if (this._configuration) {
  772. setTimeout(function() {
  773. callback(that._configuration);
  774. }, 0);
  775. } else {
  776. this.on('configuration_ready', function() {
  777. callback(that._configuration);
  778. });
  779. }
  780. };
  781. Datafeed.Container.prototype.resolveSymbol = function(symbolName, onSymbolResolvedCallback,
  782. onResolveErrorCallback) {
  783. this._logMessage("GOWNO :: resolve symbol " + symbolName);
  784. Promise.resolve().then(() => {
  785. // this._logMessage("GOWNO :: onResultReady inject "+'AAPL');
  786. onSymbolResolvedCallback({
  787. "name": this_vue.symbol,
  788. "timezone": "Asia/Shanghai",
  789. "pricescale": this_vue.priceScale,
  790. "minmov": 1, //minmov(最小波动), pricescale(价格精度), minmove2, fractional(分数)
  791. "minmov2": 0, //这是一个神奇的数字来格式化复杂情况下的价格。
  792. "ticker": this_vue.symbol,
  793. "description": "",
  794. "type": "bitcoin",
  795. "volume_precision": 8,
  796. // "exchange-traded": "sdt",
  797. // "exchange-listed": "sdt",
  798. //现在,这两个字段都为某个交易所的略称。将被显示在图表的图例中,以表示此商品。目前此字段不用于其他目的。
  799. "has_intraday": true,
  800. "has_weekly_and_monthly": true,
  801. "has_no_volume": false, //布尔表示商品是否拥有成交量数据。
  802. 'session': '24x7',
  803. 'supported_resolutions': ['1', '3', '5', '15', '30', '60', '120', '240', '360', '720', '1D', '3D',
  804. '1W',
  805. '1M'
  806. ]
  807. });
  808. })
  809. };
  810. //初始化数据
  811. Datafeed.Container.prototype.getBars = function(symbolInfo, resolution, rangeStartDate, rangeEndDate,
  812. onHistoryCallback, onErrorCallback) {
  813. // if (rangeStartDate > 0 && (rangeStartDate + '').length > 10) {
  814. // throw new Error(['Got a JS time instead of Unix one.', rangeStartDate, rangeEndDate]);
  815. // }
  816. if (resolution.indexOf('D') == -1 && resolution.indexOf('W') == -1 && resolution.indexOf('M') == -1) {
  817. resolution = resolution + 'min'
  818. } else if (resolution.indexOf('W') != -1 || resolution.indexOf('M') != -1) {
  819. resolution = resolution
  820. }
  821. // console.log(rangeStartDate);
  822. // console.log(rangeEndDate)
  823. // console.log(resolution);
  824. // console.log(symbolInfo.name)
  825. $.ajax({
  826. url: this_vue.url + 'api/currency/new_timeshar?' + 'from=' + rangeStartDate + '&to=' + rangeEndDate +
  827. '&symbol=' + symbolInfo.name + '&period=' + resolution,
  828. type: 'get',
  829. success: function(res) {
  830. // console.log(res.data)
  831. if (res.code == 1 && res.data && res.data.length > 0) {
  832. res.data.forEach((item, i) => {
  833. item.open = Number(item.open)
  834. item.close = Number(item.close)
  835. item.high = Number(item.high)
  836. item.low = Number(item.low)
  837. // if(len==i){
  838. // console.log(i)
  839. // this_vue.newprice = item.close - 0
  840. // this_vue.maxprice = item.high - 0
  841. // this_vue.minprice = item.low - 0
  842. // this_vue.dayvom = Number(item.vol).toFixed(2);
  843. // this_vue.updown = ((item.close - item.open) / (item.open - 0) * 100).toFixed(4).toString();
  844. // }
  845. })
  846. onHistoryCallback(res.data, {
  847. noData: false
  848. })
  849. onHistoryCallback([], {
  850. noData: true
  851. })
  852. }
  853. if (!res.data || res.code == -1) {
  854. onHistoryCallback([], {
  855. noData: true
  856. })
  857. }
  858. if (res.data && res.data.length == 0) {
  859. onHistoryCallback([], {
  860. noData: true
  861. })
  862. }
  863. }
  864. })
  865. };
  866. //实时数据
  867. Datafeed.Container.prototype.subscribeBars = function(symbolInfo, resolution, onRealtimeCallback,
  868. listenerGUID,
  869. onResetCacheNeededCallback) {
  870. this_vue.connect(onRealtimeCallback)
  871. //this._barsPulseUpdater.subscribeDataListener(symbolInfo, resolution, onRealtimeCallback, listenerGUID, onResetCacheNeededCallback);
  872. };
  873. Datafeed.Container.prototype.unsubscribeBars = function(listenerGUID) {
  874. this._barsPulseUpdater.unsubscribeDataListener(listenerGUID);
  875. };
  876. return new Datafeed.Container;
  877. },
  878. updateWidget(item) {
  879. this.symbolInfo = {
  880. name: item,
  881. ticker: item,
  882. description: "",
  883. session: "24x7",
  884. supported_resolutions: ['1', '5', '30', '60', '240', '1D', '3D', '1W', '1M'],
  885. has_intraday: true,
  886. has_daily: true,
  887. has_weekly_and_monthly: true,
  888. timezone: "UTC",
  889. }
  890. this.removeWidget();
  891. this.createWidget();
  892. },
  893. removeWidget() {
  894. if (this.widget) {
  895. this.widget.remove();
  896. this.widget = null;
  897. }
  898. },
  899. overrides() {
  900. let style = {
  901. up: "#02C289",
  902. down: "#e86d43",
  903. bg: "#131f30",
  904. grid: "#1E2740",
  905. cross: "#1E2740",
  906. border: "#4e5b85",
  907. text: "#61688A",
  908. areatop: "rgba(122, 152, 247, .1)",
  909. areadown: "rgba(122, 152, 247, .02)"
  910. };
  911. return {
  912. 'volumePaneSize': "small", //large, medium, small, tiny
  913. 'paneProperties.topMargin': '20',
  914. "scalesProperties.lineColor": style.bg,
  915. "scalesProperties.textColor": style.text,
  916. "paneProperties.background": style.bg, //改变背景色的重要代码
  917. "paneProperties.vertGridProperties.color": style.grid,
  918. "paneProperties.horzGridProperties.color": style.grid,
  919. "paneProperties.crossHairProperties.color": style.cross,
  920. "paneProperties.legendProperties.showLegend": true,
  921. "paneProperties.legendProperties.showStudyArguments": true,
  922. "paneProperties.legendProperties.showStudyTitles": true,
  923. "paneProperties.legendProperties.showStudyValues": true,
  924. "paneProperties.legendProperties.showSeriesTitle": true,
  925. "paneProperties.legendProperties.showSeriesOHLC": true,
  926. "mainSeriesProperties.candleStyle.upColor": style.up,
  927. "mainSeriesProperties.candleStyle.downColor": style.down,
  928. "mainSeriesProperties.candleStyle.drawWick": true,
  929. "mainSeriesProperties.candleStyle.drawBorder": true,
  930. "mainSeriesProperties.candleStyle.borderColor": style.border,
  931. "mainSeriesProperties.candleStyle.borderUpColor": style.up,
  932. "mainSeriesProperties.candleStyle.borderDownColor": style.down,
  933. "mainSeriesProperties.candleStyle.wickUpColor": style.up,
  934. "mainSeriesProperties.candleStyle.wickDownColor": style.down,
  935. "mainSeriesProperties.candleStyle.barColorsOnPrevClose": false,
  936. "mainSeriesProperties.hollowCandleStyle.upColor": style.up,
  937. "mainSeriesProperties.hollowCandleStyle.downColor": style.down,
  938. "mainSeriesProperties.hollowCandleStyle.drawWick": true,
  939. "mainSeriesProperties.hollowCandleStyle.drawBorder": true,
  940. "mainSeriesProperties.hollowCandleStyle.borderColor": style.border,
  941. "mainSeriesProperties.hollowCandleStyle.borderUpColor": style.up,
  942. "mainSeriesProperties.hollowCandleStyle.borderDownColor": style.down,
  943. "mainSeriesProperties.hollowCandleStyle.wickColor": style.line,
  944. "mainSeriesProperties.haStyle.upColor": style.up,
  945. "mainSeriesProperties.haStyle.downColor": style.down,
  946. "mainSeriesProperties.haStyle.drawWick": true,
  947. "mainSeriesProperties.haStyle.drawBorder": true,
  948. "mainSeriesProperties.haStyle.borderColor": style.border,
  949. "mainSeriesProperties.haStyle.borderUpColor": style.up,
  950. "mainSeriesProperties.haStyle.borderDownColor": style.down,
  951. "mainSeriesProperties.haStyle.wickColor": style.border,
  952. "mainSeriesProperties.haStyle.barColorsOnPrevClose": false,
  953. "mainSeriesProperties.barStyle.upColor": style.up,
  954. "mainSeriesProperties.barStyle.downColor": style.down,
  955. "mainSeriesProperties.barStyle.barColorsOnPrevClose": false,
  956. "mainSeriesProperties.barStyle.dontDrawOpen": false,
  957. "mainSeriesProperties.lineStyle.color": style.border,
  958. "mainSeriesProperties.lineStyle.linewidth": 1,
  959. "mainSeriesProperties.lineStyle.priceSource": "close",
  960. "mainSeriesProperties.areaStyle.color1": style.areatop,
  961. "mainSeriesProperties.areaStyle.color2": style.areadown,
  962. "mainSeriesProperties.areaStyle.linecolor": style.borders,
  963. "mainSeriesProperties.areaStyle.linewidth": 1,
  964. "mainSeriesProperties.areaStyle.priceSource": "close"
  965. }
  966. },
  967. chose() {
  968. this.widget.setLanguage('en') //设置语言
  969. }
  970. },
  971. })
  972. })
  973. </script>
  974. </body>
  975. </html>