umychart.data.wechat.js 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796
  1. /*
  2. copyright (c) 2018 jones
  3. http://www.apache.org/licenses/LICENSE-2.0
  4. 开源项目 https://github.com/jones2000/HQChart
  5. jones_2000@163.com
  6. 行情数据结构 及计算方法
  7. */
  8. import
  9. {
  10. JSCommonCoordinateData_MARKET_SUFFIX_NAME as MARKET_SUFFIX_NAME
  11. } from "./umychart.coordinatedata.wechat.js";
  12. function Guid()
  13. {
  14. function S4()
  15. {
  16. return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  17. }
  18. return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
  19. }
  20. //历史K线数据
  21. function HistoryData()
  22. {
  23. this.Date;
  24. this.YClose;
  25. this.Open;
  26. this.Close;
  27. this.High;
  28. this.Low;
  29. this.Vol;
  30. this.Amount;
  31. this.Time; //分钟 HHMM / 秒HHMMSS
  32. this.FlowCapital = 0; //流通股本
  33. this.Position = null; //持仓量
  34. //指数才有的数据
  35. this.Stop; //停牌家数
  36. this.Up; //上涨
  37. this.Down; //下跌
  38. this.Unchanged; //平盘
  39. }
  40. //数据复制
  41. HistoryData.Copy=function(data)
  42. {
  43. var newData=new HistoryData();
  44. newData.Date=data.Date;
  45. newData.YClose=data.YClose;
  46. newData.Open=data.Open;
  47. newData.Close=data.Close;
  48. newData.High=data.High;
  49. newData.Low=data.Low;
  50. newData.Vol=data.Vol;
  51. newData.Amount=data.Amount;
  52. newData.Time=data.Time;
  53. newData.FlowCapital = data.FlowCapital;
  54. newData.Position = data.Position;
  55. //指数才有的数据
  56. newData.Stop = data.Stop;
  57. newData.Up = data.Up;
  58. newData.Down = data.Down;
  59. newData.Unchanged = data.Unchanged;
  60. return newData;
  61. }
  62. //把数据 src 复制到 dest中
  63. HistoryData.CopyTo = function (dest, src)
  64. {
  65. dest.Date = src.Date;
  66. dest.YClose = src.YClose;
  67. dest.Open = src.Open;
  68. dest.Close = src.Close;
  69. dest.High = src.High;
  70. dest.Low = src.Low;
  71. dest.Vol = src.Vol;
  72. dest.Amount = src.Amount;
  73. dest.Time = src.Time;
  74. dest.FlowCapital = src.FlowCapital;
  75. dest.Stop = src.Stop;
  76. dest.Up = src.Up;
  77. dest.Down = src.Down;
  78. dest.Unchanged = src.Unchanged;
  79. }
  80. //数据复权拷贝
  81. HistoryData.CopyRight=function(data,seed)
  82. {
  83. var newData=new HistoryData();
  84. newData.Date=data.Date;
  85. newData.YClose=data.YClose*seed;
  86. newData.Open=data.Open*seed;
  87. newData.Close=data.Close*seed;
  88. newData.High=data.High*seed;
  89. newData.Low=data.Low*seed;
  90. newData.Vol=data.Vol;
  91. newData.Amount=data.Amount;
  92. newData.FlowCapital = data.FlowCapital;
  93. newData.Position = data.Position;
  94. return newData;
  95. }
  96. //分钟数据
  97. function MinuteData()
  98. {
  99. this.Close;
  100. this.Open;
  101. this.High;
  102. this.Low;
  103. this.Vol;
  104. this.Amount;
  105. this.DateTime;
  106. this.Increase;
  107. this.Risefall;
  108. this.AvPrice;
  109. this.Date;
  110. this.Time;
  111. this.Position = null; //持仓量
  112. }
  113. //单指标数据
  114. function SingleData()
  115. {
  116. this.Date; //日期
  117. this.Value; //数据
  118. }
  119. function DataPlus() { }; //外部数据计算方法接口
  120. DataPlus.GetMinutePeriodData = null;
  121. /*
  122. DataPlus.GetMinutePeriodData=function(period,data,self)
  123. {
  124. }
  125. */
  126. //////////////////////////////////////////////////////////////////////
  127. // 数据集合
  128. function ChartData()
  129. {
  130. this.Data=new Array();
  131. this.DataOffset=0; //数据偏移
  132. this.Period=0; //周期 0 日线 1 周线 2 月线 3年线
  133. this.Right=0; //复权 0 不复权 1 前复权 2 后复权
  134. this.Symbol; //股票代码
  135. this.Data2=new Array(); //第1组数据 走势图:历史分钟数据
  136. this.GetCloseMA=function(dayCount)
  137. {
  138. var result=new Array();
  139. for (var i = 0, len = this.Data.length; i < len; i++)
  140. {
  141. if (i < dayCount)
  142. {
  143. result[i]=null;
  144. continue;
  145. }
  146. var sum = 0;
  147. for (var j = 0; j < dayCount; j++)
  148. {
  149. sum += this.Data[i - j].Close;
  150. }
  151. result[i]=sum / dayCount;
  152. }
  153. return result;
  154. }
  155. this.GetVolMA=function(dayCount)
  156. {
  157. var result=new Array();
  158. for (var i = 0, len = this.Data.length; i < len; i++)
  159. {
  160. if (i < dayCount)
  161. {
  162. result[i]=null;
  163. continue;
  164. }
  165. var sum = 0;
  166. for (var j = 0; j < dayCount; j++)
  167. {
  168. sum += this.Data[i - j].Vol;
  169. }
  170. result[i]=sum / dayCount;
  171. }
  172. return result;
  173. }
  174. this.GetAmountMA=function(dayCount)
  175. {
  176. var result=new Array();
  177. for (var i = 0, len = this.Data.length; i < len; i++)
  178. {
  179. if (i < dayCount)
  180. {
  181. result[i]=null;
  182. continue;
  183. }
  184. var sum = 0;
  185. for (var j = 0; j < dayCount; j++)
  186. {
  187. sum += this.Data[i - j].Amount;
  188. }
  189. result[i]=sum / dayCount;
  190. }
  191. return result;
  192. }
  193. //获取收盘价
  194. this.GetClose=function()
  195. {
  196. var result=new Array();
  197. for(var i in this.Data)
  198. {
  199. result[i]=this.Data[i].Close;
  200. }
  201. return result;
  202. }
  203. this.GetYClose=function()
  204. {
  205. var result=new Array();
  206. for(var i in this.Data)
  207. {
  208. result[i]=this.Data[i].YClose;
  209. }
  210. return result;
  211. }
  212. this.GetHigh=function()
  213. {
  214. var result=new Array();
  215. for(var i in this.Data)
  216. {
  217. result[i]=this.Data[i].High;
  218. }
  219. return result;
  220. }
  221. this.GetLow=function()
  222. {
  223. var result=new Array();
  224. for(var i in this.Data)
  225. {
  226. result[i]=this.Data[i].Low;
  227. }
  228. return result;
  229. }
  230. this.GetOpen=function()
  231. {
  232. var result=new Array();
  233. for(var i in this.Data)
  234. {
  235. result[i]=this.Data[i].Open;
  236. }
  237. return result;
  238. }
  239. this.GetVol=function()
  240. {
  241. var result=new Array();
  242. for(var i in this.Data)
  243. {
  244. result[i]=this.Data[i].Vol;
  245. }
  246. return result;
  247. }
  248. this.GetAmount=function()
  249. {
  250. var result=new Array();
  251. for(var i in this.Data)
  252. {
  253. result[i]=this.Data[i].Amount;
  254. }
  255. return result;
  256. }
  257. this.GetPosition = function ()
  258. {
  259. var result = new Array();
  260. for (var i in this.Data)
  261. {
  262. result[i] = this.Data[i].Position;
  263. }
  264. return result;
  265. }
  266. this.GetDate = function ()
  267. {
  268. var result = [];
  269. for (var i in this.Data)
  270. {
  271. result[i] = this.Data[i].Date;
  272. }
  273. return result;
  274. }
  275. this.GetTime = function ()
  276. {
  277. var result = [];
  278. for (var i in this.Data)
  279. {
  280. result[i] = this.Data[i].Time;
  281. }
  282. return result;
  283. }
  284. this.GetUp = function () //上涨家数
  285. {
  286. var result = [];
  287. for (var i in this.Data) {
  288. result[i] = this.Data[i].Up;
  289. }
  290. return result;
  291. }
  292. this.GetDown = function () //下跌家数
  293. {
  294. var result = [];
  295. for (var i in this.Data) {
  296. result[i] = this.Data[i].Down;
  297. }
  298. return result;
  299. }
  300. this.GetYear=function()
  301. {
  302. var result=new Array();
  303. for(var i in this.Data)
  304. {
  305. result[i]=parseInt(this.Data[i].Date/10000);
  306. }
  307. return result;
  308. }
  309. this.GetMonth=function()
  310. {
  311. var result=new Array();
  312. for(var i in this.Data)
  313. {
  314. result[i]=parseInt(this.Data[i].Date%10000/100);
  315. }
  316. return result;
  317. }
  318. //分时图均价
  319. this.GetAvPrice=function()
  320. {
  321. var result=new Array();
  322. for(var i in this.Data)
  323. {
  324. var value=this.Data[i].AvPrice;
  325. if (ChartData.IsNumber(value))
  326. result[i]=value;
  327. else
  328. result[i]=0;
  329. }
  330. return result;
  331. }
  332. //获取数据日期和时间范围
  333. this.GetDateRange=function()
  334. {
  335. if (!this.Data || this.Data.length<=0) return null;
  336. var start=this.Data[0];
  337. var end=this.Data[this.Data.length-1];
  338. var range={ Start:{Date:start.Date}, End:{Date:end.Date} };
  339. if (ChartData.IsNumber(start.Time)) range.Start.Time=start.Time;
  340. if (ChartData.IsNumber(end.Time)) range.End.Time=end.Time;
  341. return range;
  342. }
  343. this.GetDateIndex = function (data) //日期转化 对应数据索引
  344. {
  345. for (var i = 0, j = 0; i < this.Data.length;)
  346. {
  347. var date = this.Data[i].Date;
  348. if (j >= data.length) break;
  349. var dateItem = data[j];
  350. if (dateItem.Date == date)
  351. {
  352. dateItem.Index = i;
  353. ++j;
  354. }
  355. else if (dateItem.Date < date)
  356. {
  357. ++j;
  358. }
  359. else
  360. {
  361. ++i;
  362. }
  363. }
  364. }
  365. this.GetDateTimeIndex = function (data) //日期 时间转化 对应数据索引
  366. {
  367. for (var i = 0, j = 0; i < this.Data.length;)
  368. {
  369. var date = this.Data[i].Date;
  370. var time = this.Data[i].Time;
  371. if (j >= data.length) break;
  372. var dateTimeItem = data[j];
  373. if (dateTimeItem.Date == date && dateTimeItem.Time == time)
  374. {
  375. dateTimeItem.Index = i;
  376. ++j;
  377. }
  378. else if (dateTimeItem.Date < date || (dateTimeItem.Date == date && dateTimeItem.Time < time))
  379. {
  380. ++j;
  381. }
  382. else
  383. {
  384. ++i;
  385. }
  386. }
  387. }
  388. this.GetMinutePeriodData=function(period)
  389. {
  390. if (DataPlus.GetMinutePeriodData) return DataPlus.GetMinutePeriodData(period, this.Data, this);
  391. if (period > CUSTOM_MINUTE_PERIOD_START && period <= CUSTOM_MINUTE_PERIOD_END)
  392. return this.GetMinuteCustomPeriodData(period - CUSTOM_MINUTE_PERIOD_START);
  393. var result = [];
  394. var periodDataCount = 5;
  395. if (period == 5)
  396. periodDataCount = 5;
  397. else if (period == 6)
  398. periodDataCount = 15;
  399. else if (period == 7)
  400. periodDataCount = 30;
  401. else if (period == 8)
  402. periodDataCount = 60;
  403. else if (period == 11)
  404. periodDataCount = 120;
  405. else if (period == 12)
  406. periodDataCount = 240;
  407. else
  408. return this.Data;
  409. var bFirstPeriodData = false;
  410. var newData = null;
  411. var preTime = null; //上一次的计算时间
  412. for (var i = 0; i < this.Data.length; )
  413. {
  414. bFirstPeriodData = true;
  415. for (var j = 0; j < periodDataCount && i < this.Data.length; ++i)
  416. {
  417. if (bFirstPeriodData)
  418. {
  419. newData = new HistoryData();
  420. result.push(newData);
  421. bFirstPeriodData = false;
  422. }
  423. var minData = this.Data[i];
  424. if (minData == null)
  425. {
  426. ++j;
  427. continue;
  428. }
  429. if (minData.Time == 925 && (preTime == null || preTime != 924)) //9:25, 9:30 不连续就不算个数
  430. {
  431. }
  432. else if (minData.Time == 930 && (preTime == null || preTime != 929))
  433. {
  434. }
  435. else if (minData.Time == 1300 && (preTime == null || preTime != 1259)) //1点的数据 如果不是连续的 就不算个数
  436. {
  437. }
  438. else
  439. ++j;
  440. newData.Date = minData.Date;
  441. newData.Time = minData.Time;
  442. preTime = newData.Time;
  443. if (minData.Open==null || minData.Close==null)
  444. continue;
  445. if (newData.Open==null || newData.Close==null)
  446. {
  447. newData.Open=minData.Open;
  448. newData.High=minData.High;
  449. newData.Low=minData.Low;
  450. newData.YClose=minData.YClose;
  451. newData.Close=minData.Close;
  452. newData.Vol=minData.Vol;
  453. newData.Amount=minData.Amount;
  454. newData.Position = minData.Position;
  455. newData.FlowCapital = minData.FlowCapital;
  456. }
  457. else
  458. {
  459. if (newData.High<minData.High)
  460. newData.High=minData.High;
  461. if (newData.Low>minData.Low)
  462. newData.Low=minData.Low;
  463. newData.Close=minData.Close;
  464. newData.Vol+=minData.Vol;
  465. newData.Amount+=minData.Amount;
  466. newData.Position = minData.Position;
  467. newData.FlowCapital = minData.FlowCapital;
  468. }
  469. if (i + 1 < this.Data.length) //判断下一个数据是否是不同日期的
  470. {
  471. var nextItem = this.Data[i + 1];
  472. if (nextItem && nextItem.Date != minData.Date) //不同日期的, 周期结束
  473. {
  474. ++i;
  475. break;
  476. }
  477. }
  478. }
  479. }
  480. return result;
  481. }
  482. //自定义分钟
  483. this.GetMinuteCustomPeriodData = function (count)
  484. {
  485. var result = new Array();
  486. var periodDataCount = count;
  487. var bFirstPeriodData = false;
  488. var newData = null;
  489. for (var i = 0; i < this.Data.length;)
  490. {
  491. bFirstPeriodData = true;
  492. for (var j = 0; j < periodDataCount && i < this.Data.length; ++i, ++j)
  493. {
  494. if (bFirstPeriodData)
  495. {
  496. newData = new HistoryData();
  497. result.push(newData);
  498. bFirstPeriodData = false;
  499. }
  500. var minData = this.Data[i];
  501. if (minData == null) continue;
  502. newData.Date = minData.Date;
  503. newData.Time = minData.Time;
  504. if (minData.Open == null || minData.Close == null) continue;
  505. if (newData.Open == null || newData.Close == null)
  506. {
  507. newData.Open = minData.Open;
  508. newData.High = minData.High;
  509. newData.Low = minData.Low;
  510. newData.YClose = minData.YClose;
  511. newData.Close = minData.Close;
  512. newData.Vol = minData.Vol;
  513. newData.Amount = minData.Amount;
  514. newData.FlowCapital = minData.FlowCapital;
  515. newData.Position = minData.Position;
  516. }
  517. else
  518. {
  519. if (newData.High < minData.High) newData.High = minData.High;
  520. if (newData.Low > minData.Low) newData.Low = minData.Low;
  521. newData.Close = minData.Close;
  522. newData.Vol += minData.Vol;
  523. newData.Amount += minData.Amount;
  524. newData.FlowCapital = minData.FlowCapital;
  525. newData.Position = minData.Position;
  526. }
  527. }
  528. }
  529. return result;
  530. }
  531. this.GetDayPeriodData=function(period)
  532. {
  533. if (period > CUSTOM_DAY_PERIOD_START && period <= CUSTOM_DAY_PERIOD_END) //自定义周期
  534. return this.GetDayCustomPeriodData(period - CUSTOM_DAY_PERIOD_START);
  535. var isBit = MARKET_SUFFIX_NAME.IsBIT(this.Symbol);
  536. var result=[];
  537. var index=0;
  538. var startDate=0;
  539. var weekCount = 2;
  540. var newData=null;
  541. for(var i in this.Data)
  542. {
  543. var isNewData=false;
  544. var dayData=this.Data[i];
  545. switch(period)
  546. {
  547. case 1: //周线
  548. if (isBit) var fridayDate = ChartData.GetSunday(dayData.Date);
  549. else var fridayDate=ChartData.GetFirday(dayData.Date);
  550. if (fridayDate!=startDate)
  551. {
  552. isNewData=true;
  553. startDate=fridayDate;
  554. }
  555. break;
  556. case 21: //双周
  557. if (isBit) var fridayDate = ChartData.GetSunday(dayData.Date);
  558. else var fridayDate = ChartData.GetFirday(dayData.Date);
  559. if (fridayDate != startDate)
  560. {
  561. ++weekCount;
  562. if (weekCount >= 2)
  563. {
  564. isNewData = true;
  565. weekCount = 0;
  566. }
  567. startDate = fridayDate;
  568. }
  569. break;
  570. case 2: //月线
  571. if (parseInt(dayData.Date/100)!=parseInt(startDate/100))
  572. {
  573. isNewData=true;
  574. startDate=dayData.Date;
  575. }
  576. break;
  577. case 3: //年线
  578. if (parseInt(dayData.Date/10000)!=parseInt(startDate/10000))
  579. {
  580. isNewData=true;
  581. startDate=dayData.Date;
  582. }
  583. break;
  584. case 9: //季线
  585. var now = ChartData.GetQuarter(dayData.Date);
  586. now = parseInt(dayData.Date / 10000) * 10 + now;
  587. var last = ChartData.GetQuarter(startDate);
  588. last = parseInt(startDate / 10000) * 10 + last;
  589. if (now != last)
  590. {
  591. isNewData = true;
  592. startDate = dayData.Date;
  593. }
  594. break;
  595. }
  596. if (isNewData)
  597. {
  598. newData=new HistoryData();
  599. newData.Date=dayData.Date;
  600. result.push(newData);
  601. if (dayData.Open==null || dayData.Close==null) continue;
  602. newData.Open=dayData.Open;
  603. newData.High=dayData.High;
  604. newData.Low=dayData.Low;
  605. newData.YClose=dayData.YClose;
  606. newData.Close=dayData.Close;
  607. newData.Vol=dayData.Vol;
  608. newData.Amount=dayData.Amount;
  609. newData.FlowCapital = dayData.FlowCapital;
  610. newData.Position = dayData.Position;
  611. }
  612. else
  613. {
  614. if (newData==null) continue;
  615. if (dayData.Open==null || dayData.Close==null) continue;
  616. if (newData.Open==null || newData.Close==null)
  617. {
  618. newData.Open=dayData.Open;
  619. newData.High=dayData.High;
  620. newData.Low=dayData.Low;
  621. newData.YClose=dayData.YClose;
  622. newData.Close=dayData.Close;
  623. newData.Vol=dayData.Vol;
  624. newData.Amount=dayData.Amount;
  625. newData.FlowCapital = dayData.FlowCapital;
  626. newData.Position = dayData.Position;
  627. }
  628. else
  629. {
  630. if (newData.High<dayData.High) newData.High=dayData.High;
  631. if (newData.Low>dayData.Low) newData.Low=dayData.Low;
  632. newData.Close=dayData.Close;
  633. newData.Vol+=dayData.Vol;
  634. newData.Amount+=dayData.Amount;
  635. newData.Date=dayData.Date;
  636. newData.FlowCapital = dayData.FlowCapital;
  637. newData.Position = dayData.Position;
  638. }
  639. }
  640. }
  641. return result;
  642. }
  643. this.GetDayCustomPeriodData = function (count) //自定义日线周期
  644. {
  645. var result = [];
  646. var periodDataCount = count;
  647. var bFirstPeriodData = false;
  648. var newData = null;
  649. for (var i = 0; i < this.Data.length;)
  650. {
  651. bFirstPeriodData = true;
  652. for (var j = 0; j < periodDataCount && i < this.Data.length; ++i, ++j)
  653. {
  654. if (bFirstPeriodData)
  655. {
  656. newData = new HistoryData();
  657. result.push(newData);
  658. bFirstPeriodData = false;
  659. }
  660. var dayData = this.Data[i];
  661. if (dayData == null) continue;
  662. newData.Date = dayData.Date;
  663. if (dayData.Open == null || dayData.Close == null) continue;
  664. if (newData.Open == null || newData.Close == null)
  665. {
  666. newData.Open = dayData.Open;
  667. newData.High = dayData.High;
  668. newData.Low = dayData.Low;
  669. newData.YClose = dayData.YClose;
  670. newData.Close = dayData.Close;
  671. newData.Vol = dayData.Vol;
  672. newData.Amount = dayData.Amount;
  673. newData.FlowCapital = dayData.FlowCapital;
  674. newData.Position = dayData.Position;
  675. }
  676. else
  677. {
  678. if (newData.High < dayData.High) newData.High = dayData.High;
  679. if (newData.Low > dayData.Low) newData.Low = dayData.Low;
  680. newData.Close = dayData.Close;
  681. newData.Vol += dayData.Vol;
  682. newData.Amount += dayData.Amount;
  683. newData.Position = dayData.Position;
  684. newData.FlowCapital = dayData.FlowCapital;
  685. }
  686. }
  687. }
  688. return result;
  689. }
  690. //周期数据 1=周 2=月 3=年 9=季
  691. this.GetPeriodData=function(period)
  692. {
  693. if (period == 1 || period == 2 || period == 3 || period == 9 || period == 21 || (period > CUSTOM_DAY_PERIOD_START && period <= CUSTOM_DAY_PERIOD_END)) return this.GetDayPeriodData(period);
  694. if (period == 5 || period == 6 || period == 7 || period == 8 || period == 11 || period == 12 ||(period > CUSTOM_MINUTE_PERIOD_START && period <= CUSTOM_MINUTE_PERIOD_END)) return this.GetMinutePeriodData(period);
  695. }
  696. //复权 0 不复权 1 前复权 2 后复权
  697. this.GetRightDate=function(right)
  698. {
  699. var result=[];
  700. if (this.Data.length<=0) return result;
  701. if (right==1)
  702. {
  703. var index=this.Data.length-1;
  704. var seed=1; //复权系数
  705. var yClose=this.Data[index].YClose;
  706. result[index]=HistoryData.Copy(this.Data[index]);
  707. for(--index; index>=0; --index)
  708. {
  709. if (yClose!=this.Data[index].Close) break;
  710. result[index]=HistoryData.Copy(this.Data[index]);
  711. yClose=this.Data[index].YClose;
  712. }
  713. for(; index>=0; --index)
  714. {
  715. if(yClose!=this.Data[index].Close)
  716. seed *= yClose/this.Data[index].Close;
  717. result[index]=HistoryData.CopyRight(this.Data[index],seed);
  718. yClose=this.Data[index].YClose;
  719. }
  720. }
  721. else if (right==2)
  722. {
  723. var index=0;
  724. var seed=1;
  725. var close=this.Data[index].Close;
  726. result[index]=HistoryData.Copy(this.Data[index]);
  727. for(++index;index<this.Data.length;++index)
  728. {
  729. if (close!=this.Data[index].YClose) break;
  730. result[index]=HistoryData.Copy(this.Data[index]);
  731. close=this.Data[index].Close;
  732. }
  733. for(;index<this.Data.length;++index)
  734. {
  735. if(close!=this.Data[index].YClose)
  736. seed *= close/this.Data[index].YClose;
  737. result[index]=HistoryData.CopyRight(this.Data[index],seed);
  738. close=this.Data[index].Close;
  739. }
  740. }
  741. return result;
  742. }
  743. //叠加数据和主数据拟合,去掉主数据没有日期的数据
  744. this.GetOverlayData=function(overlayData)
  745. {
  746. var result=[];
  747. for(var i=0,j=0;i<this.Data.length;)
  748. {
  749. var date=this.Data[i].Date;
  750. if (j>=overlayData.length)
  751. {
  752. result[i]=new HistoryData();
  753. result[i].Date=date;
  754. ++i;
  755. continue;;
  756. }
  757. var overlayDate=overlayData[j].Date;
  758. if (overlayDate==date)
  759. {
  760. result[i]=new HistoryData();
  761. result[i].Date=overlayData[j].Date;
  762. result[i].YClose=overlayData[j].YClose;
  763. result[i].Open=overlayData[j].Open;
  764. result[i].High=overlayData[j].High;
  765. result[i].Low=overlayData[j].Low;
  766. result[i].Close=overlayData[j].Close;
  767. result[i].Vol=overlayData[j].Vol;
  768. result[i].Amount=overlayData[j].Amount;
  769. //涨跌家数数据
  770. result[i].Stop = overlayData[j].Stop;
  771. result[i].Up = overlayData[j].Up;
  772. result[i].Down = overlayData[j].Down;
  773. result[i].Unchanged = overlayData[j].Unchanged;
  774. ++j;
  775. ++i;
  776. }
  777. else if (overlayDate<date)
  778. {
  779. ++j;
  780. }
  781. else
  782. {
  783. result[i]=new HistoryData();
  784. result[i].Date=date;
  785. ++i;
  786. }
  787. }
  788. return result;
  789. }
  790. /*
  791. 技术指标数据方法
  792. */
  793. //以主图数据 拟合,返回 SingleData 数组
  794. this.GetFittingData=function(overlayData)
  795. {
  796. var result=new Array();
  797. for(var i=0,j=0;i<this.Data.length;)
  798. {
  799. var date=this.Data[i].Date;
  800. if (j>=overlayData.length)
  801. {
  802. result[i]=null;
  803. ++i;
  804. continue;;
  805. }
  806. var overlayDate=overlayData[j].Date;
  807. if (overlayDate==date)
  808. {
  809. var item=new SingleData();
  810. item.Date=overlayData[j].Date;
  811. item.Value=overlayData[j].Value;
  812. result[i]=item;
  813. ++j;
  814. ++i;
  815. }
  816. else if (overlayDate<date)
  817. {
  818. ++j;
  819. }
  820. else
  821. {
  822. result[i]=new SingleData();
  823. result[i].Date=date;
  824. ++i;
  825. }
  826. }
  827. return result;
  828. }
  829. // 缺省数据使用 emptyValue填充
  830. this.GetFittingData2 = function (overlayData, emptyValue)
  831. {
  832. var result = new Array();
  833. for (var i = 0, j = 0; i < this.Data.length;)
  834. {
  835. var date = this.Data[i].Date;
  836. if (j >= overlayData.length)
  837. {
  838. result[i] = new SingleData();
  839. result[i].Date = date;
  840. result[i].Value = emptyValue;
  841. ++i;
  842. continue;;
  843. }
  844. var overlayDate = overlayData[j].Date;
  845. if (overlayDate == date)
  846. {
  847. var item = new SingleData();
  848. item.Date = overlayData[j].Date;
  849. item.Value = overlayData[j].Value;
  850. result[i] = item;
  851. ++j;
  852. ++i;
  853. }
  854. else if (overlayDate < date)
  855. {
  856. ++j;
  857. }
  858. else
  859. {
  860. result[i] = new SingleData();
  861. result[i].Date = date;
  862. result[i].Value = emptyValue;
  863. ++i;
  864. }
  865. }
  866. return result;
  867. }
  868. this.GetMinuteFittingData = function (overlayData) // 分钟数据拟合
  869. {
  870. var result = [];
  871. for (var i = 0, j = 0; i < this.Data.length;)
  872. {
  873. var date = this.Data[i].Date;
  874. var time = this.Data[i].Time;
  875. if (j >= overlayData.length)
  876. {
  877. result[i] = null;
  878. ++i;
  879. continue;;
  880. }
  881. var overlayDate = overlayData[j].Date;
  882. var overlayTime = overlayData[j].Time;
  883. const overlayItem = overlayData[j];
  884. if (overlayDate == date && overlayTime == time)
  885. {
  886. var item = new SingleData();
  887. item.Date = overlayItem.Date;
  888. item.Time = overlayItem.Time;
  889. item.Value = overlayItem.Value;
  890. result[i] = item;
  891. ++j;
  892. ++i;
  893. }
  894. else if (overlayDate < date || (overlayDate == date && overlayTime < time))
  895. {
  896. ++j;
  897. }
  898. else
  899. {
  900. var item = new SingleData();
  901. item.Date = date;
  902. item.Time = time;
  903. result[i] = item;
  904. ++i;
  905. }
  906. }
  907. return result;
  908. }
  909. //把财报数据拟合到主图数据,返回 SingleData 数组
  910. this.GetFittingFinanceData = function (financeData)
  911. {
  912. var result = [];
  913. for (var i = 0, j = 0; i < this.Data.length;)
  914. {
  915. var date = this.Data[i].Date;
  916. if (j<financeData.length)
  917. {
  918. var fDate=financeData[j].Date;
  919. if (date<fDate)
  920. {
  921. ++i;
  922. continue;
  923. }
  924. }
  925. if (j + 1 < financeData.length)
  926. {
  927. if (financeData[j].Date < date && financeData[j + 1].Date <= date)
  928. {
  929. ++j;
  930. continue;
  931. }
  932. }
  933. var item = new SingleData();
  934. item.Date = date;
  935. item.Value = financeData[j].Value;
  936. item.FinanceDate = financeData[j].Date; //财务日期 调试用
  937. result[i] = item;
  938. ++i;
  939. }
  940. return result;
  941. }
  942. //财务数据拟合到分钟数据上 返回 SingleData 数组
  943. this.GetMinuteFittingFinanceData=function(financeData)
  944. {
  945. var result=[];
  946. if (!Array.isArray(financeData) || financeData.length<=0) return result;
  947. var i=0;
  948. var firstItem=financeData[0];
  949. for(i=0;i<this.Data.length;++i)
  950. {
  951. var date=this.Data[i].Date;
  952. var time=this.Data[i].Time;
  953. if (date>firstItem.Date || (date==firstItem.Date && time>=firstItem.Time))
  954. {
  955. break;
  956. }
  957. }
  958. for(var j=0;i<this.Data.length;)
  959. {
  960. var date=this.Data[i].Date;
  961. var time=this.Data[i].Time;
  962. if (j+1<financeData.length)
  963. {
  964. if ((financeData[j].Date<date && financeData[j+1].Date<=date) ||
  965. (financeData[j].Date==date && financeData[j].Time<time && financeData[j+1].Time<=time) )
  966. {
  967. ++j;
  968. continue;
  969. }
  970. }
  971. var item=new SingleData();
  972. item.Date=date;
  973. item.Time=time;
  974. if (j<financeData.length)
  975. {
  976. item.Value=financeData[j].Value;
  977. item.FinanceDate=financeData[j].Date; //财务日期 调试用
  978. item.FinanceTime=financeData[j].Time; //财务日期 调试用
  979. }
  980. else
  981. {
  982. item.Value=null;
  983. item.FinanceDate=null;
  984. item.FinanceTime=null;
  985. }
  986. result[i]=item;
  987. ++i;
  988. }
  989. return result;
  990. }
  991. //市值计算 financeData.Value 是股数
  992. this.GetFittingMarketValueData = function (financeData)
  993. {
  994. var result = [];
  995. for (var i = 0, j = 0; i < this.Data.length;)
  996. {
  997. var date = this.Data[i].Date;
  998. var price = this.Data[i].Close;
  999. if (j + 1 < financeData.length)
  1000. {
  1001. if (financeData[j].Date < date && financeData[j + 1].Date <= date)
  1002. {
  1003. ++j;
  1004. continue;
  1005. }
  1006. }
  1007. var item = new SingleData();
  1008. item.Date = date;
  1009. item.Value = financeData[j].Value * price; //市值计算 收盘价*股数
  1010. item.FinanceDate = financeData[j].Date; //财务日期 调试用
  1011. result[i] = item;
  1012. ++i;
  1013. }
  1014. return result;
  1015. }
  1016. //月线数据拟合
  1017. this.GetFittingMonthData = function (overlayData) {
  1018. var result = new Array();
  1019. var preDate = null;
  1020. for (var i = 0, j = 0; i < this.Data.length;) {
  1021. var date = this.Data[i].Date;
  1022. if (j >= overlayData.length) {
  1023. result[i] = null;
  1024. ++i;
  1025. continue;;
  1026. }
  1027. var overlayDate = overlayData[j].Date;
  1028. if (overlayDate == date) {
  1029. var item = new SingleData();
  1030. item.Date = overlayData[j].Date;
  1031. item.Value = overlayData[j].Value;
  1032. item.Text = overlayData[j].Text;
  1033. result[i] = item;
  1034. ++j;
  1035. ++i;
  1036. }
  1037. else if (preDate != null && preDate < overlayDate && date > overlayDate) {
  1038. var item = new SingleData();
  1039. item.Date = date;
  1040. item.OverlayDate = overlayData[j].Date;
  1041. item.Value = overlayData[j].Value;
  1042. item.Text = overlayData[j].Text;
  1043. result[i] = item;
  1044. ++j;
  1045. ++i;
  1046. }
  1047. else if (overlayDate < date) {
  1048. ++j;
  1049. }
  1050. else {
  1051. result[i] = new SingleData();
  1052. result[i].Date = date;
  1053. ++i;
  1054. }
  1055. preDate = date;
  1056. }
  1057. return result;
  1058. }
  1059. this.GetValue=function()
  1060. {
  1061. var result=new Array();
  1062. for(var i in this.Data)
  1063. {
  1064. if (this.Data[i]==null || this.Data[i].Value == null)
  1065. {
  1066. result[i] = null;
  1067. }
  1068. else
  1069. {
  1070. // console.log(this.Data[i].Value);
  1071. // console.log(i);
  1072. if (!isNaN(this.Data[i].Value))
  1073. result[i] = this.Data[i].Value;
  1074. else if (this.Data[i].Value instanceof Array) //支持数组
  1075. result[i] = this.Data[i].Value;
  1076. else
  1077. result[i] = null;
  1078. }
  1079. }
  1080. return result;
  1081. }
  1082. this.GetPeriodSingleData=function(period)
  1083. {
  1084. var result=new Array();
  1085. var index=0;
  1086. var startDate=0;
  1087. var newData=null;
  1088. for(var i in this.Data)
  1089. {
  1090. var isNewData=false;
  1091. var dayData=this.Data[i];
  1092. if (dayData==null || dayData.Date==null) continue;
  1093. switch(period)
  1094. {
  1095. case 1: //周线
  1096. var fridayDate=ChartData.GetFirday(dayData.Date);
  1097. if (fridayDate!=startDate)
  1098. {
  1099. isNewData=true;
  1100. startDate=fridayDate;
  1101. }
  1102. break;
  1103. case 2: //月线
  1104. if (parseInt(dayData.Date/100)!=parseInt(startDate/100))
  1105. {
  1106. isNewData=true;
  1107. startDate=dayData.Date;
  1108. }
  1109. break;
  1110. case 3: //年线
  1111. if (parseInt(dayData.Date/10000)!=parseInt(startDate/10000))
  1112. {
  1113. isNewData=true;
  1114. startDate=dayData.Date;
  1115. }
  1116. break;
  1117. }
  1118. if (isNewData)
  1119. {
  1120. newData=new SingleData();
  1121. newData.Date=dayData.Date;
  1122. newData.Value=dayData.Value;
  1123. result.push(newData);
  1124. }
  1125. else
  1126. {
  1127. if (newData==null) continue;
  1128. if (dayData.Value==null || isNaN(dayData.Value)) continue;
  1129. if (newData.Value==null || isNaN(newData.Value)) newData.Value=dayData.Value;
  1130. }
  1131. }
  1132. return result;
  1133. }
  1134. /*
  1135. 分钟数据方法
  1136. this.GetClose() 每分钟价格
  1137. this.GetVol() 每分钟成交量
  1138. */
  1139. //分钟均线
  1140. this.GetMinuteAvPrice=function()
  1141. {
  1142. var result=new Array();
  1143. for(var i in this.Data)
  1144. {
  1145. result[i]=this.Data[i].AvPrice;
  1146. }
  1147. return result;
  1148. }
  1149. this.MergeMinuteData = function (data) //合并数据
  1150. {
  1151. var sourceFirstItem = this.Data[0];
  1152. var firstItemID = 0;
  1153. var firstItem = null;
  1154. for (var i = 0; i < data.length; ++i) //查找比原始数据起始位置大的数据位置
  1155. {
  1156. var item = data[i];
  1157. if (item.Date >sourceFirstItem.Date)
  1158. {
  1159. firstItemID = i;
  1160. firstItem = item;
  1161. break;
  1162. }
  1163. if (item.Date == sourceFirstItem.Date && item.Time >= sourceFirstItem.Time)
  1164. {
  1165. firstItemID = i;
  1166. firstItem = item;
  1167. break;
  1168. }
  1169. }
  1170. if (firstItem == null) return false;
  1171. var index = null;
  1172. var bFind = false; //第1个数据是否完全匹配
  1173. for (var i = this.Data.length - 1; i >= 0; --i)
  1174. {
  1175. var date = this.Data[i].Date;
  1176. var time = this.Data[i].Time;
  1177. if (firstItem.Date > date || (firstItem.Date == date && firstItem.Time >= time) )
  1178. {
  1179. index = i;
  1180. if (firstItem.Date == date && firstItem.Time == time) bFind = true;
  1181. break;
  1182. }
  1183. }
  1184. if (index == null) return false;
  1185. var j = index;
  1186. var i = firstItemID;
  1187. if (bFind == true) //第1个数据匹配,覆盖
  1188. {
  1189. var item = data[i];
  1190. if (j - 1 > 0 && !item.YClose) item.YClose = this.Data[j - 1].Close; //前收盘如果没有就是上一记录的收盘
  1191. var newItem = HistoryData.Copy(item);
  1192. this.Data[j] = newItem;
  1193. ++j;
  1194. ++i;
  1195. }
  1196. else
  1197. {
  1198. ++j;
  1199. }
  1200. for (; i < data.length;)
  1201. {
  1202. var item = data[i];
  1203. if (j >= this.Data.length - 1)
  1204. {
  1205. if (j - 1 > 0 && !item.YClose) item.YClose = this.Data[j - 1].YClose; //前收盘如果没有就是上一记录的收盘
  1206. var newItem = HistoryData.Copy(item);
  1207. this.Data[j] = newItem;
  1208. ++j;
  1209. ++i;
  1210. }
  1211. else
  1212. {
  1213. var oldItem = this.Data[j];
  1214. if (oldItem.Date == item.Date && oldItem.Time == item.Time) //更新数据
  1215. {
  1216. HistoryData.CopyTo(oldItem, item);
  1217. ++j;
  1218. ++i;
  1219. }
  1220. else
  1221. {
  1222. ++j;
  1223. }
  1224. }
  1225. }
  1226. //console.log('[ChartData::MergeMinuteData] ', this.Data, data);
  1227. return true;
  1228. }
  1229. //日线拟合交易数据, 不做平滑处理
  1230. this.GetFittingTradeData=function(tradeData, nullValue, bExactMatch)
  1231. {
  1232. var result=[];
  1233. var bMatch=false;
  1234. for(var i=0,j=0;i<this.Data.length;)
  1235. {
  1236. var date=this.Data[i].Date;
  1237. if (j<tradeData.length)
  1238. {
  1239. if (tradeData[j].Date>date)
  1240. {
  1241. var item=new SingleData();
  1242. item.Date=date;
  1243. item.Value=nullValue;
  1244. result[i]=item;
  1245. ++i;
  1246. continue;
  1247. }
  1248. }
  1249. if (j+1<tradeData.length)
  1250. {
  1251. if (tradeData[j].Date<date && tradeData[j+1].Date<=date)
  1252. {
  1253. ++j;
  1254. bMatch=false;
  1255. continue;
  1256. }
  1257. }
  1258. var item=new SingleData();
  1259. item.Date=date;
  1260. item.Value=nullValue;
  1261. item.FinanceDate=null;
  1262. if (j<tradeData.length)
  1263. {
  1264. var tradeItem=tradeData[j];
  1265. if (this.Period==0 && bExactMatch===true) //日线完全匹配
  1266. {
  1267. if (tradeItem.Date==item.Date)
  1268. {
  1269. item.Value=tradeItem.Value;
  1270. item.FinanceDate=tradeItem.Date; //财务日期 调试用
  1271. bMatch=true;
  1272. }
  1273. }
  1274. else //其他日线周期
  1275. {
  1276. if (bMatch==false)
  1277. {
  1278. item.Value=tradeItem.Value;
  1279. item.FinanceDate=tradeItem.Date; //财务日期 调试用
  1280. bMatch=true;
  1281. }
  1282. }
  1283. }
  1284. result[i]=item;
  1285. ++i;
  1286. }
  1287. return result;
  1288. }
  1289. this.GetMinuteFittingTradeData=function(tradeData, nullValue,bExactMatch)
  1290. {
  1291. var result=[];
  1292. var bMatch=false;
  1293. for(var i=0,j=0;i<this.Data.length;)
  1294. {
  1295. var date=this.Data[i].Date;
  1296. var time=this.Data[i].Time;
  1297. if (j<tradeData.length)
  1298. {
  1299. if (tradeData[j].Date>date || (tradeData[j].Date==date && tradeData[j].Time>time))
  1300. {
  1301. var item=new SingleData();
  1302. item.Date=date;
  1303. item.Time=time;
  1304. item.Value=nullValue;
  1305. result[i]=item;
  1306. ++i;
  1307. continue;
  1308. }
  1309. }
  1310. if (j+1<tradeData.length)
  1311. {
  1312. if ( (tradeData[j].Date<date && tradeData[j+1].Date<=date) ||
  1313. (tradeData[j].Date==date && tradeData[j].Time<time && tradeData[j+1].Time<=time) )
  1314. {
  1315. ++j;
  1316. bMatch=false;
  1317. continue;
  1318. }
  1319. }
  1320. var item=new SingleData();
  1321. item.Date=date;
  1322. item.FinanceDate=null;
  1323. item.Time=time;
  1324. item.Value=nullValue;
  1325. if (j<tradeData.length)
  1326. {
  1327. var tradeItem=tradeData[j];
  1328. if (this.Period==4 && bExactMatch===true) //1分钟线完全匹配
  1329. {
  1330. if (tradeItem.Date==item.Date && tradeItem.Time==item.Time) //完全匹配
  1331. {
  1332. item.Value=tradeItem.Value;
  1333. item.FinanceDate=tradeItem.Date; //财务日期 调试用
  1334. item.FinanceTime=tradeItem.Time;
  1335. bMatch=true;
  1336. }
  1337. }
  1338. else //其他日线周期
  1339. {
  1340. if (bMatch==false)
  1341. {
  1342. item.Value=tradeItem.Value;
  1343. item.FinanceDate=tradeItem.Date; //财务日期 调试用
  1344. item.FinanceTime=tradeItem.Time;
  1345. bMatch=true;
  1346. }
  1347. }
  1348. }
  1349. result[i]=item;
  1350. ++i;
  1351. }
  1352. return result;
  1353. }
  1354. }
  1355. ChartData.IsNumber=function(value)
  1356. {
  1357. if (value==null) return false;
  1358. if (isNaN(value)) return false;
  1359. return true;
  1360. }
  1361. ChartData.GetFirday=function(value)
  1362. {
  1363. var date=new Date(parseInt(value/10000),(value/100%100-1),value%100);
  1364. var day=date.getDay();
  1365. if (day==5) return value;
  1366. var timestamp=date.getTime();
  1367. if (day<5)
  1368. {
  1369. var prevTimestamp=(24*60*60*1000)*(5-day);
  1370. timestamp+=prevTimestamp;
  1371. }
  1372. else
  1373. {
  1374. var prevTimestamp=(24*60*60*1000)*(day-5);
  1375. timestamp-=prevTimestamp;
  1376. }
  1377. date.setTime(timestamp);
  1378. var fridayDate= date.getFullYear()*10000+(date.getMonth()+1)*100+date.getDate();
  1379. var week=date.getDay();
  1380. return fridayDate;
  1381. }
  1382. ChartData.GetSunday = function (value)
  1383. {
  1384. var date = new Date(parseInt(value / 10000), (value / 100 % 100 - 1), value % 100);
  1385. var day = date.getDay();
  1386. if (day == 0) return value;
  1387. var timestamp = date.getTime();
  1388. if (day > 0)
  1389. {
  1390. var prevTimestamp = (24 * 60 * 60 * 1000) * (7 - day);
  1391. timestamp += prevTimestamp;
  1392. }
  1393. date.setTime(timestamp);
  1394. var sundayDate = date.getFullYear() * 10000 + (date.getMonth() + 1) * 100 + date.getDate();
  1395. var week = date.getDay();
  1396. return sundayDate;
  1397. }
  1398. ChartData.GetQuarter = function (value)
  1399. {
  1400. var month = parseInt(value % 10000 / 100);
  1401. if (month == 1 || month == 2 || month == 3) return 1;
  1402. else if (month == 4 || month == 5 || month == 6) return 2;
  1403. else if (month == 7 || month == 8 || month == 9) return 3;
  1404. else if (month == 10 || month == 11 || month == 12) return 4;
  1405. else return 0;
  1406. }
  1407. //是否是日线周期 0=日线 1=周线 2=月线 3=年线 9=季线 21=双周 [40001-50000) 自定义日线 (isIncludeBase 是否包含基础日线周期)
  1408. var CUSTOM_DAY_PERIOD_START = 40000, CUSTOM_DAY_PERIOD_END = 49999;
  1409. ChartData.IsDayPeriod = function (period, isIncludeBase)
  1410. {
  1411. if (period == 1 || period == 2 || period == 3 || period == 9 || period==21 ) return true;
  1412. if (period > CUSTOM_DAY_PERIOD_START && period <= CUSTOM_DAY_PERIOD_END) return true;
  1413. if (period == 0 && isIncludeBase == true) return true;
  1414. return false;
  1415. }
  1416. //是否是分钟周期 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟 11=2h 12=4h[20001-30000) 自定义分钟 (isIncludeBase 是否包含基础1分钟周期)
  1417. var CUSTOM_MINUTE_PERIOD_START = 20000, CUSTOM_MINUTE_PERIOD_END = 29999;
  1418. ChartData.IsMinutePeriod = function (period, isIncludeBase)
  1419. {
  1420. if (period == 5 || period == 6 || period == 7 || period == 8 || period == 11 || period == 12) return true;
  1421. if (period > CUSTOM_MINUTE_PERIOD_START && period <= CUSTOM_MINUTE_PERIOD_END) return true;
  1422. if (period == 4 && isIncludeBase == true) return true;
  1423. return false;
  1424. }
  1425. //是否是秒周期 [30001-32000)
  1426. var CUSTOM_SECOND_PERIOD_START = 30000, CUSTOM_SECOND_PERIOD_END = 32000;
  1427. ChartData.IsSecondPeriod = function (period)
  1428. {
  1429. if (period > CUSTOM_SECOND_PERIOD_START && period <= CUSTOM_SECOND_PERIOD_END) return true;
  1430. return false;
  1431. }
  1432. //是否是分笔图
  1433. ChartData.IsTickPeriod = function (period)
  1434. {
  1435. return period == 10;
  1436. }
  1437. //获取周期名字
  1438. ChartData.GetPeriodName = function (period)
  1439. {
  1440. var mapName = new Map(
  1441. [
  1442. [0, '日线'], [1, '周线'], [2, '月线'], [3, '年线'], [9, '季线'], [21, '双周'],
  1443. [4, '1分'], [5, '5分'], [6, '15分'], [7, '30分'], [8, '60分'], [11, '2小时'], [12, '4小时'],
  1444. [10, '分笔']
  1445. ]);
  1446. if (mapName.has(period)) return mapName.get(period);
  1447. return '';
  1448. }
  1449. function Rect(x, y, width, height)
  1450. {
  1451. this.Left = x,
  1452. this.Top = y;
  1453. this.Right = x + width;
  1454. this.Bottom = y + height;
  1455. this.IsPointIn = function (x, y)
  1456. {
  1457. if (x >= this.Left && x <= this.Right && y >= this.Top && y <= this.Bottom) return true;
  1458. return false;
  1459. }
  1460. }
  1461. //修正线段有毛刺
  1462. function ToFixedPoint(value)
  1463. {
  1464. //return value;
  1465. return parseInt(value) + 0.5;
  1466. }
  1467. function ToFixedRect(value)
  1468. {
  1469. var rounded;
  1470. return rounded = (0.5 + value) << 0;
  1471. }
  1472. var JSCHART_EVENT_ID =
  1473. {
  1474. RECV_INDEX_DATA: 2, //接收指标数据
  1475. RECV_HISTROY_DATA: 3,//接收到历史数据
  1476. RECV_TRAIN_MOVE_STEP: 4, //接收K线训练,移动一次K线
  1477. CHART_STATUS: 5, //每次Draw() 以后会调用
  1478. BARRAGE_PLAY_END: 6, //单个弹幕播放完成
  1479. RECV_START_AUTOUPDATE: 9, //开始自动更新
  1480. RECV_STOP_AUTOUPDATE: 10, //停止自动更新
  1481. ON_TITLE_DRAW: 12, //标题信息绘制事件
  1482. RECV_MINUTE_DATA: 14, //分时图数据到达
  1483. ON_CLICK_INDEXTITLE:15, //点击指标标题事件
  1484. RECV_KLINE_UPDATE_DATA: 16, //K线日,分钟更新数据到达
  1485. ON_INDEXTITLE_DRAW: 19, //指标标题重绘事件
  1486. ON_CUSTOM_VERTICAL_DRAW: 20, //自定义X轴绘制事件
  1487. ON_ENABLE_SPLASH_DRAW:22, //开启/关闭过场动画事件
  1488. ON_DRAW_DEPTH_TOOLTIP:25, //绘制深度图tooltip事件
  1489. ON_PHONE_TOUCH:27, //手势点击事件 包含 TouchStart 和 TouchEnd
  1490. ON_SPLIT_YCOORDINATE:29, //分割Y轴及格式化刻度文字
  1491. }
  1492. function PhoneDBClick()
  1493. {
  1494. this.Start=[];
  1495. this.Clear=function()
  1496. {
  1497. this.Start=[];
  1498. }
  1499. this.AddTouchStart=function(x, y, time)
  1500. {
  1501. if (this.Start.length>0)
  1502. {
  1503. var item=this.Start[this.Start.length-1];
  1504. var spanTime=time-item.Time;
  1505. if (spanTime>0 && spanTime<300)
  1506. {
  1507. this.Start.push({ X:x, Y:y, Time:time });
  1508. }
  1509. else
  1510. {
  1511. this.Start=[];
  1512. }
  1513. }
  1514. else
  1515. {
  1516. this.Start.push({ X:x, Y:y, Time:time });
  1517. }
  1518. }
  1519. this.IsVaildDBClick=function()
  1520. {
  1521. if (this.Start.length==2) return true;
  1522. return false;
  1523. }
  1524. this.AddTouchEnd=function(time)
  1525. {
  1526. if (this.Start.length<=0) return;
  1527. var item=this.Start[this.Start.length-1];
  1528. var spanTime=time-item.Time;
  1529. if (spanTime>=0 && spanTime<150)
  1530. {
  1531. }
  1532. else
  1533. {
  1534. this.Start=[];
  1535. }
  1536. }
  1537. }
  1538. //导出统一使用JSCommon命名空间名
  1539. module.exports =
  1540. {
  1541. JSCommonData:
  1542. {
  1543. HistoryData: HistoryData,
  1544. ChartData: ChartData,
  1545. SingleData: SingleData,
  1546. MinuteData: MinuteData,
  1547. Rect: Rect,
  1548. DataPlus: DataPlus,
  1549. JSCHART_EVENT_ID:JSCHART_EVENT_ID,
  1550. PhoneDBClick:PhoneDBClick,
  1551. },
  1552. //单个类导出
  1553. JSCommon_ChartData: ChartData,
  1554. JSCommon_HistoryData: HistoryData,
  1555. JSCommon_SingleData: SingleData,
  1556. JSCommon_MinuteData: MinuteData,
  1557. JSCommon_CUSTOM_DAY_PERIOD_START: CUSTOM_DAY_PERIOD_START,
  1558. JSCommon_CUSTOM_DAY_PERIOD_END: CUSTOM_DAY_PERIOD_END,
  1559. JSCommon_CUSTOM_MINUTE_PERIOD_START: CUSTOM_MINUTE_PERIOD_START,
  1560. JSCommon_CUSTOM_MINUTE_PERIOD_END: CUSTOM_MINUTE_PERIOD_END,
  1561. JSCommon_CUSTOM_SECOND_PERIOD_START: CUSTOM_SECOND_PERIOD_START,
  1562. JSCommon_CUSTOM_SECOND_PERIOD_END: CUSTOM_SECOND_PERIOD_END,
  1563. JSCommon_Rect: Rect,
  1564. JSCommon_DataPlus: DataPlus,
  1565. JSCommon_Guid: Guid,
  1566. JSCommon_ToFixedPoint: ToFixedPoint,
  1567. JSCommon_ToFixedRect: ToFixedRect,
  1568. JSCommon_JSCHART_EVENT_ID:JSCHART_EVENT_ID,
  1569. JSCommon_PhoneDBClick:PhoneDBClick,
  1570. };