umychart.complier.wechat.js 351 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690
  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. //日志
  9. import { JSConsole } from "./umychart.console.wechat.js"
  10. import { JSCommonData } from "./umychart.data.wechat.js"; //行情数据结构体 及涉及到的行情算法(复权,周期等)
  11. //配色资源
  12. import {
  13. JSCommonResource_Global_JSChartResource as g_JSChartResource,
  14. JSCommonResource_JSCHART_LANGUAGE_ID as JSCHART_LANGUAGE_ID,
  15. JSCommonResource_Global_JSChartLocalization as g_JSChartLocalization,
  16. } from './umychart.resource.wechat.js'
  17. import
  18. {
  19. JSCommonSplit_IFrameSplitOperator as IFrameSplitOperator,
  20. } from './umychart.framesplit.wechat.js'
  21. var g_JSComplierResource=
  22. {
  23. Domain : "https://opensource.zealink.com", //API域名
  24. CacheDomain : "https://opensourcecache.zealink.com", //缓存域名
  25. CustomFunction: //定制函数
  26. {
  27. Data:new Map() //自定义函数 key=函数名, Value:{ID:函数名, Callback: }
  28. },
  29. CustomVariant: //自定义变量
  30. {
  31. Data:new Map() //自定义函数 key=变量名, Value:{ Name:变量名, Description:描述信息 }
  32. },
  33. IsCustomFunction:function(name)
  34. {
  35. if (g_JSComplierResource.CustomFunction.Data.has(name)) return true;
  36. return false;
  37. },
  38. IsCustomVariant:function(name)
  39. {
  40. if (g_JSComplierResource.CustomVariant.Data.has(name)) return true;
  41. return false;
  42. }
  43. }
  44. var Messages = {
  45. BadGetterArity: 'Getter must not have any formal parameters',
  46. BadSetterArity: 'Setter must have exactly one formal parameter',
  47. BadSetterRestParameter: 'Setter function argument must not be a rest parameter',
  48. ConstructorIsAsync: 'Class constructor may not be an async method',
  49. ConstructorSpecialMethod: 'Class constructor may not be an accessor',
  50. DeclarationMissingInitializer: 'Missing initializer in %0 declaration',
  51. DefaultRestParameter: 'Unexpected token =',
  52. DuplicateBinding: 'Duplicate binding %0',
  53. DuplicateConstructor: 'A class may only have one constructor',
  54. DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals',
  55. ForInOfLoopInitializer: '%0 loop variable declaration may not have an initializer',
  56. GeneratorInLegacyContext: 'Generator declarations are not allowed in legacy contexts',
  57. IllegalBreak: 'Illegal break statement',
  58. IllegalContinue: 'Illegal continue statement',
  59. IllegalExportDeclaration: 'Unexpected token',
  60. IllegalImportDeclaration: 'Unexpected token',
  61. IllegalLanguageModeDirective: 'Illegal \'use strict\' directive in function with non-simple parameter list',
  62. IllegalReturn: 'Illegal return statement',
  63. InvalidEscapedReservedWord: 'Keyword must not contain escaped characters',
  64. InvalidHexEscapeSequence: 'Invalid hexadecimal escape sequence',
  65. InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
  66. InvalidLHSInForIn: 'Invalid left-hand side in for-in',
  67. InvalidLHSInForLoop: 'Invalid left-hand side in for-loop',
  68. InvalidModuleSpecifier: 'Unexpected token',
  69. InvalidRegExp: 'Invalid regular expression',
  70. LetInLexicalBinding: 'let is disallowed as a lexically bound name',
  71. MissingFromClause: 'Unexpected token',
  72. MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
  73. NewlineAfterThrow: 'Illegal newline after throw',
  74. NoAsAfterImportNamespace: 'Unexpected token',
  75. NoCatchOrFinally: 'Missing catch or finally after try',
  76. ParameterAfterRestParameter: 'Rest parameter must be last formal parameter',
  77. Redeclaration: '%0 \'%1\' has already been declared',
  78. StaticPrototype: 'Classes may not have static property named prototype',
  79. StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
  80. StrictDelete: 'Delete of an unqualified identifier in strict mode.',
  81. StrictFunction: 'In strict mode code, functions can only be declared at top level or inside a block',
  82. StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
  83. StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
  84. StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
  85. StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
  86. StrictModeWith: 'Strict mode code may not include a with statement',
  87. StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
  88. StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
  89. StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
  90. StrictReservedWord: 'Use of future reserved word in strict mode',
  91. StrictVarName: 'Variable name may not be eval or arguments in strict mode',
  92. TemplateOctalLiteral: 'Octal literals are not allowed in template strings.',
  93. UnexpectedEOS: 'Unexpected end of input',
  94. UnexpectedIdentifier: 'Unexpected identifier',
  95. UnexpectedNumber: 'Unexpected number',
  96. UnexpectedReserved: 'Unexpected reserved word',
  97. UnexpectedString: 'Unexpected string',
  98. UnexpectedTemplate: 'Unexpected quasi %0',
  99. UnexpectedToken: 'Unexpected token %0',
  100. UnexpectedTokenIllegal: 'Unexpected token ILLEGAL',
  101. UnknownLabel: 'Undefined label \'%0\'',
  102. UnterminatedRegExp: 'Invalid regular expression: missing /'
  103. };
  104. var Regex = {
  105. // Unicode v8.0.0 NonAsciiIdentifierStart:
  106. NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/,
  107. // Unicode v8.0.0 NonAsciiIdentifierPart:
  108. NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
  109. }
  110. var Character =
  111. {
  112. FromCodePoint: function (cp) {
  113. return (cp < 0x10000) ? String.fromCharCode(cp) :
  114. String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) +
  115. String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023));
  116. },
  117. //是否是空格 https://tc39.github.io/ecma262/#sec-white-space
  118. IsWhiteSpace:function(cp)
  119. {
  120. return (cp === 0x20) || (cp === 0x09) || (cp === 0x0B) || (cp === 0x0C) || (cp === 0xA0) ||
  121. (cp >= 0x1680 && [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(cp) >= 0);
  122. },
  123. //是否换行 https://tc39.github.io/ecma262/#sec-line-terminators
  124. IsLineTerminator:function(cp)
  125. {
  126. return (cp === 0x0A) || (cp === 0x0D) || (cp === 0x2028) || (cp === 0x2029);
  127. },
  128. // https://tc39.github.io/ecma262/#sec-names-and-keywords
  129. IsIdentifierStart:function(cp)
  130. {
  131. return (cp === 0x24) || (cp === 0x5F) ||
  132. (cp >= 0x41 && cp <= 0x5A) ||
  133. (cp >= 0x61 && cp <= 0x7A) ||
  134. (cp === 0x5C) ||
  135. //【】
  136. (cp===0x3010 || cp===0x3011) ||
  137. ((cp >= 0x80) && Regex.NonAsciiIdentifierStart.test(Character.FromCodePoint(cp)));
  138. },
  139. IsIdentifierPart: function (cp)
  140. {
  141. return (cp === 0x24) || (cp === 0x5F) ||
  142. (cp >= 0x41 && cp <= 0x5A) ||
  143. (cp >= 0x61 && cp <= 0x7A) ||
  144. (cp >= 0x30 && cp <= 0x39) ||
  145. (cp === 0x5C) ||
  146. //【】
  147. (cp===0x3010 || cp===0x3011) ||
  148. ((cp >= 0x80) && Regex.NonAsciiIdentifierPart.test(Character.FromCodePoint(cp)));
  149. },
  150. // https://tc39.github.io/ecma262/#sec-literals-numeric-literals
  151. IsDecimalDigit: function (cp)
  152. {
  153. return (cp >= 0x30 && cp <= 0x39); // 0..9
  154. },
  155. IsHexDigit: function (cp)
  156. {
  157. return (cp >= 0x30 && cp <= 0x39) || (cp >= 0x41 && cp <= 0x46) || (cp >= 0x61 && cp <= 0x66); // a..f
  158. },
  159. isOctalDigit: function (cp)
  160. {
  161. return (cp >= 0x30 && cp <= 0x37); // 0..7
  162. }
  163. }
  164. var TOKEN_NAME={};
  165. TOKEN_NAME[1 /* BooleanLiteral */] = 'Boolean';
  166. TOKEN_NAME[2 /* EOF */] = '<end>';
  167. TOKEN_NAME[3 /* Identifier */] = 'Identifier';
  168. TOKEN_NAME[4 /* Keyword */] = 'Keyword';
  169. TOKEN_NAME[5 /* NullLiteral */] = 'Null';
  170. TOKEN_NAME[6 /* NumericLiteral */] = 'Numeric';
  171. TOKEN_NAME[7 /* Punctuator */] = 'Punctuator';
  172. TOKEN_NAME[8 /* StringLiteral */] = 'String';
  173. TOKEN_NAME[9 /* RegularExpression */] = 'RegularExpression';
  174. TOKEN_NAME[10 /* Template */] = 'Template';
  175. //编译异常, 错误类
  176. function ErrorHandler()
  177. {
  178. this.Error=[];
  179. this.RecordError=function(error)
  180. {
  181. this.Error.push(error);
  182. }
  183. this.ConstructError=function(msg,column)
  184. {
  185. let error=new Error(msg);
  186. //通过自己抛异常并自己截获 来获取调用堆栈信息
  187. try
  188. {
  189. throw error;
  190. }
  191. catch(base)
  192. {
  193. if (Object.create && Object.defineProperties)
  194. {
  195. error=Object.create(base);
  196. error.Column=column;
  197. }
  198. }
  199. return error;
  200. }
  201. this.CreateError=function(index, line, col, description)
  202. {
  203. let msg='Line ' + line + ': ' + description;
  204. let error=this.ConstructError(msg,col);
  205. error.Index=index;
  206. error.LineNumber=line;
  207. error.Description=description;
  208. return error;
  209. }
  210. this.ThrowError=function(index, line, col, description)
  211. {
  212. let error=this.CreateError(index,line,col,description);
  213. throw error;
  214. }
  215. }
  216. //扫描类
  217. function Scanner(code, ErrorHandler)
  218. {
  219. this.Source=code;
  220. this.ErrorHandler=ErrorHandler;
  221. this.Length=code.length;
  222. this.Index=0;
  223. this.LineNumber=(code.length>0)?1:0;
  224. this.LineStart=0;
  225. this.CurlyStack=[];
  226. this.SaveState=function() //保存当前扫描状态
  227. {
  228. return { Index:this.Index, LineNumber:this.LineNumber, LineStart:this.LineStart };
  229. }
  230. this.RestoreState=function(state) //还原扫描状态
  231. {
  232. this.Index=state.Index;
  233. this.LineNumber=state.LineNumber;
  234. this.LineStart=state.LineStart;
  235. }
  236. this.IsEOF=function() //否是已经结束
  237. {
  238. return this.Index>=this.Length;
  239. }
  240. this.IsKeyword=function(id)
  241. {
  242. return false;
  243. }
  244. this.CodePointAt = function (i)
  245. {
  246. let cp = this.Source.charCodeAt(i);
  247. if (cp >= 0xD800 && cp <= 0xDBFF)
  248. {
  249. let second = this.Source.charCodeAt(i + 1);
  250. if (second >= 0xDC00 && second <= 0xDFFF) {
  251. var first = cp;
  252. cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
  253. }
  254. }
  255. return cp;
  256. }
  257. this.Lex=function()
  258. {
  259. if (this.IsEOF()) return { Type:2/*EOF*/, Value:'', LineNumber:this.LineNumber, LineStart:this.LineStart, Start:this.Index, End:this.Index };
  260. let cp=this.Source.charCodeAt(this.Index);
  261. //变量名 或 关键字
  262. if (Character.IsIdentifierStart(cp)) return this.ScanIdentifier();
  263. //( ) ; 开头 操作符扫描
  264. if (cp === 0x28 || cp === 0x29 || cp === 0x3B) return this.ScanPunctuator();
  265. //' " 开头 字符串扫描
  266. if (cp === 0x27 || cp === 0x22) return this.ScanStringLiteral();
  267. //. 开头 浮点型
  268. if (cp==0x2E)
  269. {
  270. if (Character.IsDecimalDigit(this.Source.charCodeAt(this.Index + 1)))
  271. return this.ScanNumericLiteral();
  272. return this.ScanPunctuator();
  273. }
  274. //数字
  275. if (Character.IsDecimalDigit(cp)) return this.ScanNumericLiteral();
  276. if (cp >= 0xD800 && cp < 0xDFFF)
  277. {
  278. if (Character.IsIdentifierStart(this.CodePointAt(this.Index))) return this.ScanIdentifier();
  279. }
  280. return this.ScanPunctuator();
  281. }
  282. //关键字 变量名 https://tc39.github.io/ecma262/#sec-names-and-keywords
  283. this.ScanIdentifier=function()
  284. {
  285. let type;
  286. let start=this.Index;
  287. //0x5C 反斜杠
  288. let id=(this.Source.charCodeAt(start)=== 0x5C) ? this.GetComplexIdentifier() : this.GetIdentifier();
  289. if (id.length) type=3; //Identifier
  290. else if (this.IsKeyword(id)) type=4; //Keyword
  291. else if (id==null) type=5; //NullLiteral
  292. else if (id=='true' || id=='false') type=1; //BooleanLiteral
  293. else type=3; //Identifier
  294. if (type!=3 && (start+id.length!=this.Index))
  295. {
  296. let restore=this.Index;
  297. this.Index=start;
  298. throw Messages.InvalidEscapedReservedWord;
  299. this.Index=restore;
  300. }
  301. if (id=='AND' || id=='OR') type=7 /*Punctuator*/;
  302. return { Type:type, Value:id, LineNumber:this.LineNumber, LineStart:this.LineStart, Start:start, End:this.Index};
  303. }
  304. this.GetIdentifier=function()
  305. {
  306. let start=this.Index++; //start 保存进来的位置
  307. while(!this.IsEOF())
  308. {
  309. let ch=this.Source.charCodeAt(this.Index);
  310. if (ch==0x5C)
  311. {
  312. this.Index=start;
  313. return this.GetComplexIdentifier();
  314. }
  315. else if (ch >= 0xD800 && ch < 0xDFFF)
  316. {
  317. this.Index=start;
  318. return this.GetComplexIdentifier();
  319. }
  320. if (Character.IsIdentifierPart(ch)) ++this.Index;
  321. else break;
  322. }
  323. return this.Source.slice(start,this.Index);
  324. }
  325. //操作符 https://tc39.github.io/ecma262/#sec-punctuators
  326. this.ScanPunctuator=function()
  327. {
  328. let start=this.Index;
  329. let str=this.Source[this.Index];
  330. switch(str)
  331. {
  332. case '(':
  333. ++this.Index;
  334. break;
  335. case ')':
  336. case ';':
  337. case ',':
  338. ++this.Index;
  339. break;
  340. case '.':
  341. ++this.Index;
  342. /*if (this.Source[this.Index] === '.' && this.Source[this.Index + 1] === '.')
  343. {
  344. //Spread operator: ...
  345. this.Index += 2;
  346. str = '...';
  347. }
  348. */
  349. break;
  350. default:
  351. str=this.Source.substr(this.Index,3);
  352. if (str=='AND')
  353. {
  354. this.Index+=3;
  355. }
  356. else
  357. {
  358. str = this.Source.substr(this.Index, 2);
  359. if (str === '&&' || str === '||' || str === '==' || str === '!=' || str === '<>' || str === '<=' || str === '>=' || str === '=>' || str==':=' || str=='OR')
  360. {
  361. this.Index += 2;
  362. }
  363. else
  364. {
  365. str=this.Source[this.Index];
  366. if ('<>=!+-*%&|^/:'.indexOf(str) >= 0) ++this.Index;
  367. }
  368. }
  369. }
  370. if (this.Index==start)
  371. this.ThrowUnecpectedToken();
  372. return { Type:7/*Punctuator*/, Value:str, LineNumber:this.LineNumber, LineStart:this.LineStart, Start:start, End:this.Index };
  373. }
  374. //字符串 https://tc39.github.io/ecma262/#sec-literals-string-literals
  375. this.ScanStringLiteral=function()
  376. {
  377. let start=this.Index;
  378. let quote=this.Source[this.Index];
  379. ++this.Index;
  380. var octal=false;
  381. let str='';
  382. while(!this.IsEOF())
  383. {
  384. let ch=this.Source[this.Index++];
  385. if (ch==quote)
  386. {
  387. quote='';
  388. break;
  389. }
  390. else if (ch=='\\') //字符串转义
  391. {
  392. throw "not complete";
  393. }
  394. else if (Character.IsLineTerminator(ch.charCodeAt(0)))
  395. {
  396. break;
  397. }
  398. else
  399. {
  400. str+=ch;
  401. }
  402. }
  403. if (quote!='')
  404. {
  405. this.Index=start;
  406. this.ThrowUnecpectedToken();
  407. }
  408. return {Type:8/*StringLiteral*/, Value:str, LineNumber:this.LineNumber, LineStart:this.LineStart, Start:start, End:this.Index};
  409. }
  410. this.ScanNumericLiteral=function()
  411. {
  412. let start=this.Index;
  413. let ch=this.Source[this.Index];
  414. let num='';
  415. if (ch!='.')
  416. {
  417. num=this.Source[this.Index++];
  418. ch=this.Source[this.Index];
  419. // Hex number starts with '0x'. 16进制
  420. if (num=='0')
  421. {
  422. if (ch=='x' || ch=='X')
  423. {
  424. ++this.Index;
  425. return this.ScanHexLiteral(start);
  426. }
  427. }
  428. while(Character.IsDecimalDigit(this.Source.charCodeAt(this.Index)))
  429. {
  430. num+=this.Source[this.Index++];
  431. }
  432. ch=this.Source[this.Index];
  433. }
  434. if (ch=='.')
  435. {
  436. num+=this.Source[this.Index++];
  437. while(Character.IsDecimalDigit(this.Source.charCodeAt(this.Index)))
  438. {
  439. num+=this.Source[this.Index++];
  440. }
  441. ch=this.Source[this.Index];
  442. }
  443. //科学计数法
  444. if (ch=='e' || ch=='E')
  445. {
  446. num+=this.Source[this.Index++];
  447. ch=this.Source[this.Index];
  448. if (ch=='+' || ch=='-') num+=this.Source[this.Index];
  449. if (Character.IsDecimalDigit(this.Source.charCodeAt(this.Index)))
  450. {
  451. while(Character.IsDecimalDigit(this.Source.charCodeAt(this.Index)))
  452. {
  453. num+=this.Source[this.Index++];
  454. }
  455. }
  456. else
  457. {
  458. this.ThrowUnecpectedToken();
  459. }
  460. }
  461. if (Character.IsIdentifierStart(this.Source.charCodeAt(this.Index)))
  462. {
  463. this.ThrowUnecpectedToken();
  464. }
  465. return { Type:6/*NumericLiteral*/, Value:parseFloat(num), LineNumber:this.LineNumber, LineStart:this.LineStart, Start:start, End:this.Index };
  466. }
  467. //空格 或 注释
  468. this.ScanComments=function()
  469. {
  470. let comments;
  471. let start=(this.Index==0);
  472. while(!this.IsEOF())
  473. {
  474. let ch=this.Source.charCodeAt(this.Index);
  475. if (Character.IsWhiteSpace(ch)) //过滤掉空格
  476. {
  477. ++this.Index;
  478. }
  479. else if (Character.IsLineTerminator(ch))
  480. {
  481. ++this.Index;
  482. if (ch==0x0D && this.Source.charCodeAt(this.Index)==0x0A) ++this.Index; //回车+换行
  483. ++this.LineNumber;
  484. this.LineStart=this.Index;
  485. start=true;
  486. }
  487. else if (ch==0x2F) // //注释
  488. {
  489. ch=this.Source.charCodeAt(this.Index+1);
  490. if (ch==0x2F)
  491. {
  492. this.Index+=2;
  493. let comment=this.SkipSingleLineComment(2);
  494. start=true;
  495. }
  496. else
  497. {
  498. break;
  499. }
  500. }
  501. else if (ch == 0x7B) //{ } 注释
  502. {
  503. this.Index += 1;
  504. let comment = this.SkipMultiLineComment();
  505. }
  506. else
  507. {
  508. break;
  509. }
  510. }
  511. return comments;
  512. }
  513. this.SkipMultiLineComment = function ()
  514. {
  515. var comments = [];
  516. while (!this.IsEOF())
  517. {
  518. var ch = this.Source.charCodeAt(this.Index);
  519. if (Character.IsLineTerminator(ch))
  520. {
  521. ++this.LineNumber;
  522. ++this.Index;
  523. this.LineStart = this.Index;
  524. }
  525. else if (ch == 0x7D)
  526. {
  527. this.Index += 1;
  528. return comments;
  529. }
  530. else
  531. {
  532. ++this.Index;
  533. }
  534. }
  535. return comments;
  536. }
  537. //单行注释 https://tc39.github.io/ecma262/#sec-comments
  538. this.SkipSingleLineComment=function(offset)
  539. {
  540. let comments=[];
  541. while(!this.IsEOF())
  542. {
  543. let ch=this.Source.charCodeAt(this.Index);
  544. ++this.Index;
  545. if (Character.IsLineTerminator(ch))
  546. {
  547. if (ch === 13 && this.Source.charCodeAt(this.Index) === 10)
  548. ++this.Index;
  549. ++this.LineNumber;
  550. this.LineStart=this.Index;
  551. return comments;
  552. }
  553. }
  554. return comments;
  555. }
  556. this.ThrowUnecpectedToken=function(message)
  557. {
  558. if (!message) message = Messages.UnexpectedTokenIllegal;
  559. return this.ErrorHandler.ThrowError(this.Index, this.LineNumber, this.Index - this.LineStart + 1, message);
  560. }
  561. }
  562. function Tokenizer(code)
  563. {
  564. this.ErrorHandler=new ErrorHandler(); //错误信息处理类
  565. this.Scanner=new Scanner(code,this.ErrorHandler);
  566. this.Buffer=[];
  567. this.GetNextToken=function()
  568. {
  569. if (this.Buffer.length==0)
  570. {
  571. let comments=this.Scanner.ScanComments();
  572. if (!this.Scanner.IsEOF())
  573. {
  574. let token=this.Scanner.Lex();
  575. let entry={ Type:TOKEN_NAME[token.Type], Value:this.Scanner.Source.slice(token.Start, token.End)};
  576. this.Buffer.push(entry);
  577. }
  578. }
  579. return this.Buffer.shift();
  580. }
  581. }
  582. var Syntax = {
  583. AssignmentExpression: 'AssignmentExpression',
  584. AssignmentPattern: 'AssignmentPattern',
  585. ArrayExpression: 'ArrayExpression',
  586. ArrayPattern: 'ArrayPattern',
  587. ArrowFunctionExpression: 'ArrowFunctionExpression',
  588. AwaitExpression: 'AwaitExpression',
  589. BlockStatement: 'BlockStatement',
  590. BinaryExpression: 'BinaryExpression',
  591. BreakStatement: 'BreakStatement',
  592. CallExpression: 'CallExpression',
  593. CatchClause: 'CatchClause',
  594. ClassBody: 'ClassBody',
  595. ClassDeclaration: 'ClassDeclaration',
  596. ClassExpression: 'ClassExpression',
  597. ConditionalExpression: 'ConditionalExpression',
  598. ContinueStatement: 'ContinueStatement',
  599. DoWhileStatement: 'DoWhileStatement',
  600. DebuggerStatement: 'DebuggerStatement',
  601. EmptyStatement: 'EmptyStatement',
  602. ExportAllDeclaration: 'ExportAllDeclaration',
  603. ExportDefaultDeclaration: 'ExportDefaultDeclaration',
  604. ExportNamedDeclaration: 'ExportNamedDeclaration',
  605. ExportSpecifier: 'ExportSpecifier',
  606. ExpressionStatement: 'ExpressionStatement',
  607. ForStatement: 'ForStatement',
  608. ForOfStatement: 'ForOfStatement',
  609. ForInStatement: 'ForInStatement',
  610. FunctionDeclaration: 'FunctionDeclaration',
  611. FunctionExpression: 'FunctionExpression',
  612. Identifier: 'Identifier',
  613. IfStatement: 'IfStatement',
  614. ImportDeclaration: 'ImportDeclaration',
  615. ImportDefaultSpecifier: 'ImportDefaultSpecifier',
  616. ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
  617. ImportSpecifier: 'ImportSpecifier',
  618. Literal: 'Literal',
  619. LabeledStatement: 'LabeledStatement',
  620. LogicalExpression: 'LogicalExpression',
  621. MemberExpression: 'MemberExpression',
  622. MetaProperty: 'MetaProperty',
  623. MethodDefinition: 'MethodDefinition',
  624. NewExpression: 'NewExpression',
  625. ObjectExpression: 'ObjectExpression',
  626. ObjectPattern: 'ObjectPattern',
  627. Program: 'Program',
  628. Property: 'Property',
  629. RestElement: 'RestElement',
  630. ReturnStatement: 'ReturnStatement',
  631. SequenceExpression: 'SequenceExpression',
  632. SpreadElement: 'SpreadElement',
  633. Super: 'Super',
  634. SwitchCase: 'SwitchCase',
  635. SwitchStatement: 'SwitchStatement',
  636. TaggedTemplateExpression: 'TaggedTemplateExpression',
  637. TemplateElement: 'TemplateElement',
  638. TemplateLiteral: 'TemplateLiteral',
  639. ThisExpression: 'ThisExpression',
  640. ThrowStatement: 'ThrowStatement',
  641. TryStatement: 'TryStatement',
  642. UnaryExpression: 'UnaryExpression',
  643. UpdateExpression: 'UpdateExpression',
  644. VariableDeclaration: 'VariableDeclaration',
  645. VariableDeclarator: 'VariableDeclarator',
  646. WhileStatement: 'WhileStatement',
  647. WithStatement: 'WithStatement',
  648. YieldExpression: 'YieldExpression'
  649. };
  650. function Node()
  651. {
  652. this.IsNeedIndexData=false; //是否需要大盘数据
  653. this.IsNeedLatestData=false; //是否需要最新的个股行情数据
  654. this.IsNeedSymbolData=false; //是否需要下载股票数据
  655. this.IsNeedMarginData = new Set();
  656. this.IsNeedNewsAnalysisData = new Set(); //新闻统计数据
  657. this.IsNeedBlockIncreaseData = new Set(); //是否需要市场涨跌股票数据统计
  658. this.IsNeedSymbolExData = new Set(); //下载股票行情的其他数据
  659. this.FunctionData=[]; //{ID:, Args:, FunctionName: } FINVALUE(ID),FINONE(ID,Y,MMDD), FINANCE(ID)
  660. this.Dynainfo=[]; //{ID:, Args:, FunctionName: } DYNAINFO()
  661. this.IsAPIData = [] //加载API数据
  662. this.GetDataJobList=function() //下载数据任务列表
  663. {
  664. let jobs=[];
  665. if (this.IsNeedSymbolData) jobs.push({ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_SYMBOL_DATA});
  666. if (this.IsNeedIndexData) jobs.push({ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_INDEX_DATA});
  667. //最新的个股行情数据
  668. for(var i=0;i<this.Dynainfo.length;++i)
  669. {
  670. var item=this.Dynainfo[i];
  671. jobs.push(item);
  672. }
  673. //涨跌停家数统计
  674. for (var blockSymbol of this.IsNeedBlockIncreaseData)
  675. {
  676. jobs.push({ ID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_INDEX_INCREASE_DATA, Symbol: blockSymbol });
  677. }
  678. //加载融资融券
  679. for (var jobID of this.IsNeedMarginData)
  680. {
  681. jobs.push({ID:jobID});
  682. }
  683. //加载新闻统计
  684. for (var jobID of this.IsNeedNewsAnalysisData)
  685. {
  686. jobs.push({ID:jobID});
  687. }
  688. for (var i in this.IsAPIData)
  689. {
  690. var item = this.IsAPIData[i];
  691. jobs.push(item);
  692. }
  693. //行情其他数据
  694. for (var jobID of this.IsNeedSymbolExData)
  695. {
  696. jobs.push({ ID:jobID });
  697. }
  698. for(var i in this.FunctionData)
  699. {
  700. var item=this.FunctionData[i];
  701. jobs.push(item);
  702. }
  703. return jobs;
  704. }
  705. this.VerifySymbolVariable = function (varName, token)
  706. {
  707. let setIndexName = new Set(['INDEXA', 'INDEXC', 'INDEXH', 'INDEXL', "INDEXO", "INDEXV", 'INDEXDEC', 'INDEXADV']);
  708. if (setIndexName.has(varName))
  709. {
  710. this.IsNeedIndexData=true;
  711. return;
  712. }
  713. let setSymbolDataName=new Set(['CLOSE','C','VOL','V','OPEN','O','HIGH','H','LOW','L','AMOUNT']);
  714. if (setSymbolDataName.has(varName))
  715. {
  716. this.IsNeedSymbolData=true;
  717. return;
  718. }
  719. if (varName === 'VOLR')
  720. {
  721. if (!this.IsNeedSymbolExData.has(JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_VOLR_DATA))
  722. this.IsNeedSymbolExData.add(JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_VOLR_DATA);
  723. return;
  724. }
  725. //CAPITAL流通股本(手), EXCHANGE 换手率, TOTALCAPITAL 总股本(手)
  726. let setVariantName=new Set(
  727. [
  728. "CAPITAL","TOTALCAPITAL","EXCHANGE",
  729. "HYBLOCK","DYBLOCK","GNBLOCK","FGBLOCK","ZSBLOCK","ZHBLOCK","ZDBLOCK","HYZSCODE",
  730. "GNBLOCKNUM","FGBLOCKNUM","ZSBLOCKNUM","ZHBLOCKNUM","ZDBLOCKNUM",
  731. "HYSYL","HYSJL"
  732. ]);
  733. if (setVariantName.has(varName))
  734. {
  735. var item={ ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_VARIANT, VariantName:varName };
  736. if (token) item.Token={ Index:token.Start, Line:token.LineNumber };
  737. this.FunctionData.push(item);
  738. return;
  739. }
  740. if (g_JSComplierResource.IsCustomVariant(varName)) //自定义函数
  741. {
  742. var item={ VariantName:varName, ID:JS_EXECUTE_JOB_ID.JOB_CUSTOM_VARIANT_DATA };
  743. if (token) item.Token={ Index:token.Start, Line:token.LineNumber };
  744. this.FunctionData.push(item);
  745. return;
  746. }
  747. }
  748. this.VerifySymbolFunction = function (callee, args, token)
  749. {
  750. //自定义函数 可以覆盖系统内置函数
  751. if (g_JSComplierResource.IsCustomFunction(callee.Name))
  752. {
  753. var item={FunctionName:callee.Name, ID:JS_EXECUTE_JOB_ID.JOB_CUSTOM_FUNCTION_DATA, Args:args}
  754. if (token) item.Token={ Index:token.Start, Line:token.LineNumber};
  755. this.FunctionData.push(item);
  756. return;
  757. }
  758. if (callee.Name=='DYNAINFO')
  759. {
  760. var item={ ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_SYMBOL_LATEST_DATA, Args:args, FunctionName:callee.Name };
  761. this.Dynainfo.push(item);
  762. return;
  763. }
  764. //财务函数
  765. if (callee.Name=='FINANCE')
  766. {
  767. var item={ ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_FINANCE, Args:args, FunctionName:callee.Name };
  768. if (token) item.Token={ Index:token.Start, Line:token.LineNumber };
  769. this.FunctionData.push(item);
  770. return;
  771. }
  772. if (callee.Name=="FINVALUE")
  773. {
  774. var item={ ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_FINVALUE, Args:args, FunctionName:callee.Name };
  775. if (token) item.Token={ Index:token.Start, Line:token.LineNumber };
  776. this.FunctionData.push(item);
  777. return;
  778. }
  779. if (callee.Name=="FINONE")
  780. {
  781. var item={ ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_FINONE, Args:args, FunctionName:callee.Name };
  782. if (token) item.Token={ Index:token.Start, Line:token.LineNumber };
  783. this.FunctionData.push(item);
  784. return;
  785. }
  786. if (callee.Name=='GPJYVALUE')
  787. {
  788. var item={ ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_GPJYVALUE, Args:args, FunctionName:callee.Name };
  789. if (token) item.Token={ Index:token.Start, Line:token.LineNumber };
  790. this.FunctionData.push(item);
  791. return;
  792. }
  793. if (callee.Name === 'MARGIN')
  794. {
  795. let jobID = JS_EXECUTE_JOB_ID.GetMarginJobID(args[0].Value);
  796. if (jobID && !this.IsNeedMarginData.has(jobID)) this.IsNeedMarginData.add(jobID);
  797. return;
  798. }
  799. if (callee.Name === 'NEWS')
  800. {
  801. let jobID = JS_EXECUTE_JOB_ID.GetNewsAnalysisID(args[0].Value);
  802. if (jobID && !this.IsNeedNewsAnalysisData.has(jobID)) this.IsNeedNewsAnalysisData.add(jobID);
  803. return;
  804. }
  805. if (callee.Name == 'COST' || callee.Name == 'WINNER') //筹码都需要换手率
  806. {
  807. //下载流通股
  808. var item={ ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_FINANCE, Args:[7], FunctionName:"FINANCE", FunctionName2:callee.Name };
  809. if (token) item.Token={ Index:token.Start, Line:token.LineNumber };
  810. this.FunctionData.push(item);
  811. return;
  812. }
  813. if (callee.Name=="INBLOCK")
  814. {
  815. var item={ ID:JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_VARIANT, VariantName:"INBLOCK" }; //下载所有板块
  816. if (token) item.Token={ Index:token.Start, Line:token.LineNumber };
  817. this.FunctionData.push(item);
  818. return;
  819. }
  820. if (callee.Name === 'BETA') //beta需要下载上证指数
  821. {
  822. this.IsNeedIndexData = true;
  823. return;
  824. }
  825. if (callee.Name == 'UPCOUNT' || callee.Name == 'DOWNCOUNT') //上涨下跌个数
  826. {
  827. var blockSymbol = args[0].Value;
  828. if (!this.IsNeedBlockIncreaseData.has(blockSymbol)) this.IsNeedBlockIncreaseData.add(blockSymbol);
  829. return;
  830. }
  831. if (callee.Name == "LOADAPIDATA") //加载API数据
  832. {
  833. var item = { Name: callee.Name, ID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_CUSTOM_API_DATA, Args: args };
  834. if (token) item.Token = { Index: token.Start, Line: token.LineNumber };
  835. this.IsAPIData.push(item);
  836. return;
  837. }
  838. }
  839. this.ExpressionStatement=function(expression)
  840. {
  841. return { Type:Syntax.ExpressionStatement, Expression:expression };
  842. }
  843. this.Script=function(body)
  844. {
  845. return {Type:Syntax.Program, Body:body, SourceType:'通达信脚本' };
  846. }
  847. this.SequenceExpression=function(expression)
  848. {
  849. return {Type:Syntax.SequenceExpression, Expression:expression };
  850. }
  851. this.BinaryExpression=function(operator, left, right)
  852. {
  853. let logical = (operator === '||' || operator === '&&' || operator=='AND' || operator=='OR');
  854. let type = logical ? Syntax.LogicalExpression : Syntax.BinaryExpression;
  855. return { Type:type, Operator:operator, Left:left, Right:right };
  856. }
  857. this.Literal=function(value,raw)
  858. {
  859. return { Type:Syntax.Literal, Value:value, Raw:raw };
  860. }
  861. this.Identifier = function (name, token)
  862. {
  863. this.VerifySymbolVariable(name, token);
  864. return { Type:Syntax.Identifier, Name:name};
  865. }
  866. this.AssignmentExpression=function (operator, left, right)
  867. {
  868. return { Type:Syntax.AssignmentExpression, Operator:operator, Left:left, Right:right };
  869. }
  870. this.UnaryExpression=function(operator, argument)
  871. {
  872. return { Type:Syntax.UnaryExpression, Operator:operator, Argument:argument, Prefix:true };
  873. }
  874. this.EmptyStatement=function()
  875. {
  876. return { Type:Syntax.EmptyStatement };
  877. }
  878. this.CallExpression = function (callee, args, token)
  879. {
  880. this.VerifySymbolFunction(callee, args, token);
  881. return { Type:Syntax.CallExpression, Callee:callee, Arguments:args };
  882. }
  883. this.StaticMemberExpression = function (object, property)
  884. {
  885. return { Type: Syntax.MemberExpression, Computed: false, Object: object, Property: property };
  886. }
  887. }
  888. function JSParser(code)
  889. {
  890. this.ErrorHandler=new ErrorHandler();
  891. this.Scanner=new Scanner(code, this.ErrorHandler);
  892. this.Node=new Node(); //节点创建
  893. this.LookAhead={Type:2, Value:'', LineNumber:this.Scanner.LineNumber, LineStart:0, Start:0, End:0 };
  894. this.HasLineTerminator=false;
  895. this.Context = {
  896. IsModule: false,
  897. await: false,
  898. allowIn: true,
  899. allowStrictDirective: true,
  900. allowYield: true,
  901. FirstCoverInitializedNameError: null,
  902. IsAssignmentTarget: false,
  903. IsBindingElement: false,
  904. InFunctionBody: false,
  905. inIteration: false,
  906. inSwitch: false,
  907. labelSet: {},
  908. Strict: false
  909. };
  910. this.PeratorPrecedence =
  911. {
  912. ')': 0,
  913. ';': 0,
  914. ',': 0,
  915. ']': 0,
  916. '||': 1,
  917. 'OR':1,
  918. '&&': 2,
  919. 'AND':2,
  920. '|': 3,
  921. '^': 4,
  922. '&': 5,
  923. '=': 6,
  924. '==': 6,
  925. '!=': 6,
  926. '<>': 6,
  927. '===': 6,
  928. '!==': 6,
  929. '<': 7,
  930. '>': 7,
  931. '<=': 7,
  932. '>=': 7,
  933. '<<': 8,
  934. '>>': 8,
  935. '>>>': 8,
  936. '+': 9,
  937. '-': 9,
  938. '*': 11,
  939. '/': 11,
  940. '%': 11
  941. };
  942. this.StartMarker={Index:0, Line: this.Scanner.LineNumber, Column:0 };
  943. this.LastMarker={Index:0, Line: this.Scanner.LineNumber, Column:0 };
  944. this.Initialize=function()
  945. {
  946. this.NextToken();
  947. this.LastMarker={ Index:this.Scanner.Index, Line:this.Scanner.LineNumber, Column:this.Scanner.Index-this.Scanner.LineStart };
  948. }
  949. this.CreateNode=function()
  950. {
  951. return { Index:this.StartMarker.Index, Line:this.StartMarker.Line, Column:this.StartMarker.Column };
  952. }
  953. this.StartNode=function(token, lastLineStart)
  954. {
  955. if (lastLineStart==void 0) { lastLineStart=0; }
  956. let column = token.Start - token.LineStart;
  957. let line = token.LineNumber;
  958. if (column < 0)
  959. {
  960. column += lastLineStart;
  961. line--;
  962. }
  963. return { Index: token.Start, Line: line, Column: column };
  964. }
  965. this.Match=function(value)
  966. {
  967. return this.LookAhead.Type==7 /*Punctuator*/ && this.LookAhead.Value==value;
  968. }
  969. this.Expect=function(value)
  970. {
  971. let token=this.NextToken();
  972. if (token.Type!=7 /*Punctuator*/ || token.Value!=value)
  973. this.ThrowUnexpectedToken(token);
  974. }
  975. //是否是赋值操作符
  976. this.MatchAssign=function()
  977. {
  978. if (this.LookAhead.Type!=7 /*Punctuator*/) return false;
  979. let op=this.LookAhead.Value;
  980. return op==':' || op==':=';
  981. }
  982. this.GetTokenRaw=function(token)
  983. {
  984. return this.Scanner.Source.slice(token.Start, token.End);
  985. }
  986. this.NextToken=function()
  987. {
  988. let token=this.LookAhead;
  989. this.LastMarker.Index=this.Scanner.Index;
  990. this.LastMarker.Line=this.Scanner.LineNumber;
  991. this.LastMarker.Column=this.Scanner.Index-this.Scanner.LineStart;
  992. this.CollectComments(); //过滤注释 空格
  993. if (this.Scanner.Index !== this.StartMarker.Index)
  994. {
  995. this.StartMarker.Index = this.Scanner.Index;
  996. this.StartMarker.Line = this.Scanner.LineNumber;
  997. this.StartMarker.Column = this.Scanner.Index - this.Scanner.LineStart;
  998. }
  999. let next=this.Scanner.Lex();
  1000. this.HasLineTerminator=(token.LineNumber!=next.LineNumber);
  1001. if (next && this.Context.Strict && next.Type==3/*Identifier */)
  1002. {
  1003. //TODO:
  1004. }
  1005. this.LookAhead=next;
  1006. return token;
  1007. }
  1008. this.CollectComments=function()
  1009. {
  1010. this.Scanner.ScanComments();
  1011. }
  1012. this.ParseScript=function()
  1013. {
  1014. let node=this.CreateNode();
  1015. let body=this.ParseDirectivePrologues();
  1016. while(this.LookAhead.Type!=2 /*EOF*/)
  1017. {
  1018. body.push(this.ParseStatementListItem())
  1019. }
  1020. return this.Finalize(node,this.Node.Script(body));
  1021. }
  1022. //https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive
  1023. this.ParseDirective=function()
  1024. {
  1025. let token=this.LookAhead;
  1026. let node=this.CreateNode();
  1027. let expr=this.ParseExpression();
  1028. }
  1029. this.ParseDirectivePrologues=function()
  1030. {
  1031. let firstRestricted=null;
  1032. let body=[];
  1033. while(true)
  1034. {
  1035. let token=this.LookAhead;
  1036. if (token.Type!=8 /*StringLiteral*/) break;
  1037. let statement=this.ParseDirective();
  1038. body.push(statement);
  1039. }
  1040. return body;
  1041. }
  1042. // https://tc39.github.io/ecma262/#sec-block
  1043. this.ParseStatementListItem=function()
  1044. {
  1045. let statement;
  1046. this.Context.IsAssignmentTarget=true;
  1047. this.Context.IsBindingElement=true;
  1048. if (this.LookAhead.Type==4 /*Keyword*/)
  1049. {
  1050. }
  1051. else
  1052. {
  1053. statement=this.ParseStatement();
  1054. }
  1055. return statement;
  1056. }
  1057. // https://tc39.github.io/ecma262/#sec-ecmascript-language-statements-and-declarations
  1058. this.ParseStatement=function()
  1059. {
  1060. let statement;
  1061. switch(this.LookAhead.Type)
  1062. {
  1063. case 1 /* BooleanLiteral */:
  1064. case 5 /* NullLiteral */:
  1065. case 6 /* NumericLiteral */:
  1066. case 8 /* StringLiteral */:
  1067. case 10 /* Template */:
  1068. case 9 /* RegularExpression */:
  1069. statement = this.ParseExpressionStatement();
  1070. break;
  1071. case 7 /* Punctuator */:
  1072. let value = this.LookAhead.Value;
  1073. if (value === '(') statement = this.ParseExpressionStatement();
  1074. else if (value === ';') statement = this.ParseEmptyStatement();
  1075. else statement = this.ParseExpressionStatement();
  1076. break;
  1077. case 3 /* Identifier */:
  1078. statement = this.ParseLabelledStatement();
  1079. break;
  1080. case 4 /* Keyword */:
  1081. break;
  1082. default:
  1083. statement="error";
  1084. }
  1085. return statement;
  1086. }
  1087. // https://tc39.github.io/ecma262/#sec-empty-statement
  1088. this.ParseEmptyStatement=function()
  1089. {
  1090. let node=this.CreateNode();
  1091. this.Expect(';');
  1092. return this.Finalize(node, this.Node.EmptyStatement());
  1093. }
  1094. //https://tc39.github.io/ecma262/#sec-labelled-statements
  1095. this.ParseLabelledStatement=function()
  1096. {
  1097. let node=this.CreateNode();
  1098. let expr=this.ParseExpression();
  1099. this.ConsumeSemicolon();
  1100. let statement = new this.Node.ExpressionStatement(expr);
  1101. return this.Finalize(node, statement);
  1102. }
  1103. // https://tc39.github.io/ecma262/#sec-comma-operator
  1104. this.ParseExpression=function()
  1105. {
  1106. let startToken=this.LookAhead;
  1107. let expr=this.IsolateCoverGrammar(this.ParseAssignmentExpression);
  1108. if (this.Match(','))
  1109. {
  1110. let expressions=[];
  1111. expressions.push(expr);
  1112. while(this.LookAhead.Type!=2 /*EOF*/)
  1113. {
  1114. if (!this.Match(',')) break;
  1115. this.NextToken();
  1116. expressions.push(this.IsolateCoverGrammar(this.ParseAssignmentExpression));
  1117. }
  1118. expr=this.Finalize(this.StartNode(startToken),this.Node.SequenceExpression(expressions));
  1119. }
  1120. return expr;
  1121. }
  1122. this.ParseAssignmentExpression=function()
  1123. {
  1124. let expr;
  1125. let startToken=this.LookAhead;
  1126. let token=startToken;
  1127. expr=this.ParseConditionalExpression();
  1128. if (this.MatchAssign())
  1129. {
  1130. if (!this.Context.IsAssignmentTarget)
  1131. {
  1132. let marker=expr.Marker;
  1133. this.ThrowUnexpectedError(marker.Index,marker.Line,marker.Column,Messages.InvalidLHSInAssignment);
  1134. }
  1135. if (!this.Match('=') && !this.Match(':'))
  1136. {
  1137. this.Context.IsAssignmentTarget=false;
  1138. this.Context.IsBindingElement=false;
  1139. }
  1140. else
  1141. {
  1142. this.ReinterpretExpressionAsPattern(expr);
  1143. }
  1144. token=this.NextToken();
  1145. let operator=token.Value;
  1146. let right=this.IsolateCoverGrammar(this.ParseAssignmentExpression);
  1147. expr=this.Finalize(this.StartNode(startToken), this.Node.AssignmentExpression(operator, expr, right));
  1148. this.Context.FirstCoverInitializedNameError=null;
  1149. }
  1150. return expr;
  1151. }
  1152. this.ParseConditionalExpression=function()
  1153. {
  1154. let startToken=this.LookAhead;
  1155. let expr=this.InheritCoverGrammar(this.ParseBinaryExpression);
  1156. return expr;
  1157. }
  1158. this.ParseBinaryExpression=function()
  1159. {
  1160. let startToken=this.LookAhead;
  1161. let expr=this.InheritCoverGrammar(this.ParseExponentiationExpression);
  1162. let token=this.LookAhead;
  1163. var prec=this.BinaryPrecedence(token);
  1164. if (prec>0)
  1165. {
  1166. this.NextToken();
  1167. this.Context.IsAssignmentTarget=false;
  1168. this.Context.IsBindingElement=false;
  1169. let markers=[startToken,this.LookAhead];
  1170. let left=expr;
  1171. let right=this.IsolateCoverGrammar(this.ParseExponentiationExpression);
  1172. let stack=[left,token.Value,right];
  1173. let precedences = [prec];
  1174. while(true)
  1175. {
  1176. prec=this.BinaryPrecedence(this.LookAhead);
  1177. if (prec<=0) break;
  1178. while(stack.length>2 && prec<=precedences[precedences.length-1])
  1179. {
  1180. right=stack.pop();
  1181. let operator=stack.pop();
  1182. precedences.pop();
  1183. left=stack.pop();
  1184. markers.pop();
  1185. let node=this.StartNode(markers[markers.length - 1]);
  1186. stack.push(this.Finalize(node, this.Node.BinaryExpression(operator, left, right)));
  1187. }
  1188. //Shift
  1189. stack.push(this.NextToken().Value);
  1190. precedences.push(prec);
  1191. markers.push(this.LookAhead);
  1192. stack.push(this.IsolateCoverGrammar(this.ParseExponentiationExpression));
  1193. }
  1194. let i=stack.length-1;
  1195. expr=stack[i];
  1196. let lastMarker=markers.pop();
  1197. while(i>1)
  1198. {
  1199. let marker=markers.pop();
  1200. let lastLineStart=lastMarker && lastMarker.LineStart;
  1201. let node=this.StartNode(marker, lastLineStart);
  1202. let operator=stack[i-1];
  1203. expr=this.Finalize(node, this.Node.BinaryExpression(operator, stack[i - 2], expr));
  1204. i-=2;
  1205. lastMarker=marker;
  1206. }
  1207. }
  1208. return expr;
  1209. }
  1210. this.ParseExponentiationExpression=function()
  1211. {
  1212. let startToken=this.LookAhead;
  1213. let expr=this.InheritCoverGrammar(this.ParseUnaryExpression);
  1214. return expr;
  1215. }
  1216. this.ParseUnaryExpression=function()
  1217. {
  1218. let expr;
  1219. if (this.Match('+') || this.Match('-'))
  1220. {
  1221. let node=this.StartNode(this.LookAhead);
  1222. let token=this.NextToken();
  1223. expr=this.InheritCoverGrammar(this.ParseUnaryExpression);
  1224. expr=this.Finalize(node, this.Node.UnaryExpression(token.Value, expr));
  1225. this.Context.IsAssignmentTarget=false;
  1226. this.Context.IsBindingElement=false;
  1227. }
  1228. else
  1229. {
  1230. expr=this.ParseUpdateExpression();
  1231. }
  1232. return expr;
  1233. }
  1234. // https://tc39.github.io/ecma262/#sec-update-expressions
  1235. this.ParseUpdateExpression=function()
  1236. {
  1237. let expr;
  1238. let startToken=this.LookAhead;
  1239. expr=this.InheritCoverGrammar(this.ParseLeftHandSideExpressionAllowCall);
  1240. return expr;
  1241. }
  1242. this.ParseLeftHandSideExpressionAllowCall=function()
  1243. {
  1244. let startToken=this.LookAhead;
  1245. let expr;
  1246. expr=this.InheritCoverGrammar(this.ParsePrimaryExpression);
  1247. while(true)
  1248. {
  1249. if (this.Match('.'))
  1250. {
  1251. this.Context.IsBindingElement = false;
  1252. this.Context.IsAssignmentTarget = true;
  1253. this.Expect('.');
  1254. const property = this.ParseIdentifierName();
  1255. expr = this.Finalize(this.StartNode(startToken), this.Node.StaticMemberExpression(expr, property));
  1256. }
  1257. else if (this.Match('('))
  1258. {
  1259. this.Context.IsBindingElement=false;
  1260. this.Context.IsAssignmentTarget=false;
  1261. var args=this.ParseArguments(); //解析 调用参数
  1262. expr = this.Finalize(this.StartNode(startToken), this.Node.CallExpression(expr, args, startToken));
  1263. }
  1264. else
  1265. {
  1266. break;
  1267. }
  1268. }
  1269. return expr;
  1270. }
  1271. /*
  1272. BooleanLiteral = 1,
  1273. EOF=2,
  1274. Identifier=3,
  1275. Keyword=4,
  1276. NullLiteral=5,
  1277. NumericLiteral=6,
  1278. Punctuator=7,
  1279. StringLiteral=9,
  1280. RegularExpression=9,
  1281. Template=10
  1282. */
  1283. this.IsIdentifierName = function (token)
  1284. {
  1285. return token.Type === 3 //Identifier
  1286. || token.Type === 4 //Keyword
  1287. || token.Type === 1 //BooleanLiteral
  1288. || token.Type === 5;//NullLiteral;
  1289. }
  1290. this.ParseIdentifierName = function ()
  1291. {
  1292. const node = this.CreateNode();
  1293. const token = this.NextToken();
  1294. if (!this.IsIdentifierName(token))
  1295. {
  1296. this.ThrowUnexpectedToken(token);
  1297. }
  1298. return this.Finalize(node, this.Node.Identifier(token.Value, token));
  1299. }
  1300. // https://tc39.github.io/ecma262/#sec-left-hand-side-expressions
  1301. this.ParseArguments=function()
  1302. {
  1303. this.Expect('(');
  1304. var args=[];
  1305. if (!this.Match(')'))
  1306. {
  1307. while(true)
  1308. {
  1309. let expr=this.IsolateCoverGrammar(this.ParseAssignmentExpression);
  1310. args.push(expr);
  1311. if (this.Match(')')) break;
  1312. this.ExpectCommaSeparator();
  1313. if (this.Match(')')) break;
  1314. }
  1315. }
  1316. this.Expect(')');
  1317. return args;
  1318. }
  1319. // Quietly expect a comma when in tolerant mode, otherwise delegates to expect().
  1320. this.ExpectCommaSeparator=function()
  1321. {
  1322. this.Expect(',');
  1323. }
  1324. // https://tc39.github.io/ecma262/#sec-primary-expression
  1325. this.ParsePrimaryExpression=function()
  1326. {
  1327. let node=this.CreateNode();
  1328. let expr;
  1329. var token, raw;
  1330. switch(this.LookAhead.Type)
  1331. {
  1332. case 3:/* Identifier */
  1333. token = this.NextToken();
  1334. expr = this.Finalize(node, this.Node.Identifier(token.Value, token));
  1335. break;
  1336. case 6:/* NumericLiteral */
  1337. case 8:/* StringLiteral */
  1338. this.Context.IsAssignmentTarget=false;
  1339. this.Context.IsBindingElement=false;
  1340. token=this.NextToken();
  1341. raw=this.GetTokenRaw(token);
  1342. expr=this.Finalize(node, this.Node.Literal(token.Value,raw));
  1343. break;
  1344. case 7:/* Punctuator */
  1345. switch(this.LookAhead.Value)
  1346. {
  1347. case '(':
  1348. this.Context.IsBindingElement=false;
  1349. expr=this.InheritCoverGrammar(this.ParseGroupExpression);
  1350. break;
  1351. default:
  1352. expr=this.ThrowUnexpectedToken(this.NextToken())
  1353. }
  1354. break;
  1355. default:
  1356. expr = this.ThrowUnexpectedToken(this.NextToken());
  1357. }
  1358. return expr;
  1359. }
  1360. this.ParseGroupExpression=function()
  1361. {
  1362. let expr;
  1363. this.Expect('(');
  1364. if (this.Match(')'))
  1365. {
  1366. this.NextToken();
  1367. }
  1368. else
  1369. {
  1370. let startToken=this.LookAhead;
  1371. let params=[];
  1372. let arrow=false;
  1373. this.Context.IsBindingElement=true;
  1374. expr=this.InheritCoverGrammar(this.ParseAssignmentExpression);
  1375. if (this.Match(','))
  1376. {
  1377. let expressions=[];
  1378. this.Context.IsAssignmentTarget=false;
  1379. expressions.push(expr);
  1380. while(this.LookAhead.Type!=2 /* EOF */)
  1381. {
  1382. if (!this.Match(',')) break;
  1383. this.NextToken();
  1384. if (this.Match(')'))
  1385. {
  1386. }
  1387. }
  1388. }
  1389. if (!arrow)
  1390. {
  1391. this.Expect(')');
  1392. this.Context.IsBindingElement=false;
  1393. }
  1394. }
  1395. return expr;
  1396. }
  1397. // https://tc39.github.io/ecma262/#sec-expression-statement
  1398. this.ParseExpressionStatement=function()
  1399. {
  1400. let node=this.CreateNode();
  1401. let expr=this.ParseExpression();
  1402. this.ConsumeSemicolon();
  1403. return this.Finalize(node,this.Node.ExpressionStatement(expr));
  1404. }
  1405. this.ConsumeSemicolon=function()
  1406. {
  1407. if (this.Match(';'))
  1408. {
  1409. this.NextToken();
  1410. }
  1411. else if (!this.HasLineTerminator)
  1412. {
  1413. //if (this.LookAhead.Type!=2/*EOF*/ && !this.Match('}'))
  1414. this.LastMarker.Index=this.StartMarker.Index;
  1415. this.LastMarker.Line=this.StartMarker.Line;
  1416. this.LastMarker.Column=this.StartMarker.Column;
  1417. }
  1418. }
  1419. this.ReinterpretExpressionAsPattern=function(expr)
  1420. {
  1421. switch(expr.Type)
  1422. {
  1423. case Syntax.Identifier:
  1424. case Syntax.MemberExpression:
  1425. case Syntax.AssignmentExpression:
  1426. break;
  1427. default:
  1428. break;
  1429. }
  1430. }
  1431. this.Finalize=function(marker,node)
  1432. {
  1433. node.Marker={ Line:marker.Line, Column:marker.Column, Index:marker.Index };
  1434. return node;
  1435. }
  1436. this.BinaryPrecedence = function (token)
  1437. {
  1438. let op = token.Value;
  1439. let precedence;
  1440. if (token.Type === 7 /* Punctuator */) precedence = this.PeratorPrecedence[op] || 0;
  1441. else precedence = 0;
  1442. return precedence;
  1443. };
  1444. this.IsolateCoverGrammar=function(parseFunction)
  1445. {
  1446. let previousIsBindingElement=this.Context.IsBindingElement;
  1447. let previousIsAssignmentTarget=this.Context.IsAssignmentTarget;
  1448. let previousFirstCoverInitializedNameError=this.Context.FirstCoverInitializedNameError;
  1449. this.Context.IsBindingElement=true;
  1450. this.Context.IsAssignmentTarget=true;
  1451. this.Context.FirstCoverInitializedNameError=null;
  1452. let result=parseFunction.call(this);
  1453. if (this.Context.FirstCoverInitializedNameError!=null)
  1454. {
  1455. //错误 this.throwUnexpectedToken(this.context.firstCoverInitializedNameError);
  1456. }
  1457. this.Context.IsBindingElement=previousIsBindingElement;
  1458. this.Context.IsAssignmentTarget=previousIsAssignmentTarget;
  1459. this.Context.FirstCoverInitializedNameError=previousFirstCoverInitializedNameError;
  1460. return result;
  1461. }
  1462. this.InheritCoverGrammar = function (parseFunction)
  1463. {
  1464. let previousIsBindingElement = this.Context.IsBindingElement;
  1465. let previousIsAssignmentTarget = this.Context.IsAssignmentTarget;
  1466. let previousFirstCoverInitializedNameError = this.Context.FirstCoverInitializedNameError;
  1467. this.Context.IsBindingElement = true;
  1468. this.Context.IsAssignmentTarget = true;
  1469. this.Context.FirstCoverInitializedNameError = null;
  1470. let result = parseFunction.call(this);
  1471. this.Context.IsBindingElement = this.Context.IsBindingElement && previousIsBindingElement;
  1472. this.Context.IsAssignmentTarget = this.Context.IsAssignmentTarget && previousIsAssignmentTarget;
  1473. this.Context.FirstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.Context.FirstCoverInitializedNameError;
  1474. return result;
  1475. };
  1476. this.ThrowUnexpectedToken=function(token,message)
  1477. {
  1478. throw this.UnexpectedTokenError(token,message);
  1479. }
  1480. this.ThrowUnexpectedError=function(index,line,column,message)
  1481. {
  1482. let msg=message || "执行异常";
  1483. return this.ErrorHandler.ThrowError(index,line,column,msg);
  1484. }
  1485. this.UnexpectedTokenError=function(token,message)
  1486. {
  1487. let msg=message || Messages.UnexpectedToken;
  1488. let value='ILLEGAL';
  1489. if (token)
  1490. {
  1491. if (!message)
  1492. {
  1493. }
  1494. value=token.Value;
  1495. }
  1496. msg=msg.replace("%0",value);
  1497. if (token && typeof(token.LineNumber)=='number')
  1498. {
  1499. let index=token.Start;
  1500. let line=token.LineNumber;
  1501. let lastMarkerLineStart=this.LastMarker.Index-this.LastMarker.Column;
  1502. let column=token.Start-lastMarkerLineStart+1;
  1503. return this.ErrorHandler.CreateError(index,line,column,msg);
  1504. }
  1505. else
  1506. {
  1507. let index=this.LastMarker.Index;
  1508. let line=this.LastMarker.Line;
  1509. let column=this.LastMarker.Column+1;
  1510. return this.ErrorHandler.CreateError(index,line,column,msg);
  1511. }
  1512. }
  1513. }
  1514. /*
  1515. 算法类
  1516. */
  1517. function JSAlgorithm(errorHandler, symbolData)
  1518. {
  1519. this.ErrorHandler=errorHandler;
  1520. this.SymbolData = symbolData; //股票数据
  1521. //相加
  1522. this.Add=function(data,data2)
  1523. {
  1524. let isNumber=typeof(data)=='number';
  1525. let isNumber2=typeof(data2)=='number';
  1526. //单数值相加
  1527. if (isNumber && isNumber2) return data+data2;
  1528. //都是数组相加
  1529. let result=[];
  1530. if (!isNumber && !isNumber2)
  1531. {
  1532. let count=Math.max(data.length, data2.length);
  1533. for(let i=0;i<count;++i)
  1534. {
  1535. result[i]=null; //初始化
  1536. if (i<data.length && i<data2.length)
  1537. {
  1538. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=data[i]+data2[i];
  1539. }
  1540. }
  1541. return result;
  1542. }
  1543. //单数据和数组相加
  1544. let value;
  1545. let aryData;
  1546. if (isNumber)
  1547. {
  1548. value=data;
  1549. aryData=data2;
  1550. }
  1551. else
  1552. {
  1553. value=data2;
  1554. aryData=data;
  1555. }
  1556. for(let i in aryData)
  1557. {
  1558. result[i]=null;
  1559. if (!isNaN(aryData[i]) && !isNaN(value)) result[i]=value+aryData[i];
  1560. }
  1561. return result;
  1562. }
  1563. //相减
  1564. this.Subtract=function(data,data2)
  1565. {
  1566. let isNumber=typeof(data)=='number';
  1567. let isNumber2=typeof(data2)=='number';
  1568. //单数值相减
  1569. if (isNumber && isNumber2) return data-data2;
  1570. //都是数组相减
  1571. let result=[];
  1572. if (!isNumber && !isNumber2)
  1573. {
  1574. let count=Math.max(data.length, data2.length);
  1575. for(let i=0;i<count;++i)
  1576. {
  1577. result[i]=null; //初始化
  1578. if (i<data.length && i<data2.length)
  1579. {
  1580. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=data[i]-data2[i];
  1581. }
  1582. }
  1583. return result;
  1584. }
  1585. if (isNumber) //单数据-数组
  1586. {
  1587. for(let i in data2)
  1588. {
  1589. result[i]=null;
  1590. if (!isNaN(data) && !isNaN(data2[i])) result[i]=data-data2[i];
  1591. }
  1592. }
  1593. else //数组-单数据
  1594. {
  1595. for(let i in data)
  1596. {
  1597. result[i]=null;
  1598. if (!isNaN(data[i]) && !isNaN(data2)) result[i]=data[i]-data2;
  1599. }
  1600. }
  1601. return result;
  1602. }
  1603. //相乘
  1604. this.Multiply=function(data,data2)
  1605. {
  1606. let isNumber=typeof(data)=='number';
  1607. let isNumber2=typeof(data2)=='number';
  1608. //单数值相乘
  1609. if (isNumber && isNumber2) return data*data2;
  1610. //都是数组相乘
  1611. let result=[];
  1612. if (!isNumber && !isNumber2)
  1613. {
  1614. let count=Math.max(data.length, data2.length);
  1615. for(let i=0;i<count;++i)
  1616. {
  1617. result[i]=null; //初始化
  1618. if (i<data.length && i<data2.length)
  1619. {
  1620. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=data[i]*data2[i];
  1621. }
  1622. }
  1623. return result;
  1624. }
  1625. //单数据和数组相乘
  1626. let value;
  1627. let aryData;
  1628. if (isNumber)
  1629. {
  1630. value=data;
  1631. aryData=data2;
  1632. }
  1633. else
  1634. {
  1635. value=data2;
  1636. aryData=data;
  1637. }
  1638. for(let i in aryData)
  1639. {
  1640. result[i]=null;
  1641. if (!isNaN(aryData[i]) && !isNaN(value)) result[i]=value*aryData[i];
  1642. }
  1643. return result;
  1644. }
  1645. //相除
  1646. this.Divide=function(data,data2)
  1647. {
  1648. let isNumber=typeof(data)=='number';
  1649. let isNumber2=typeof(data2)=='number';
  1650. //单数值相除
  1651. if (isNumber && isNumber2)
  1652. {
  1653. if (data2==0) return null; //除0判断
  1654. return data/data2;
  1655. }
  1656. //都是数组相除
  1657. let result=[];
  1658. if (!isNumber && !isNumber2)
  1659. {
  1660. let count=Math.max(data.length, data2.length);
  1661. for(let i=0;i<count;++i)
  1662. {
  1663. result[i]=null; //初始化
  1664. if (i<data.length && i<data2.length)
  1665. {
  1666. if ( this.IsNumber(data[i]) && this.IsDivideNumber(data2[i]) ) result[i]=data[i]/data2[i];
  1667. }
  1668. }
  1669. return result;
  1670. }
  1671. if (isNumber) //单数据-数组
  1672. {
  1673. for(let i in data2)
  1674. {
  1675. result[i]=null;
  1676. if ( this.IsNumber(data) && this.IsDivideNumber(data2[i]) ) result[i]=data/data2[i];
  1677. }
  1678. }
  1679. else //数组-单数据
  1680. {
  1681. for(let i in data)
  1682. {
  1683. result[i]=null;
  1684. if ( this.IsNumber(data[i]) && this.IsDivideNumber(data2) ) result[i]=data[i]/data2;
  1685. }
  1686. }
  1687. return result;
  1688. }
  1689. //大于
  1690. this.GT=function(data,data2)
  1691. {
  1692. let isNumber=typeof(data)=='number';
  1693. let isNumber2=typeof(data2)=='number';
  1694. //单数值比较
  1695. if (isNumber && isNumber2) return (data>data2 ? 1 : 0);
  1696. //都是数组比较
  1697. let result=[];
  1698. if (!isNumber && !isNumber2)
  1699. {
  1700. let count=Math.max(data.length, data2.length);
  1701. for(let i=0;i<count;++i)
  1702. {
  1703. result[i]=null; //初始化
  1704. if (i<data.length && i<data2.length)
  1705. {
  1706. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=(data[i]>data2[i] ? 1:0);
  1707. }
  1708. }
  1709. return result;
  1710. }
  1711. if (isNumber) //单数据-数组
  1712. {
  1713. for(let i in data2)
  1714. {
  1715. result[i]=null;
  1716. if ( !isNaN(data) && !isNaN(data2[i]) ) result[i]=(data>data2[i] ? 1 : 0);
  1717. }
  1718. }
  1719. else //数组-单数据
  1720. {
  1721. for(let i in data)
  1722. {
  1723. result[i]=null;
  1724. if ( !isNaN(data[i]) && !isNaN(data2) ) result[i]=(data[i]>data2 ? 1 : 0);
  1725. }
  1726. }
  1727. return result;
  1728. }
  1729. //大于等于
  1730. this.GTE=function(data,data2)
  1731. {
  1732. let isNumber=typeof(data)=='number';
  1733. let isNumber2=typeof(data2)=='number';
  1734. //单数值比较
  1735. if (isNumber && isNumber2) return (data>=data2 ? 1 : 0);
  1736. //都是数组比较
  1737. let result=[];
  1738. if (!isNumber && !isNumber2)
  1739. {
  1740. let count=Math.max(data.length, data2.length);
  1741. for(let i=0;i<count;++i)
  1742. {
  1743. result[i]=null; //初始化
  1744. if (i<data.length && i<data2.length)
  1745. {
  1746. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=(data[i]>=data2[i] ? 1:0);
  1747. }
  1748. }
  1749. return result;
  1750. }
  1751. if (isNumber) //单数据-数组
  1752. {
  1753. for(let i in data2)
  1754. {
  1755. result[i]=null;
  1756. if ( !isNaN(data) && !isNaN(data2[i]) ) result[i]=(data>=data2[i] ? 1 : 0);
  1757. }
  1758. }
  1759. else //数组-单数据
  1760. {
  1761. for(let i in data)
  1762. {
  1763. result[i]=null;
  1764. if ( !isNaN(data[i]) && !isNaN(data2) ) result[i]=(data[i]>=data2 ? 1 : 0);
  1765. }
  1766. }
  1767. return result;
  1768. }
  1769. //小于
  1770. this.LT=function(data,data2)
  1771. {
  1772. let isNumber=typeof(data)=='number';
  1773. let isNumber2=typeof(data2)=='number';
  1774. //单数值比较
  1775. if (isNumber && isNumber2) return (data<data2 ? 1 : 0);
  1776. //都是数组比较
  1777. let result=[];
  1778. if (!isNumber && !isNumber2)
  1779. {
  1780. let count=Math.max(data.length, data2.length);
  1781. for(let i=0;i<count;++i)
  1782. {
  1783. result[i]=null; //初始化
  1784. if (i<data.length && i<data2.length)
  1785. {
  1786. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=(data[i]<data2[i] ? 1:0);
  1787. }
  1788. }
  1789. return result;
  1790. }
  1791. if (isNumber) //单数据-数组
  1792. {
  1793. for(let i in data2)
  1794. {
  1795. result[i]=null;
  1796. if ( !isNaN(data) && !isNaN(data2[i]) ) result[i]=(data<data2[i] ? 1 : 0);
  1797. }
  1798. }
  1799. else //数组-单数据
  1800. {
  1801. for(let i in data)
  1802. {
  1803. result[i]=null;
  1804. if ( !isNaN(data[i]) && !isNaN(data2) ) result[i]=(data[i]<data2 ? 1 : 0);
  1805. }
  1806. }
  1807. return result;
  1808. }
  1809. //小于等于
  1810. this.LTE=function(data,data2)
  1811. {
  1812. let isNumber=typeof(data)=='number';
  1813. let isNumber2=typeof(data2)=='number';
  1814. //单数值比较
  1815. if (isNumber && isNumber2) return (data>=data2 ? 1 : 0);
  1816. //都是数组比较
  1817. let result=[];
  1818. if (!isNumber && !isNumber2)
  1819. {
  1820. let count=Math.max(data.length, data2.length);
  1821. for(let i=0;i<count;++i)
  1822. {
  1823. result[i]=null; //初始化
  1824. if (i<data.length && i<data2.length)
  1825. {
  1826. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=(data[i]<=data2[i] ? 1:0);
  1827. }
  1828. }
  1829. return result;
  1830. }
  1831. if (isNumber) //单数据-数组
  1832. {
  1833. for(let i in data2)
  1834. {
  1835. result[i]=null;
  1836. if ( !isNaN(data) && !isNaN(data2[i]) ) result[i]=(data<=data2[i] ? 1 : 0);
  1837. }
  1838. }
  1839. else //数组-单数据
  1840. {
  1841. for(let i in data)
  1842. {
  1843. result[i]=null;
  1844. if ( !isNaN(data[i]) && !isNaN(data2) ) result[i]=(data[i]<=data2 ? 1 : 0);
  1845. }
  1846. }
  1847. return result;
  1848. }
  1849. //等于
  1850. this.EQ=function(data,data2)
  1851. {
  1852. let isNumber=typeof(data)=='number';
  1853. let isNumber2=typeof(data2)=='number';
  1854. //单数值比较
  1855. if (isNumber && isNumber2) return (data==data2 ? 1 : 0);
  1856. //都是数组比较
  1857. let result=[];
  1858. if (!isNumber && !isNumber2)
  1859. {
  1860. let count=Math.max(data.length, data2.length);
  1861. for(let i=0;i<count;++i)
  1862. {
  1863. result[i]=null; //初始化
  1864. if (i<data.length && i<data2.length)
  1865. {
  1866. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=(data[i]==data2[i] ? 1:0);
  1867. }
  1868. }
  1869. return result;
  1870. }
  1871. if (isNumber) //单数据-数组
  1872. {
  1873. for(let i in data2)
  1874. {
  1875. result[i]=null;
  1876. if ( !isNaN(data) && !isNaN(data2[i]) ) result[i]=(data==data2[i] ? 1 : 0);
  1877. }
  1878. }
  1879. else //数组-单数据
  1880. {
  1881. for(let i in data)
  1882. {
  1883. result[i]=null;
  1884. if ( !isNaN(data[i]) && !isNaN(data2) ) result[i]=(data[i]==data2 ? 1 : 0);
  1885. }
  1886. }
  1887. return result;
  1888. }
  1889. //不等于
  1890. this.NEQ = function (data, data2)
  1891. {
  1892. let isNumber = typeof (data) == 'number';
  1893. let isNumber2 = typeof (data2) == 'number';
  1894. //单数值比较
  1895. if (isNumber && isNumber2) return (data != data2 ? 1 : 0);
  1896. //都是数组比较
  1897. let result = [];
  1898. if (!isNumber && !isNumber2)
  1899. {
  1900. let count = Math.max(data.length, data2.length);
  1901. for (let i = 0; i < count; ++i)
  1902. {
  1903. result[i] = null; //初始化
  1904. if (i < data.length && i < data2.length)
  1905. {
  1906. if (!isNaN(data[i]) && !isNaN(data2[i])) result[i] = (data[i] != data2[i] ? 1 : 0);
  1907. }
  1908. }
  1909. return result;
  1910. }
  1911. if (isNumber) //单数据-数组
  1912. {
  1913. for (let i in data2)
  1914. {
  1915. result[i] = null;
  1916. if (!isNaN(data) && !isNaN(data2[i])) result[i] = (data != data2[i] ? 1 : 0);
  1917. }
  1918. }
  1919. else //数组-单数据
  1920. {
  1921. for (let i in data)
  1922. {
  1923. result[i] = null;
  1924. if (!isNaN(data[i]) && !isNaN(data2)) result[i] = (data[i] != data2 ? 1 : 0);
  1925. }
  1926. }
  1927. return result;
  1928. }
  1929. //AND &&
  1930. this.And=function(data,data2)
  1931. {
  1932. let isNumber=typeof(data)=='number';
  1933. let isNumber2=typeof(data2)=='number';
  1934. //单数值 &&
  1935. if (isNumber && isNumber2) return (data && data2 ? 1 : 0);
  1936. //都是数组 &&
  1937. let result=[];
  1938. if (!isNumber && !isNumber2)
  1939. {
  1940. let count=Math.max(data.length, data2.length);
  1941. for(let i=0;i<count;++i)
  1942. {
  1943. result[i]=null; //初始化
  1944. if (i<data.length && i<data2.length)
  1945. {
  1946. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=(data[i] && data2[i] ? 1:0);
  1947. }
  1948. }
  1949. return result;
  1950. }
  1951. if (isNumber) //单数据-数组
  1952. {
  1953. for(let i in data2)
  1954. {
  1955. result[i]=null;
  1956. if ( !isNaN(data) && !isNaN(data2[i]) ) result[i]=(data && data2[i] ? 1 : 0);
  1957. }
  1958. }
  1959. else //数组-单数据
  1960. {
  1961. for(let i in data)
  1962. {
  1963. result[i]=null;
  1964. if ( !isNaN(data[i]) && !isNaN(data2) ) result[i]=(data[i] && data2 ? 1 : 0);
  1965. }
  1966. }
  1967. return result;
  1968. }
  1969. //OR ||
  1970. this.Or=function(data,data2)
  1971. {
  1972. let isNumber=typeof(data)=='number';
  1973. let isNumber2=typeof(data2)=='number';
  1974. //单数值 &&
  1975. if (isNumber && isNumber2) return (data || data2 ? 1 : 0);
  1976. //都是数组 &&
  1977. let result=[];
  1978. if (!isNumber && !isNumber2)
  1979. {
  1980. let count=Math.max(data.length, data2.length);
  1981. for(let i=0;i<count;++i)
  1982. {
  1983. result[i]=null; //初始化
  1984. if (i<data.length && i<data2.length)
  1985. {
  1986. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=(data[i] || data2[i] ? 1:0);
  1987. }
  1988. }
  1989. return result;
  1990. }
  1991. if (isNumber) //单数据-数组
  1992. {
  1993. for(let i in data2)
  1994. {
  1995. result[i]=null;
  1996. if ( !isNaN(data) && !isNaN(data2[i]) ) result[i]=(data || data2[i] ? 1 : 0);
  1997. }
  1998. }
  1999. else //数组-单数据
  2000. {
  2001. for(let i in data)
  2002. {
  2003. result[i]=null;
  2004. if ( !isNaN(data[i]) && !isNaN(data2) ) result[i]=(data[i] || data2 ? 1 : 0);
  2005. }
  2006. }
  2007. return result;
  2008. }
  2009. this.IF=function(data,trueData,falseData)
  2010. {
  2011. let isNumber=this.IsNumber(data);
  2012. let isNumber2=this.IsNumber(trueData);
  2013. let isNumber3=this.IsNumber(falseData);
  2014. var isArray2=Array.isArray(trueData);
  2015. var isArray3=Array.isArray(falseData);
  2016. //单数值
  2017. if (isNumber)
  2018. {
  2019. if (isNumber2 && isNumber3) return data?trueData:falseData;
  2020. return data? trueData:falseData;
  2021. }
  2022. //都是数组
  2023. let result=[];
  2024. for(let i in data)
  2025. {
  2026. if (data[i])
  2027. {
  2028. if (isNumber2) result[i]=trueData;
  2029. else if (isArray2) result[i]=trueData[i];
  2030. else result[i]=null;
  2031. }
  2032. else
  2033. {
  2034. if (isNumber3) result[i]=falseData;
  2035. else if (isArray3) result[i]=falseData[i];
  2036. else result[i]=null;
  2037. }
  2038. }
  2039. return result;
  2040. }
  2041. /*
  2042. 根据条件求不同的值,同IF判断相反.
  2043. 用法: IFN(X,A,B)若X不为0则返回B,否则返回A
  2044. 例如: IFN(CLOSE>OPEN,HIGH,LOW)表示该周期收阴则返回最高值,否则返回最低值
  2045. */
  2046. this.IFN=function(data,trueData,falseData)
  2047. {
  2048. return this.IF(data,falseData,trueData);
  2049. }
  2050. //指标函数 函数名全部大写
  2051. this.REF=function(data,n)
  2052. {
  2053. let result=[];
  2054. if (typeof(n)=='number')
  2055. {
  2056. if (data.length<=0) return result;
  2057. if (n>=data.length) return result;
  2058. result=data.slice(0,data.length-n);
  2059. for(let i=0;i<n;++i)
  2060. result.unshift(null);
  2061. }
  2062. else //n 为数组的情况
  2063. {
  2064. for(let i=0;i<data.length;++i)
  2065. {
  2066. result[i]=null;
  2067. if (i>=n.length) continue;
  2068. var value=n[i];
  2069. if (value>0 && value<=i) result[i]=data[i-value];
  2070. else if (i) result[i]=result[i-1];
  2071. else result[i]=data[i];
  2072. }
  2073. }
  2074. return result;
  2075. }
  2076. //引用若干周期前的数据(未作平滑处理).
  2077. //用法: REFV(X,A),引用A周期前的X值.A可以是变量.
  2078. //平滑处理:当引用不到数据时进行的操作.
  2079. //例如: REFV(CLOSE,BARSCOUNT(C)-1)表示第二根K线的收盘价.
  2080. this.REFV=function(data,n)
  2081. {
  2082. let result=[];
  2083. if (typeof(n)=='number')
  2084. {
  2085. if (data.length<=0) return result;
  2086. if (n>=data.length) return result;
  2087. result=data.slice(0,data.length-n);
  2088. for(let i=0;i<n;++i) //不作平滑处理
  2089. result.unshift(null);
  2090. }
  2091. else //n 为数组的情况
  2092. {
  2093. for(let i=0;i<data.length;++i)
  2094. {
  2095. result[i]=null;
  2096. if (i>=n.length) continue;
  2097. var value=n[i];
  2098. if (value>=0 && value<=i) result[i]=data[i-value];
  2099. }
  2100. }
  2101. return result;
  2102. }
  2103. //属于未来函数,引用若干周期后的数据(平滑处理).
  2104. //用法: REFX(X,A),引用A周期后的X值.A可以是变量.
  2105. //平滑处理:当引用不到数据时进行的操作.此函数中,平滑时使用上一个周期的引用值.
  2106. //例如: TT:=IF(C>O,1,2);
  2107. // REFX(CLOSE,TT);表示阳线引用下一周期的收盘价,阴线引用日后第二周期的收盘价.
  2108. this.REFX=function(data,n)
  2109. {
  2110. let result=[];
  2111. if (typeof(n)=='number')
  2112. {
  2113. if (data.length<=0) return result;
  2114. if (n>=data.length) return result;
  2115. result=data.slice(n,data.length);
  2116. //平滑处理
  2117. var lastData=data[data.length-1];
  2118. for(let i=0;i<n;++i)
  2119. result.push(lastData);
  2120. }
  2121. else //n 为数组的情况
  2122. {
  2123. var dataCount=data.length;
  2124. for(let i=0;i<data.length;++i)
  2125. {
  2126. result[i]=null;
  2127. if (i>=n.length) continue;
  2128. var value=n[i];
  2129. if (value>=0 && value+i<dataCount) result[i]=data[i+value];
  2130. else if (i) result[i]=result[i-1];
  2131. else result[i]=data[i];
  2132. }
  2133. }
  2134. return result;
  2135. }
  2136. //属于未来函数,引用若干周期后的数据(未作平滑处理).
  2137. //用法:REFXV(X,A),引用A周期后的X值.A可以是变量.
  2138. //平滑处理:当引用不到数据时进行的操作.
  2139. //例如: REFXV(CLOSE,1)表示下一周期的收盘价,在日线上就是明天收盘价
  2140. this.REFXV=function(data,n)
  2141. {
  2142. let result=[];
  2143. if (typeof(n)=='number')
  2144. {
  2145. if (data.length<=0) return result;
  2146. if (n>=data.length) return result;
  2147. result=data.slice(n,data.length);
  2148. //平滑处理
  2149. for(let i=0;i<n;++i)
  2150. result.push(null);
  2151. }
  2152. else //n 为数组的情况
  2153. {
  2154. var dataCount=data.length;
  2155. for(let i=0;i<data.length;++i)
  2156. {
  2157. result[i]=null;
  2158. if (i>=n.length) continue;
  2159. var value=n[i];
  2160. if (value>=0 && value+i<dataCount) result[i]=data[i+value];
  2161. }
  2162. }
  2163. return result;
  2164. }
  2165. this.MAX=function(data,data2)
  2166. {
  2167. let isNumber=typeof(data)=='number';
  2168. let isNumber2=typeof(data2)=='number';
  2169. //单数值
  2170. if (isNumber && isNumber2) return Math.max(data,data2);
  2171. //都是数组
  2172. let result=[];
  2173. if (!isNumber && !isNumber2)
  2174. {
  2175. let count=Math.max(data.length, data2.length);
  2176. for(let i=0;i<count;++i)
  2177. {
  2178. result[i]=null; //初始化
  2179. if (i<data.length && i<data2.length)
  2180. {
  2181. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=Math.max(data[i], data2[i]);
  2182. }
  2183. }
  2184. return result;
  2185. }
  2186. if (isNumber) //单数据-数组
  2187. {
  2188. for(let i in data2)
  2189. {
  2190. result[i]=null;
  2191. if ( !isNaN(data) && !isNaN(data2[i]) ) result[i]=Math.max(data, data2[i]);
  2192. }
  2193. }
  2194. else //数组-单数据
  2195. {
  2196. for(let i in data)
  2197. {
  2198. result[i]=null;
  2199. if ( !isNaN(data[i]) && !isNaN(data2) ) result[i]=Math.max(data[i], data2);
  2200. }
  2201. }
  2202. return result;
  2203. }
  2204. this.MIN=function(data,data2)
  2205. {
  2206. let isNumber=typeof(data)=='number';
  2207. let isNumber2=typeof(data2)=='number';
  2208. //单数值
  2209. if (isNumber && isNumber2) return Math.min(data,data2);
  2210. //都是数组
  2211. let result=[];
  2212. if (!isNumber && !isNumber2)
  2213. {
  2214. let count=Math.max(data.length, data2.length);
  2215. for(let i=0;i<count;++i)
  2216. {
  2217. result[i]=null; //初始化
  2218. if (i<data.length && i<data2.length)
  2219. {
  2220. if ( !isNaN(data[i]) && !isNaN(data2[i]) ) result[i]=Math.min(data[i], data2[i]);
  2221. }
  2222. }
  2223. return result;
  2224. }
  2225. if (isNumber) //单数据-数组
  2226. {
  2227. for(let i in data2)
  2228. {
  2229. result[i]=null;
  2230. if ( !isNaN(data) && !isNaN(data2[i]) ) result[i]=Math.min(data, data2[i]);
  2231. }
  2232. }
  2233. else //数组-单数据
  2234. {
  2235. for(let i in data)
  2236. {
  2237. result[i]=null;
  2238. if ( !isNaN(data[i]) && !isNaN(data2) ) result[i]=Math.min(data[i], data2);
  2239. }
  2240. }
  2241. return result;
  2242. }
  2243. //取正数
  2244. this.ABS=function(data)
  2245. {
  2246. let result=[];
  2247. for(let i in data)
  2248. {
  2249. result[i]=null;
  2250. if (!isNaN(data[i])) result[i]=Math.abs(data[i]);
  2251. }
  2252. return result;
  2253. }
  2254. this.MA=function(data,dayCount)
  2255. {
  2256. if (dayCount <= 0) return [];
  2257. let result = [];
  2258. if (!data || !data.length) return result;
  2259. for (var i = 0; i < data.length; ++i)
  2260. {
  2261. result[i] = null;
  2262. if (this.IsNumber(data[i])) break;
  2263. }
  2264. var data = data.slice(0); //复制一份数据出来 需要把data数据里的null数据用前一个数据覆盖
  2265. for (var days = 0; i < data.length; ++i, ++days)
  2266. {
  2267. if (days < dayCount - 1)
  2268. {
  2269. result[i] = null;
  2270. continue;
  2271. }
  2272. let preValue = data[i - (dayCount - 1)];
  2273. let sum = 0;
  2274. for (let j = dayCount - 1; j >= 0; --j)
  2275. {
  2276. var value = data[i - j];
  2277. if (!this.IsNumber(value))
  2278. {
  2279. value = preValue; //空数据就取上一个数据
  2280. data[i - j] = value;
  2281. }
  2282. else
  2283. {
  2284. preValue = value;
  2285. }
  2286. sum += value;
  2287. }
  2288. result[i] = sum / dayCount;
  2289. }
  2290. return result;
  2291. }
  2292. //指数平均数指标 EMA(close,10)
  2293. this.EMA=function(data,dayCount)
  2294. {
  2295. var result = [];
  2296. var offset=0;
  2297. if (offset>=data.length) return result;
  2298. //取首个有效数据
  2299. for(;offset<data.length;++offset)
  2300. {
  2301. if (data[offset]!=null && !isNaN(data[offset]))
  2302. break;
  2303. }
  2304. var p1Index=offset;
  2305. var p2Index=offset+1;
  2306. result[p1Index]=data[p1Index];
  2307. for(var i=offset+1;i<data.length;++i,++p1Index,++p2Index)
  2308. {
  2309. result[p2Index]=((2*data[p2Index]+(dayCount-1)*result[p1Index]))/(dayCount+1);
  2310. }
  2311. return result;
  2312. }
  2313. this.XMA = function (data, n)
  2314. {
  2315. var result = [];
  2316. var offset = 0;
  2317. for (; offset < data.length; ++offset)
  2318. {
  2319. if (this.IsNumber(data[offset])) break;
  2320. }
  2321. var p = parseInt((n - 2) / 2);
  2322. var sum = 0;
  2323. var count = 0, start = 0, end = 0;
  2324. for (var i = offset, j=0; i < data.length; ++i)
  2325. {
  2326. start = i - p - 1;
  2327. end = i + (n - p) - 1;
  2328. for (j = start; j < end; ++j)
  2329. {
  2330. if (j >= 0 && j < data.length)
  2331. {
  2332. if (this.IsNumber(data[j]))
  2333. {
  2334. sum += data[j];
  2335. ++count;
  2336. }
  2337. }
  2338. }
  2339. if (count != 0) result[i] = (sum / count);
  2340. else result[i] = null;
  2341. sum = 0;
  2342. count = 0;
  2343. }
  2344. return result;
  2345. }
  2346. /*
  2347. SMA 移动平均
  2348. 返回移动平均。
  2349. 用法: SMA(X,N,M) X的M日移动平均,M为权重,如Y=(X*M+Y'*(N-M))/N
  2350. */
  2351. this.SMA=function(data,n,m)
  2352. {
  2353. var result = [];
  2354. var i=0;
  2355. var lastData=null;
  2356. for(;i<data.length; ++i)
  2357. {
  2358. if (data[i]==null || isNaN(data[i])) continue;
  2359. lastData=data[i];
  2360. result[i]=lastData; //第一天的数据
  2361. break;
  2362. }
  2363. for(++i;i<data.length;++i)
  2364. {
  2365. result[i]=(m*data[i]+(n-m)*lastData)/n;
  2366. lastData=result[i];
  2367. }
  2368. return result;
  2369. }
  2370. /*
  2371. 求动态移动平均.
  2372. 用法: DMA(X,A),求X的动态移动平均.
  2373. 算法: 若Y=DMA(X,A)则 Y=A*X+(1-A)*Y',其中Y'表示上一周期Y值,A必须小于1.
  2374. 例如:DMA(CLOSE,VOL/CAPITAL)表示求以换手率作平滑因子的平均价
  2375. */
  2376. this.DMA=function(data,data2)
  2377. {
  2378. var result = [];
  2379. if (data.length<0 || data.length!=data2.length) return result;
  2380. var index=0;
  2381. for(;index<data.length;++index)
  2382. {
  2383. if (data[index]!=null && !isNaN(data[index]) && data2[index]!=null && !isNaN(data2[index]))
  2384. {
  2385. result[index]=data[index];
  2386. break;
  2387. }
  2388. }
  2389. for(index=index+1;index<data.length;++index)
  2390. {
  2391. if (data[index]==null || data2[index]==null)
  2392. result[index]=null;
  2393. else
  2394. {
  2395. if (data[index]<1)
  2396. result[index]=(data2[index]*data[index])+(1-data2[index])*result[index-1];
  2397. else
  2398. result[index]= data[index];
  2399. }
  2400. }
  2401. return result;
  2402. }
  2403. /*
  2404. 返回加权移动平均
  2405. 用法:WMA(X,N):X的N日加权移动平均.
  2406. 算法:Yn=(1*X1+2*X2+...+n*Xn)/(1+2+...+n)
  2407. */
  2408. this.WMA = function (data, dayCount)
  2409. {
  2410. let result = [];
  2411. if (!data || !data.length) return result;
  2412. if (dayCount < 1) dayCount = 1;
  2413. var i = 0;
  2414. for (i = 0; i < data.length && !this.IsNumber(data[i]); ++i)
  2415. {
  2416. result[i] = null;
  2417. }
  2418. var data = data.slice(0);
  2419. for (var days = 0; i < data.length; ++i, ++days)
  2420. {
  2421. if (days < dayCount - 1)
  2422. {
  2423. result[i] = null;
  2424. continue;
  2425. }
  2426. var preValue = data[i - (dayCount - 1)];
  2427. var sum = 0;
  2428. var count = 0;
  2429. for (var j = dayCount - 1; j >= 0; --j)
  2430. {
  2431. var value = data[i - j];
  2432. if (!this.IsNumber(value))
  2433. {
  2434. value = preValue;
  2435. data[i - j] = value;
  2436. }
  2437. else
  2438. preValue = value;
  2439. count += dayCount - j;
  2440. sum += value * (dayCount - j);
  2441. }
  2442. result[i] = sum / count;
  2443. }
  2444. return result;
  2445. }
  2446. /*
  2447. 返回平滑移动平均
  2448. 用法:MEMA(X,N):X的N日平滑移动平均,如Y=(X+Y'*(N-1))/N
  2449. MEMA(X,N)相当于SMA(X,N,1)
  2450. */
  2451. this.MEMA = function (data, dayCount)
  2452. {
  2453. let result = [];
  2454. if (!data || !data.length) return result;
  2455. var i = 0, j = 0;
  2456. for (j = 0; j < data.length && !this.IsNumber(data[j]); ++j)
  2457. {
  2458. result[j] = null;
  2459. }
  2460. i = j;
  2461. if (dayCount < 1 || i + dayCount >= data.length) return result;
  2462. var sum = 0;
  2463. var data = data.slice(0);
  2464. for (; i < j + dayCount; ++i)
  2465. {
  2466. result[i] = null;
  2467. if (!this.IsNumber(data[i]) && i - 1 >= 0)
  2468. data[i] = data[i - 1];
  2469. sum += data[i];
  2470. }
  2471. result[i - 1] = sum / dayCount;
  2472. for (; i < data.length; ++i)
  2473. {
  2474. if (this.IsNumber(result[i - 1]) && this.IsNumber(data[i]))
  2475. result[i] = (data[i] + result[i - 1] * (dayCount - 1)) / dayCount;
  2476. else if (i - 1 > -1 && this.IsNumber(result[i - 1]))
  2477. result[i] = result[i - 1];
  2478. else
  2479. result[i] = null;
  2480. }
  2481. return result;
  2482. }
  2483. /*
  2484. 加权移动平均
  2485. 返回加权移动平均
  2486. 用法:EXPMA(X,M):X的M日加权移动平均
  2487. EXPMA[i]=buffer[i]*para+(1-para)*EXPMA[i-1] para=2/(1+__para)
  2488. */
  2489. this.EXPMA=function(data,dayCount)
  2490. {
  2491. let result=[];
  2492. if (dayCount>=data.length) return result;
  2493. let i=dayCount;
  2494. for(;i<data.length;++i) //获取第1个有效数据
  2495. {
  2496. if (data[i]!=null)
  2497. {
  2498. result[i]=data[i];
  2499. break;
  2500. }
  2501. }
  2502. for (i=i+1; i < data.length; ++i)
  2503. {
  2504. if (result[i-1]!=null && data[i]!=null)
  2505. result[i]=(2*data[i]+(dayCount-1)*result[i-1])/(dayCount+1);
  2506. else if (result[i-1]!=null)
  2507. result[i]=result[i-1];
  2508. }
  2509. return result;
  2510. }
  2511. //加权平滑平均,MEMA[i]=SMA[i]*para+(1-para)*SMA[i-1] para=2/(1+__para)
  2512. this.EXPMEMA=function(data,dayCount)
  2513. {
  2514. var result=[];
  2515. if (dayCount>=data.length) return result;
  2516. var index=0;
  2517. for(;index<data.length;++index)
  2518. {
  2519. if (data[index] && !isNaN(data[index])) break;
  2520. }
  2521. var sum=0;
  2522. for(var i=0; index<data.length && i<dayCount;++i, ++index)
  2523. {
  2524. if (data[index] && !isNaN(data[index]))
  2525. sum+=data[index];
  2526. else
  2527. sum+=data[index-1];
  2528. }
  2529. result[index-1]=sum/dayCount;
  2530. for(;index<data.length;++index)
  2531. {
  2532. if(result[index-1]!=null && data[index]!=null)
  2533. result[index]=(2*data[index]+(dayCount-1)*result[index-1])/(dayCount+1);
  2534. else if(result[index-1]!=null)
  2535. result[index] = result[index-1];
  2536. }
  2537. return result;
  2538. }
  2539. /*
  2540. 向前累加到指定值到现在的周期数.
  2541. 用法:SUMBARS(X,A):将X向前累加直到大于等于A,返回这个区间的周期数
  2542. 例如:SUMBARS(VOL,CAPITAL)求完全换手到现在的周期数
  2543. */
  2544. this.SUMBARS = function (data, data2)
  2545. {
  2546. var result = [];
  2547. if (!data || !data.length || !data2 || !data2.length) return result;
  2548. var start = 0, i = 0, j = 0;
  2549. for (; start < data.length && !this.IsNumber(data[start]); ++start)
  2550. {
  2551. result[start] = null;
  2552. }
  2553. var total = 0;
  2554. for (i = data.length - 1; i >= start; --i)
  2555. {
  2556. for (j = i, total = 0; j >= start && total < data2[i]; --j)
  2557. total += data[j];
  2558. if (j < start) result[i] = null;
  2559. else result[i] = i - j;
  2560. }
  2561. for (i = start + 1; i < data.length; ++i)
  2562. {
  2563. if (result[i] == null)
  2564. result[i] = result[i - 1];
  2565. }
  2566. return result;
  2567. }
  2568. /*
  2569. 求相反数.
  2570. 用法:REVERSE(X)返回-X.
  2571. 例如:REVERSE(CLOSE)返回-CLOSE
  2572. */
  2573. this.REVERSE = function (data)
  2574. {
  2575. var result = [];
  2576. var i = 0;
  2577. for (; i < data.length && !this.isNumber(data[i]); ++i)
  2578. {
  2579. result[i] = null;
  2580. }
  2581. for (; i < data.length; ++i)
  2582. {
  2583. if (!this.isNumber(data[i]))
  2584. result[i] = null;
  2585. else
  2586. result[i] = 0 - data[i];
  2587. }
  2588. return result;
  2589. }
  2590. this.COUNT=function(data,n)
  2591. {
  2592. if (Array.isArray(n))
  2593. {
  2594. var start=null;
  2595. var dataCount=data.length;
  2596. for(var i=0;i<dataCount;++i)
  2597. {
  2598. if (this.IsNumber(data[i]))
  2599. {
  2600. start=i;
  2601. break;
  2602. }
  2603. }
  2604. if (start==null) return [];
  2605. var result=[];
  2606. var count=0;
  2607. for(var i=0;i<n.length;++i)
  2608. {
  2609. var period=n[i];
  2610. if (!this.IsNumber(period)) continue;
  2611. if (period<1) period=i+1;
  2612. count=0;
  2613. for(var j=i, k=0 ;j>=0 && k<period ;--j,++k) //当前往前period天 统计
  2614. {
  2615. if (data[j]) ++count;
  2616. }
  2617. result[i]=count;
  2618. }
  2619. return result;
  2620. }
  2621. else
  2622. {
  2623. var period=n;
  2624. var dataCount=data.length;
  2625. var period=period<1?dataCount:period;
  2626. var i=0,j=0;
  2627. for(;i<dataCount;++i) // 取第1个有效数据
  2628. {
  2629. if (this.IsNumber(data[i])) break;
  2630. }
  2631. var result=[];
  2632. var days=0;
  2633. for(;i<dataCount && j<period; ++i,++j)
  2634. {
  2635. days=data[i]?days+1:days;
  2636. result[i]=days;
  2637. }
  2638. for(;i<dataCount;++i)
  2639. {
  2640. if (data[i-period] && days) days--;
  2641. days=data[i] ? days+1 : days;
  2642. result[i]=days;
  2643. }
  2644. return result;
  2645. }
  2646. }
  2647. /*
  2648. HHV 最高值
  2649. 求最高值。
  2650. 用法: HHV(X,N) 求N周期内X最高值,N=0则从第一个有效值开始。
  2651. 例如: HHV(HIGH,30) 表示求30日最高价。
  2652. */
  2653. this.HHV=function(data,n)
  2654. {
  2655. let result = [];
  2656. if (Array.isArray(n))
  2657. {
  2658. var max = null;
  2659. for (var i = 0, j = 0; i < data.length; ++i)
  2660. {
  2661. result[i] = null;
  2662. if (i >= n.length) continue;
  2663. max = null;
  2664. var count = n[i];
  2665. if (count > 0 && count <= i)
  2666. {
  2667. for (j = i - count; j <= i; ++j)
  2668. {
  2669. if (max == null || max < data[j]) max = data[j];
  2670. }
  2671. }
  2672. else
  2673. {
  2674. count = i;
  2675. for (j = 0; j <= i; ++j)
  2676. {
  2677. if (max == null || max < data[j]) max = data[j];
  2678. }
  2679. }
  2680. result[i] = max;
  2681. }
  2682. }
  2683. else
  2684. {
  2685. if (n > data.length) return result;
  2686. if (n <= 0) n = data.length - 1;
  2687. var nMax = 0;
  2688. for (nMax = 0; nMax < data.length; ++nMax)
  2689. {
  2690. if (this.IsNumber(data[nMax])) break;
  2691. }
  2692. if (nMax < data.length) result[nMax] = data[nMax];
  2693. for (var i = nMax + 1, j = 2; i < data.length && j < n; ++i, ++j)
  2694. {
  2695. if (data[i] >= data[nMax]) nMax = i;
  2696. result[i] = data[nMax];
  2697. }
  2698. for (; i < data.length; ++i)
  2699. {
  2700. if (i - nMax < n)
  2701. {
  2702. nMax = data[i] < data[nMax] ? nMax : i;
  2703. }
  2704. else
  2705. {
  2706. for (j = nMax = (i - n + 1); j <= i; ++j)
  2707. {
  2708. nMax = data[j] < data[nMax] ? nMax : j;
  2709. }
  2710. }
  2711. result[i] = data[nMax];
  2712. }
  2713. }
  2714. return result;
  2715. }
  2716. /*
  2717. LLV 最低值
  2718. 求最低值。
  2719. 用法: LLV(X,N) 求N周期内X最低值,N=0则从第一个有效值开始。
  2720. 例如: LLV(LOW,0) 表示求历史最低价。
  2721. */
  2722. this.LLV=function(data,n)
  2723. {
  2724. var result = [];
  2725. if (Array.isArray(n))
  2726. {
  2727. for (var i = 0; i < data.length; ++i)
  2728. {
  2729. result[i] = null;
  2730. if (i >= n.length) continue;
  2731. var min = null;
  2732. var count = n[i];
  2733. if (count > 0 && count <= i)
  2734. {
  2735. for (var j = i - count; j <= i; ++j)
  2736. {
  2737. if (min == null || min > data[j]) min = data[j];
  2738. }
  2739. }
  2740. else
  2741. {
  2742. count = i;
  2743. for (var j = 0; j <= i; ++j)
  2744. {
  2745. if (min == null || min > data[j]) min = data[j];
  2746. }
  2747. }
  2748. result[i] = min;
  2749. }
  2750. }
  2751. else
  2752. {
  2753. if (n>data.length) return result;
  2754. if (n<=0) n=data.length-1;
  2755. var nMin=0;
  2756. for(nMin=0;nMin<data.length;++nMin)
  2757. {
  2758. if (this.IsNumber(data[nMin])) break;
  2759. }
  2760. if (nMin<data.length) result[nMin]=data[nMin];
  2761. for(var i=nMin+1,j=2;i<data.length && j<n;++i,++j)
  2762. {
  2763. if (data[i]<=data[nMin]) nMin=i;
  2764. result[i]=data[nMin];
  2765. }
  2766. for(;i<data.length;++i)
  2767. {
  2768. if (i-nMin<n)
  2769. {
  2770. nMin=data[i]>data[nMin]?nMin:i;
  2771. }
  2772. else
  2773. {
  2774. for(j=nMin=(i-n+1);j<=i;++j)
  2775. {
  2776. nMin=data[j]>data[nMin]?nMin:j;
  2777. }
  2778. }
  2779. result[i]=data[nMin];
  2780. }
  2781. }
  2782. return result;
  2783. }
  2784. this.STD=function(data,n)
  2785. {
  2786. var result=[];
  2787. var nStart=this.GetFirstVaildIndex(data);
  2788. if (!IFrameSplitOperator.IsNumber(n)) return result;
  2789. if(nStart+n>data.length || n<1) return result;
  2790. var i=nStart, j=0, bFirst=true, dTotal=0, dAvg=0;
  2791. for(i+=n-1;i<data.length;++i)
  2792. {
  2793. dTotal = 0;
  2794. if(bFirst)
  2795. {
  2796. bFirst = false;
  2797. for(j=i-n+1;j<=i;++j)
  2798. {
  2799. dAvg += data[j];
  2800. }
  2801. dAvg /= n;
  2802. }
  2803. else
  2804. {
  2805. dAvg += (data[i]-data[i-n])/n;
  2806. }
  2807. for(j=i-n+1;j<=i;++j)
  2808. {
  2809. dTotal += (data[j]-dAvg)*(data[j]-dAvg);
  2810. }
  2811. result[i] = Math.sqrt(dTotal/(n-1));
  2812. }
  2813. return result;
  2814. }
  2815. //平均绝对方差
  2816. this.AVEDEV=function(data,n)
  2817. {
  2818. var result=[];
  2819. var total=0;
  2820. var averageData=[]; //平均值
  2821. for(var i=n-1;i<data.length;++i)
  2822. {
  2823. total=0;
  2824. for(var j=0;j<n;++j)
  2825. {
  2826. total+=data[i-j];
  2827. }
  2828. averageData[i]=total/n;
  2829. }
  2830. for(var i=n-1;i<data.length;++i)
  2831. {
  2832. total=0;
  2833. for(var j=0;j<n;++j)
  2834. {
  2835. total+=Math.abs(data[i-j]-averageData[i]);
  2836. }
  2837. result[i]=total/n;
  2838. }
  2839. return result;
  2840. }
  2841. //上穿
  2842. this.CROSS=function(data,data2)
  2843. {
  2844. var result = [];
  2845. if (Array.isArray(data) && Array.isArray(data2))
  2846. {
  2847. if (data.length != data2.length) return result = [];
  2848. var index = 0;
  2849. for (; index < data.length; ++index)
  2850. {
  2851. if (this.IsNumber(data[index]) && this.IsNumber(data2[index]))
  2852. break;
  2853. }
  2854. for (++index; index < data.length; ++index)
  2855. {
  2856. result[index] = (data[index] > data2[index] && data[index - 1] < data2[index - 1]) ? 1 : 0;
  2857. }
  2858. }
  2859. else if (Array.isArray(data) && typeof (data2) == 'number')
  2860. {
  2861. var index = 0;
  2862. for (; index < data.length; ++index)
  2863. {
  2864. if (this.IsNumber(data[index])) break;
  2865. }
  2866. for (++index; index < data.length; ++index)
  2867. {
  2868. result[index] = (data[index] > data2 && data[index - 1] < data2) ? 1 : 0;
  2869. }
  2870. }
  2871. else if (typeof (data) == 'number' && Array.isArray(data2))
  2872. {
  2873. var index = 0;
  2874. for (; index < data2.length; ++index)
  2875. {
  2876. if (this.IsNumber(data2[index])) break;
  2877. }
  2878. for (++index; index < data2.length; ++index)
  2879. {
  2880. result[index] = (data2[index] < data && data2[index - 1] > data) ? 1 : 0;
  2881. }
  2882. }
  2883. return result;
  2884. }
  2885. //累乘
  2886. this.MULAR=function(data,n)
  2887. {
  2888. var result=[];
  2889. if(data.length<n) return result;
  2890. var index=n;
  2891. for(;index<data.length;++index)
  2892. {
  2893. if (data[index]!=null && !isNaN(data[index]))
  2894. {
  2895. result[index]=data[index];
  2896. break;
  2897. }
  2898. }
  2899. for(++index;index<data.length;++index)
  2900. {
  2901. result[index]=result[index-1]*data[index];
  2902. }
  2903. return result;
  2904. }
  2905. this.SUM=function(data,n)
  2906. {
  2907. var result=[];
  2908. if (n==0)
  2909. {
  2910. result[0]=data[0];
  2911. for (var i=1; i<data.length; ++i)
  2912. {
  2913. result[i] = result[i-1]+data[i];
  2914. }
  2915. }
  2916. else
  2917. {
  2918. for(var i=n-1,j=0;i<data.length;++i,++j)
  2919. {
  2920. for(var k=0;k<n;++k)
  2921. {
  2922. if (k==0) result[i]=data[k+j];
  2923. else result[i]+=data[k+j];
  2924. }
  2925. }
  2926. }
  2927. return result;
  2928. }
  2929. /*
  2930. BARSCOUNT 有效数据周期数
  2931. 求总的周期数。
  2932. 用法: BARSCOUNT(X) 第一个有效数据到当前的天数。
  2933. 例如: BARSCOUNT(CLOSE) 对于日线数据取得上市以来总交易日数,对于分笔成交取得当日成交笔数,对于1分钟线取得当日交易分钟数。
  2934. */
  2935. this.BARSCOUNT=function(data)
  2936. {
  2937. let result=[];
  2938. let days=null;
  2939. for(let i in data)
  2940. {
  2941. result[i]=0;
  2942. if (days==null)
  2943. {
  2944. if (!this.IsNumber(data[i])) contnue;
  2945. days=0;
  2946. }
  2947. result[i]=days;
  2948. ++days;
  2949. }
  2950. return result;
  2951. }
  2952. //DEVSQ 数据偏差平方和
  2953. //DEVSQ(X,N)  返回数据偏差平方和。
  2954. this.DEVSQ=function(data,n)
  2955. {
  2956. var result=[];
  2957. if (typeof(n)!='number') n=parseInt(n); //字符串的转成数值型
  2958. var num = n;
  2959. var datanum = data.length;
  2960. var i = 0, j = 0, k = 0;
  2961. var E = 0, DEV = 0;
  2962. for(i = 0; i < datanum && !this.isNumber(data[i]); ++i)
  2963. {
  2964. result[i] = null;
  2965. }
  2966. if (num < 1 || i+num>datanum) return result;
  2967. for(E=0; i < datanum && j < num; ++i,++j)
  2968. E += data[i]/num;
  2969. if (j == num)
  2970. {
  2971. DEV = 0;
  2972. for(i--; k < num; k++)
  2973. DEV += (data[i-k]-E) * (data[i-k]-E);
  2974. result[i] = DEV;
  2975. i++;
  2976. }
  2977. for(; i < datanum; ++i)
  2978. {
  2979. E += (data[i] - data[i-num]) / num;
  2980. for(DEV=0, k = 0; k < num; ++k)
  2981. DEV += (data[i-k]-E) * (data[i-k]-E);
  2982. result[i] = DEV;
  2983. }
  2984. return result;
  2985. }
  2986. //NOT 取反
  2987. //求逻辑非。
  2988. //用法: NOT(X) 返回非X,即当X=0时返回1,否则返回0。
  2989. //例如: NOT(ISUP) 表示平盘或收阴。
  2990. this.NOT=function(data)
  2991. {
  2992. let isNumber=typeof(data)=='number';
  2993. if (isNumber) return data? 0:1;
  2994. let result=[];
  2995. for(let i in data)
  2996. {
  2997. result[i]=null;
  2998. if (this.IsNumber(data[i])) result[i]=data[i]?0:1;
  2999. }
  3000. return result;
  3001. }
  3002. //FORCAST 线性回归预测值
  3003. //FORCAST(X,N)  返回线性回归预测值。
  3004. this.FORCAST=function(data,n)
  3005. {
  3006. var result=[];
  3007. if (typeof(n)!='number') n=parseInt(n); //字符串的转成数值型
  3008. var num = n;
  3009. var datanum = data.length;
  3010. if (num < 1 || num >= datanum)
  3011. return result;
  3012. var Ex = 0, Ey = 0, Sxy = 0, Sxx = 0, Const, Slope;
  3013. var i, j,x;
  3014. for(j = 0; j < datanum && !this.IsNumber(data[j]); ++j)
  3015. {
  3016. result[j] = null;
  3017. }
  3018. for(i = j+num-1; i < datanum; ++i)
  3019. {
  3020. Ex = Ey = Sxy = Sxx = 0;
  3021. for (j = 0, x = num; j < num && j <= i; ++j,--x)
  3022. {
  3023. Ex +=x;
  3024. Ey += data[i - j];
  3025. }
  3026. Ex /= num;
  3027. Ey /= num;
  3028. for (j = 0, x = num; j < num && j <= i; ++j, --x)
  3029. {
  3030. Sxy += (x-Ex)*(data[i-j]-Ey);
  3031. Sxx += (x-Ex)*(x-Ex);
  3032. }
  3033. Slope = Sxy / Sxx;
  3034. Const = Ey - Ex*Slope;
  3035. result[i] = Slope * num + Const;
  3036. }
  3037. return result;
  3038. }
  3039. //SLOPE 线性回归斜率
  3040. //SLOPE(X,N)  返回线性回归斜率。
  3041. this.SLOPE=function(data,n)
  3042. {
  3043. let result=[];
  3044. if (typeof(n)!='number') n=parseInt(n); //字符串的转成数值型
  3045. if (n<1 || !data.length) return result;
  3046. if (n>=data.length) return result;
  3047. let start=0;
  3048. for(let i=0;i<data.length;++i,++start)
  3049. {
  3050. result[i]=null;
  3051. if (this.IsNumber(data[i])) break;
  3052. }
  3053. let x,y,xy,xx;
  3054. for(let i=start+n-1;i<data.length;++i)
  3055. {
  3056. result[i]=null;
  3057. x=y=xy=xx=0;
  3058. for(var j=0;j<n && j<=i; ++j)
  3059. {
  3060. x+=(i-j); //数据索引相加
  3061. y+=data[i-j]; //数据相加
  3062. }
  3063. x=x/n; y=y/n;
  3064. for(j=0;j<n && j<=i; ++j)
  3065. {
  3066. xy+=(i-j-x)*(data[i-j]-y);
  3067. xx+=(i-j-x)*(i-j-x);
  3068. }
  3069. if (xx) result[i]= xy/xx;
  3070. else if (i) result[i]=result[i-1];
  3071. }
  3072. return result;
  3073. }
  3074. //STDP 总体标准差
  3075. //STDP(X,N)  返回总体标准差。
  3076. this.STDP=function(data,n)
  3077. {
  3078. var result=[];
  3079. var nStart=this.GetFirstVaildIndex(data);
  3080. if (!IFrameSplitOperator.IsNumber(n)) return result;
  3081. if(nStart+n>data.length || n<1) return result;
  3082. var i=nStart, j=0, bFirst=true, dTotal=0, dAvg=0;
  3083. for(i+=n-1;i<data.length;++i)
  3084. {
  3085. dTotal = 0;
  3086. if(bFirst)
  3087. {
  3088. bFirst = false;
  3089. for(j=i-n+1;j<=i;++j)
  3090. {
  3091. dAvg += data[j];
  3092. }
  3093. dAvg /= n;
  3094. }
  3095. else
  3096. {
  3097. dAvg += (data[i]-data[i-n])/n;
  3098. }
  3099. for(j=i-n+1;j<=i;++j)
  3100. {
  3101. dTotal += (data[j]-dAvg)*(data[j]-dAvg);
  3102. }
  3103. result[i] = Math.sqrt(dTotal/n);
  3104. }
  3105. return result;
  3106. }
  3107. //VAR 估算样本方差
  3108. //VAR(X,N)  返回估算样本方差。
  3109. this.VAR=function(data,n)
  3110. {
  3111. var result=[];
  3112. if (typeof(n)!='number') n=parseInt(n); //字符串的转成数值型
  3113. var num = n;
  3114. var datanum = data.length;
  3115. if (num <= 1 || num >= datanum)
  3116. return result;
  3117. var i, j;
  3118. for (i = 0; i < datanum && !this.IsNumber(data[i]); ++i)
  3119. {
  3120. result[i] = null;
  3121. }
  3122. var SigmaPowerX, SigmaX;
  3123. for (j = 0, i = i+num-1; i < datanum; ++i)
  3124. {
  3125. SigmaPowerX = SigmaX = 0;
  3126. for(j=0; j < num && j <= i; ++j)
  3127. {
  3128. SigmaPowerX += data[i-j] * data[i-j];
  3129. SigmaX += data[i-j];
  3130. }
  3131. result[i] = (num*SigmaPowerX - SigmaX*SigmaX) / num * (num -1);
  3132. }
  3133. return result;
  3134. }
  3135. //VARP 总体样本方差
  3136. //VARP(X,N)  返回总体样本方差 。
  3137. this.VARP=function(data,n)
  3138. {
  3139. var result=[];
  3140. if (typeof(n)!='number') n=parseInt(n); //字符串的转成数值型
  3141. var num = n;
  3142. var datanum = data.length;
  3143. if (num < 1 || num >= datanum)
  3144. return result;
  3145. var i = 0, j = 0;
  3146. for (i = 0; i < datanum && !this.IsNumber(data[i]); ++i)
  3147. {
  3148. result[i] = null;
  3149. }
  3150. var SigmaPowerX = 0, SigmaX = 0;
  3151. for (; i < datanum && j < num; ++i, ++j)
  3152. {
  3153. SigmaPowerX += data[i] * data[i];
  3154. SigmaX += data[i];
  3155. }
  3156. if (j == num)
  3157. result[i-1] = (num*SigmaPowerX - SigmaX*SigmaX) / (num*num);
  3158. for(; i < datanum; ++i)
  3159. {
  3160. SigmaPowerX += data[i]*data[i] - data[i-num]*data[i-num];
  3161. SigmaX += data[i] - data[i-num];
  3162. result[i] = (num*SigmaPowerX - SigmaX*SigmaX) / (num*num);
  3163. }
  3164. return result;
  3165. }
  3166. //RANGE(A,B,C)表示A>B AND A<C;
  3167. this.RANGE=function(data,range,range2)
  3168. {
  3169. let isNumber=typeof(data)=='number';
  3170. let isNumber2=typeof(range)=='number';
  3171. let isNumber3=typeof(range2)=='number';
  3172. if (isNumber && isNumber2 && isNumber3)
  3173. {
  3174. if (data>Math.min(range,range2) && data<Math.max(range,range2)) return 1;
  3175. else return 0;
  3176. }
  3177. let result=[];
  3178. let value, rangeValue,rangValue2;
  3179. for(let i=0; i<data.length; ++i)
  3180. {
  3181. result[i]=null;
  3182. value=data[i];
  3183. if (!this.IsNumber(value)) continue;
  3184. if (!isNumber2)
  3185. {
  3186. if (i>=range.length) continue;
  3187. rangeValue=range[i];
  3188. }
  3189. else
  3190. {
  3191. rangeValue=range;
  3192. }
  3193. if (!this.IsNumber(rangeValue)) continue;
  3194. if (!isNumber3)
  3195. {
  3196. if (i>=range2.length) continue;
  3197. rangeValue2=range2[i];
  3198. }
  3199. else
  3200. {
  3201. rangeValue2=range2;
  3202. }
  3203. if (!this.IsNumber(rangeValue2)) continue;
  3204. result[i]= (value>Math.min(rangeValue,rangeValue2) && value<Math.max(rangeValue,rangeValue2)) ? 1:0;
  3205. }
  3206. return result;
  3207. }
  3208. this.EXIST=function(data,n)
  3209. {
  3210. n=parseInt(n);
  3211. if (typeof(data)=='number') return 0;
  3212. var latestID; //最新满足条件的数据索引
  3213. var result=[];
  3214. var value;
  3215. for(let i=0;i<data.length;++i)
  3216. {
  3217. result[i]=null;
  3218. value=data[i];
  3219. if (this.IsNumber(value) && value>0) latestID==i;
  3220. if (i-latestID<n) result[i]=1;
  3221. else result[i]=0;
  3222. }
  3223. return result;
  3224. }
  3225. this.TFILTER=function(data,data2,n)
  3226. {
  3227. n=parseInt(n);
  3228. var result=[];
  3229. let isNumber=typeof(data)=='number';
  3230. let isNumber2=typeof(range)=='number';
  3231. let count=Math.max(data.length, data2.length);
  3232. for(let i=0;i<count;++i)
  3233. {
  3234. }
  3235. return result;
  3236. }
  3237. /*
  3238. 过滤连续出现的信号.
  3239. 用法:FILTER(X,N):X满足条件后,将其后N周期内的数据置为0,N为常量.
  3240. 例如:
  3241. FILTER(CLOSE>OPEN,5)查找阳线,5天内再次出现的阳线不被记录在内
  3242. */
  3243. this.FILTER = function (data, n)
  3244. {
  3245. var result = [];
  3246. for (let i = 0, j = 0; i < data.length; ++i)
  3247. {
  3248. if (data[i])
  3249. {
  3250. result[i] = 1;
  3251. for (j = 0; j < n && j + i + 1 < data.length; ++j)
  3252. {
  3253. result[j + i + 1] = 0;
  3254. }
  3255. i += n;
  3256. }
  3257. else
  3258. {
  3259. result[i] = 0;
  3260. }
  3261. }
  3262. return result;
  3263. }
  3264. this.BARSLAST=function(data)
  3265. {
  3266. var result=[];
  3267. if (!data) return result;
  3268. let day=null;
  3269. for(let i=0;i<data.length;++i)
  3270. {
  3271. result[i]=null;
  3272. if (data[i]>0) day=0;
  3273. else if (day!=null) ++day;
  3274. if (day!=null) result[i]=day;
  3275. }
  3276. return result;
  3277. }
  3278. /*
  3279. N周期内第一个条件成立到当前的周期数.
  3280. 用法:
  3281. BARSSINCEN(X,N):N周期内第一次X不为0到现在的天数,N为常量
  3282. 例如:
  3283. BARSSINCEN(HIGH>10,10)表示10个周期内股价超过10元时到当前的周期数
  3284. */
  3285. this.BARSSINCEN = function (data, n)
  3286. {
  3287. var result=[];
  3288. if (this.IsNumber(n) && Array.isArray(data))
  3289. {
  3290. var nPeriod=n;
  3291. if (nPeriod<1) nPeriod=data.length;
  3292. var i=this.GetFirstVaildIndex(data);
  3293. if (i>=data.length) return result;
  3294. var j=0;
  3295. if (i <= nPeriod - 1) j = nPeriod - 1;
  3296. else j = i;
  3297. result[j] = j - i;
  3298. for (; j < data.length; ++j)
  3299. {
  3300. if (this.IsNumber(result[j - 1]))
  3301. {
  3302. if (result[j - 1] + 1 < nPeriod)
  3303. {
  3304. result[j] = result[j - 1] + 1;
  3305. }
  3306. else
  3307. {
  3308. for (var k = j - nPeriod+1; k <= j; ++k)
  3309. {
  3310. if (!(Math.abs(data[k]) < 0.000001))
  3311. {
  3312. result[j] = j - k;
  3313. break;
  3314. }
  3315. }
  3316. }
  3317. }
  3318. else
  3319. {
  3320. if (!(Math.abs(data[j]) < 0.000001))
  3321. result[j] = 0;
  3322. }
  3323. }
  3324. }
  3325. return result;
  3326. }
  3327. /*
  3328. 第一个条件成立到当前的周期数.
  3329. 用法:
  3330. BARSSINCE(X):第一次X不为0到现在的天数
  3331. 例如:
  3332. BARSSINCE(HIGH>10)表示股价超过10元时到当前的周期数
  3333. */
  3334. this.BARSSINCE = function (data)
  3335. {
  3336. var result = [];
  3337. var day = null;
  3338. for (let i = 0; i < data.length; ++i)
  3339. {
  3340. result[i] = null;
  3341. if (day == null)
  3342. {
  3343. if (data[i]) day = 0;
  3344. }
  3345. else
  3346. {
  3347. ++day;
  3348. }
  3349. if (day) result[i] = day;
  3350. }
  3351. return result;
  3352. }
  3353. /*三角函数调用 func 三角函数
  3354. 反正切值. 用法: ATAN(X)返回X的反正切值
  3355. 余弦值. 用法: COS(X)返回X的余弦值
  3356. 正弦值. 用法: SIN(X)返回X的正弦值
  3357. 正切值. 用法: TAN(X)返回X的正切值
  3358. 求自然对数. 用法: LN(X)以e为底的对数 例如: LN(CLOSE)求收盘价的对数
  3359. 求10为底的对数. 用法: LOG(X)取得X的对数 例如: LOG(100)等于2
  3360. 指数. 用法: EXP(X)为e的X次幂 例如: EXP(CLOSE)返回e的CLOSE次幂
  3361. 开平方. 用法: SQRT(X)为X的平方根 例如: SQRT(CLOSE)收盘价的平方根
  3362. */
  3363. this.Trigonometric = function (data, func)
  3364. {
  3365. if (!Array.isArray(data))
  3366. {
  3367. if (this.IsNumber(data)) return func(data);
  3368. return null;
  3369. }
  3370. else
  3371. {
  3372. var result = [];
  3373. for (let i in data)
  3374. {
  3375. var item = data[i];
  3376. if (this.IsNumber(item)) result[i] = func(item);
  3377. else result[i] = null;
  3378. }
  3379. return result;
  3380. }
  3381. }
  3382. //反正弦值. 用法: ASIN(X)返回X的反正弦值
  3383. this.ASIN = function (data)
  3384. {
  3385. if (!Array.isArray(data))
  3386. {
  3387. if (this.IsNumber(data)) return Math.acos(data);
  3388. return null;
  3389. }
  3390. else
  3391. {
  3392. var result = [];
  3393. for (let i in data)
  3394. {
  3395. var item = data[i];
  3396. result[i] = null;
  3397. if (this.IsNumber(item))
  3398. {
  3399. if (item >= -1 && item <= 1)
  3400. {
  3401. result[i] = Math.asin(item);
  3402. }
  3403. else if (i - 1 >= 0)
  3404. {
  3405. var preItem = result[i - 1];
  3406. if (this.IsNumber(preItem)) result[i] = preItem;
  3407. }
  3408. }
  3409. }
  3410. return result;
  3411. }
  3412. }
  3413. //反余弦值. 用法: ACOS(X)返回X的反余弦值
  3414. this.ACOS = function (data)
  3415. {
  3416. if (!Array.isArray(data))
  3417. {
  3418. if (this.IsNumber(data)) return Math.acos(data);
  3419. return null;
  3420. }
  3421. else
  3422. {
  3423. var result = [];
  3424. for (let i in data)
  3425. {
  3426. var item = data[i];
  3427. result[i] = null;
  3428. if (this.IsNumber(item))
  3429. {
  3430. if (item >= -1 && item <= 1)
  3431. {
  3432. result[i] = Math.acos(item);
  3433. }
  3434. else if (i - 1 >= 0) //超出范围使用上一个数值
  3435. {
  3436. var preItem = result[i - 1];
  3437. if (this.IsNumber(preItem)) result[i] = preItem;
  3438. }
  3439. }
  3440. }
  3441. return result;
  3442. }
  3443. }
  3444. /*
  3445. LAST(X,A,B):持续存在.
  3446. 用法:
  3447. LAST(CLOSE>OPEN,10,5)
  3448. 表示从前10日到前5日内一直阳线
  3449. 若A为0,表示从第一天开始,B为0,表示到最后日止
  3450. */
  3451. this.LAST = function (data, n, n2)
  3452. {
  3453. var result = [];
  3454. if (n2 <= 0) n2 = data.length - 1;
  3455. if (n2 > n) return result;
  3456. var day = 0;
  3457. for (let i = 0, j = 0; i < data.length; ++i) {
  3458. result[i] = 0;
  3459. day = 0;
  3460. var start = i - n;
  3461. var end = i - n2;
  3462. if (start < 0 || end < 0) continue;
  3463. for (j = start; j < data.length && j <= end; ++j, ++day) {
  3464. if (!data[j]) break;
  3465. }
  3466. if (day == end - start + 1) //[start,end]
  3467. result[i] = 1;
  3468. }
  3469. return result;
  3470. }
  3471. /*
  3472. 属于未来函数,之字转向.
  3473. 用法: ZIG(K,N),当价格变化量超过N%时转向,K表示0:开盘价,1:最高价,2:最低价,3:收盘价,其余:数组信息
  3474. 例如: ZIG(3,5)表示收盘价的5%的ZIG转向
  3475. */
  3476. this.ZIG=function(data,n)
  3477. {
  3478. var hisData=this.SymbolData.Data;
  3479. var result=[];
  3480. if (typeof(data)=='number')
  3481. {
  3482. switch(data)
  3483. {
  3484. case 0:
  3485. data=hisData.GetOpen();
  3486. break;
  3487. case 1:
  3488. data=hisData.GetHigh();
  3489. break;
  3490. case 2:
  3491. data=hisData.GetLow();
  3492. break;
  3493. case 3:
  3494. data=hisData.GetClose();
  3495. break;
  3496. default:
  3497. return result;
  3498. }
  3499. }
  3500. return this.ZIG_Calculate(data,n);
  3501. }
  3502. this.ZIG_Calculate=function(data,dRate)
  3503. {
  3504. var dest=[];
  3505. var nDataCount=data.length;
  3506. var m=this.GetFirstVaildIndex(data);
  3507. var i = 0, lLastPos = 0, lState = 0, j = 0;
  3508. var dif = 0;
  3509. for (i = m + 1, lLastPos = lState = m; i<nDataCount - 1 && lState == m; ++i)
  3510. {
  3511. lState = Math.abs(data[i] - data[m]) * 100 >= dRate*data[m] ? (data[i]>data[m] ? i : -i) : m;
  3512. }
  3513. for (; i<nDataCount - 1; ++i)
  3514. {
  3515. if (data[i] >= data[i - 1] && data[i] >= data[i + 1])
  3516. {
  3517. if (lState<0)
  3518. {
  3519. if ((data[i] - data[-lState]) * 100<dRate*data[-lState]) continue;
  3520. else
  3521. {
  3522. dif = (data[lLastPos] - data[j = -lState]) / (-lState - lLastPos);
  3523. dest[j--]=data[-lState];
  3524. for (; j >= lLastPos; j--)
  3525. dest[j]=data[-lState] + (-lState - j)*dif;
  3526. lLastPos = -lState;
  3527. lState = i;
  3528. }
  3529. }
  3530. else if (data[i]>data[lState]) lState = i;
  3531. }
  3532. else if (data[i] <= data[i - 1] && data[i] <= data[i + 1])
  3533. {
  3534. if (lState>0)
  3535. {
  3536. if ((data[lState] - data[i]) * 100<dRate*data[lState]) continue;
  3537. else
  3538. {
  3539. dif = (data[lState] - data[j = lLastPos]) / (lState - lLastPos);
  3540. dest[j++]=data[lLastPos];
  3541. for (; j <= lState; ++j)
  3542. dest[j]=data[lLastPos] + (j - lLastPos)*dif;
  3543. lLastPos = lState;
  3544. lState = -i;
  3545. }
  3546. }
  3547. else if (data[i]<data[-lState]) lState = -i;
  3548. }
  3549. }
  3550. if (Math.abs(lState) >= nDataCount - 2)
  3551. {
  3552. if (lState>0 && data[nDataCount - 1] >= data[lState]) lState = nDataCount - 1;
  3553. if (lState<0 && data[nDataCount - 1] <= data[-lState]) lState = 1 - nDataCount;
  3554. }
  3555. if (lState>0)
  3556. {
  3557. dif = (data[lState] - data[j = lLastPos]) / (lState - lLastPos );
  3558. dest[j++]=data[lLastPos];
  3559. for (; j <= lState; ++j)
  3560. dest[j]=data[lLastPos] + (j - lLastPos)*dif;
  3561. }
  3562. else
  3563. {
  3564. dif = (data[lLastPos] - data[j = -lState]) / (-lState - lLastPos);
  3565. dest[j--]=data[-lState];
  3566. for (; j >= lLastPos; j--)
  3567. dest[j]=(data[-lState] + (-lState - j)*dif);
  3568. }
  3569. if ((lState = Math.abs(lState))<nDataCount - 1)
  3570. {
  3571. if (data[nDataCount - 1] >= data[lState])
  3572. {
  3573. dif = (data[nDataCount - 1] - data[j = lState]) / (nDataCount - lState);
  3574. dest[j++]=(data[lState]);
  3575. for (; j<nDataCount; ++j)
  3576. dest[j]=(data[lState] + (j - lState)*dif);
  3577. }
  3578. else
  3579. {
  3580. dif = (data[lState] - data[j = nDataCount - 1]) / (nDataCount - lState);
  3581. dest[j--]=(data[nDataCount - 1]);
  3582. for (; j >= lState; j--)
  3583. dest[j]=(data[nDataCount - 1] + (nDataCount - j)*dif);
  3584. }
  3585. }
  3586. return dest;
  3587. }
  3588. this.GetFirstVaildIndex=function(data)
  3589. {
  3590. for (var i = 0; i <data.length; ++i)
  3591. {
  3592. if (this.IsNumber(data[i]))
  3593. return i;
  3594. }
  3595. return data.length;
  3596. }
  3597. this.JSDraw = null;
  3598. this.CalculateZIGLine = function (firstData, secondData, thridData, data, result)
  3599. {
  3600. if (this.JSDraw == null) this.JSDraw = new JSDraw(this.ErrorHandler);
  3601. var isUp = secondData.Up;
  3602. var findData = firstData;
  3603. if (isUp)
  3604. {
  3605. for (var i = firstData.ID + 1; i < thridData.ID; ++i) //查找最高点
  3606. {
  3607. var subItem = data[i];
  3608. if (!this.IsNumber(subItem)) continue;
  3609. if (findData.Value < subItem) findData = { ID: i, Value: subItem };
  3610. }
  3611. }
  3612. else
  3613. {
  3614. for (var i = firstData.ID + 1; i < thridData.ID; ++i) //查找最低点
  3615. {
  3616. var subItem = data[i];
  3617. if (!this.IsNumber(subItem)) continue;
  3618. if (findData.Value > subItem) findData = { ID: i, Value: subItem };
  3619. }
  3620. }
  3621. secondData.Value = findData.Value;
  3622. secondData.ID = findData.ID;
  3623. var lineCache = { Start: { ID: firstData.ID, Value: firstData.Value }, End: { ID: secondData.ID, Value: secondData.Value } };
  3624. var lineData = this.JSDraw.CalculateDrawLine(lineCache);//计算2个点的线上 其他点的数值
  3625. for (var i in lineData)
  3626. {
  3627. var lineItem = lineData[i];
  3628. result[lineItem.ID] = lineItem.Value;
  3629. }
  3630. if (thridData.ID == data.length - 1) //最后一组数据
  3631. {
  3632. //最后2个点的数据连成线
  3633. lineCache = { Start: { ID: secondData.ID, Value: secondData.Value }, End: { ID: thridData.ID, Value: thridData.Value } };
  3634. lineData = this.JSDraw.CalculateDrawLine(lineCache);//计算2个点的线上 其他点的数值
  3635. for (var i in lineData)
  3636. {
  3637. var lineItem = lineData[i];
  3638. result[lineItem.ID] = lineItem.Value;
  3639. }
  3640. }
  3641. else
  3642. {
  3643. firstData.ID = secondData.ID;
  3644. firstData.Value = secondData.Value;
  3645. secondData.ID = thridData.ID;
  3646. secondData.Value = thridData.Value;
  3647. secondData.Up = firstData.Value < secondData.Value;
  3648. }
  3649. }
  3650. /*
  3651. 属于未来函数,前M个ZIG转向波谷到当前距离.
  3652. 用法:
  3653. TROUGHBARS(K,N,M)表示之字转向ZIG(K,N)的前M个波谷到当前的周期数,M必须大于等于1
  3654. 例如:
  3655. TROUGHBARS(2,5,2)表示%5最低价ZIG转向的前2个波谷到当前的周期数
  3656. */
  3657. this.TROUGHBARS=function(data,n,n2)
  3658. {
  3659. var zigData=this.ZIG(data,n); //计算ZIG
  3660. var dest=[];
  3661. var lEnd =n2;
  3662. if (lEnd<1) return dest;
  3663. var nDataCount = zigData.length;
  3664. var trough = [];
  3665. for(var i=0;i<lEnd;++i) trough[i]=0;
  3666. var lFlag = 0;
  3667. var i = this.GetFirstVaildIndex(zigData) + 1;
  3668. for (lEnd--; i<nDataCount && zigData[i]>zigData[i - 1]; ++i);
  3669. for (; i<nDataCount && zigData[i]<zigData[i - 1]; ++i);
  3670. for (trough[0] = --i; i<nDataCount - 1; ++i)
  3671. {
  3672. if (zigData[i]<zigData[i + 1])
  3673. {
  3674. if (lFlag)
  3675. {
  3676. if (lEnd)
  3677. {
  3678. var tempTrough=trough.slice(0);
  3679. for(var j=0;j<lEnd;++j)
  3680. {
  3681. trough[j+1]=tempTrough[j];
  3682. }
  3683. }
  3684. trough[lFlag = 0] = i;
  3685. }
  3686. }
  3687. else lFlag = 1;
  3688. if (trough[lEnd]) dest[i]=(i - trough[lEnd]);
  3689. }
  3690. if (trough[lEnd]) dest[i]=(i - trough[lEnd]);
  3691. return dest;
  3692. }
  3693. this.TROUGH=function(data,n,n2)
  3694. {
  3695. var zigData=this.ZIG(data,n); //计算ZIG
  3696. var dest=[];
  3697. var End=n2;
  3698. if(End<1) return dest;
  3699. var nDataCount = zigData.length;
  3700. var trough=[];
  3701. for(var i=0;i<End;++i) trough[i]=0;
  3702. var i=1,Flag=0;
  3703. var i = this.GetFirstVaildIndex(zigData) + 1;
  3704. for(End--; i<nDataCount && zigData[i]>zigData[i-1]; ++i);
  3705. for(; i<nDataCount && zigData[i]<zigData[i-1]; ++i);
  3706. for(trough[0]=--i;i<nDataCount-1;++i)
  3707. {
  3708. if(zigData[i]<zigData[i+1])
  3709. {
  3710. if(Flag)
  3711. {
  3712. if(End)
  3713. {
  3714. var tempTrough=trough.slice(0);
  3715. for(var j=0;j<End;++j)
  3716. {
  3717. trough[j+1]=tempTrough[j];
  3718. }
  3719. }
  3720. trough[Flag=0]=i;
  3721. }
  3722. }
  3723. else Flag=1;
  3724. if(trough[End]) dest[i]=zigData[trough[End]];
  3725. }
  3726. if(trough[End]) dest[i]=zigData[trough[End]];
  3727. return dest;
  3728. }
  3729. /*
  3730. 属于未来函数,前M个ZIG转向波峰到当前距离.
  3731. 用法:
  3732. PEAKBARS(K,N,M)表示之字转向ZIG(K,N)的前M个波峰到当前的周期数,M必须大于等于1
  3733. 例如:
  3734. PEAKBARS(0,5,1)表示%5开盘价ZIG转向的上一个波峰到当前的周期数
  3735. */
  3736. this.PEAKBARS=function(data,n,n2)
  3737. {
  3738. var zigData=this.ZIG(data,n); //计算ZIG
  3739. var dest=[];
  3740. var nDataCount = zigData.length;
  3741. var lEnd = n2;
  3742. if (lEnd < 1) return dest;
  3743. var peak = [];
  3744. for(var i=0;i<lEnd;++i) peak[i]=0;
  3745. var lFlag = 0;
  3746. var i = this.GetFirstVaildIndex(zigData) + 1;
  3747. for (lEnd--; i<nDataCount && zigData[i]<zigData[i - 1]; ++i);
  3748. for (; i<nDataCount && zigData[i]>zigData[i - 1]; ++i);
  3749. for (peak[0] = --i; i<nDataCount - 1; ++i)
  3750. {
  3751. if (zigData[i]>zigData[i + 1])
  3752. {
  3753. if (lFlag)
  3754. {
  3755. if (lEnd)
  3756. {
  3757. var tempPeak=peak.slice(0);
  3758. for(var j=0;j<lEnd;++j)
  3759. {
  3760. peak[j+1]=tempPeak[j];
  3761. }
  3762. }
  3763. peak[lFlag = 0] = i;
  3764. }
  3765. }
  3766. else lFlag = 1;
  3767. if (peak[lEnd]) dest[i]=(i - peak[lEnd]);
  3768. }
  3769. if (peak[lEnd])dest[i]=(i - peak[lEnd]);
  3770. return dest;
  3771. }
  3772. this.PEAK=function(data,n,n2)
  3773. {
  3774. var zigData=this.ZIG(data,n); //计算ZIG
  3775. var dest=[];
  3776. var nDataCount = zigData.length;
  3777. var lEnd = n2;
  3778. if (lEnd < 1) return dest;
  3779. var lFlag = 0;
  3780. var peak = [];
  3781. for(var i=0;i<lEnd;++i) peak[i]=0;
  3782. var i = this.GetFirstVaildIndex(zigData) + 1;
  3783. for (lEnd--; i<nDataCount && zigData[i]<zigData[i - 1]; ++i);
  3784. for (; i<nDataCount && zigData[i]>zigData[i - 1]; ++i);
  3785. for (peak[0] = --i; i<nDataCount - 1; ++i)
  3786. {
  3787. if (zigData[i]>zigData[i + 1])
  3788. {
  3789. if (lFlag)
  3790. {
  3791. if (lEnd)
  3792. {
  3793. var tempPeak=peak.slice(0);
  3794. for(var j=0;j<lEnd;++j)
  3795. {
  3796. peak[j+1]=tempPeak[j];
  3797. }
  3798. }
  3799. peak[lFlag = 0] = i;
  3800. }
  3801. }
  3802. else lFlag = 1;
  3803. if (peak[lEnd]) dest[i]=(zigData[peak[lEnd]]);
  3804. }
  3805. if (peak[lEnd]) dest[i]=(zigData[peak[lEnd]]);
  3806. return dest;
  3807. }
  3808. /*
  3809. 一直存在.
  3810. 例如:
  3811. EVERY(CLOSE>OPEN,N)
  3812. 表示N日内一直阳线(N应大于0,小于总周期数,N支持变量)
  3813. */
  3814. this.EVERY = function (data, n)
  3815. {
  3816. var result = [];
  3817. if (n < 1) return result;
  3818. var i = 0;
  3819. for (; i < data.length; ++i)
  3820. {
  3821. result[i] = null;
  3822. if (this.IsNumber(data[i])) break;
  3823. }
  3824. var flag = 0;
  3825. for (; i < data.length; ++i)
  3826. {
  3827. if (data[i]) flag += 1;
  3828. else flag = 0;
  3829. if (flag == n)
  3830. {
  3831. result[i] = 1;
  3832. --flag;
  3833. }
  3834. else
  3835. {
  3836. result[i] = 0;
  3837. }
  3838. }
  3839. return result;
  3840. }
  3841. /*
  3842. 成本分布情况.
  3843. 用法:
  3844. COST(10),表示10%获利盘的价格是多少,即有10%的持仓量在该价格以下,其余90%在该价格以上,为套牢盘
  3845. 该函数仅对日线分析周期有效
  3846. */
  3847. this.COST = function (data, node)
  3848. {
  3849. var result=[];
  3850. var rate=data/100;
  3851. if(rate<0.000001 || rate>1) return result;
  3852. var kData=this.SymbolData.Data.Data;
  3853. if (!kData || kData.length<=0) return result;
  3854. var aryCapital=this.SymbolData.GetStockCacheData({ FunctionName:"FINANCE", Args:[7], ArgCount:1, Node:node } ); //流通股本
  3855. var dMaxPrice=kData[0].High,dMinPrice=kData[0].Low;
  3856. for(var i=0;i<kData.length;++i)
  3857. {
  3858. var item=kData[i];
  3859. dMinPrice = Math.min(dMinPrice,item.Low);
  3860. dMaxPrice = Math.max(dMaxPrice,item.High);
  3861. }
  3862. if (dMinPrice > 2000 || dMinPrice < 0 || dMaxPrice>2000 || dMinPrice < 0)
  3863. this.ThrowUnexpectedNode(node,'COST() 历史K线最大最小值错误, 超出(0,1000)范围');
  3864. var lMaxPrice = parseInt(dMaxPrice * 100 + 1);
  3865. var lMinPrice = parseInt(dMinPrice * 100 - 1);
  3866. var lLow = 0, lHigh = 0, lClose = 0;
  3867. //去掉小数
  3868. dMaxPrice = lMaxPrice / 100.0;
  3869. dMinPrice = lMinPrice / 100.0;
  3870. var lSpeed = lMaxPrice - lMinPrice + 1;
  3871. if (lSpeed < 1) return result;
  3872. var aryVolPrice=[],aryPerVol=[];
  3873. for(var i=0;i<lSpeed;++i)
  3874. {
  3875. aryVolPrice[i]=0;
  3876. aryPerVol[i]=0;
  3877. }
  3878. var dHSL = 0, dTotalVol = 0, dVol = 0, dCost=0;
  3879. for(var i=0;i<kData.length;++i)
  3880. {
  3881. if (i >= aryCapital.length) continue;
  3882. if (aryCapital[i]>1)
  3883. {
  3884. var kItem=kData[i]
  3885. dHSL = kItem.Vol/aryCapital[i];
  3886. for( var j=0;j<lSpeed;j++)
  3887. aryVolPrice[j]*=(1-dHSL);
  3888. lLow=parseInt(Math.min(lMaxPrice,Math.max(lMinPrice,kItem.Low *100)))-lMinPrice;
  3889. lHigh=parseInt(Math.min(lMaxPrice,Math.max(lMinPrice,kItem.High*100)))-lMinPrice;
  3890. lClose=parseInt(Math.min(lMaxPrice,Math.max(lMinPrice,kItem.Close*100)))-lMinPrice;
  3891. for(var j=0;j<lSpeed;++j) aryPerVol[j]=0;
  3892. var lHalf =parseInt((lLow + lHigh + 2 * lClose) / 4);
  3893. if (lHalf == lHigh || lHalf == lLow)
  3894. {
  3895. aryPerVol[lHalf] += kItem.Vol;
  3896. }
  3897. else
  3898. {
  3899. var dVH = kItem.Vol / (lHalf - lLow);
  3900. for (var k = lLow; k<lHalf; ++k)
  3901. {
  3902. aryPerVol[k] += (k - lLow)*(dVH / (lHalf - lLow));
  3903. }
  3904. for (k; k <= lHigh; ++k)
  3905. {
  3906. aryPerVol[k] += (k - lHigh)*(dVH / (lHalf - lHigh));
  3907. }
  3908. }
  3909. var dTotalVol = 0;
  3910. for (var j = lLow; j <= lHigh; j++)
  3911. {
  3912. aryVolPrice[j] += aryPerVol[j];
  3913. }
  3914. for (var j = 0; j < lSpeed; j++)
  3915. {
  3916. dTotalVol += aryVolPrice[j];
  3917. }
  3918. for(j=0,dCost=dVol=0;j<lSpeed;++j)
  3919. {
  3920. dVol+=aryVolPrice[j];
  3921. if(dVol>=dTotalVol*rate)
  3922. {
  3923. dCost=(dMaxPrice-dMinPrice)*j/lSpeed+dMinPrice;
  3924. break;
  3925. }
  3926. }
  3927. }
  3928. result[i]=dCost;
  3929. }
  3930. return result;
  3931. }
  3932. /*
  3933. 获利盘比例.
  3934. 用法:
  3935. WINNER(CLOSE),表示以当前收市价卖出的获利盘比例,例如返回0.1表示10%获利盘;WINNER(10.5)表示10.5元价格的获利盘比例
  3936. 该函数仅对日线分析周期有效
  3937. !!!!计算比较耗时间
  3938. */
  3939. this.WINNER = function (data,node)
  3940. {
  3941. var result=[];
  3942. var kData=this.SymbolData.Data.Data;
  3943. if (!kData || kData.length<=0) return result;
  3944. var aryCapital=this.SymbolData.GetStockCacheData({ FunctionName:"FINANCE", Args:[7], ArgCount:1, Node:node } ); //流通股本
  3945. var dMaxPrice=kData[0].High,dMinPrice=kData[0].Low;
  3946. for(var i=0;i<kData.length;++i)
  3947. {
  3948. var item=kData[i];
  3949. dMinPrice = Math.min(dMinPrice,item.Low);
  3950. dMaxPrice = Math.max(dMaxPrice,item.High);
  3951. }
  3952. if (dMinPrice > 1000 || dMinPrice < 0 || dMaxPrice>1000 || dMinPrice < 0)
  3953. this.ThrowUnexpectedNode(node,'WINNER() 历史K线最大最小值错误, 超出(0,1000)范围');
  3954. var lMaxPrice = parseInt(dMaxPrice * 100 + 1);
  3955. var lMinPrice = parseInt(dMinPrice * 100 - 1);
  3956. var lLow = 0, lHigh = 0, lClose = 0;
  3957. //去掉小数
  3958. dMaxPrice = lMaxPrice / 100.0;
  3959. dMinPrice = lMinPrice / 100.0;
  3960. var lSpeed = lMaxPrice - lMinPrice + 1;
  3961. if (lSpeed < 1) return result;
  3962. var aryVolPrice=[],aryPerVol=[];
  3963. for(var i=0;i<lSpeed;++i)
  3964. {
  3965. aryVolPrice[i]=0;
  3966. aryPerVol[i]=0;
  3967. }
  3968. var dHSL = 0, dTotalVol = 0, dVol = 0;
  3969. for(var i=0;i<kData.length;++i)
  3970. {
  3971. if (i >= aryCapital.length) continue;
  3972. if (!(aryCapital[i]>1)) continue;
  3973. var kItem=kData[i]
  3974. dHSL = kItem.Vol/aryCapital[i];
  3975. for( var j=0;j<lSpeed;j++)
  3976. aryVolPrice[j]*=(1-dHSL);
  3977. lLow=parseInt(Math.min(lMaxPrice,Math.max(lMinPrice,kItem.Low *100)))-lMinPrice;
  3978. lHigh=parseInt(Math.min(lMaxPrice,Math.max(lMinPrice,kItem.High*100)))-lMinPrice;
  3979. lClose=parseInt(Math.min(lMaxPrice,Math.max(lMinPrice,kItem.Close*100)))-lMinPrice;
  3980. for(var j=0;j<lSpeed;++j) aryPerVol[j]=0;
  3981. var lHalf =parseInt((lLow + lHigh + 2 * lClose) / 4);
  3982. if (lHalf == lHigh || lHalf == lLow)
  3983. {
  3984. aryPerVol[lHalf] += kItem.Vol;
  3985. }
  3986. else
  3987. {
  3988. var dVH = kItem.Vol / (lHalf - lLow);
  3989. for (var k = lLow; k<lHalf; ++k)
  3990. {
  3991. aryPerVol[k] += (k - lLow)*(dVH / (lHalf - lLow));
  3992. }
  3993. for (k; k <= lHigh; ++k)
  3994. {
  3995. aryPerVol[k] += (k - lHigh)*(dVH / (lHalf - lHigh));
  3996. }
  3997. }
  3998. var dTotalVol = 0;
  3999. for (var j = lLow; j <= lHigh; j++)
  4000. {
  4001. aryVolPrice[j] += aryPerVol[j];
  4002. }
  4003. for (var j = 0; j < lSpeed; j++)
  4004. {
  4005. dTotalVol += aryVolPrice[j];
  4006. }
  4007. if (Array.isArray(data))
  4008. lHigh = parseInt(Math.min((data[i] * 100) - lMinPrice, lSpeed - 1));
  4009. else
  4010. lHigh = parseInt(Math.min((data * 100) - lMinPrice, lSpeed - 1));
  4011. for (var j = 0, dVol = 0; j <= lHigh; j++)
  4012. {
  4013. dVol += aryVolPrice[j];
  4014. }
  4015. if (dTotalVol > 0) result[i]=dVol / dTotalVol;
  4016. else if (i - 1 >= 0) result[i] = result[i - 1];
  4017. }
  4018. return result;
  4019. }
  4020. //计算截至到某一天的历史所有筹码
  4021. this.CalculateChip = function (index, exchangeData, hisData, dRate)
  4022. {
  4023. var result = { Min: null, Max: null, Data: [] };
  4024. var seed = 1;//筹码历史衰减换手系数
  4025. var max = null, min = null;
  4026. for (let i = index; i >= 0; --i)
  4027. {
  4028. let item = {}; //Vol:量 High:最高 Low:最低
  4029. var kData = hisData[i];
  4030. if (i == index) item.Vol = kData.Vol * exchangeData[i];
  4031. else item.Vol = kData.Vol * seed;
  4032. item.Date = kData.Date;
  4033. item.High = kData.High;
  4034. item.Low = kData.Low;
  4035. if (max == null) max = item.High;
  4036. else if (max < item.High) max = item.High;
  4037. if (min == null) min = item.Low;
  4038. else if (min < item.Low) min = item.Low;
  4039. result.Data[i] = item;
  4040. seed *= (1 - (exchangeData[i] / 100) * dRate); //换手率累乘
  4041. }
  4042. result.Max = max;
  4043. result.Min = min;
  4044. return result;
  4045. }
  4046. /*
  4047. 返回是否连涨周期数.
  4048. 用法:
  4049. UPNDAY(CLOSE,M)
  4050. 表示连涨M个周期,M为常量
  4051. */
  4052. this.UPNDAY = function (data, n)
  4053. {
  4054. var result = [];
  4055. if (n < 1) return result;
  4056. if (data == null || n > data.length) return result;
  4057. var days = 0;
  4058. for (let i = 0; i < data.length; ++i)
  4059. {
  4060. result[i] = 0;
  4061. if (i - 1 < 0) continue;
  4062. if (!this.IsNumber(data[i]) || !this.IsNumber(data[i - 1])) //无效数都不算连涨
  4063. {
  4064. days = 0;
  4065. continue;
  4066. }
  4067. if (data[i] > data[i - 1])++days;
  4068. else days = 0;
  4069. if (days == n)
  4070. {
  4071. result[i] = 1;
  4072. --days;
  4073. }
  4074. }
  4075. return result;
  4076. }
  4077. /*
  4078. 返回是否连跌周期.
  4079. 用法:
  4080. DOWNNDAY(CLOSE,M)
  4081. 表示连跌M个周期,M为常量
  4082. */
  4083. this.DOWNNDAY = function (data, n)
  4084. {
  4085. var result = [];
  4086. if (n < 1) return result;
  4087. if (data == null || n > data.length) return result;
  4088. var days = 0;
  4089. for (let i = 0; i < data.length; ++i)
  4090. {
  4091. result[i] = 0;
  4092. if (i - 1 < 0) continue;
  4093. if (!this.IsNumber(data[i]) || !this.IsNumber(data[i - 1])) //无效数都不算连涨
  4094. {
  4095. days = 0;
  4096. continue;
  4097. }
  4098. if (data[i] < data[i - 1])++days;
  4099. else days = 0;
  4100. if (days == n)
  4101. {
  4102. result[i] = 1;
  4103. --days;
  4104. }
  4105. }
  4106. return result;
  4107. }
  4108. /*
  4109. 返回是否持续存在X>Y
  4110. 用法:
  4111. NDAY(CLOSE,OPEN,3)
  4112. 表示连续3日收阳线
  4113. */
  4114. this.NDAY = function (data, data2, n)
  4115. {
  4116. var result = [];
  4117. if (n < 1) return result;
  4118. if (!Array.isArray(data) && !Array.isArray(data2)) return result;
  4119. if (data == null || data2 == null) return result;
  4120. if (Array.isArray(data) && Array.isArray(data2))
  4121. {
  4122. if (n >= data.length || n >= data2.length) return result;
  4123. var count = Math.max(data.length, data2.length);
  4124. var days = 0;
  4125. for (let i = 0; i < count; ++i)
  4126. {
  4127. result[i] = 0;
  4128. if (i >= data.length || i >= data2.length) continue;
  4129. if (!this.IsNumber(data[i]) || !this.IsNumber(data2[i]))
  4130. {
  4131. days = 0;
  4132. continue;
  4133. }
  4134. if (data[i] > data2[i])++days;
  4135. else days = 0;
  4136. if (days == n)
  4137. {
  4138. result[i] = 1;
  4139. --days;
  4140. }
  4141. }
  4142. }
  4143. else if (Array.isArray(data) && !Array.isArray(data2))
  4144. {
  4145. if (n >= data.length || !this.IsNumber(data2)) return;
  4146. var days = 0;
  4147. for (let i in data)
  4148. {
  4149. result[i] = 0;
  4150. if (!this.IsNumber(data[i]))
  4151. {
  4152. days = 0;
  4153. continue;
  4154. }
  4155. if (data[i] > data2)++days;
  4156. else days = 0;
  4157. if (days == n)
  4158. {
  4159. result[i] = 1;
  4160. --days;
  4161. }
  4162. }
  4163. }
  4164. else if (!Array.isArray(data) && Array.isArray(data2))
  4165. {
  4166. if (n >= data2.length || !this.IsNumber(data)) return;
  4167. var days = 0;
  4168. for (let i in data2)
  4169. {
  4170. result[i] = 0;
  4171. if (!this.IsNumber(data2[i]))
  4172. {
  4173. days = 0;
  4174. continue;
  4175. }
  4176. if (data > data2[i])++days;
  4177. else days = 0;
  4178. if (days == n)
  4179. {
  4180. result[i] = 1;
  4181. --days;
  4182. }
  4183. }
  4184. }
  4185. return result;
  4186. }
  4187. /*
  4188. 两条线维持一定周期后交叉.
  4189. 用法:LONGCROSS(A,B,N)表示A在N周期内都小于B,本周期从下方向上穿过B时返回1,否则返回0
  4190. */
  4191. this.LONGCROSS = function (data, data2, n)
  4192. {
  4193. var result = [];
  4194. var count = Math.max(data.length, data2.length);
  4195. for (let i = 0; i < count; ++i)
  4196. {
  4197. result[i] = 0;
  4198. if (i - 1 < 0) continue;
  4199. if (i >= data.length || i >= data2.length) continue;
  4200. if (!this.IsNumber(data[i]) || !this.IsNumber(data2[i]) || !this.IsNumber(data[i - 1]) || !this.IsNumber(data2[i - 1])) continue;
  4201. if (data[i] > data2[i] && data[i - 1] < data2[i - 1]) result[i] = 1;
  4202. }
  4203. for (let i = 0, j = 0; i < count; ++i)
  4204. {
  4205. if (!result[i]) continue;
  4206. for (j = 1; j <= n && i - j >= 0; ++j)
  4207. {
  4208. if (data[i - j] >= data2[i - j])
  4209. {
  4210. result[i] = 0;
  4211. break;
  4212. }
  4213. }
  4214. }
  4215. return result;
  4216. }
  4217. /*
  4218. EXISTR(X,A,B):是否存在(前几日到前几日间).
  4219. 例如: EXISTR(CLOSE>OPEN,10,5)
  4220. 表示从前10日内到前5日内存在着阳线
  4221. 若A为0,表示从第一天开始,B为0,表示到最后日止
  4222. */
  4223. this.EXISTR = function (data, n, n2)
  4224. {
  4225. var result = [];
  4226. if (!Array.isArray(data)) return result;
  4227. n = parseInt(n);
  4228. n2 = parseInt(n2);
  4229. if (n <= 0) n = data.length;
  4230. if (n2 <= 0) n2 = 1;
  4231. if (n2 > n) return result;
  4232. var result = [];
  4233. var value;
  4234. for (let i = 0, j = 0; i < data.length; ++i)
  4235. {
  4236. result[i] = null;
  4237. if (i - n < 0 || i - n2 < 0) continue;
  4238. result[i] = 0;
  4239. for (j = n; j >= n2; --j)
  4240. {
  4241. var value = data[i - j];
  4242. if (this.IsNumber(value) && value)
  4243. {
  4244. result[i] = 1;
  4245. break;
  4246. }
  4247. }
  4248. }
  4249. return result;
  4250. }
  4251. /*
  4252. RELATE(X,Y,N) 返回X和Y的N周期的相关系数
  4253. RELATE(X,Y,N)=(∑[(Xi-Avg(X))(Yi-Avg(y))])/N ÷ √((∑(Xi-Avg(X))^2)/N * (∑(Yi-Avg(Y))^2)/N)
  4254. 其中 avg(x)表示x的N周期均值: avg(X) = (∑Xi)/N
  4255. √(...)表示开平方
  4256. */
  4257. this.RELATE = function (data, data2, n)
  4258. {
  4259. var result = [];
  4260. if (n < 1) n = 1;
  4261. if (!Array.isArray(data) || !Array.isArray(data2)) return result;
  4262. var dataAverage = this.CalculateAverage(data, n);
  4263. var data2Average = this.CalculateAverage(data2, n);
  4264. var count = Math.max(data.length, data2.length);
  4265. for (let i = 0, j = 0; i < count; ++i)
  4266. {
  4267. result[i] = null;
  4268. if (i >= data.length || i >= data2.length || i >= dataAverage.length || i >= data2Average.length) continue;
  4269. var average = dataAverage[i];
  4270. var average2 = data2Average[i];
  4271. var total = 0, total2 = 0, total3 = 0;
  4272. for (j = i - n + 1; j <= i; ++j)
  4273. {
  4274. total += (data[j] - average) * (data2[j] - average2); //∑[(Xi-Avg(X))(Yi-Avg(y))])
  4275. total2 += Math.pow(data[j] - average, 2); //∑(Xi-Avg(X))^2
  4276. total3 += Math.pow(data2[j] - average2, 2); //∑(Yi-Avg(Y))^2)
  4277. }
  4278. result[i] = (total / n) / (Math.sqrt(total2 / n) * Math.sqrt(total3 / n));
  4279. }
  4280. return result;
  4281. }
  4282. //计算数组n周期内的均值
  4283. this.CalculateAverage = function (data, n)
  4284. {
  4285. var result = [];
  4286. if (n < 1) return result;
  4287. var total = 0;
  4288. for (var i = 0; i < data.length; ++i) //去掉开始的无效数
  4289. {
  4290. if (this.IsNumber(data[i])) break;
  4291. }
  4292. for (; i < data.length && i < n; ++i) //计算第1个周期的数据
  4293. {
  4294. result[i] = null;
  4295. var value = data[i];
  4296. if (!this.IsNumber(value)) continue;
  4297. total += value;
  4298. }
  4299. result[i - 1] = total / n;
  4300. for (; i < data.length; ++i) //计算后面的周期数据
  4301. {
  4302. var value = data[i];
  4303. var preValue = data[i - n]; //上一个周期的第1个数据
  4304. if (!this.IsNumber(value)) value = 0;
  4305. if (!this.IsNumber(preValue)) preValue = 0;
  4306. total = total - preValue + value; //当前周期的数据 等于上一个周期数据 去掉上一个周期的第1个数据 加上这个周期的最后1个数据
  4307. result[i] = total / n;
  4308. }
  4309. return result;
  4310. }
  4311. /*
  4312. COVAR(X,Y,N) 返回X和Y的N周期的协方差
  4313. */
  4314. this.COVAR = function (data, data2, n)
  4315. {
  4316. var result = [];
  4317. if (n < 1) n = 1;
  4318. if (!Array.isArray(data) || !Array.isArray(data2)) return result;
  4319. var dataAverage = this.CalculateAverage(data, n);
  4320. var data2Average = this.CalculateAverage(data2, n);
  4321. var count = Math.max(data.length, data2.length);
  4322. var count = Math.max(data.length, data2.length);
  4323. for (let i = 0, j = 0; i < count; ++i)
  4324. {
  4325. result[i] = null;
  4326. if (i >= data.length || i >= data2.length || i >= dataAverage.length || i >= data2Average.length) continue;
  4327. var average = dataAverage[i];
  4328. var average2 = data2Average[i];
  4329. var total = 0;
  4330. for (j = i - n + 1; j <= i; ++j)
  4331. {
  4332. total += (data[j] - average) * (data2[j] - average2);
  4333. }
  4334. result[i] = (total / n);
  4335. }
  4336. return result;
  4337. }
  4338. /*
  4339. 求上一高点到当前的周期数.
  4340. 用法:
  4341. HHVBARS(X,N):求N周期内X最高值到当前周期数,N=0表示从第一个有效值开始统计
  4342. 例如:
  4343. HHVBARS(HIGH,0)求得历史新高到到当前的周期数
  4344. */
  4345. this.HHVBARS = function (data, n)
  4346. {
  4347. var result = [];
  4348. if (!Array.isArray(data)) return result;
  4349. if (Array.isArray(n))
  4350. {
  4351. for(var i=0;i<n.length;++i)
  4352. {
  4353. result[i]=null;
  4354. var period=n[i];
  4355. if (!this.IsNumber(period)) continue;
  4356. var start=i-period;
  4357. if (start<0) start=0;
  4358. var nMax=null;
  4359. var j=start;
  4360. for(; j<data.length;++j)
  4361. {
  4362. if (this.IsNumber(data[j]))
  4363. {
  4364. nMax=j;
  4365. break;
  4366. }
  4367. }
  4368. for(var k=0; j<data.length && k<period;++k, ++j)
  4369. {
  4370. if (data[j]>=data[nMax]) nMax=j;
  4371. }
  4372. if (nMax!=null)
  4373. result[i]=(i-nMax);
  4374. }
  4375. }
  4376. else
  4377. {
  4378. if (n < 1) n = data.length;
  4379. var nMax = null; //最大值索引
  4380. for (var i = 0; i < data.length; ++i)
  4381. {
  4382. result[i] = null;
  4383. if (this.IsNumber(data[i])) {
  4384. nMax = i;
  4385. break;
  4386. }
  4387. }
  4388. var j = 0;
  4389. for (i = nMax + 1; i < data.length && j < n; ++i, ++j) //求第1个最大值
  4390. {
  4391. if (data[i] >= data[nMax]) nMax = i;
  4392. if (n == data.length) result[i] = (i - nMax);
  4393. }
  4394. for (; i < data.length; ++i)
  4395. {
  4396. if (i - nMax < n)
  4397. {
  4398. if (data[i] >= data[nMax]) nMax = i;
  4399. }
  4400. else
  4401. {
  4402. nMax = i - n + 1;
  4403. for (j = nMax; j <= i; ++j) //计算区间最大值
  4404. {
  4405. if (data[j] >= data[nMax]) nMax = j;
  4406. }
  4407. }
  4408. result[i] = i - nMax;
  4409. }
  4410. }
  4411. return result;
  4412. }
  4413. /*
  4414. 求上一低点到当前的周期数.
  4415. 用法: LLVBARS(X,N):求N周期内X最低值到当前周期数,N=0表示从第一个有效值开始统计
  4416. 例如: LLVBARS(HIGH,20)求得20日最低点到当前的周期数
  4417. */
  4418. this.LLVBARS = function (data, n)
  4419. {
  4420. var result = [];
  4421. if (!Array.isArray(data)) return result;
  4422. if (Array.isArray(n))
  4423. {
  4424. for(var i=0;i<n.length;++i)
  4425. {
  4426. result[i]=null;
  4427. var period=n[i];
  4428. if (!this.IsNumber(period)) continue;
  4429. var start=i-period;
  4430. if (start<0) start=0;
  4431. var nMin=null;
  4432. var j=start;
  4433. for(; j<data.length;++j)
  4434. {
  4435. if (this.IsNumber(data[j]))
  4436. {
  4437. nMin=j;
  4438. break;
  4439. }
  4440. }
  4441. for(var k=0; j<data.length && k<period;++k, ++j)
  4442. {
  4443. if (data[j]<=data[nMin]) nMin=j;
  4444. }
  4445. if (nMin!=null)
  4446. result[i]=(i-nMin);
  4447. }
  4448. }
  4449. else
  4450. {
  4451. if (n < 1) n = data.length;
  4452. var nMin = null; //最小值索引
  4453. for (var i = 0; i < data.length; ++i)
  4454. {
  4455. result[i] = null;
  4456. if (this.IsNumber(data[i]))
  4457. {
  4458. nMin = i;
  4459. break;
  4460. }
  4461. }
  4462. var j = 0;
  4463. for (i = nMin + 1; i < data.length && j < n; ++i, ++j) //求第1个最大值
  4464. {
  4465. if (data[i] <= data[nMin]) nMin = i;
  4466. if (n == data.length) result[i] = (i - nMin);
  4467. }
  4468. for (; i < data.length; ++i)
  4469. {
  4470. if (i - nMin < n)
  4471. {
  4472. if (data[i] <= data[nMin]) nMin = i;
  4473. }
  4474. else
  4475. {
  4476. nMin = i - n + 1;
  4477. for (j = nMin; j <= i; ++j) //计算区间最小值
  4478. {
  4479. if (data[j] <= data[nMin]) nMin = j;
  4480. }
  4481. }
  4482. result[i] = i - nMin;
  4483. }
  4484. }
  4485. return result;
  4486. }
  4487. /*
  4488. β(Beta)系数
  4489. BETA(N) 返回当前证券N周期收益与对应大盘指数收益相比的贝塔系数
  4490. 需要下载上证指数历史数据
  4491. 涨幅(X)=(现价-上一个交易日收盘价)/上一个交易日收盘价
  4492. 公式=股票和指数协方差/股票方差
  4493. */
  4494. this.BETA = function (n)
  4495. {
  4496. var result = [];
  4497. var stockData = this.SymbolData.Data;
  4498. var indexData = this.SymbolData.IndexData;
  4499. if (n <= 0) n = 1;
  4500. var stockProfit = []; //股票涨幅
  4501. var indexProfit = []; //指数涨幅
  4502. for (let i = 0; i < stockData.Data.length; ++i)
  4503. {
  4504. stockProfit[i] = 0;
  4505. indexProfit[i] = 0;
  4506. var stockItem = stockData.Data[i];
  4507. var indexItem = indexData.Data[i];
  4508. if (stockItem.Close > 0 && stockItem.YClose > 0) stockProfit[i] = (stockItem.Close - stockItem.YClose) / stockItem.YClose;
  4509. if (indexItem.Close > 0 && indexItem.YClose > 0) indexProfit[i] = (indexItem.Close - indexItem.YClose) / indexItem.YClose;
  4510. }
  4511. //计算均值数组
  4512. var averageStockProfit = this.CalculateAverage(stockProfit, n);
  4513. var averageIndexProfit = this.CalculateAverage(indexProfit, n);
  4514. for (var i = 0, j = 0; i < stockData.Data.length; ++i)
  4515. {
  4516. result[i] = null;
  4517. if (i >= stockProfit.length || i >= indexProfit.length || i >= averageStockProfit.length || i >= averageIndexProfit.length) continue;
  4518. var averageStock = averageStockProfit[i];
  4519. var averageIndex = averageIndexProfit[i];
  4520. var covariance = 0; //协方差
  4521. var variance = 0; //方差
  4522. for (j = i - n + 1; j <= i; ++j)
  4523. {
  4524. var value = (indexProfit[j] - averageIndex);
  4525. var value2 = (stockProfit[j] - averageStock);
  4526. covariance += value * value2;
  4527. variance += value * value;
  4528. }
  4529. if (this.IsDivideNumber(variance) && this.IsNumber(covariance))
  4530. result[i] = covariance / variance; //(covariance/n)/(variance/n)=covariance/variance;
  4531. }
  4532. return result;
  4533. }
  4534. /*
  4535. 用法:BETA2(X,Y,N)为X与Y的N周期相关放大系数,表示Y变化1%,则X将变化N%
  4536. 例如:BETA2(CLOSE,INDEXC,10)表示收盘价与大盘指数之间的10周期相关放大率
  4537. */
  4538. this.BETA2 = function (x, y, n)
  4539. {
  4540. var result = [];
  4541. if (n <= 0) n = 1;
  4542. var xProfit = [null]; //x数据的涨幅
  4543. var yProfit = [null]; //y数据的涨幅
  4544. var count = Math.max(x.length, y.length);
  4545. var lastItem = { X: x[0], Y: y[0] };
  4546. for (var i = 1; i < count; ++i)
  4547. {
  4548. xProfit[i] = 0;
  4549. yProfit[i] = 0;
  4550. var xItem = x[i];
  4551. var yItem = y[i];
  4552. if (lastItem.X > 0) xProfit[i] = (xItem - lastItem.X) / lastItem.X;
  4553. if (lastItem.Y > 0) yProfit[i] = (yItem - lastItem.Y) / lastItem.Y;
  4554. lastItem = { X: xItem, Y: yItem };
  4555. }
  4556. //计算均值数组
  4557. var averageXProfit = this.CalculateAverage(xProfit, n);
  4558. var averageYProfit = this.CalculateAverage(yProfit, n);
  4559. for (var i = 0, j = 0; i < count; ++i)
  4560. {
  4561. result[i] = null;
  4562. if (i >= xProfit.length || i >= yProfit.length || i >= averageXProfit.length || i >= averageYProfit.length) continue;
  4563. var averageX = averageXProfit[i];
  4564. var averageY = averageYProfit[i];
  4565. var covariance = 0; //协方差
  4566. var variance = 0; //方差
  4567. for (j = i - n + 1; j <= i; ++j)
  4568. {
  4569. var value = (xProfit[j] - averageX);
  4570. var value2 = (yProfit[j] - averageY);
  4571. covariance += value * value2;
  4572. variance += value * value;
  4573. }
  4574. if (this.IsDivideNumber(variance) && this.IsNumber(covariance))
  4575. result[i] = covariance / variance; //(covariance/n)/(variance/n)=covariance/variance;
  4576. }
  4577. return result;
  4578. }
  4579. /*
  4580. 抛物转向.
  4581. 用法:
  4582. SAR(N,S,M),N为计算周期,S为步长,M为极值
  4583. 例如:
  4584. SAR(10,2,20)表示计算10日抛物转向,步长为2%,极限值为20%
  4585. */
  4586. this.SAR = function (n, step, exValue)
  4587. {
  4588. var result = [];
  4589. var stockData = this.SymbolData.Data;
  4590. if (n >= stockData.Data.length) return result;
  4591. var high = null, low = null;
  4592. for (var i = 0; i < n; ++i)
  4593. {
  4594. var item = stockData.Data[i];
  4595. if (high == null) high = item.High;
  4596. else if (high < item.High) high = item = high;
  4597. if (low == null) low = item.Low;
  4598. else if (low > item.Low) low = item.Low;
  4599. }
  4600. const SAR_LONG = 0, SAR_SHORT = 1;
  4601. var position = SAR_LONG;
  4602. result[n - 1] = low;
  4603. var nextSar = low, sip = stockData.Data[0].High, af = exValue / 100;
  4604. for (var i = n; i < stockData.Data.length; ++i)
  4605. {
  4606. var ysip = sip;
  4607. var item = stockData.Data[i];
  4608. var yitem = stockData.Data[i - 1];
  4609. if (position == SAR_LONG)
  4610. {
  4611. if (item.Low < result[i - 1])
  4612. {
  4613. position = SAR_SHORT;
  4614. sip = item.Low;
  4615. af = step / 100;
  4616. nextSar = Math.max(item.High, yitem.High);
  4617. nextSar = Math.max(nextSar, ysip + af * (sip - ysip));
  4618. }
  4619. else
  4620. {
  4621. position = SAR_LONG;
  4622. if (item.High > ysip)
  4623. {
  4624. sip = item.High;
  4625. af = Math.min(af + step / 100, exValue / 100);
  4626. }
  4627. nextSar = Math.min(item.Low, yitem.Low);
  4628. nextSar = Math.min(nextSar, result[i - 1] + af * (sip - result[i - 1]));
  4629. }
  4630. }
  4631. else if (position == SAR_SHORT)
  4632. {
  4633. if (item.High > result[i - 1])
  4634. {
  4635. position = SAR_LONG;
  4636. sip = item.High;
  4637. af = step / 100;
  4638. nextSar = Math.min(item.Low, yitem.Low);
  4639. nextSar = Math.min(nextSar, result[i - 1] + af * (sip - ysip));
  4640. }
  4641. else
  4642. {
  4643. position = SAR_SHORT;
  4644. if (item.Low < ysip)
  4645. {
  4646. sip = item.Low;
  4647. af = Math.min(af + step / 100, exValue / 100);
  4648. }
  4649. nextSar = Math.max(item.High, yitem.High);
  4650. nextSar = Math.max(nextSar, result[i - 1] + af * (sip - result[i - 1]));
  4651. }
  4652. }
  4653. result[i] = nextSar;
  4654. }
  4655. return result;
  4656. }
  4657. /*
  4658. 抛物转向点.
  4659. 用法:
  4660. SARTURN(N,S,M),N为计算周期,S为步长,M为极值,若发生向上转向则返回1,若发生向下转向则返回-1,否则为0
  4661. 其用法与SAR函数相同
  4662. */
  4663. this.SARTURN = function (n, step, exValue)
  4664. {
  4665. var result = [];
  4666. var sar = this.SAR(n, step, exValue);
  4667. var stockData = this.SymbolData.Data;
  4668. var index = 0;
  4669. for (index = 0; index < sar.length; ++index)
  4670. {
  4671. if (this.IsNumber(sar[index])) break;
  4672. }
  4673. var flag = 0;
  4674. if (index < stockData.Data.length) flag = stockData.Data[index].Close > sar[index];
  4675. for (var i = index + 1; i < stockData.Data.length; ++i)
  4676. {
  4677. var item = stockData.Data[i];
  4678. if (item.Close < sar[i] && flag) result[i] = -1;
  4679. else result[i] = (item.Close > sar[i] && !flag) ? 1 : 0;
  4680. flag = item.Close > sar[i];
  4681. }
  4682. return result;
  4683. }
  4684. /*
  4685. 属于未来函数,将当前位置到若干周期前的数据设为1.
  4686. 用法:
  4687. BACKSET(X,N),若X非0,则将当前位置到N周期前的数值设为1.
  4688. 例如:
  4689. BACKSET(CLOSE>OPEN,2)若收阳则将该周期及前一周期数值设为1,否则为0
  4690. */
  4691. this.BACKSET = function (condition, n)
  4692. {
  4693. var result = [];
  4694. if (!condition) return result;
  4695. var dataCount = condition.length;
  4696. if (!this.IsNumber(dataCount) || dataCount <= 0) return result;
  4697. if (Array.isArray(n))
  4698. {
  4699. for(var i=0;i<dataCount;++i) //初始化0
  4700. {
  4701. result[i]=0;
  4702. }
  4703. for(var i=0;i<dataCount;++i)
  4704. {
  4705. var value=condition[i];
  4706. var period=n[i];
  4707. if (this.IsNumber(value) && value && this.IsNumber(period))
  4708. {
  4709. for(var j=i,k=0; j>=0 && k<period; --j,++k)
  4710. {
  4711. result[j]=1;
  4712. }
  4713. }
  4714. }
  4715. }
  4716. else
  4717. {
  4718. for (var i = 0; i < dataCount; ++i) //初始化0
  4719. {
  4720. result[i] = 0;
  4721. }
  4722. for (var pos = 0; pos < dataCount; ++pos)
  4723. {
  4724. if (this.IsNumber(condition[pos])) break;
  4725. }
  4726. if (pos == dataCount) return result;
  4727. var num = Math.min(dataCount - pos, Math.max(n, 1));
  4728. for (var i = dataCount - 1, j = 0; i >= 0; --i)
  4729. {
  4730. var value = condition[i];
  4731. if (this.IsNumber(value) && value)
  4732. {
  4733. for (j = i; j > i - num; --j)
  4734. {
  4735. result[j] = 1;
  4736. }
  4737. }
  4738. }
  4739. if (condition[i])
  4740. {
  4741. for (j = i; j >= pos; --j) result[j] = 1;
  4742. }
  4743. }
  4744. return result;
  4745. }
  4746. //STRCAT(A,B):将两个字符串A,B(非序列化)相加成一个字符串C.
  4747. //用法: STRCAT('多头','开仓')将两个字符串'多头','开仓'相加成一个字符串'多头开仓'
  4748. this.STRCAT = function (str1, str2)
  4749. {
  4750. var result=[];
  4751. if (this.IsString(str1) && this.IsString(str2))
  4752. result=str1+str2;
  4753. return result;
  4754. }
  4755. //VARCAT(A,B):将两个字符串A,B相加成一个字符串C.
  4756. //用法: DRAWTEXT(CLOSE>OPEN,LOW,VARCAT('多头',VAR2STR(C,2))) 将两个字符串相加成一个字符串并按条件显示出来
  4757. this.VARCAT=function(data,data2)
  4758. {
  4759. var result=[];
  4760. if (Array.isArray(data) && Array.isArray(data2))
  4761. {
  4762. var nCount=Math.max(data.length, data2.length);
  4763. var strValue="";
  4764. for(var i=0;i<nCount;++i)
  4765. {
  4766. result[i]=null;
  4767. strValue="";
  4768. if (i<data.length)
  4769. {
  4770. var item=data[i];
  4771. if (this.IsString(item))
  4772. strValue+=item;
  4773. }
  4774. if (i<data2.length)
  4775. {
  4776. var item=data2[i];
  4777. if (this.IsString(item))
  4778. strValue+=item;
  4779. }
  4780. if (strValue!="")
  4781. result[i]=strValue;
  4782. }
  4783. }
  4784. else if (this.IsString(data) && Array.isArray(data2))
  4785. {
  4786. for(var i=0;i<data2.length;++i)
  4787. {
  4788. result[i]=null;
  4789. var item=data2[i];
  4790. if (this.IsString(item))
  4791. {
  4792. result[i]=data+item;
  4793. }
  4794. }
  4795. }
  4796. else if (Array.isArray(data) && this.IsString(data2))
  4797. {
  4798. for(var i=0;i<data.length;++i)
  4799. {
  4800. result[i]=null;
  4801. var item=data[i];
  4802. if (this.IsString(item))
  4803. {
  4804. result[i]=item+data2;
  4805. }
  4806. }
  4807. }
  4808. else if (this.IsString(data) && this.IsString(data2))
  4809. {
  4810. result=data+data2;
  4811. }
  4812. return result;
  4813. }
  4814. //STRSPACE(A):字符串附带一空格
  4815. this.STRSPACE=function(data)
  4816. {
  4817. var result=[];
  4818. if (Array.isArray(data))
  4819. {
  4820. for(var i=0;i<data.length;++i)
  4821. {
  4822. result[i]=null;
  4823. var item=data[i];
  4824. if (TouchList.IsString(item))
  4825. result[i]=item+' ';
  4826. }
  4827. }
  4828. else
  4829. {
  4830. if (this.IsString(data))
  4831. result=data+" ";
  4832. }
  4833. return result;
  4834. }
  4835. //CON2STR(A,N):取A最后的值(非序列值)转为字符串,小数位数N.
  4836. //用法: CON2STR(FINANCE(20),3)表示取营业收入,以3位小数转为字符串
  4837. this.CON2STR = function (data, n)
  4838. {
  4839. var result = [];
  4840. if (Array.isArray(data))
  4841. {
  4842. for (var i = data.length - 1; i >= 0; --i)
  4843. {
  4844. var item = data[i];
  4845. if (this.IsNumber(item))
  4846. {
  4847. result = item.toFixed(n);
  4848. return result;
  4849. }
  4850. }
  4851. }
  4852. else
  4853. {
  4854. if (this.IsNumber(data))
  4855. result = data.toFixed(n);
  4856. }
  4857. return result;
  4858. }
  4859. //VAR2STR(A,N):取A的每一个值转为字符串,小数位数N.
  4860. //用法: VAR2STR(C,3)表示取收盘价,以3位小数转为字符串
  4861. this.VAR2STR=function(data,n)
  4862. {
  4863. var result=[];
  4864. if (Array.isArray(data))
  4865. {
  4866. for(var i=0;i<data.length;++i)
  4867. {
  4868. result[i]=null;
  4869. var item=data[i];
  4870. if (this.IsNumber(item))
  4871. result[i]=item.toFixed(n);
  4872. }
  4873. }
  4874. else
  4875. {
  4876. if (this.IsNumber(data))
  4877. result=data.toFixed(n);
  4878. }
  4879. return result;
  4880. }
  4881. this.ZTPRICE = function (data, rate)
  4882. {
  4883. if (!this.IsNumber(rate)) return null;
  4884. if (Array.isArray(data))
  4885. {
  4886. var result = [];
  4887. for (var i in data)
  4888. {
  4889. var item = data[i];
  4890. if (this.IsNumber(item)) result[i] = (1 + rate) * item;
  4891. else result[i] = null;
  4892. }
  4893. return result;
  4894. }
  4895. else if (this.IsNumber(data))
  4896. {
  4897. var result = (1 + rate) * data;
  4898. return result;
  4899. }
  4900. }
  4901. this.DTPRICE = function (data, rate)
  4902. {
  4903. if (!this.IsNumber(rate)) return null;
  4904. if (Array.isArray(data))
  4905. {
  4906. var result = [];
  4907. for (var i in data)
  4908. {
  4909. var item = data[i];
  4910. if (this.IsNumber(item)) result[i] = (1 - rate) * item;
  4911. else result[i] = null;
  4912. }
  4913. return result;
  4914. }
  4915. else if (this.IsNumber(data))
  4916. {
  4917. var result = (1 - rate) * data;
  4918. return result;
  4919. }
  4920. }
  4921. /*
  4922. FRACPART(A) 取得小数部分
  4923. 含义:FRACPART(A)返回数值的小数部分
  4924. 阐释:例如FRACPART(12.3)求得0.3,FRACPART(-3.5)求得-0.5
  4925. */
  4926. this.FRACPART = function (data)
  4927. {
  4928. if (Array.isArray(data))
  4929. {
  4930. var result = [];
  4931. var integer = 0;
  4932. for (var i in data)
  4933. {
  4934. var item = data[i];
  4935. if (this.IsNumber(item))
  4936. {
  4937. integer = parseInt(item);
  4938. result[i] = item - integer;
  4939. }
  4940. else result[i] = null;
  4941. }
  4942. return result;
  4943. }
  4944. else if (this.IsNumber(data))
  4945. {
  4946. integer = parseInt(data);
  4947. var result = data - integer;
  4948. return result;
  4949. }
  4950. }
  4951. /*
  4952. 统计连续满足条件的周期数.
  4953. 用法: BARSLASTCOUNT(X),统计连续满足X条件的周期数.
  4954. 例如: BARSLASTCOUNT(CLOSE>OPEN)表示统计连续收阳的周期数
  4955. */
  4956. this.BARSLASTCOUNT=function(data)
  4957. {
  4958. var result=null;
  4959. if (Array.isArray(data))
  4960. {
  4961. result=[];
  4962. if (data.length>0)
  4963. {
  4964. var count=0;
  4965. for(var i=data.length-1;i>=0;--i)
  4966. {
  4967. count=0;
  4968. for(var j=i;j>=0;--j)
  4969. {
  4970. if (data[j]) ++count;
  4971. else break;
  4972. }
  4973. result[i]=count;
  4974. }
  4975. }
  4976. }
  4977. else
  4978. {
  4979. if (data) result=1;
  4980. else result=0;
  4981. }
  4982. return result;
  4983. }
  4984. //取整.
  4985. //用法: INTPART(A)返回沿A绝对值减小方向最接近的整数
  4986. //例如:INTPART(12.3)求得12,INTPART(-3.5)求得-3
  4987. this.INTPART=function(data)
  4988. {
  4989. var result=null;
  4990. if (Array.isArray(data))
  4991. {
  4992. result=[];
  4993. for(var i in data)
  4994. {
  4995. var item=data[i];
  4996. if (this.IsNumber(item)) result[i]=parseInt(item);
  4997. else result[i]=null;
  4998. }
  4999. }
  5000. else if (this.IsNumber(data))
  5001. {
  5002. result=parseInt(data);
  5003. }
  5004. return result;
  5005. }
  5006. //函数调用
  5007. this.CallFunction=function(name,args,node)
  5008. {
  5009. switch(name)
  5010. {
  5011. case 'MAX':
  5012. return this.MAX(args[0], args[1]);
  5013. case 'MIN':
  5014. return this.MIN(args[0], args[1]);
  5015. case 'REF':
  5016. return this.REF(args[0], args[1]);
  5017. case "REFV":
  5018. return this.REFV(args[0], args[1]);
  5019. case 'REFX':
  5020. return this.REFX(args[0], args[1]);
  5021. case "REFXV":
  5022. return this.REFXV(args[0], args[1]);
  5023. case 'ABS':
  5024. return this.ABS(args[0]);
  5025. case 'MA':
  5026. return this.MA(args[0], args[1]);
  5027. case "EMA":
  5028. return this.EMA(args[0], args[1]);
  5029. case "SMA":
  5030. return this.SMA(args[0], args[1],args[2]);
  5031. case "DMA":
  5032. return this.DMA(args[0], args[1]);
  5033. case "XMA":
  5034. return this.XMA(args[0], args[1]);
  5035. case 'EXPMA':
  5036. return this.EXPMA(args[0], args[1]);
  5037. case 'EXPMEMA':
  5038. return this.EXPMEMA(args[0], args[1]);
  5039. case 'COUNT':
  5040. return this.COUNT(args[0], args[1]);
  5041. case 'LLV':
  5042. return this.LLV(args[0], args[1]);
  5043. case 'LLVBARS':
  5044. return this.LLVBARS(args[0], args[1]);
  5045. case 'HHV':
  5046. return this.HHV(args[0], args[1]);
  5047. case 'HHVBARS':
  5048. return this.HHVBARS(args[0], args[1]);
  5049. case 'MULAR':
  5050. return this.MULAR(args[0], args[1]);
  5051. case 'CROSS':
  5052. return this.CROSS(args[0], args[1]);
  5053. case 'LONGCROSS':
  5054. return this.LONGCROSS(args[0], args[1], args[2]);
  5055. case 'AVEDEV':
  5056. return this.AVEDEV(args[0], args[1]);
  5057. case 'STD':
  5058. return this.STD(args[0], args[1]);
  5059. case 'IF':
  5060. case 'IFF':
  5061. return this.IF(args[0], args[1], args[2]);
  5062. case 'IFN':
  5063. return this.IFN(args[0], args[1], args[2]);
  5064. case 'NOT':
  5065. return this.NOT(args[0]);
  5066. case 'SUM':
  5067. return this.SUM(args[0], args[1]);
  5068. case 'RANGE':
  5069. return this.RANGE(args[0],args[1],args[2]);
  5070. case 'EXIST':
  5071. return this.EXIST(args[0],args[1]);
  5072. case 'EXISTR':
  5073. return this.EXISTR(args[0], args[1], args[2]);
  5074. case 'FILTER':
  5075. return this.FILTER(args[0], args[1]);
  5076. case 'TFILTER':
  5077. return this.TFILTER(args[0],args[1],args[2]);
  5078. case 'SLOPE':
  5079. return this.SLOPE(args[0],args[1]);
  5080. case 'BARSLAST':
  5081. return this.BARSLAST(args[0]);
  5082. case 'BARSCOUNT':
  5083. return this.BARSCOUNT(args[0]);
  5084. case 'BARSSINCEN':
  5085. return this.BARSSINCEN(args[0], args[1]);
  5086. case 'BARSSINCE':
  5087. return this.BARSSINCE(args[0]);
  5088. case 'LAST':
  5089. return this.LAST(args[0], args[1], args[2]);
  5090. case 'EVERY':
  5091. return this.EVERY(args[0], args[1]);
  5092. case 'ZIG':
  5093. return this.ZIG(args[0], args[1]);
  5094. case 'TROUGHBARS':
  5095. return this.TROUGHBARS(args[0], args[1], args[2]);
  5096. case "TROUGH":
  5097. return this.TROUGH(args[0],args[1],args[2]);
  5098. case 'PEAKBARS':
  5099. return this.PEAKBARS(args[0], args[1], args[2]);
  5100. case 'PEAK':
  5101. return this.PEAK(args[0],args[1],args[2]);
  5102. case 'COST':
  5103. return this.COST(args[0], node);
  5104. case 'WINNER':
  5105. return this.WINNER(args[0], node);
  5106. case 'UPNDAY':
  5107. return this.UPNDAY(args[0], args[1]);
  5108. case 'DOWNNDAY':
  5109. return this.DOWNNDAY(args[0], args[1]);
  5110. case 'NDAY':
  5111. return this.NDAY(args[0], args[1], args[2]);
  5112. case 'DEVSQ':
  5113. return this.DEVSQ(args[0], args[1]);
  5114. case 'FORCAST':
  5115. return this.FORCAST(args[0], args[1]);
  5116. case 'STDP':
  5117. return this.STDP(args[0], args[1]);
  5118. case 'VAR':
  5119. return this.VAR(args[0], args[1]);
  5120. case 'VARP':
  5121. return this.VARP(args[0], args[1]);
  5122. case 'RELATE':
  5123. return this.RELATE(args[0], args[1], args[2]);
  5124. case 'COVAR':
  5125. return this.COVAR(args[0], args[1], args[2]);
  5126. case 'BETA':
  5127. return this.BETA(args[0]);
  5128. case 'BETA2':
  5129. return this.BETA2(args[0], args[1], args[2]);
  5130. case 'WMA':
  5131. return this.WMA(args[0], args[1]);
  5132. case 'MEMA':
  5133. return this.MEMA(args[0], args[1]);
  5134. case 'SUMBARS':
  5135. return this.SUMBARS(args[0], args[1]);
  5136. case 'REVERSE':
  5137. return this.REVERSE(args[0]);
  5138. case 'SAR':
  5139. return this.SAR(args[0], args[1], args[2]);
  5140. case 'SARTURN':
  5141. return this.SARTURN(args[0], args[1], args[2]);
  5142. case 'BACKSET':
  5143. return this.BACKSET(args[0], args[1]);
  5144. case 'STRCAT':
  5145. return this.STRCAT(args[0], args[1]);
  5146. case "VARCAT":
  5147. return this.VARCAT(args[0], args[1]);
  5148. case "VAR2STR":
  5149. return this.VAR2STR(args[0], args[1]);
  5150. case 'CON2STR':
  5151. return this.CON2STR(args[0], args[1]);
  5152. case "STRSPACE":
  5153. return this.STRSPACE(args[0]);
  5154. case 'DTPRICE':
  5155. return this.DTPRICE(args[0], args[1]);
  5156. case 'ZTPRICE':
  5157. return this.ZTPRICE(args[0], args[1]);
  5158. case 'FRACPART':
  5159. return this.FRACPART(args[0]);
  5160. case 'BARSLASTCOUNT':
  5161. return this.BARSLASTCOUNT(args[0]);
  5162. case 'INTPART':
  5163. return this.INTPART(args[0]);
  5164. //三角函数
  5165. case 'ATAN':
  5166. return this.Trigonometric(args[0], Math.atan);
  5167. case 'ACOS':
  5168. return this.ACOS(args[0]);
  5169. case 'ASIN':
  5170. return this.ASIN(args[0]);
  5171. case 'COS':
  5172. return this.Trigonometric(args[0], Math.cos);
  5173. case 'SIN':
  5174. return this.Trigonometric(args[0], Math.sin);
  5175. case 'TAN':
  5176. return this.Trigonometric(args[0], Math.tan);
  5177. case 'LN':
  5178. return this.Trigonometric(args[0], Math.log);
  5179. case 'LOG':
  5180. return this.Trigonometric(args[0], Math.log10);
  5181. case 'EXP':
  5182. return this.Trigonometric(args[0], Math.exp);
  5183. case 'SQRT':
  5184. return this.Trigonometric(args[0], Math.sqrt);
  5185. default:
  5186. this.ThrowUnexpectedNode(node,'函数'+name+'不存在');
  5187. }
  5188. }
  5189. //调用自定义函数 返回数据格式{Out:输出数据, Draw:绘图数据(可选)}
  5190. this.CallCustomFunction=function(name, args, symbolData, node)
  5191. {
  5192. var functionInfo=g_JSComplierResource.CustomFunction.Data.get(name);
  5193. var dwonloadData=symbolData.GetStockCacheData({ CustomName:name, Node:node });
  5194. if (!functionInfo.Invoke)
  5195. return { Out: dwonloadData }
  5196. JSConsole.Complier.Log('[JSAlgorithm::CallCustomFunction] call custom function functionInfo=',functionInfo);
  5197. var self=this;
  5198. var obj=
  5199. {
  5200. Name:name,
  5201. Args:args,
  5202. Symbol:symbolData.Symbol, Period:symbolData.Period, Right:symbolData.Right,
  5203. KData:symbolData.Data, //K线数据
  5204. DownloadData:dwonloadData,
  5205. ThrowError:function(error)
  5206. {
  5207. self.ThrowUnexpectedNode(node, error);
  5208. }
  5209. };
  5210. return functionInfo.Invoke(obj);
  5211. }
  5212. this.ThrowUnexpectedNode=function(node,message)
  5213. {
  5214. let marker=node.Marker;
  5215. let msg=message || "执行异常";
  5216. return this.ErrorHandler.ThrowError(marker.Index,marker.Line,marker.Column,msg);
  5217. }
  5218. }
  5219. //是否有是有效的数字
  5220. JSAlgorithm.prototype.IsNumber=function(value)
  5221. {
  5222. if (value==null) return false;
  5223. if (isNaN(value)) return false;
  5224. return true;
  5225. }
  5226. //是否是整形
  5227. JSAlgorithm.prototype.IsInteger=function(x)
  5228. {
  5229. return (typeof x === 'number') && (x % 1 === 0);
  5230. }
  5231. //是否有是有效的除数
  5232. JSAlgorithm.prototype.IsDivideNumber=function(value)
  5233. {
  5234. if (value==null) return false;
  5235. if (isNaN(value)) return false;
  5236. if (value==0) return false;
  5237. return true;
  5238. }
  5239. //是否是字符串
  5240. JSAlgorithm.prototype.IsString=function(value)
  5241. {
  5242. if (value && typeof(value)=='string') return true;
  5243. return false;
  5244. }
  5245. /*
  5246. 绘图函数
  5247. */
  5248. function JSDraw(errorHandler, symbolData)
  5249. {
  5250. this.ErrorHandler=errorHandler;
  5251. this.SymbolData = symbolData;
  5252. this.DRAWTEXT=function(condition,price,text)
  5253. {
  5254. let drawData=[];
  5255. let result={DrawData:drawData, DrawType:'DRAWTEXT',Text:text};
  5256. if (Array.isArray(condition))
  5257. {
  5258. var IsNumber=this.IsNumber(price);
  5259. for(var i in condition)
  5260. {
  5261. drawData[i]=null;
  5262. if (isNaN(condition[i]) || !condition[i]) continue;
  5263. if (IsNumber)
  5264. {
  5265. drawData[i]=price;
  5266. }
  5267. else
  5268. {
  5269. if (this.IsNumber(price[i])) drawData[i]=price[i];
  5270. }
  5271. }
  5272. }
  5273. else if (this.IsNumber(condition) && condition)
  5274. {
  5275. var IsNumber=this.IsNumber(price);
  5276. for(var i=0;i<this.SymbolData.Data.Data.length;++i)
  5277. {
  5278. if (IsNumber) drawData[i]=price;
  5279. else if (this.IsNumber(price[i])) drawData[i]=price[i];
  5280. }
  5281. }
  5282. return result;
  5283. }
  5284. this.DRAWTEXT_FIX=function(condition,x,y,type,text)
  5285. {
  5286. let result={Position:null, DrawType:'DRAWTEXT_FIX',Text:text};
  5287. if (condition.length<=0) return result;
  5288. for(var i in condition)
  5289. {
  5290. if (isNaN(condition[i]) || !condition[i]) continue;
  5291. result.Position={X:x, Y:y, Type:type};
  5292. return result;
  5293. }
  5294. return result;
  5295. }
  5296. //direction 文字Y轴位置 0=middle 1=价格的顶部 2=价格的底部
  5297. //offset 文字Y轴偏移
  5298. this.SUPERDRAWTEXT = function (condition, price, text, direction, offset)
  5299. {
  5300. let drawData = [];
  5301. let result = { DrawData: drawData, DrawType: 'SUPERDRAWTEXT', Text: text, YOffset: offset, Direction: direction, TextAlign: 'center' };
  5302. if (condition.length <= 0) return result;
  5303. var IsNumber = typeof (price) == "number";
  5304. for (var i in condition)
  5305. {
  5306. drawData[i] = null;
  5307. if (isNaN(condition[i]) || !condition[i]) continue;
  5308. if (IsNumber)
  5309. {
  5310. drawData[i] = price;
  5311. }
  5312. else
  5313. {
  5314. if (this.IsNumber(price[i])) drawData[i] = price[i];
  5315. }
  5316. }
  5317. return result;
  5318. }
  5319. this.STICKLINE=function(condition,data,data2,width,type)
  5320. {
  5321. let drawData=[];
  5322. let result={DrawData:drawData, DrawType:'STICKLINE',Width:width, Type:type};
  5323. var IsNumber=typeof(data)=="number";
  5324. var IsNumber2=typeof(data2)=="number";
  5325. if (Array.isArray(condition)) //数组
  5326. {
  5327. if(condition.length<=0) return result;
  5328. for(var i in condition)
  5329. {
  5330. drawData[i]=null;
  5331. if (isNaN(condition[i]) || !condition[i]) continue;
  5332. if (IsNumber && IsNumber2)
  5333. {
  5334. drawData[i]={Value:data,Value2:data2};
  5335. }
  5336. else if (IsNumber && !IsNumber2)
  5337. {
  5338. if (isNaN(data2[i])) continue;
  5339. drawData[i]={Value:data,Value2:data2[i]};
  5340. }
  5341. else if (!IsNumber && IsNumber2)
  5342. {
  5343. if (isNaN(data[i])) continue;
  5344. drawData[i]={Value:data[i],Value2:data2};
  5345. }
  5346. else
  5347. {
  5348. if (isNaN(data[i]) || isNaN(data2[i])) continue;
  5349. drawData[i]={Value:data[i],Value2:data2[i]};
  5350. }
  5351. }
  5352. }
  5353. else
  5354. {
  5355. if(!condition) return result;
  5356. for(var i=0;i<this.SymbolData.Data.Data.length;++i) //以K线长度为数据长度
  5357. {
  5358. drawData[i]=null;
  5359. if (IsNumber && IsNumber2)
  5360. {
  5361. drawData[i]={Value:data,Value2:data2};
  5362. }
  5363. else if (IsNumber && !IsNumber2)
  5364. {
  5365. if (!this.IsNumber(data2[i])) continue;
  5366. drawData[i]={Value:data,Value2:data2[i]};
  5367. }
  5368. else if (!IsNumber && IsNumber2)
  5369. {
  5370. if (!this.IsNumber(data[i])) continue;
  5371. drawData[i]={Value:data[i],Value2:data2};
  5372. }
  5373. else
  5374. {
  5375. if (!this.IsNumber(data[i]) || !this.IsNumber(data2[i])) continue;
  5376. drawData[i]={Value:data[i],Value2:data2[i]};
  5377. }
  5378. }
  5379. }
  5380. return result;
  5381. }
  5382. /*
  5383. DRAWLINE 绘制直线段
  5384. 在图形上绘制直线段。
  5385. 用法: DRAWLINE(COND1,PRICE1,COND2,PRICE2,EXPAND)
  5386. 当COND1条件满足时,在PRICE1位置画直线起点,当COND2条件满足时,在PRICE2位置画直线终点,EXPAND为延长类型。
  5387. 例如: DRAWLINE(HIGH>=HHV(HIGH,20),HIGH,LOW<=LLV(LOW,20),LOW,1) 表示在创20天新高与创20天新低之间画直线并且向右延长。
  5388. */
  5389. this.DRAWLINE=function(condition,data,condition2,data2,expand)
  5390. {
  5391. let drawData=[];
  5392. let result={DrawData:drawData, DrawType:'DRAWLINE', Expand:expand};
  5393. if(condition.length<=0) return result;
  5394. let count=Math.max(condition.length,condition2.length);
  5395. let bFirstPoint=false;
  5396. let bSecondPont=false;
  5397. let lineCache={Start:{ },End:{ }, List:new Array()};
  5398. for(let i=0;i<count;++i)
  5399. {
  5400. drawData[i]=null;
  5401. if (i<condition.length && i<condition2.length)
  5402. {
  5403. if (bFirstPoint==false && bSecondPont==false)
  5404. {
  5405. if (condition[i]==null || !condition[i]) continue;
  5406. bFirstPoint=true;
  5407. lineCache.Start={ID:i, Value:data[i]}; //第1个点
  5408. }
  5409. else if (bFirstPoint==true && bSecondPont==false)
  5410. {
  5411. var bCondition2=(condition2[i]!=null && condition2[i]); //条件2
  5412. if (!bCondition2) continue;
  5413. if (bCondition2)
  5414. {
  5415. bSecondPont=true;
  5416. lineCache.End={ID:i, Value:data2[i]}; //第2个点
  5417. }
  5418. }
  5419. if (bFirstPoint==true && bSecondPont==true) //2个点都有了, 等待下一次的点出现
  5420. {
  5421. let lineData=this.CalculateDrawLine(lineCache); //计算2个点的线上 其他点的数值
  5422. for(let j in lineData)
  5423. {
  5424. let item=lineData[j];
  5425. drawData[item.ID]=item.Value;
  5426. }
  5427. bFirstPoint=bSecondPont=false;
  5428. lineCache={Start:{ },End:{ }};
  5429. }
  5430. }
  5431. }
  5432. if (expand==1) //右延长线
  5433. {
  5434. var x2=null;
  5435. for(var i=drawData.length-1;i>=0;--i)
  5436. {
  5437. if (this.IsNumber(drawData[i]))
  5438. {
  5439. x2=i;
  5440. break;
  5441. }
  5442. }
  5443. //y3=(y1-y2)*(x3-x1)/(x2-x1)
  5444. if (x2!=null && x2-1>=0)
  5445. {
  5446. var x1=x2-1;
  5447. for(var i=x2+1;i<drawData.length;++i)
  5448. {
  5449. var y1=drawData[x1];
  5450. var y2=drawData[x2];
  5451. var y3=(y1-y2)*(i-x1)/(x2-x1);
  5452. drawData[i]=y1-y3;
  5453. }
  5454. }
  5455. }
  5456. return result;
  5457. }
  5458. /*
  5459. 画出带状线.
  5460. 用法: DRAWBAND(VAL1,COLOR1,VAL2,COLOR2),当VAL1>VAL2时,在VAL1和VAL2之间填充COLOR1;当VAL1<VAL2时,填充COLOR2,这里的颜色均使用RGB函数计算得到.
  5461. 例如: DRAWBAND(OPEN,RGB(0,224,224),CLOSE,RGB(255,96,96));
  5462. */
  5463. this.DRAWBAND=function(data,color,data2,color2)
  5464. {
  5465. let drawData=[];
  5466. let result = { DrawData: drawData, DrawType: 'DRAWBAND', Color: [color.toLowerCase(), color2.toLowerCase()]};
  5467. let count=Math.max(data.length, data2.length);
  5468. for(let i=0;i<count;++i)
  5469. {
  5470. let item={Value:null, Value2:null};
  5471. if (i<data.length) item.Value=data[i];
  5472. if (i<data2.length) item.Value2=data2[i];
  5473. drawData.push(item);
  5474. }
  5475. return result;
  5476. }
  5477. this.DRAWKLINE = function (high, open, low, close)
  5478. {
  5479. let drawData = [];
  5480. let result = { DrawData: drawData, DrawType: 'DRAWKLINE' };
  5481. let count = Math.max(high.length, open.length, low.length, close.length);
  5482. for (let i = 0; i < count; ++i)
  5483. {
  5484. let item = { Open: null, High: null, Low: null, Close: null };
  5485. if (i < high.length && i < open.length && i < low.length && i < close.length)
  5486. {
  5487. item.Open = open[i];
  5488. item.High = high[i];
  5489. item.Low = low[i];
  5490. item.Close = close[i];
  5491. }
  5492. drawData[i] = item;
  5493. }
  5494. return result;
  5495. }
  5496. //满足条件画一根K线
  5497. this.DRAWKLINE_IF = function (condition, high, open, low, close)
  5498. {
  5499. let drawData = [];
  5500. let result = { DrawData: drawData, DrawType: 'DRAWKLINE_IF' };
  5501. let count = Math.max(condition.length, high.length, open.length, low.length, close.length);
  5502. for (let i = 0; i < count; ++i) {
  5503. let item = { Open: null, High: null, Low: null, Close: null };
  5504. if (i < high.length && i < open.length && i < low.length && i < close.length && i < condition.length)
  5505. {
  5506. if (condition[i])
  5507. {
  5508. item.Open = open[i];
  5509. item.High = high[i];
  5510. item.Low = low[i];
  5511. item.Close = close[i];
  5512. }
  5513. }
  5514. drawData[i] = item;
  5515. }
  5516. return result;
  5517. }
  5518. /*
  5519. PLOYLINE 折线段
  5520. 在图形上绘制折线段。
  5521. 用法: PLOYLINE(COND,PRICE),当COND条件满足时,以PRICE位置为顶点画折线连接。
  5522. 例如: PLOYLINE(HIGH>=HHV(HIGH,20),HIGH)表示在创20天新高点之间画折线。
  5523. */
  5524. this.POLYLINE = function (condition, data)
  5525. {
  5526. let drawData = [];
  5527. let result = { DrawData: drawData, DrawType: 'POLYLINE' };
  5528. let isNumber = typeof (data) == 'number';
  5529. let bFirstPoint = false;
  5530. let bSecondPont = false;
  5531. if (isNumber)
  5532. {
  5533. for (let i in condition)
  5534. {
  5535. drawData[i] = null;
  5536. if (bFirstPoint == false)
  5537. {
  5538. if (!condition[i]) continue;
  5539. drawData[i] = data;
  5540. bFirstPoint = true;
  5541. }
  5542. else {
  5543. drawData[i] = data;
  5544. }
  5545. }
  5546. }
  5547. else
  5548. {
  5549. let lineCache = { Start: {}, End: {}, List: new Array() };
  5550. for (let i in condition)
  5551. {
  5552. drawData[i] = null;
  5553. if (bFirstPoint == false && bSecondPont == false)
  5554. {
  5555. if (condition[i] == null || !condition[i]) continue;
  5556. if (i >= data.length || !this.IsNumber(data[i])) continue;
  5557. bFirstPoint = true;
  5558. lineCache.Start = { ID: parseInt(i), Value: data[i] }; //第1个点
  5559. }
  5560. else if (bFirstPoint == true && bSecondPont == false)
  5561. {
  5562. if (condition[i] == null || !condition[i]) continue;
  5563. if (i >= data.length || !this.IsNumber(data[i])) continue;
  5564. lineCache.End = { ID: parseInt(i), Value: data[i] }; //第2个点
  5565. //根据起始点和结束点 计算中间各个点的数据
  5566. let lineData = this.CalculateDrawLine(lineCache); //计算2个点的线上 其他点的数值
  5567. for (let j in lineData)
  5568. {
  5569. let item = lineData[j];
  5570. drawData[item.ID] = item.Value;
  5571. }
  5572. let start = { ID: lineCache.End.ID, Value: lineCache.End.Value };
  5573. lineCache = { Start: start, End: {} };
  5574. }
  5575. }
  5576. }
  5577. return result
  5578. }
  5579. /*
  5580. 画出数字.
  5581. 用法:
  5582. DRAWNUMBER(COND,PRICE,NUMBER),当COND条件满足时,在PRICE位置书写数字NUMBER.
  5583. 例如:
  5584. DRAWNUMBER(CLOSE/OPEN>1.08,LOW,C)表示当日实体阳线大于8%时在最低价位置显示收盘价.
  5585. */
  5586. this.DRAWNUMBER = function (condition, data, data2)
  5587. {
  5588. let drawData = { Value: new Array(), Text: new Array() };
  5589. let result = { DrawData: drawData, DrawType: 'DRAWNUMBER' };
  5590. var isArrayData=Array.isArray(data);
  5591. let isNumber = typeof (data2) == 'number';
  5592. let text;
  5593. if (isNumber)
  5594. {
  5595. if (this.IsInteger(data2)) text=data2.toString();
  5596. else text=data2.toFixed(2);
  5597. }
  5598. for (let i in condition)
  5599. {
  5600. drawData.Value[i] = null;
  5601. if (!condition[i]) continue;
  5602. if (isArrayData)
  5603. {
  5604. if (i >= data.length || !this.IsNumber(data[i])) continue;
  5605. if (isNumber)
  5606. {
  5607. drawData.Value[i] = data[i];
  5608. drawData.Text[i] = text;
  5609. }
  5610. else
  5611. {
  5612. if (i >= data2.length || !data2[i]) continue;
  5613. drawData.Value[i] = data[i];
  5614. if (typeof(data2[i])=='number')
  5615. drawData.Text[i] = data2[i].toFixed(2);
  5616. else
  5617. drawData.Text[i] = data2[i].toString();
  5618. }
  5619. }
  5620. else if (this.IsNumber(data))
  5621. {
  5622. if (isNumber)
  5623. {
  5624. drawData.Value[i]=data;
  5625. drawData.Text[i]=text;
  5626. }
  5627. else
  5628. {
  5629. if (i>=data2.length || !data2[i]) continue;
  5630. drawData.Value[i]=data;
  5631. if (this.IsNumber(data2[i]))
  5632. drawData.Text[i] = data2[i].toFixed(2);
  5633. else
  5634. drawData.Text[i] = data2[i].toString();
  5635. }
  5636. }
  5637. }
  5638. return result;
  5639. }
  5640. /*
  5641. 在图形上绘制小图标.
  5642. 用法:
  5643. DRAWICON(COND,PRICE,TYPE),当COND条件满足时,在PRICE位置画TYPE号图标(TYPE为1--41).
  5644. 例如:
  5645. DRAWICON(CLOSE>OPEN,LOW,1)表示当收阳时在最低价位置画1号图标.
  5646. */
  5647. this.DRAWICON = function (condition, data, type)
  5648. {
  5649. //图标对应的字符代码
  5650. let mapIcon = new Map([
  5651. [1, { Symbol: '⇧', Color: 'rgb(207, 38, 38)' }], [2, { Symbol: '⇩', Color: 'rgb(0, 112, 54)' }],
  5652. [3, { Symbol: '😧' }], [4, { Symbol: '😨' }], [5, { Symbol: '😁' }], [6, { Symbol: '😱' }],
  5653. [7, { Symbol: '◼', Color: 'rgb(238,44,44)' }], [8, { Symbol: '◆', Color: 'rgb(0,139,69)' }],
  5654. [9, { Symbol: '💰' }], [10, { Symbol: '📪' }], [11, { Symbol: '👆' }], [12, { Symbol: '👇' }],
  5655. [13, { Symbol: 'B', Color: 'rgb(178,34,34)' },], [14, { Symbol: 'S', Color: 'rgb(0,139,69)' }],
  5656. [36, { Symbol: 'Χ', Color: 'rgb(238,44,44)' }], [37, { Symbol: 'X', Color: 'rgb(0,139,69)' }],
  5657. [38, { Symbol: '▲', Color: 'rgb(238,44,44)' }], [39, { Symbol: '▼', Color: 'rgb(0,139,69)' }],
  5658. ]);
  5659. let icon = mapIcon.get(type);
  5660. if (!icon) icon = { Symbol: '●', Color: 'rgb(0,139,69)'};
  5661. let drawData = [];
  5662. let result = { DrawData: drawData, DrawType: 'DRAWICON', Icon: icon };
  5663. if (condition.length <= 0) return result;
  5664. var IsNumber = typeof (data) == "number";
  5665. if (typeof (condition) == 'number')
  5666. {
  5667. if (!condition) return result;
  5668. for (var i = 0; i < this.SymbolData.Data.Data.length; ++i)
  5669. {
  5670. if (IsNumber)
  5671. {
  5672. drawData[i] = data;
  5673. }
  5674. else
  5675. {
  5676. if (i < data.length && this.IsNumber(data[i])) drawData[i] = data[i];
  5677. else drawData[i] = null;
  5678. }
  5679. }
  5680. return result;
  5681. }
  5682. for (var i in condition)
  5683. {
  5684. drawData[i] = null;
  5685. if (!condition[i]) continue;
  5686. if (IsNumber)
  5687. {
  5688. drawData[i] = data;
  5689. }
  5690. else
  5691. {
  5692. if (this.IsNumber(data[i])) drawData[i] = data[i];
  5693. }
  5694. }
  5695. return result;
  5696. }
  5697. // 相对位置上画矩形.
  5698. //用法: DRAWRECTREL(LEFT,TOP,RIGHT,BOTTOM,COLOR),以图形窗口(LEFT,TOP)为左上角,(RIGHT,BOTTOM)为右下角绘制矩形,坐标单位是窗口沿水平和垂直方向的1/1000,取值范围是0—999,超出范围则可能显示在图形窗口外,矩形中间填充颜色COLOR,COLOR为0表示不填充.
  5699. //例如: DRAWRECTREL(0,0,500,500,RGB(255,255,0))表示在图形最左上部1/4位置用黄色绘制矩形
  5700. this.DRAWRECTREL = function (left, top, right, bottom, color)
  5701. {
  5702. let drawData =
  5703. {
  5704. Rect:
  5705. {
  5706. Left: Math.min(left,right), Top: Math.min(top,bottom),
  5707. Right: Math.max(left,right), Bottom: Math.max(top,bottom)
  5708. },
  5709. Color: color
  5710. };
  5711. if (color == 0) drawData.Color = null;
  5712. let result = { DrawData: drawData, DrawType: 'DRAWRECTREL' };
  5713. return result;
  5714. }
  5715. //填充背景.
  5716. //用法: DRAWGBK(COND,COLOR1,COLOR2,colorAngle) colorAngle=渐近色角度
  5717. //例如: DRAWGBK(O>C,RGB(0,255,0),RGB(255,0,0),0);
  5718. this.DRAWGBK=function(condition, color, color2, colorAngle)
  5719. {
  5720. let drawData={ Color:[], Angle:colorAngle };
  5721. if (color) drawData.Color.push(color);
  5722. if (color2) drawData.Color.push(color2);
  5723. let result={DrawData:null, DrawType:'DRAWGBK'};
  5724. if (Array.isArray(condition))
  5725. {
  5726. for(var i in condition)
  5727. {
  5728. var item=condition[i];
  5729. if (item)
  5730. {
  5731. result.DrawData=drawData;
  5732. break;
  5733. }
  5734. }
  5735. }
  5736. else
  5737. {
  5738. if (condition) result.DrawData=drawData;
  5739. }
  5740. return result;
  5741. }
  5742. this.DRAWGBK2=function(condition, color, color2, colorAngle)
  5743. {
  5744. let drawData={ Color:[], Angle:colorAngle };
  5745. if (color) drawData.Color.push(color);
  5746. if (color2) drawData.Color.push(color2);
  5747. let result={DrawData:null, DrawType:'DRAWGBK2'};
  5748. if (Array.isArray(condition))
  5749. {
  5750. drawData.Data=[];
  5751. for(var i in condition)
  5752. {
  5753. var item=condition[i];
  5754. drawData.Data[i]=item ? 1:0;
  5755. }
  5756. result.DrawData=drawData;
  5757. }
  5758. else
  5759. {
  5760. if (condition)
  5761. {
  5762. result.DrawData=drawData;
  5763. result.DrawType="DRAWGBK";
  5764. }
  5765. }
  5766. return result;
  5767. }
  5768. this.RGB = function (r, g, b)
  5769. {
  5770. var rgb = `rgb(${r},${g},${b})`;
  5771. return rgb;
  5772. }
  5773. this.RGBA = function (r, g, b, a)
  5774. {
  5775. var rgba = `rgba(${r},${g},${b},${a})`;
  5776. return rgba;
  5777. }
  5778. }
  5779. JSDraw.prototype.CalculateDrawLine=function(lineCache)
  5780. {
  5781. lineCache.List=[];
  5782. for(let i=lineCache.Start.ID; i<=lineCache.End.ID; ++i) lineCache.List.push(i);
  5783. let height=Math.abs(lineCache.Start.Value-lineCache.End.Value);
  5784. let width=lineCache.List.length-1;
  5785. var result=[];
  5786. result.push({ID:lineCache.Start.ID, Value:lineCache.Start.Value}); //第1个点
  5787. if (lineCache.Start.Value>lineCache.End.Value)
  5788. {
  5789. for(let i=1;i<lineCache.List.length-1;++i)
  5790. {
  5791. var value=height*(lineCache.List.length-1-i)/width+lineCache.End.Value;
  5792. result.push({ID:lineCache.List[i], Value:value});
  5793. }
  5794. }
  5795. else
  5796. {
  5797. for(let i=1;i<lineCache.List.length-1;++i)
  5798. {
  5799. var value=height*i/width+lineCache.Start.Value;
  5800. result.push({ID:lineCache.List[i], Value:value});
  5801. }
  5802. }
  5803. result.push({ID:lineCache.End.ID, Value:lineCache.End.Value}); //最后一个点
  5804. return result;
  5805. }
  5806. //是否有是有效的数字
  5807. JSDraw.prototype.IsNumber = function (value)
  5808. {
  5809. if (value == null) return false;
  5810. if (isNaN(value)) return false;
  5811. return true;
  5812. }
  5813. //是否是整形
  5814. JSDraw.prototype.IsInteger=function(x)
  5815. {
  5816. return (typeof x === 'number') && (x % 1 === 0);
  5817. }
  5818. JSDraw.prototype.IsDrawFunction=function(name)
  5819. {
  5820. let setFunctionName = new Set(["STICKLINE", "DRAWTEXT", 'SUPERDRAWTEXT', "DRAWTEXT_FIX", 'DRAWLINE', 'DRAWBAND', 'DRAWKLINE', 'DRAWKLINE_IF', 'PLOYLINE', 'POLYLINE', 'DRAWNUMBER', 'DRAWICON','DRAWRECTREL', "DRAWGBK", "DRAWGBK2"]);
  5821. if (setFunctionName.has(name)) return true;
  5822. return false;
  5823. }
  5824. //http://www.newone.com.cn/helpcontroller/index?code=zszy_pc
  5825. var DYNAINFO_ARGUMENT_ID=
  5826. {
  5827. YCLOSE:3,
  5828. OPEN:4,
  5829. HIGH:5,
  5830. LOW:6,
  5831. CLOSE: 7,
  5832. VOL: 8,
  5833. AMOUNT: 10,
  5834. AMPLITUDE:13, //振幅
  5835. INCREASE:14, //涨幅
  5836. EXCHANGERATE:37, //换手率
  5837. };
  5838. function JSSymbolData(ast,option,jsExecute)
  5839. {
  5840. this.AST=ast; //语法树
  5841. this.Execute=jsExecute;
  5842. this.Symbol='600000.sh';
  5843. this.Name;
  5844. this.Data=null; //个股数据
  5845. this.SourceData = null; //不复权的个股数据
  5846. this.MarketValue = null; //总市值
  5847. this.Period=0; //周期
  5848. this.Right=0; //复权
  5849. this.DataType = 0; //默认K线数据 2=分钟走势图数据
  5850. this.KLineApiUrl = g_JSComplierResource.Domain+"/API/KLine2"; //日线
  5851. this.MinuteKLineApiUrl = g_JSComplierResource.Domain +'/API/KLine3'; //分钟K线
  5852. this.RealtimeApiUrl = g_JSComplierResource.Domain +'/API/stock'; //实时行情
  5853. this.StockHistoryDayApiUrl = g_JSComplierResource.Domain +'/API/StockHistoryDay'; //历史财务数据
  5854. this.StockHistoryDay3ApiUrl = g_JSComplierResource.Domain +'/API/StockHistoryDay3'; //历史财务数据
  5855. this.StockNewsAnalysisApiUrl = g_JSComplierResource.CacheDomain+'/cache/newsanalyze'; //新闻分析数据
  5856. this.MaxReqeustDataCount=1000;
  5857. this.MaxRequestMinuteDayCount=5;
  5858. this.LatestData=new Map(); //最新行情
  5859. this.IndexData; //大盘指数
  5860. this.MarginData = new Map(); //融资融券
  5861. this.NewsAnalysisData = new Map(); //新闻统计
  5862. this.ExtendData = new Map(); //其他的扩展数据
  5863. //股票数据缓存 key=函数名(参数) { Data: value=拟合的数据 , Error: }
  5864. //FinValue(id)
  5865. this.StockData=new Map();
  5866. this.NetworkFilter; //网络请求回调 function(data, callback);
  5867. //使用option初始化
  5868. if (option)
  5869. {
  5870. if (option.HQDataType) this.DataType = option.HQDataType;
  5871. if (option.Data)
  5872. {
  5873. this.Data=option.Data;
  5874. if (this.DataType != 2) //2=分钟走势图数据 没有周期和复权
  5875. {
  5876. this.Period=option.Data.Period; //周期
  5877. this.Right=option.Data.Right; //复权
  5878. }
  5879. //this.Data=null;
  5880. }
  5881. if (option.SourceData) this.SourceData = option.SourceData;
  5882. if (option.Symbol) this.Symbol=option.Symbol;
  5883. if (option.Symbol) this.Symbol = option.Symbol;
  5884. if (option.MaxReqeustDataCount>0) this.MaxReqeustDataCount=option.MaxReqeustDataCount;
  5885. if (option.MaxRequestMinuteDayCount>0) this.MaxRequestMinuteDayCount=option.MaxRequestMinuteDayCount;
  5886. if (option.KLineApiUrl) this.KLineApiUrl=option.KLineApiUrl;
  5887. if (option.NetworkFilter) this.NetworkFilter = option.NetworkFilter;
  5888. }
  5889. this.GetLatestDataKey=function(key)
  5890. {
  5891. var key=`DYNAINFO-${key}`;
  5892. return key;
  5893. }
  5894. //最新行情
  5895. this.GetLatestData=function(jobItem)
  5896. {
  5897. var aryArgs=this.JobArgumentsToArray(jobItem, 1);
  5898. var lID=aryArgs[0];
  5899. var key=this.GetLatestDataKey(lID);
  5900. if (this.LatestData.has(key)) return this.Execute.RunNextJob();
  5901. var self=this;
  5902. wx.request({
  5903. url: self.RealtimeApiUrl,
  5904. data:
  5905. {
  5906. "field": ["name","symbol","yclose","open","price","high","low","vol","amount","date","time","increase","exchangerate","amplitude"],
  5907. "symbol": [this.Symbol]
  5908. },
  5909. method:"POST",
  5910. dataType: "json",
  5911. success: function (recvData)
  5912. {
  5913. self.RecvLatestData(recvData);
  5914. self.Execute.RunNextJob();
  5915. },
  5916. error: function(request)
  5917. {
  5918. self.RecvError(request);
  5919. }
  5920. });
  5921. }
  5922. this.RecvLatestData = function (recvData)
  5923. {
  5924. let data=recvData.data;
  5925. if (data.ver==2.0)
  5926. {
  5927. this.RecvLatestDataVer2(data);
  5928. return;
  5929. }
  5930. if (!data.stock || data.stock.length!=1) return;
  5931. let stock=data.stock[0];
  5932. if (!stock) return;
  5933. if (IFrameSplitOperator.IsNumber(stock.yclose)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.YCLOSE,stock.yclose);
  5934. if (IFrameSplitOperator.IsNumber(stock.open)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.OPEN,stock.open);
  5935. if (IFrameSplitOperator.IsNumber(stock.high)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.HIGH,stock.high);
  5936. if (IFrameSplitOperator.IsNumber(stock.low)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.LOW,stock.low);
  5937. if (IFrameSplitOperator.IsNumber(stock.price)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.CLOSE,stock.price);
  5938. if (IFrameSplitOperator.IsNumber(stock.vol)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.VOL,stock.vol);
  5939. if (IFrameSplitOperator.IsNumber(stock.amount)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.AMOUNT,stock.amount);
  5940. if (IFrameSplitOperator.IsNumber(stock.increase)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.INCREASE,stock.increase);
  5941. if (IFrameSplitOperator.IsNumber(stock.exchangerate)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.EXCHANGERATE,stock.exchangerate);
  5942. if (IFrameSplitOperator.IsNumber(stock.amplitude)) this.LatestData.set(DYNAINFO_ARGUMENT_ID.AMPLITUDE,stock.amplitude);
  5943. /*
  5944. this.LatestData={ Symbol:stock.symbol, Name:stock.name, Date:stock.date, Time:stock.time,
  5945. YClose:stock.yclose,Price:stock.price, Open:stock.open, High:stock.high, Low:stock.low, Vol:stock.vol, Amount:stock.amount,
  5946. Increase:stock.increase, Exchangerate:stock.exchangerate, Amplitude:stock.amplitude};
  5947. */
  5948. JSConsole.Complier.Log('[JSSymbolData::RecvLatestData] symbol, LatestData', stock.symbol, this.LatestData);
  5949. }
  5950. //data:[{ id:, value: }]
  5951. this.RecvLatestDataVer2=function(recvData)
  5952. {
  5953. let data=recvData.data;
  5954. if (!IFrameSplitOperator.IsNonEmptyArray(data.data)) return;
  5955. var symbol=data.symbol;
  5956. for(var i=0;i<data.data.length;++i)
  5957. {
  5958. var item=data.data[i];
  5959. if (!item) continue;
  5960. if (!IFrameSplitOperator.IsNumber(item.id)) continue;
  5961. if (IFrameSplitOperator.IsNumber(item.value) || IFrameSplitOperator.IsString(item.value))
  5962. {
  5963. JSConsole.Complier.Log(`[JSSymbolData::RecvLatestDataVer2] symbol=${symbol} DYNAINFO(${item.id})=${item.value}.`);
  5964. this.LatestData.set(item.id, item.value);
  5965. }
  5966. }
  5967. JSConsole.Complier.Log('[JSSymbolData::RecvLatestDataVer2]', this.LatestData);
  5968. }
  5969. this.GetLatestCacheData=function(dataname)
  5970. {
  5971. if (this.LatestData && this.LatestData.has(dataname)) return this.LatestData.get(dataname);
  5972. return null;
  5973. }
  5974. this.GetVolRateData = function (job, node) {
  5975. var volrKey = job.ID.toString() + '-VolRate-' + this.Symbol;
  5976. if (this.ExtendData.has(volrKey)) return this.Execute.RunNextJob();
  5977. var self = this;
  5978. wx.request({
  5979. url: self.RealtimeApiUrl,
  5980. data:
  5981. {
  5982. "field": ["name", "symbol", "avgvol5", 'date'],
  5983. "symbol": [this.Symbol]
  5984. },
  5985. method: "POST",
  5986. dataType: "json",
  5987. async: true,
  5988. success: function (recvData)
  5989. {
  5990. self.RecvVolRateData(recvData, volrKey);
  5991. self.Execute.RunNextJob();
  5992. },
  5993. error: function (request)
  5994. {
  5995. self.RecvError(request);
  5996. }
  5997. });
  5998. }
  5999. this.RecvVolRateData = function (recvData, key)
  6000. {
  6001. var data=recvData.data;
  6002. if (!data.stock || data.stock.length != 1) return;
  6003. var avgVol5 = data.stock[0].avgvol5;
  6004. var date = data.stock[0].date;
  6005. var item = { AvgVol5: avgVol5, Date: date };
  6006. this.ExtendData.set(key, item);
  6007. JSConsole.Complier.Log('[JSSymbolData::RecvVolRateData]', item);
  6008. }
  6009. this.GetVolRateCacheData = function (node)
  6010. {
  6011. var key = JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_VOLR_DATA.toString() + '-VolRate-' + this.Symbol;
  6012. if (!key || !this.ExtendData.has(key)) this.Execute.ThrowUnexpectedNode(node, '不支持VOLR');
  6013. var result = [];
  6014. var value = this.ExtendData.get(key);
  6015. var avgVol5 = value.AvgVol5 / 241;
  6016. var totalVol = 0;
  6017. //5日成交总量只取了最新一天的,历史的暂时没有取,所以数据计算的时候只计算最新的一天, 其他都空
  6018. for (var i = 0, j = 0; i < this.Data.Data.length; ++i)
  6019. {
  6020. result[i] = null;
  6021. var item = this.Data.Data[i];
  6022. var dateTime = item.DateTime; //日期加时间
  6023. if (!dateTime) continue;
  6024. var aryValue = dateTime.split(' ');
  6025. if (aryValue.length != 2) continue;
  6026. var date = parseInt(aryValue[0]);
  6027. if (date != value.Date) continue;
  6028. totalVol += item.Vol;
  6029. if (avgVol5 > 0) result[i] = totalVol / (j + 1) / avgVol5 * 100;
  6030. ++j;
  6031. }
  6032. return result;
  6033. }
  6034. //获取大盘指数数据
  6035. this.GetIndexData=function()
  6036. {
  6037. if (this.IndexData) return this.Execute.RunNextJob();
  6038. var self=this;
  6039. if (JSCommonData.ChartData.IsDayPeriod(this.Period,true)) //请求日线数据
  6040. {
  6041. wx.request({
  6042. url: self.KLineApiUrl,
  6043. data:
  6044. {
  6045. "field": ["name", "symbol", "yclose", "open", "price", "high", "low", "vol", 'up', 'down', 'stop', 'unchanged'],
  6046. "symbol": '000001.sh',
  6047. "start": -1,
  6048. "count": self.MaxReqeustDataCount+500 //多请求2年的数据 确保股票剔除停牌日期以后可以对上
  6049. },
  6050. method: 'POST',
  6051. dataType: "json",
  6052. success: function (recvData)
  6053. {
  6054. self.RecvIndexHistroyData(recvData);
  6055. self.Execute.RunNextJob();
  6056. },
  6057. error: function(request)
  6058. {
  6059. self.RecvError(request);
  6060. }
  6061. });
  6062. }
  6063. else if (JSCommonData.ChartData.IsMinutePeriod(this.Period, true)) //请求分钟数据
  6064. {
  6065. wx.request({
  6066. url: self.MinuteKLineApiUrl,
  6067. data:
  6068. {
  6069. "field": ["name","symbol","yclose","open","price","high","low","vol"],
  6070. "symbol": '000001.sh',
  6071. "start": -1,
  6072. "count": self.MaxRequestMinuteDayCount+5
  6073. },
  6074. method: 'POST',
  6075. dataType: "json",
  6076. success: function (data)
  6077. {
  6078. self.RecvIndexMinuteHistroyData(data);
  6079. self.Execute.RunNextJob();
  6080. },
  6081. error: function(request)
  6082. {
  6083. self.RecvError(request);
  6084. }
  6085. });
  6086. }
  6087. }
  6088. this.RecvIndexHistroyData=function(recvData)
  6089. {
  6090. let data = recvData.data;
  6091. JSConsole.Complier.Log('[JSSymbolData::RecvIndexHistroyData] recv data' , data);
  6092. let hisData=this.JsonDataToHistoryData(data);
  6093. this.IndexData = new JSCommonData.ChartData();
  6094. this.IndexData.DataType=0; /*日线数据 */
  6095. this.IndexData.Data=hisData;
  6096. var aryOverlayData = this.SourceData.GetOverlayData(this.IndexData.Data); //和主图数据拟合以后的数据
  6097. this.IndexData.Data=aryOverlayData;
  6098. if (JSCommonData.ChartData.IsDayPeriod(this.Period, false)) //周期数据
  6099. {
  6100. let periodData=this.IndexData.GetPeriodData(this.Period);
  6101. this.IndexData.Data=periodData;
  6102. }
  6103. }
  6104. this.RecvIndexMinuteHistroyData = function (recvData)
  6105. {
  6106. let data = recvData.data;
  6107. JSConsole.Complier.Log('[JSSymbolData::RecvIndexMinuteHistroyData] recv data' , data);
  6108. let hisData=this.JsonDataToMinuteHistoryData(data);
  6109. this.IndexData = new JSCommonData.ChartData();
  6110. this.IndexData.DataType=1; /*分钟线数据 */
  6111. this.IndexData.Data=hisData;
  6112. if (JSCommonData.ChartData.IsMinutePeriod(this.Period, false)) //周期数据
  6113. {
  6114. let periodData=this.IndexData.GetPeriodData(this.Period);
  6115. this.IndexData.Data=periodData;
  6116. }
  6117. }
  6118. //获取大盘指数缓存数据
  6119. this.GetIndexCacheData=function(dataName)
  6120. {
  6121. if (!this.IndexData) return new Array();
  6122. switch(dataName)
  6123. {
  6124. case 'INDEXA':
  6125. return this.IndexData.GetAmount();
  6126. case 'INDEXC':
  6127. return this.IndexData.GetClose();
  6128. case 'INDEXH':
  6129. return this.IndexData.GetHigh();
  6130. case 'INDEXL':
  6131. return this.IndexData.GetLow();
  6132. case 'INDEXO':
  6133. return this.IndexData.GetOpen();
  6134. case 'INDEXV':
  6135. return this.IndexData.GetVol();
  6136. case 'INDEXADV':
  6137. return this.IndexData.GetUp();
  6138. case 'INDEXDEC':
  6139. return this.IndexData.GetDown();
  6140. }
  6141. }
  6142. //分钟涨幅股票个数统计数据下载
  6143. this.GetIndexIncreaseData = function (job)
  6144. {
  6145. var upKey = job.ID.toString() + '-UpCount-' + job.Symbol;
  6146. var downKey = job.ID.toString() + '-DownCount-' + job.Symbol;
  6147. if (this.ExtendData.has(upKey) && this.ExtendData.has(downKey)) return this.Execute.RunNextJob();
  6148. var symbol = job.Symbol;
  6149. symbol = symbol.replace('.CI', '.ci');
  6150. var self = this;
  6151. var apiUrl = g_JSComplierResource.CacheDomain + '/cache/analyze/increaseanalyze/' + symbol + '.json';
  6152. JSConsole.Complier.Log('[JSSymbolData::GetIndexIncreaseData] Get url=', apiUrl);
  6153. wx.request({
  6154. url: apiUrl,
  6155. method: "GET",
  6156. dataType: "json",
  6157. success: function (data)
  6158. {
  6159. self.RecvMinuteIncreaseData(data, { UpKey: upKey, DownKey: downKey });
  6160. self.Execute.RunNextJob();
  6161. },
  6162. error: function (request)
  6163. {
  6164. self.RecvError(request);
  6165. }
  6166. });
  6167. }
  6168. this.RecvMinuteIncreaseData = function (recvData, key)
  6169. {
  6170. JSConsole.Complier.Log('[JSSymbolData::RecvMinuteIncreaseData] recv data', recvData);
  6171. var data=recvData.data;
  6172. if (!data.minute) return;
  6173. var minuteData = data.minute;
  6174. if (!minuteData.time || !minuteData.up || !minuteData.down) return;
  6175. var upData = [], downData = [];
  6176. for (var i = 0; i < minuteData.time.length; ++i) {
  6177. upData[i] = minuteData.up[i];
  6178. downData[i] = minuteData.down[i];
  6179. }
  6180. this.ExtendData.set(key.UpKey, upData);
  6181. this.ExtendData.set(key.DownKey, downData);
  6182. }
  6183. //分钟涨幅股票个数统计数据
  6184. this.GetIndexIncreaseCacheData = function (funcName, symbol, node) {
  6185. var key;
  6186. if (funcName == 'UPCOUNT') key = JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_INDEX_INCREASE_DATA.toString() + '-UpCount-' + symbol;
  6187. else if (funcName == 'DOWNCOUNT') key = JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_INDEX_INCREASE_DATA.toString() + '-DownCount-' + symbol;
  6188. if (!key || !this.ExtendData.has(key)) this.Execute.ThrowUnexpectedNode(node, '不支持函数' + funcName + '(' + symbol + ')');
  6189. return this.ExtendData.get(key);
  6190. }
  6191. this.GetSymbolData=function()
  6192. {
  6193. if (this.Data) return this.Execute.RunNextJob();
  6194. let self=this;
  6195. if (this.DataType === 2) //当天分钟数据
  6196. {
  6197. wx.request({
  6198. url: self.RealtimeApiUrl,
  6199. data:
  6200. {
  6201. "field": ["name", "symbol", "yclose", "open", "price", "high", "low", "vol", "amount", "date", "minute", "time", "minutecount"],
  6202. "symbol": [self.Symbol],
  6203. "start": -1
  6204. },
  6205. method: 'POST',
  6206. dataType: "json",
  6207. async: true,
  6208. success: function (recvData) {
  6209. self.RecvMinuteData(recvData);
  6210. self.Execute.RunNextJob();
  6211. }
  6212. });
  6213. return;
  6214. }
  6215. if (JSCommonData.ChartData.IsDayPeriod(this.Period,true)) //请求日线数据
  6216. {
  6217. wx.request({
  6218. url: self.KLineApiUrl,
  6219. data:
  6220. {
  6221. "field": [ "name", "symbol","yclose","open","price","high","low","vol"],
  6222. "symbol": self.Symbol,
  6223. "start": -1,
  6224. "count": self.MaxReqeustDataCount
  6225. },
  6226. method: 'POST',
  6227. dataType: "json",
  6228. async:true,
  6229. success: function (recvData)
  6230. {
  6231. self.RecvHistroyData(recvData);
  6232. self.Execute.RunNextJob();
  6233. },
  6234. error: function(request)
  6235. {
  6236. self.RecvError(request);
  6237. }
  6238. });
  6239. }
  6240. else if (JSCommonData.ChartData.IsMinutePeriod(this.Period, true)) //请求分钟数据
  6241. {
  6242. wx.request({
  6243. url: this.MinuteKLineApiUrl,
  6244. data:
  6245. {
  6246. "field": ["name","symbol","yclose","open","price","high","low","vol"],
  6247. "symbol": self.Symbol,
  6248. "start": -1,
  6249. "count": self.MaxRequestMinuteDayCount
  6250. },
  6251. method: 'POST',
  6252. dataType: "json",
  6253. async:true,
  6254. success: function (data)
  6255. {
  6256. self.RecvMinuteHistroyData(data);
  6257. self.Execute.RunNextJob();
  6258. },
  6259. error: function(request)
  6260. {
  6261. self.RecvError(request);
  6262. }
  6263. });
  6264. }
  6265. }
  6266. this.RecvHistroyData=function(recvData)
  6267. {
  6268. let data=recvData.data;
  6269. JSConsole.Complier.Log('[JSSymbolData::RecvHistroyData] recv data' , data);
  6270. let hisData=this.JsonDataToHistoryData(data);
  6271. this.Data=new JSCommonData.ChartData();
  6272. this.Data.DataType=0; /*日线数据 */
  6273. this.Data.Data=hisData;
  6274. this.SourceData = new JSCommonData.ChartData;
  6275. this.SourceData.Data = hisData;
  6276. if (this.Right>0) //复权
  6277. {
  6278. let rightData=this.Data.GetRightDate(this.Right);
  6279. this.Data.Data=rightData;
  6280. }
  6281. if (JSCommonData.ChartData.IsDayPeriod(this.Period, false)) //周期数据
  6282. {
  6283. let periodData=this.Data.GetPeriodData(this.Period);
  6284. this.Data.Data=periodData;
  6285. }
  6286. this.Name = data.name;
  6287. }
  6288. this.RecvMinuteHistroyData = function (recvData)
  6289. {
  6290. let data = recvData.data;
  6291. JSConsole.Complier.Log('[JSSymbolData::RecvMinuteHistroyData] recv data' , data);
  6292. let hisData=this.JsonDataToMinuteHistoryData(data);
  6293. this.Data = new JSCommonData.ChartData();
  6294. this.Data.DataType=1; /*分钟线数据 */
  6295. this.Data.Data=hisData;
  6296. this.SourceData = new JSCommonData.ChartData;
  6297. this.SourceData.Data = hisData;
  6298. if (JSCommonData.ChartData.IsMinutePeriod(this.Period, false)) //周期数据
  6299. {
  6300. let periodData=this.Data.GetPeriodData(this.Period);
  6301. this.Data.Data=periodData;
  6302. }
  6303. this.Name = data.name;
  6304. }
  6305. //最新的分钟数据走势图
  6306. this.RecvMinuteData = function (recvData)
  6307. {
  6308. let data = recvData.data;
  6309. JSConsole.Complier.Log('[JSSymbolData::RecvMinuteData] recv data', data);
  6310. var aryMinuteData = this.JsonDataToMinuteData(data);
  6311. this.Data = new JSCommonData.ChartData();
  6312. this.Data.DataType = 2; /*分钟走势图数据 */
  6313. this.Data.Data = aryMinuteData;
  6314. this.Name = data.stock[0].name;
  6315. }
  6316. this.GetSymbolCacheData=function(dataName)
  6317. {
  6318. if (!this.Data) return new Array();
  6319. switch(dataName)
  6320. {
  6321. case 'CLOSE':
  6322. case 'C':
  6323. return this.Data.GetClose();
  6324. case 'VOL':
  6325. case 'V':
  6326. return this.Data.GetVol();
  6327. case 'OPEN':
  6328. case 'O':
  6329. return this.Data.GetOpen();
  6330. case 'HIGH':
  6331. case 'H':
  6332. return this.Data.GetHigh();
  6333. case 'LOW':
  6334. case 'L':
  6335. return this.Data.GetLow();
  6336. case 'AMOUNT':
  6337. case 'AMO':
  6338. return this.Data.GetAmount();
  6339. case 'VOLINSTK':
  6340. return this.Data.GetPosition();
  6341. }
  6342. }
  6343. this.GetCurrBarsCount=function()
  6344. {
  6345. if (!this.Data || !this.Data.Data || !this.Data.Data.length) return new Array();
  6346. let lCount=this.Data.Data.length;
  6347. let result=[];
  6348. for(let i=lCount-1;i>=0;--i)
  6349. result.push(i);
  6350. return result;
  6351. }
  6352. this.GetIsLastBar = function ()
  6353. {
  6354. let result = [];
  6355. if (!this.Data || !this.Data.Data || !this.Data.Data.length) return result
  6356. let lCount = this.Data.Data.length;
  6357. for (let i = 0; i < lCount; ++i)
  6358. {
  6359. if (i == lCount - 1) result.push(1);
  6360. else result.push(0);
  6361. }
  6362. return result;
  6363. }
  6364. //融资融券函数
  6365. this.GetMarginCacheData = function (id, node)
  6366. {
  6367. let jobID = JS_EXECUTE_JOB_ID.GetMarginJobID(id);
  6368. if (!jobID) this.Execute.ThrowUnexpectedNode(node, '不支持MARGIN(' + id + ')');
  6369. if (this.MarginData.has(jobID)) return this.MarginData.get(jobID);
  6370. return [];
  6371. }
  6372. //下融资融券
  6373. this.GetMarginData = function (jobID)
  6374. {
  6375. if (this.MarginData.has(jobID)) return this.Execute.RunNextJob();
  6376. JSConsole.Complier.Log('[JSSymbolData::GetMarginData] jobID=', jobID);
  6377. var self = this;
  6378. let fieldList = ["name", "date", "symbol"];
  6379. switch (jobID)
  6380. {
  6381. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BALANCE: //融资融券余额
  6382. fieldList.push("margin.balance");
  6383. break;
  6384. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_RATE: //融资占比
  6385. fieldList.push("margin.rate");
  6386. break;
  6387. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_BALANCE: //买入信息-融资余额
  6388. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_AMOUNT: //买入信息-买入额
  6389. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_REPAY: //买入信息-偿还额
  6390. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_NET: //买入信息-融资净买入
  6391. fieldList.push("margin.buy");
  6392. break;
  6393. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_BALANCE: //卖出信息-融券余量
  6394. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_VOLUME: //卖出信息-卖出量
  6395. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_REPAY: //卖出信息-偿还量
  6396. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_NET: //卖出信息-融券净卖出
  6397. fieldList.push("margin.sell");
  6398. break;
  6399. }
  6400. //请求数据
  6401. wx.request({
  6402. url: this.StockHistoryDayApiUrl,
  6403. data:
  6404. {
  6405. "field": fieldList,
  6406. "symbol": [this.Symbol],
  6407. "orderfield": "date"
  6408. },
  6409. method: 'POST',
  6410. dataType: "json",
  6411. async: true,
  6412. success: function (recvData) {
  6413. self.RecvMarginData(recvData, jobID);
  6414. self.Execute.RunNextJob();
  6415. }
  6416. });
  6417. }
  6418. this.RecvMarginData = function (recvData, jobID)
  6419. {
  6420. var data = recvData.data;
  6421. //JSConsole.Complier.Log(data);
  6422. if (!data.stock || data.stock.length != 1) return;
  6423. let stock = data.stock[0];
  6424. var aryData = new Array();
  6425. var aryData2 = [], aryData3 = [], aryData4 = []; //其他3个数据
  6426. for (let i in stock.stockday)
  6427. {
  6428. var item = stock.stockday[i];
  6429. var marginData = item.margin;
  6430. if (!marginData) continue;
  6431. let indexData = new JSCommonData.SingleData();
  6432. indexData.Date = item.date;
  6433. switch (jobID)
  6434. {
  6435. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BALANCE:
  6436. if (!this.IsNumber(marginData.balance)) continue;
  6437. indexData.Value = marginData.balance; //融资融券余额
  6438. aryData.push(indexData);
  6439. break;
  6440. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_RATE:
  6441. if (!this.IsNumber(marginData.rate)) continue;
  6442. indexData.Value = marginData.rate; //融资占比
  6443. aryData.push(indexData);
  6444. break;
  6445. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_BALANCE: //买入信息-融资余额
  6446. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_AMOUNT: //买入信息-买入额
  6447. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_REPAY: //买入信息-偿还额
  6448. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_NET: //买入信息-融资净买入
  6449. var buyData = marginData.buy;
  6450. if (!buyData) continue;
  6451. if (!this.IsNumber(buyData.balance) || !this.IsNumber(buyData.amount) || !this.IsNumber(buyData.repay) || !this.IsNumber(buyData.net)) continue;
  6452. indexData.Value = buyData.balance;
  6453. var indexData2 = new JSCommonData.SingleData();
  6454. indexData2.Date = item.date;
  6455. indexData2.Value = buyData.amount;
  6456. var indexData3 = new JSCommonData.SingleData();
  6457. indexData3.Date = item.date;
  6458. indexData3.Value = buyData.repay;
  6459. var indexData4 = new JSCommonData.SingleData();
  6460. indexData4.Date = item.date;
  6461. indexData4.Value = buyData.net;
  6462. aryData.push(indexData);
  6463. aryData2.push(indexData2);
  6464. aryData3.push(indexData3);
  6465. aryData4.push(indexData4);
  6466. break;
  6467. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_BALANCE: //卖出信息-融券余量
  6468. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_VOLUME: //卖出信息-卖出量
  6469. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_REPAY: //卖出信息-偿还量
  6470. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_NET: //卖出信息-融券净卖出
  6471. var sellData = marginData.sell;
  6472. if (!sellData) continue;
  6473. if (!this.IsNumber(sellData.balance) || !this.IsNumber(sellData.volume) || !this.IsNumber(sellData.repay) || !this.IsNumber(sellData.net)) continue;
  6474. indexData.Value = buyData.balance;
  6475. var indexData2 = new JSCommonData.SingleData();
  6476. indexData2.Date = item.date;
  6477. indexData2.Value = buyData.volume;
  6478. var indexData3 = new JSCommonData.SingleData();
  6479. indexData3.Date = item.date;
  6480. indexData3.Value = buyData.repay;
  6481. var indexData4 = new JSCommonData.SingleData();
  6482. indexData4.Date = item.date;
  6483. indexData4.Value = buyData.net;
  6484. aryData.push(indexData);
  6485. aryData2.push(indexData2);
  6486. aryData3.push(indexData3);
  6487. aryData4.push(indexData4);
  6488. break;
  6489. default:
  6490. continue;
  6491. }
  6492. }
  6493. var allData = [];
  6494. if (jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BALANCE || jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_RATE)
  6495. {
  6496. allData.push({ JobID: jobID, Data: aryData });
  6497. }
  6498. else if (jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_BALANCE || jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_AMOUNT ||
  6499. jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_REPAY || jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_NET)
  6500. {
  6501. allData.push({ JobID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_BALANCE, Data: aryData });
  6502. allData.push({ JobID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_AMOUNT, Data: aryData2 });
  6503. allData.push({ JobID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_REPAY, Data: aryData3 });
  6504. allData.push({ JobID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_NET, Data: aryData4 });
  6505. }
  6506. else if (jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_BALANCE || jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_VOLUME ||
  6507. jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_REPAY || jobID === JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_NET)
  6508. {
  6509. allData.push({ JobID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_BALANCE, Data: aryData });
  6510. allData.push({ JobID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_VOLUME, Data: aryData2 });
  6511. allData.push({ JobID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_REPAY, Data: aryData3 });
  6512. allData.push({ JobID: JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_NET, Data: aryData4 });
  6513. }
  6514. for (let i in allData)
  6515. {
  6516. let aryFixedData = this.Data.GetFittingData(allData[i].Data);
  6517. var bindData = new JSCommonData.ChartData();
  6518. bindData.Data = aryFixedData;
  6519. bindData.Period = this.Period; //周期
  6520. if (bindData.Period > 0) //周期数据
  6521. {
  6522. var periodData = bindData.GetPeriodSingleData(bindData.Period);
  6523. bindData.Data = periodData;
  6524. }
  6525. let data = bindData.GetValue();
  6526. this.MarginData.set(allData[i].JobID, data);
  6527. }
  6528. }
  6529. this.GetNewsAnalysisCacheData = function (id, node)
  6530. {
  6531. let jobID = JS_EXECUTE_JOB_ID.GetNewsAnalysisID(id);
  6532. if (!jobID) this.Execute.ThrowUnexpectedNode(node, '不支持NEWS(' + id + ')');
  6533. if (this.NewsAnalysisData.has(jobID)) return this.NewsAnalysisData.get(jobID);
  6534. return [];
  6535. }
  6536. //下载新闻统计
  6537. this.GetNewsAnalysisData = function (jobID)
  6538. {
  6539. if (this.NewsAnalysisData.has(jobID)) return this.Execute.RunNextJob();
  6540. var self = this;
  6541. var mapFolder = new Map([
  6542. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_NEGATIVE, "negative"],
  6543. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_RESEARCH, 'research'],
  6544. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_INTERACT, 'interact'],
  6545. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE, 'holderchange'], //NEWS(4) 股东增持
  6546. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE2, 'holderchange'], //NEWS(5) 股东减持
  6547. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_TRUSTHOLDER, 'trustholder'], //NEWS(6) 信托持股
  6548. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_BLOCKTRADING, 'Blocktrading'], //NEWS(7) 大宗交易
  6549. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_COMPANYNEWS, 'companynews'], //NEWS(8) 官网新闻
  6550. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_TOPMANAGERS, 'topmanagers'], //NEWS(9) 高管要闻
  6551. [JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_PLEDGE, 'Pledge'], //NEWS(10) 股权质押
  6552. ]);
  6553. if (!mapFolder.has(jobID))
  6554. {
  6555. this.Execute.RunNextJob();
  6556. return;
  6557. }
  6558. var folderName = mapFolder.get(jobID);
  6559. var url = this.StockNewsAnalysisApiUrl + '/' + folderName + '/' + this.Symbol + '.json';
  6560. //请求数据
  6561. wx.request({
  6562. url: url,
  6563. method: 'GET',
  6564. dataType: "json",
  6565. async: true,
  6566. success: function (recvData)
  6567. {
  6568. if (recvData.statusCode==200)
  6569. self.RecvNewsAnalysisData(recvData, jobID);
  6570. else
  6571. self.RecvNewsAnalysisDataError(recvData, jobID);
  6572. self.Execute.RunNextJob();
  6573. },
  6574. fail: function (request, textStatus)
  6575. {
  6576. //self.RecvNewsAnalysisDataError(request, textStatus, jobID);
  6577. self.Execute.RunNextJob();
  6578. }
  6579. });
  6580. }
  6581. this.RecvNewsAnalysisDataError = function (recvData, jobID)
  6582. {
  6583. JSConsole.Complier.Log('[JSSymbolData::RecvNewsAnalysisDataError] request error.', recvData.statusCode);
  6584. //没有新闻使用0数据填充
  6585. var aryData = [];
  6586. for (var i = 0; i < this.Data.Data.length; ++i)
  6587. {
  6588. var item = new JSCommonData.SingleData();
  6589. item.Date = this.Data.Data[i].Date;
  6590. item.Value = 0
  6591. aryData.push(item);
  6592. }
  6593. var bindData = new JSCommonData.ChartData();
  6594. bindData.Data = aryData;
  6595. this.NewsAnalysisData.set(jobID, bindData.GetValue());
  6596. }
  6597. this.RecvNewsAnalysisData = function (recvData, jobID)
  6598. {
  6599. var data=recvData.data;
  6600. if (!data.data || !data.date) return;
  6601. if (data.data.length <= 0 || data.data.length != data.date.length) return;
  6602. JSConsole.Complier.Log('[JSSymbolData::RecvNewsAnalysisData] jobID', jobID, data.update);
  6603. if (jobID == JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE || jobID == JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE2)
  6604. {
  6605. var aryData = [], aryData2 = [];
  6606. for (var i = 0; i < data.data.length; ++i)
  6607. {
  6608. var item = new JSCommonData.SingleData();
  6609. item.Date = data.date[i];
  6610. item.Value = data.data[i];
  6611. if (this.IsNumber(item.Value)) aryData.push(item);
  6612. if (i < data.data2.length)
  6613. {
  6614. item = new JSCommonData.SingleData();
  6615. item.Date = data.date[i];
  6616. item.Value = data.data2[i];
  6617. if (this.IsNumber(item.Value)) aryData2.push(item);
  6618. }
  6619. }
  6620. let aryFixedData = this.Data.GetFittingData2(aryData, 0);
  6621. var bindData = new JSCommonData.ChartData();
  6622. bindData.Data = aryFixedData;
  6623. this.NewsAnalysisData.set(JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE, bindData.GetValue());
  6624. aryFixedData = this.Data.GetFittingData2(aryData2, 0);
  6625. bindData = new JSCommonData.ChartData();
  6626. bindData.Data = aryFixedData;
  6627. this.NewsAnalysisData.set(JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE2, bindData.GetValue());
  6628. }
  6629. else
  6630. {
  6631. var aryData = [];
  6632. for (var i = 0; i < data.data.length; ++i)
  6633. {
  6634. var item = new JSCommonData.SingleData();
  6635. item.Date = data.date[i];
  6636. item.Value = data.data[i];
  6637. aryData.push(item);
  6638. }
  6639. let aryFixedData = this.Data.GetFittingData2(aryData, 0);
  6640. var bindData = new JSCommonData.ChartData();
  6641. bindData.Data = aryFixedData;
  6642. this.NewsAnalysisData.set(jobID, bindData.GetValue());
  6643. }
  6644. }
  6645. this.GetStockDataKey=function(jobItem, aryArgs)
  6646. {
  6647. var key=jobItem.FunctionName;
  6648. if (aryArgs.length>0)
  6649. {
  6650. key+="(";
  6651. for(var i=0;i<aryArgs.length;++i)
  6652. {
  6653. if (i>0) key+=",";
  6654. key+=aryArgs[i].toString();
  6655. }
  6656. key+=")";
  6657. }
  6658. return key;
  6659. }
  6660. this.GetFinOne=function(jobItem)
  6661. {
  6662. var aryArgs=this.JobArgumentsToArray(jobItem, 3);
  6663. var key=this.GetStockDataKey(jobItem,aryArgs);
  6664. if (this.StockData.has(key)) return this.Execute.RunNextJob();
  6665. var self=this;
  6666. if (this.NetworkFilter)
  6667. {
  6668. var dateRange=this.Data.GetDateRange();
  6669. var obj=
  6670. {
  6671. Name:'JSSymbolData::GetFinOne', //类名::
  6672. Explain:'财务数据FINONE(ID,Y,MMDD)',
  6673. JobID:jobItem.ID,
  6674. Request:{ Url:self.StockHistoryDayApiUrl, Type:'POST', Data:{ Args:aryArgs, symbol: this.Symbol, daterange:dateRange } },
  6675. Self:this,
  6676. PreventDefault:false
  6677. };
  6678. this.NetworkFilter(obj, function(recvData)
  6679. {
  6680. self.RecvStockValue(recvData,jobItem,key,1);
  6681. self.Execute.RunNextJob();
  6682. });
  6683. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  6684. }
  6685. var apiDownload=new DownloadFinOneData(
  6686. {
  6687. Job:jobItem,
  6688. Symbol:this.Symbol,
  6689. Url:this.StockHistoryDayApiUrl,
  6690. Args:aryArgs,
  6691. DataKey:key,
  6692. Callback:function(recvData, jobItem, key)
  6693. {
  6694. self.RecvStockValue(recvData, jobItem, key,1);
  6695. self.Execute.RunNextJob();
  6696. },
  6697. ErrorCallback:function(strError)
  6698. {
  6699. self.AddStockValueError(key,strError);
  6700. }
  6701. });
  6702. apiDownload.Download();
  6703. }
  6704. this.GetFinValue=function(jobItem)
  6705. {
  6706. var aryArgs=this.JobArgumentsToArray(jobItem, 1);
  6707. var lID=aryArgs[0];
  6708. var key=this.GetStockDataKey(jobItem,aryArgs);
  6709. if (this.StockData.has(key)) return this.Execute.RunNextJob();
  6710. var self=this;
  6711. if (this.NetworkFilter)
  6712. {
  6713. var dateRange=this.Data.GetDateRange();
  6714. var obj=
  6715. {
  6716. Name:'JSSymbolData::GetFinValue', //类名::
  6717. Explain:'财务数据FINVALUE(ID)',
  6718. JobID:jobItem.ID,
  6719. Request:{ Url:self.StockHistoryDayApiUrl, Type:'POST', Data:{ id:lID, symbol: this.Symbol, daterange:dateRange } },
  6720. Self:this,
  6721. PreventDefault:false
  6722. };
  6723. this.NetworkFilter(obj, function(recvData)
  6724. {
  6725. self.RecvStockValue(recvData,jobItem,key,0);
  6726. self.Execute.RunNextJob();
  6727. });
  6728. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  6729. }
  6730. var apiDownload=new DownloadFinValueData(
  6731. {
  6732. Job:jobItem,
  6733. Symbol:this.Symbol,
  6734. Url:this.StockHistoryDayApiUrl,
  6735. Args:aryArgs,
  6736. DataKey:key,
  6737. Callback:function(recvData, jobItem, key)
  6738. {
  6739. self.RecvStockValue(recvData, jobItem, key,0);
  6740. self.Execute.RunNextJob();
  6741. },
  6742. ErrorCallback:function(strError)
  6743. {
  6744. self.AddStockValueError(key,strError);
  6745. }
  6746. });
  6747. apiDownload.Download();
  6748. }
  6749. this.GetFinance=function(jobItem)
  6750. {
  6751. var aryArgs=this.JobArgumentsToArray(jobItem, 1);
  6752. var lID=aryArgs[0];
  6753. var key=this.GetStockDataKey(jobItem,aryArgs);
  6754. if (this.StockData.has(key)) return this.Execute.RunNextJob();
  6755. var self=this;
  6756. if (this.NetworkFilter)
  6757. {
  6758. var dateRange=this.Data.GetDateRange();
  6759. var obj=
  6760. {
  6761. Name:'JSSymbolData::GetFinance', //类名::
  6762. Explain:'财务数据FINANCE(ID)',
  6763. JobID:jobItem.ID,
  6764. Request:{ Url:self.RealtimeApiUrl, Type:'POST', Data:{ id:lID, symbol: this.Symbol, daterange:dateRange } },
  6765. Self:this,
  6766. PreventDefault:false
  6767. };
  6768. this.NetworkFilter(obj, function(recvData)
  6769. {
  6770. self.RecvStockValue(recvData,jobItem,key,0);
  6771. self.Execute.RunNextJob();
  6772. });
  6773. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  6774. }
  6775. var apiDownload=new DownloadFinanceData(
  6776. {
  6777. Job:jobItem,
  6778. Symbol:this.Symbol,
  6779. Url:this.StockHistoryDayApiUrl,
  6780. RealtimeUrl:this.RealtimeApiUrl,
  6781. Args:aryArgs,
  6782. DataKey:key,
  6783. Callback:function(recvData, jobItem, key)
  6784. {
  6785. self.RecvStockValue(recvData, jobItem, key,0);
  6786. self.Execute.RunNextJob();
  6787. },
  6788. ErrorCallback:function(strError)
  6789. {
  6790. self.AddStockValueError(key,strError);
  6791. }
  6792. });
  6793. apiDownload.Download();
  6794. }
  6795. this.GetVariantData=function(jobItem)
  6796. {
  6797. var key=jobItem.VariantName;
  6798. if (this.StockData.has(key)) return this.Execute.RunNextJob();
  6799. var self=this;
  6800. if (this.NetworkFilter)
  6801. {
  6802. var dateRange=this.Data.GetDateRange();
  6803. var obj=
  6804. {
  6805. Name:'JSSymbolData::GetVariantData', //类名::
  6806. Explain:'变量数据下载',
  6807. JobID:jobItem.ID,
  6808. Request:{ Url:"www.121287.com", Type:'POST', Data:{ VariantName:jobItem.VariantName, symbol: this.Symbol, daterange:dateRange } },
  6809. Self:this,
  6810. PreventDefault:false
  6811. };
  6812. this.NetworkFilter(obj, function(recvData)
  6813. {
  6814. if (recvData.Error)
  6815. {
  6816. self.AddStockValueError(key,recvData.Error);
  6817. }
  6818. else
  6819. {
  6820. var dataType=0;
  6821. if (IFrameSplitOperator.IsNumber(recvData.DataType)) dataType=recvData.DataType;
  6822. self.RecvStockValue(recvData.Data,jobItem,key,dataType);
  6823. }
  6824. self.Execute.RunNextJob();
  6825. });
  6826. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  6827. }
  6828. var errorCallback=function(strError)
  6829. {
  6830. self.AddStockValueError(key,strError);
  6831. };
  6832. var apiDownload;
  6833. if (jobItem.VariantName=="CAPITAL" || jobItem.VariantName=="TOTALCAPITAL" || jobItem.VariantName=="EXCHANGE")
  6834. {
  6835. var callback=function(recvData, jobItem, key)
  6836. {
  6837. self.RecvStockValue(recvData, jobItem, key,0);
  6838. self.Execute.RunNextJob();
  6839. };
  6840. apiDownload=new DownloadFinanceData(
  6841. {
  6842. Job:jobItem,
  6843. Symbol:this.Symbol,
  6844. Url:this.StockHistoryDayApiUrl,
  6845. RealtimeUrl:this.RealtimeApiUrl,
  6846. Args:[jobItem.VariantName],
  6847. DataKey:key,
  6848. Callback:callback,
  6849. ErrorCallback:errorCallback
  6850. });
  6851. }
  6852. else if (jobItem.VariantName=="HYBLOCK" || jobItem.VariantName=="DYBLOCK" || jobItem.VariantName=="GNBLOCK")
  6853. {
  6854. var callback=function(recvData, jobItem, key, dataType)
  6855. {
  6856. self.RecvStockValue(recvData, jobItem, key, dataType);
  6857. self.Execute.RunNextJob();
  6858. };
  6859. apiDownload=new DownloadGroupData(
  6860. {
  6861. Job:jobItem,
  6862. Symbol:this.Symbol,
  6863. Url:this.StockHistoryDayApiUrl,
  6864. RealtimeUrl:this.RealtimeApiUrl,
  6865. Args:[jobItem.VariantName],
  6866. DataKey:key,
  6867. Callback:callback,
  6868. ErrorCallback:errorCallback
  6869. });
  6870. }
  6871. else if (jobItem.VariantName=="INBLOCK")
  6872. {
  6873. var errorMessage=`${jobItem.VariantName}, 请对接外部数据.`;
  6874. this.AddStockValueError(key,errorMessage);
  6875. this.Execute.RunNextJob();
  6876. return;
  6877. }
  6878. else
  6879. {
  6880. var errorMessage=`不支持变量${jobItem.VariantName}, 请对接外部数据.`;
  6881. this.AddStockValueError(key,errorMessage);
  6882. this.Execute.RunNextJob();
  6883. return;
  6884. }
  6885. apiDownload.Download();
  6886. }
  6887. this.GetGPJYValue=function(jobItem)
  6888. {
  6889. var aryArgs=this.JobArgumentsToArray(jobItem, 3);
  6890. var key=this.GetStockDataKey(jobItem,aryArgs);
  6891. if (this.StockData.has(key)) return this.Execute.RunNextJob();
  6892. var self=this;
  6893. //TYPE:为1表示做平滑处理,没有数据的周期返回上一周期的值;为0表示不做平滑处理
  6894. var dataType=aryArgs[2]==1?0:2;
  6895. if (this.NetworkFilter)
  6896. {
  6897. var dateRange=this.Data.GetDateRange();
  6898. var obj=
  6899. {
  6900. Name:'JSSymbolData::GetGPJYValue', //类名::
  6901. Explain:'股票交易类数据GPJYVALUE(ID,N,TYPE)',
  6902. JobID:jobItem.ID,
  6903. Request:{ Url:self.StockHistoryDayApiUrl, Type:'POST', Data:{ Args:aryArgs, symbol: this.Symbol, daterange:dateRange } },
  6904. Self:this,
  6905. PreventDefault:false
  6906. };
  6907. this.NetworkFilter(obj, function(recvData)
  6908. {
  6909. self.RecvStockValue(recvData,jobItem,key,dataType);
  6910. self.Execute.RunNextJob();
  6911. });
  6912. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  6913. }
  6914. var apiDownload=new DownloadGPJYValue(
  6915. {
  6916. Job:jobItem,
  6917. Symbol:this.Symbol,
  6918. Url:this.StockHistoryDayApiUrl,
  6919. Args:aryArgs,
  6920. DataKey:key,
  6921. Callback:function(recvData, jobItem, key)
  6922. {
  6923. self.RecvStockValue(recvData, jobItem, key,dataType);
  6924. self.Execute.RunNextJob();
  6925. },
  6926. ErrorCallback:function(strError)
  6927. {
  6928. self.AddStockValueError(key,strError);
  6929. }
  6930. });
  6931. apiDownload.Download();
  6932. }
  6933. //自定义变量数据下载
  6934. this.GetCustomVariantData=function(jobItem)
  6935. {
  6936. var key=jobItem.VariantName;
  6937. if (this.StockData.has(key)) return this.Execute.RunNextJob();
  6938. var variantInfo=g_JSComplierResource.CustomVariant.Data.get(key);
  6939. var self=this;
  6940. if (this.NetworkFilter)
  6941. {
  6942. var dateRange=this.Data.GetDateRange();
  6943. var obj=
  6944. {
  6945. Name:'JSSymbolData::GetCustomVariantData', //类名::函数名
  6946. Explain:'自定义变量数据下载',
  6947. JobID:jobItem.ID,
  6948. Request:{ Url:"www.121287.com", Type:'POST', Data:{ VariantName:jobItem.VariantName, symbol: this.Symbol, daterange:dateRange } },
  6949. Self:this,
  6950. VariantInfo:variantInfo,
  6951. PreventDefault:false
  6952. };
  6953. this.NetworkFilter(obj, function(recvData)
  6954. {
  6955. if (recvData.Error) self.AddStockValueError(key,recvData.Error);
  6956. else self.RecvStockValue(recvData.Data,jobItem,key,recvData.DataType);
  6957. self.Execute.RunNextJob();
  6958. });
  6959. }
  6960. else
  6961. {
  6962. this.AddStockValueError(key, `自定义变量${key}下载失败`);
  6963. this.Execute.RunNextJob();
  6964. }
  6965. }
  6966. this.GetCustomFunctionData=function(jobItem)
  6967. {
  6968. var key=jobItem.FunctionName;
  6969. var functionInfo=g_JSComplierResource.CustomFunction.Data.get(key);
  6970. if (!functionInfo.IsDownload) return this.Execute.RunNextJob();
  6971. if (this.StockData.has(key)) return this.Execute.RunNextJob(); //一个函数只能缓存一个数据, 保存多个外部自己保存
  6972. var self=this;
  6973. if (this.NetworkFilter)
  6974. {
  6975. var dateRange=this.Data.GetDateRange();
  6976. var obj=
  6977. {
  6978. Name:'JSSymbolData::GetCustomFunctionData', //类名::函数名
  6979. Explain:'自定义函数数据下载',
  6980. JobID:jobItem.ID,
  6981. Request:
  6982. {
  6983. Url:"www.121287.com", Type:'POST',
  6984. Data:
  6985. {
  6986. FunctionName:jobItem.FunctionName,
  6987. symbol: this.Symbol, daterange:dateRange,
  6988. JobItem:jobItem //函数编译信息
  6989. }
  6990. },
  6991. Self:this,
  6992. FunctionInfo:functionInfo,
  6993. PreventDefault:false
  6994. };
  6995. this.NetworkFilter(obj, function(recvData)
  6996. {
  6997. if (recvData.Error) self.AddStockValueError(key,recvData.Error);
  6998. else self.RecvStockValue(recvData.Data,jobItem,key,recvData.DataType);
  6999. self.Execute.RunNextJob();
  7000. });
  7001. }
  7002. else
  7003. {
  7004. this.AddStockValueError(key, `自定义函数${key}下载失败`);
  7005. this.Execute.RunNextJob();
  7006. }
  7007. }
  7008. this.RecvStockValue=function(recvData,jobItem,key,dataType)
  7009. {
  7010. if (!recvData)
  7011. {
  7012. //JSConsole.Complier.Log(`[JSSymbolData::RecvStockValue] key=${key} data is null`);
  7013. return;
  7014. }
  7015. if (dataType==0)
  7016. {
  7017. if (Array.isArray(recvData))
  7018. {
  7019. var kdata=this.Data; //K线
  7020. var aryFittingData;
  7021. if (JSCommonData.ChartData.IsDayPeriod(this.Period,true))
  7022. aryFittingData=kdata.GetFittingFinanceData(recvData); //数据和主图K线拟合
  7023. else if (JSCommonData.ChartData.IsMinutePeriod(this.Period,true))
  7024. aryFittingData=kdata.GetMinuteFittingFinanceData(recvData); //数据和主图K线拟合
  7025. else
  7026. return;
  7027. var bindData=new JSCommonData.ChartData();
  7028. bindData.Data=aryFittingData;
  7029. var result=bindData.GetValue();
  7030. if (key=="EXCHANGE") //计算换手率=成交量/流通股本*100
  7031. {
  7032. for(var i in result)
  7033. {
  7034. var kitem=kdata.Data[i];
  7035. if (result[i]>0)
  7036. result[i]=kitem.Vol/result[i] * 100;
  7037. }
  7038. }
  7039. this.StockData.set(key,{ Data:result });
  7040. }
  7041. else
  7042. {
  7043. this.StockData.set(key,{ Data:recvData.Value });
  7044. }
  7045. }
  7046. else if (dataType==1) //单数值
  7047. {
  7048. this.StockData.set(key,{ Data:recvData.Value });
  7049. }
  7050. else if (dataType==2) //数据不做平滑处理
  7051. {
  7052. var kdata=this.Data; //K线
  7053. var aryFittingData;
  7054. if (JSCommonData.ChartData.IsDayPeriod(this.Period,true))
  7055. aryFittingData=kdata.GetFittingTradeData(recvData, 0, false); //数据和主图K线拟合
  7056. else if (JSCommonData.ChartData.IsMinutePeriod(this.Period,true))
  7057. aryFittingData=kdata.GetMinuteFittingTradeData(recvData, 0, false); //数据和主图K线拟合
  7058. else
  7059. return;
  7060. var bindData=new JSCommonData.ChartData();
  7061. bindData.Data=aryFittingData;
  7062. var result=bindData.GetValue();
  7063. this.StockData.set(key,{ Data:result });
  7064. }
  7065. }
  7066. this.AddStockValueError=function(key, message)
  7067. {
  7068. this.StockData.set(key,{ Error:message });
  7069. }
  7070. this.GetStockCacheData=function(obj)
  7071. {
  7072. var key;
  7073. if (obj.FunctionName)
  7074. key=this.GetStockDataKey({FunctionName:obj.FunctionName}, obj.Args);
  7075. else if (obj.VariantName)
  7076. key=obj.VariantName;
  7077. else if (obj.CustomName)
  7078. key=obj.CustomName; //自定义名字
  7079. else
  7080. return null;
  7081. if (!this.StockData.has(key)) return null;
  7082. var data=this.StockData.get(key);
  7083. if (data.Error) this.Execute.ThrowUnexpectedNode(obj.Node, data.Error);
  7084. return data.Data;
  7085. }
  7086. this.IsInBlock=function(blockName, node)
  7087. {
  7088. var data=this.GetStockCacheData({ VariantName:"INBLOCK", Node:node });
  7089. if (!data) return 0;
  7090. var aryBlock=data.split('|');
  7091. for(var i=0; i<aryBlock.length; ++i)
  7092. {
  7093. var item=aryBlock[i];
  7094. if (item==blockName) return 1;
  7095. }
  7096. return 0;
  7097. }
  7098. this.JobArgumentsToArray=function(job, lCount)
  7099. {
  7100. var args=job.Args;
  7101. if (args.length!=lCount)
  7102. {
  7103. var token=job.Token;
  7104. this.Execute.ErrorHandler.ThrowError(token.Index,token.Line,0,`${job.FunctionName}() Error: argument count error.`);
  7105. }
  7106. var aryValue=[];
  7107. for(var i=0;i<args.length;++i)
  7108. {
  7109. var item=args[i];
  7110. if (this.IsNumber(item))
  7111. {
  7112. aryValue.push(item);
  7113. }
  7114. else if (item.Type==Syntax.Literal)
  7115. {
  7116. aryValue.push(item.Value);
  7117. }
  7118. else if (item.Type==Syntax.Identifier) //变量 !!只支持默认的变量值
  7119. {
  7120. var isFind=false;
  7121. for(var j in this.Arguments)
  7122. {
  7123. const argItem=this.Arguments[j];
  7124. if (argItem.Name==item.Name)
  7125. {
  7126. aryValue.push(argItem.Value);
  7127. isFind=true;
  7128. break;
  7129. }
  7130. }
  7131. if (!isFind)
  7132. {
  7133. var token=job.Token;
  7134. this.Execute.ErrorHandler.ThrowError(token.Index,token.Line,0,`${job.FunctionName}() Error: can't read ${item.Name}`);
  7135. }
  7136. }
  7137. }
  7138. return aryValue;
  7139. }
  7140. this.DownloadCustomAPIData = function (job)
  7141. {
  7142. if (!this.NetworkFilter) return this.Execute.RunNextJob();
  7143. var args = [];
  7144. for (var i in job.Args)
  7145. {
  7146. var item = job.Args[i];
  7147. if (item.Type == Syntax.Literal)
  7148. {
  7149. args.push(item.Value);
  7150. }
  7151. else if (item.Type == Syntax.Identifier) //变量 !!只支持默认的变量值
  7152. {
  7153. var isFind = false;
  7154. for (var j in this.Arguments)
  7155. {
  7156. const argItem = this.Arguments[j];
  7157. if (argItem.Name == item.Name)
  7158. {
  7159. args.push(argItem.Value);
  7160. isFind = true;
  7161. break;
  7162. }
  7163. }
  7164. if (!isFind)
  7165. {
  7166. var token = job.Token;
  7167. this.Execute.ErrorHandler.ThrowError(token.Index, token.Line, 0, `LoadAPIData() Error: can't read ${item.Name}`);
  7168. }
  7169. }
  7170. else
  7171. {
  7172. return this.Execute.RunNextJob();
  7173. }
  7174. }
  7175. var self = this;
  7176. var obj =
  7177. {
  7178. Name: 'JSSymbolData::DownloadCustomAPIData', //类名::函数名
  7179. Explain: '下载自定义api数据',
  7180. Period: this.Period,
  7181. Right: this.Right,
  7182. Symbol: this.Symbol,
  7183. KData: this.Data, //K线数据
  7184. Cache: this.CustomAPIData,
  7185. Args: args,
  7186. Self: this,
  7187. PreventDefault: false
  7188. };
  7189. this.NetworkFilter(obj, function (data) {
  7190. self.RecvCustomAPIData(data, args);
  7191. self.Execute.RunNextJob();
  7192. });
  7193. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  7194. this.Execute.RunNextJob();
  7195. }
  7196. this.RecvCustomAPIData = function (recvData, args)
  7197. {
  7198. if (!recvData || !recvData.data) return;
  7199. var data = recvData.data;
  7200. var apiKey = this.GenerateCustomAPIKey(args);
  7201. if (JSCommonData.ChartData.IsMinutePeriod(this.Period, true))
  7202. {
  7203. if (!data.date || !data.time) return;
  7204. var date = data.date;
  7205. var time = data.time;
  7206. for (var key in data)
  7207. {
  7208. if (key == 'date' || key == 'time') continue;
  7209. var item = data[key];
  7210. }
  7211. }
  7212. else if (JSCommonData.ChartData.IsDayPeriod(this.Period, true))
  7213. {
  7214. if (!data.date) return;
  7215. var date = data.date;
  7216. var result = { __Type__: "Object" };
  7217. for (var key in data) {
  7218. if (key == 'date') continue;
  7219. var item = data[key];
  7220. if (Array.isArray(item))
  7221. {
  7222. var value = this.FittingCustomAPIArray(item, date);
  7223. result[key] = value;
  7224. }
  7225. else if (this.IsNumber(item))
  7226. {
  7227. result[key] = item;
  7228. }
  7229. }
  7230. this.CustomAPIData.set(apiKey, result);
  7231. }
  7232. }
  7233. this.FittingCustomAPIArray = function (data, date, time)
  7234. {
  7235. var kdata = this.Data; //K线
  7236. var arySingleData = [];
  7237. for (var i in data)
  7238. {
  7239. var value = data[i];
  7240. var indexItem = new JSCommonData.SingleData(); //单列指标数据
  7241. indexItem.Date = date[i];
  7242. if (time && i < time.length) indexItem.Time = time[i];
  7243. indexItem.Value = value;
  7244. arySingleData.push(indexItem);
  7245. }
  7246. var aryFittingData;
  7247. if (JSCommonData.ChartData.IsDayPeriod(this.Period, true))
  7248. aryFittingData = kdata.GetFittingData(arySingleData); //数据和主图K线拟合
  7249. else if (JSCommonData.ChartData.IsMinutePeriod(this.Period, true))
  7250. aryFittingData = kdata.GetMinuteFittingData(arySingleData); //数据和主图K线拟合
  7251. else
  7252. return null;
  7253. var bindData = new JSCommonData.ChartData();
  7254. bindData.Data = aryFittingData;
  7255. var result = bindData.GetValue();
  7256. return result;
  7257. }
  7258. this.JsonDataToHistoryData=function(data)
  7259. {
  7260. var list = data.data;
  7261. var aryDayData=new Array();
  7262. var date = 0, yclose = 1, open = 2, high = 3, low = 4, close = 5, vol = 6, amount = 7;
  7263. var up = 8, down = 9, stop = 10, unchanged = 11;
  7264. for (var i = 0; i < list.length; ++i)
  7265. {
  7266. var item = new JSCommonData.HistoryData();
  7267. item.Date = list[i][date];
  7268. item.Open = list[i][open];
  7269. item.YClose = list[i][yclose];
  7270. item.Close = list[i][close];
  7271. item.High = list[i][high];
  7272. item.Low = list[i][low];
  7273. item.Vol = list[i][vol]; //原始单位股
  7274. item.Amount = list[i][amount];
  7275. if (isNaN(item.Open) || item.Open<=0) continue; //停牌的数据剔除
  7276. //上涨 下跌家数
  7277. if (list[i].length > up) item.Up = list[i][up];
  7278. if (list[i].length > down) item.Down = list[i][down];
  7279. if (list[i].length > stop) item.Stop = list[i][stop];
  7280. if (list[i].length > unchanged) item.Unchanged = list[i][unchanged];
  7281. aryDayData.push(item);
  7282. }
  7283. return aryDayData;
  7284. }
  7285. this.JsonDataToMinuteHistoryData=function(data)
  7286. {
  7287. var list = data.data;
  7288. var aryDayData=new Array();
  7289. var date = 0, yclose = 1, open = 2, high = 3, low = 4, close = 5, vol = 6, amount = 7, time = 8;
  7290. for (var i = 0; i < list.length; ++i)
  7291. {
  7292. let item = new JSCommonData.HistoryData();
  7293. item.Date = list[i][date];
  7294. item.Open = list[i][open];
  7295. item.YClose = list[i][yclose];
  7296. item.Close = list[i][close];
  7297. item.High = list[i][high];
  7298. item.Low = list[i][low];
  7299. item.Vol = list[i][vol]; //原始单位股
  7300. item.Amount = list[i][amount];
  7301. item.Time=list[i][time];
  7302. // if (isNaN(item.Open) || item.Open<=0) continue; //停牌的数据剔除
  7303. aryDayData.push(item);
  7304. }
  7305. // 无效数据处理
  7306. for(let i = 0; i < aryDayData.length; ++i)
  7307. {
  7308. var minData = aryDayData[i];
  7309. if (minData == null) coninue;
  7310. if (isNaN(minData.Open) || minData.Open <= 0 || isNaN(minData.High) || minData.High <= 0 || isNaN(minData.Low) || minData.Low <= 0
  7311. || isNaN(minData.Close) || minData.Close <= 0 || isNaN(minData.YClose) || minData.YClose <= 0)
  7312. {
  7313. if (i == 0)
  7314. {
  7315. if (minData.YClose > 0)
  7316. {
  7317. minData.Open = minData.YClose;
  7318. minData.High = minData.YClose;
  7319. minData.Low = minData.YClose;
  7320. minData.Close = minData.YClose;
  7321. }
  7322. }
  7323. else // 用前一个有效数据填充
  7324. {
  7325. for(let j = i-1; j >= 0; --j)
  7326. {
  7327. var minData2 = aryDayData[j];
  7328. if (minData2 == null) coninue;
  7329. if (minData2.Open > 0 && minData2.High > 0 && minData2.Low > 0 && minData2.Close > 0)
  7330. {
  7331. if (minData.YClose <= 0) minData.YClose = minData2.Close;
  7332. minData.Open = minData2.Open;
  7333. minData.High = minData2.High;
  7334. minData.Low = minData2.Low;
  7335. minData.Close = minData2.Close;
  7336. break;
  7337. }
  7338. }
  7339. }
  7340. }
  7341. }
  7342. return aryDayData;
  7343. }
  7344. //API 返回数据 转化为array[]
  7345. this.JsonDataToMinuteData = function (data)
  7346. {
  7347. var aryMinuteData = new Array();
  7348. for (var i in data.stock[0].minute)
  7349. {
  7350. var jsData = data.stock[0].minute[i];
  7351. var item = new JSCommonData.MinuteData();
  7352. item.Close = jsData.price;
  7353. item.Open = jsData.open;
  7354. item.High = jsData.high;
  7355. item.Low = jsData.low;
  7356. item.Vol = jsData.vol; //股
  7357. item.Amount = jsData.amount;
  7358. if (i == 0) //第1个数据 写死9:25
  7359. item.DateTime = data.stock[0].date.toString() + " 0925";
  7360. else
  7361. item.DateTime = data.stock[0].date.toString() + " " + jsData.time.toString();
  7362. item.Date = data.stock[0].date;
  7363. item.Time = jsData.time;
  7364. item.Increate = jsData.increate;
  7365. item.Risefall = jsData.risefall;
  7366. item.AvPrice = jsData.avprice;
  7367. aryMinuteData[i] = item;
  7368. }
  7369. return aryMinuteData;
  7370. }
  7371. //CODELIKE 模糊股票代码
  7372. this.CODELIKE=function(value)
  7373. {
  7374. if (this.Symbol.indexOf(value)==0) return 1;
  7375. return 0;
  7376. }
  7377. this.NAMELIKE = function (value)
  7378. {
  7379. if (this.Name && this.Name.indexOf(value) == 0) return 1;
  7380. return 0;
  7381. }
  7382. /*
  7383. SETCODE 市场类型
  7384. 0:深圳 1:上海,47:中金所期货 28:郑州商品 29:大连商品 30:上海商品,27:香港指数 31:香港主板,48:香港创业板...
  7385. */
  7386. this.SETCODE=function()
  7387. {
  7388. if (this.Symbol.indexOf('.sh')) return 1;
  7389. if (this.Symbol.indexOf('.sz')) return 0;
  7390. return 0;
  7391. }
  7392. this.GetSymbol = function () { return this.Symbol; }
  7393. this.GetName = function () { return this.Name; }
  7394. this.TIME=function()
  7395. {
  7396. var result = [];
  7397. if (!this.Data || !this.Data.Data || !this.Data.Data.length) return result;
  7398. for(let i in this.Data.Data)
  7399. {
  7400. var item=this.Data.Data[i];
  7401. if (this.IsNumber(item.Time))
  7402. result[i]=item.Time;
  7403. else
  7404. result[i]=0;
  7405. }
  7406. return result;
  7407. }
  7408. this.DATE = function ()
  7409. {
  7410. var result = [];
  7411. if (!this.Data || !this.Data.Data || !this.Data.Data.length) return result;
  7412. for (let i in this.Data.Data)
  7413. {
  7414. var item = this.Data.Data[i];
  7415. result[i] = item.Date - 19000000;;
  7416. }
  7417. return result;
  7418. }
  7419. this.YEAR = function ()
  7420. {
  7421. var result = [];
  7422. if (!this.Data || !this.Data.Data || !this.Data.Data.length) return result;
  7423. for (let i in this.Data.Data)
  7424. {
  7425. var item = this.Data.Data[i];
  7426. if (this.IsNumber(item.Date))
  7427. result[i] = parseInt(item.Date / 10000);
  7428. else
  7429. result[i] = null;
  7430. }
  7431. return result;
  7432. }
  7433. this.MONTH = function ()
  7434. {
  7435. var result = [];
  7436. if (!this.Data || !this.Data.Data || !this.Data.Data.length) return result;
  7437. for (let i in this.Data.Data)
  7438. {
  7439. var item = this.Data.Data[i];
  7440. if (this.IsNumber(item.Date))
  7441. result[i] = parseInt(item.Date % 10000 / 100);
  7442. else
  7443. result[i] = null;
  7444. }
  7445. return result;
  7446. }
  7447. //星期 1-7
  7448. this.WEEK = function ()
  7449. {
  7450. var result = [];
  7451. if (!this.Data || !this.Data.Data || !this.Data.Data.length) return result;
  7452. var tempDate = new Date();
  7453. for (let i in this.Data.Data)
  7454. {
  7455. var item = this.Data.Data[i];
  7456. result[i] = null;
  7457. if (!this.IsNumber(item.Date)) continue;
  7458. var year = parseInt(item.Date / 10000);
  7459. var month = parseInt(item.Date % 10000 / 100);
  7460. var day = item.Date % 100;
  7461. tempDate.setFullYear(year);
  7462. tempDate.setMonth(month - 1);
  7463. tempDate.setDate(day);
  7464. result[i] = tempDate.getDay();
  7465. }
  7466. return result;
  7467. }
  7468. this.REFDATE = function (data, date)
  7469. {
  7470. var result = null;
  7471. var findDate=null;
  7472. if (Array.isArray(date))
  7473. {
  7474. if (date.length>0) findDate=date[date.length-1];
  7475. }
  7476. else if (this.IsNumber(date))
  7477. {
  7478. findDate=date;
  7479. }
  7480. if (findDate==null) return null;
  7481. if (findDate<5000000) findDate+=19000000;
  7482. var index = null;
  7483. for (let i in this.Data.Data) //查找日期对应的索引
  7484. {
  7485. if (this.Data.Data[i].Date == findDate)
  7486. {
  7487. index = parseInt(i);
  7488. break;
  7489. }
  7490. }
  7491. if (index == null || index >= data.length) return null;
  7492. return data[index];
  7493. }
  7494. //用法:结果从0到11,依次分别是1/5/15/30/60分钟,日/周/月,多分钟,多日,季,年
  7495. this.PERIOD=function()
  7496. {
  7497. //Period周期 0=日线 1=周线 2=月线 3=年线 9=季线 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟
  7498. const PERIOD_MAP=[5,6,7,11, 0,1,2,3,4,5, 9];
  7499. if (this.Period >= 0 && this.Period <= PERIOD_MAP.length - 1)
  7500. return PERIOD_MAP[this.Period];
  7501. return this.Period;
  7502. }
  7503. this.GetDrawNull = function ()
  7504. {
  7505. var result = [];
  7506. if (!this.Data || !this.Data.Data || !this.Data.Data.length) return result;
  7507. for (let i in this.Data.Data)
  7508. {
  7509. result[i] = null;
  7510. }
  7511. return result;
  7512. }
  7513. }
  7514. //是否有是有效的数字
  7515. JSSymbolData.prototype.IsNumber = function (value)
  7516. {
  7517. if (value == null) return false;
  7518. if (isNaN(value)) return false;
  7519. return true;
  7520. }
  7521. JSSymbolData.prototype.IsDivideNumber = function (value)
  7522. {
  7523. if (value == null) return false;
  7524. if (isNaN(value)) return false;
  7525. if (value == 0) return false;
  7526. return true;
  7527. }
  7528. JSSymbolData.prototype.JsonDataToFinance = function (data)
  7529. {
  7530. var financeData;
  7531. for (let i = 1; i <= 4; ++i)
  7532. {
  7533. switch (i)
  7534. {
  7535. case 1:
  7536. var finance = data.finance1;
  7537. var announcement = data.announcement1;
  7538. break;
  7539. case 2:
  7540. var finance = data.finance2;
  7541. var announcement = data.announcement2;
  7542. break;
  7543. case 3:
  7544. var finance = data.finance3;
  7545. var announcement = data.announcement3;
  7546. break;
  7547. case 4:
  7548. var finance = data.finance4;
  7549. var announcement = data.announcement4;
  7550. break;
  7551. default:
  7552. break;
  7553. }
  7554. if (!finance || !announcement || !this.IsNumber(announcement.year) || !this.IsNumber(announcement.quarter)) continue;
  7555. if (financeData) //如果存在1天公布多个报告期数据 只取最新的一个公告期数据
  7556. {
  7557. if (financeData.Announcement.year < announcement.year)
  7558. financeData = { Date: item.date, Finance: finance, Announcement: announcement };
  7559. }
  7560. else
  7561. {
  7562. financeData = { Date: data.date, Finance: finance, Announcement: announcement };
  7563. }
  7564. }
  7565. return financeData;
  7566. }
  7567. var JS_EXECUTE_DEBUG_LOG=false;
  7568. var JS_EXECUTE_JOB_ID=
  7569. {
  7570. JOB_DOWNLOAD_SYMBOL_DATA:1, //下载股票的K线数据
  7571. JOB_DOWNLOAD_INDEX_DATA:2, //下载大盘的K线数据
  7572. JOB_DOWNLOAD_SYMBOL_LATEST_DATA:3, //最新的股票行情数据
  7573. JOB_DOWNLOAD_INDEX_INCREASE_DATA: 4, //涨跌股票个数统计数据
  7574. JOB_DOWNLOAD_VOLR_DATA: 5, //5日量比均量下载量比数据
  7575. JOB_DOWNLOAD_FINVALUE:301, //引用专业财务数据 FINVALUE(ID),ID为数据编号
  7576. JOB_DOWNLOAD_FINONE:302, //引用指定年和月日的某类型的财务数据 FINONE(ID,Y,MMDD),ID为数据编号,Y和MMDD表示年和月日.
  7577. JOB_DOWNLOAD_FINANCE:303, //FINANCE(ID) 基础财务数据
  7578. JOB_DOWNLOAD_GPJYVALUE:304, //引用股票交易类数据 GPJYVALUE(ID,N,TYPE),ID为数据编号,N表示第几个数据,TYPE:为1表示做平滑处理,没有数据的周期返回上一周期的值;为0表示不做平滑处理
  7579. JOB_DOWNLOAD_VARIANT:305, //CAPITAL , TOTALCAPITAL, EXCHANGE
  7580. JOB_CUSTOM_FUNCTION_DATA:6000, //自定义函数
  7581. JOB_CUSTOM_VARIANT_DATA:6001, //自定义变量
  7582. JOB_DOWNLOAD_MARGIN_BALANCE: 1000, //融资融券余额
  7583. JOB_DOWNLOAD_MARGIN_RATE: 1001, //融资占比
  7584. JOB_DOWNLOAD_MARGIN_BUY_BALANCE: 1010, //买入信息-融资余额
  7585. JOB_DOWNLOAD_MARGIN_BUY_AMOUNT: 1011, //买入信息-买入额
  7586. JOB_DOWNLOAD_MARGIN_BUY_REPAY: 1012, //买入信息-偿还额
  7587. JOB_DOWNLOAD_MARGIN_BUY_NET: 1013, //买入信息-融资净买入
  7588. JOB_DOWNLOAD_MARGIN_SELL_BALANCE: 1020, //卖出信息-融券余量
  7589. JOB_DOWNLOAD_MARGIN_SELL_VOLUME: 1021, //卖出信息-卖出量
  7590. JOB_DOWNLOAD_MARGIN_SELL_REPAY: 1022, //卖出信息-偿还量
  7591. JOB_DOWNLOAD_MARGIN_SELL_NET: 1023, //卖出信息-融券净卖出
  7592. JOB_DOWNLOAD_NEWS_ANALYSIS_NEGATIVE: 2000, //负面新闻统计
  7593. JOB_DOWNLOAD_NEWS_ANALYSIS_RESEARCH: 2001, //机构调研
  7594. JOB_DOWNLOAD_NEWS_ANALYSIS_INTERACT: 2002, //互动易
  7595. JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE: 2003, //股东增持
  7596. JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE2: 2004, //股东减持
  7597. JOB_DOWNLOAD_NEWS_ANALYSIS_TRUSTHOLDER: 2005, //信托持股
  7598. JOB_DOWNLOAD_NEWS_ANALYSIS_BLOCKTRADING: 2006, //大宗交易
  7599. JOB_DOWNLOAD_NEWS_ANALYSIS_COMPANYNEWS: 2007, //官网新闻
  7600. JOB_DOWNLOAD_NEWS_ANALYSIS_TOPMANAGERS: 2008, //高管要闻
  7601. JOB_DOWNLOAD_NEWS_ANALYSIS_PLEDGE: 2009, //股权质押
  7602. JOB_CUSTOM_FUNCTION_DATA: 6000, //自定义函数
  7603. JOB_CUSTOM_VARIANT_DATA: 6001, //自定义变量
  7604. JOB_DOWNLOAD_CUSTOM_API_DATA: 30000, //自定义数据
  7605. JOB_RUN_SCRIPT:10000, //执行脚本
  7606. //融资融券
  7607. GetMarginJobID: function (value)
  7608. {
  7609. let dataMap = new Map([
  7610. [1, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BALANCE], //MARGIN(1) 融资融券余额
  7611. [2, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_RATE], //MARGIN(2) 融资占比
  7612. [3, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_BALANCE], //MARGIN(3) 买入信息-融资余额
  7613. [4, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_AMOUNT], //MARGIN(4) 买入信息-买入额
  7614. [5, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_REPAY], //MARGIN(5) 买入信息-偿还额
  7615. [6, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_NET], //MARGIN(6) 买入信息-融资净买入
  7616. [7, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_BALANCE], //MARGIN(7) 卖出信息-融券余量
  7617. [8, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_VOLUME], //MARGIN(8) 卖出信息-卖出量
  7618. [9, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_REPAY], //MARGIN(9) 卖出信息-偿还量
  7619. [10, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_NET], //MARGIN(10) 卖出信息-融券净卖出
  7620. ]);
  7621. if (dataMap.has(value)) return dataMap.get(value);
  7622. return null;
  7623. },
  7624. GetNewsAnalysisID: function (value)
  7625. {
  7626. let dataMap = new Map([
  7627. [1, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_NEGATIVE], //NEWS(1) 负面新闻统计
  7628. [2, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_RESEARCH], //NEWS(2) 机构调研统计
  7629. [3, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_INTERACT], //NEWS(3) 互动易
  7630. [4, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE], //NEWS(4) 股东增持
  7631. [5, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE2], //NEWS(5) 股东减持
  7632. [6, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_TRUSTHOLDER], //NEWS(6) 信托持股
  7633. [7, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_BLOCKTRADING], //NEWS(7) 大宗交易
  7634. [8, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_COMPANYNEWS], //NEWS(8) 官网新闻
  7635. [9, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_TOPMANAGERS], //NEWS(9) 高管要闻
  7636. [10, JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_PLEDGE], //NEWS(10) 股权质押
  7637. ]);
  7638. if (dataMap.has(value)) return dataMap.get(value);
  7639. return null;
  7640. }
  7641. };
  7642. function JSExecute(ast,option)
  7643. {
  7644. this.AST=ast; //语法树
  7645. this.ErrorHandler=new ErrorHandler();
  7646. this.VarTable=new Map(); //变量表
  7647. this.OutVarTable=new Array(); //输出变量
  7648. this.Arguments=[];
  7649. //脚本自动变量表, 只读
  7650. this.ConstVarTable=new Map([
  7651. //个股数据
  7652. ['CLOSE', null], ['VOL', null], ['OPEN', null], ['HIGH', null], ['LOW', null], ['AMOUNT', null], ['AMO', null], ['VOLINSTK',null],
  7653. ['C', null], ['V', null], ['O', null], ['H', null], ['L', null], ['VOLR', null],
  7654. //日期类
  7655. ['DATE', null], ['YEAR', null], ['MONTH', null], ['PERIOD', null], ['WEEK', null],["TIME",null],
  7656. //大盘数据
  7657. ['INDEXA',null],['INDEXC',null],['INDEXH',null],['INDEXL',null],['INDEXO',null],['INDEXV',null],
  7658. ['INDEXADV', null], ['INDEXDEC', null],
  7659. ['CURRBARSCOUNT', null], //到最后交易日的周期数
  7660. ['ISLASTBAR', null], //判断是否为最后一个周期
  7661. ["TOTALCAPITAL",null], //总股本
  7662. ['CAPITAL', null], //流通股本(手)
  7663. ['EXCHANGE', null], //换手率
  7664. ['SETCODE', null], //市场类型
  7665. ['CODE', null], //品种代码
  7666. ['STKNAME', null], //品种名称
  7667. ['HYBLOCK', null], //所属行业板块
  7668. ['DYBLOCK', null], //所属地域板块
  7669. ['GNBLOCK', null], //所属概念
  7670. ["FGBLOCK",null], //所属风格板块
  7671. ["ZSBLOCK",null], //所属指数板块
  7672. ["ZHBLOCK",null], //所属组合板块
  7673. ["ZDBLOCK",null], //所属自定义板块
  7674. ["HYZSCODE",null],
  7675. ["GNBLOCKNUM",null], //所属概念板块的个数
  7676. ["FGBLOCKNUM",null], //所属风格板块的个数
  7677. ["ZSBLOCKNUM",null], //所属指数板块的个数
  7678. ["ZHBLOCKNUM",null], //所属组合板块的个数
  7679. ["ZDBLOCKNUM",null], //所属自定义板块的个数
  7680. ["HYSYL",null], //指数市盈率或个股所属行业的市盈率
  7681. ["HYSJL",null], //指数市净率或个股所属行业的市净率
  7682. ['DRAWNULL', null]
  7683. ]);
  7684. this.SymbolData=new JSSymbolData(this.AST,option,this);
  7685. this.Algorithm = new JSAlgorithm(this.ErrorHandler, this.SymbolData);
  7686. this.Draw = new JSDraw(this.ErrorHandler, this.SymbolData);
  7687. this.JobList=[]; //执行的任务队列
  7688. this.UpdateUICallback=null; //回调
  7689. this.CallbackParam=null;
  7690. if (option)
  7691. {
  7692. if (option.Callback) this.UpdateUICallback=option.Callback;
  7693. if (option.CallbackParam) this.CallbackParam=option.CallbackParam;
  7694. if (option.Arguments) this.Arguments=option.Arguments;
  7695. }
  7696. this.Execute=function()
  7697. {
  7698. JSConsole.Complier.Log('[JSExecute::Execute] JobList', this.JobList);
  7699. this.RunNextJob();
  7700. }
  7701. this.RunNextJob=function()
  7702. {
  7703. if (this.JobList.length<=0) return;
  7704. var jobItem=this.JobList.shift();
  7705. switch (jobItem.ID)
  7706. {
  7707. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_SYMBOL_DATA:
  7708. return this.SymbolData.GetSymbolData();
  7709. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_INDEX_DATA:
  7710. return this.SymbolData.GetIndexData();
  7711. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_INDEX_INCREASE_DATA:
  7712. return this.SymbolData.GetIndexIncreaseData(jobItem);
  7713. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_SYMBOL_LATEST_DATA:
  7714. return this.SymbolData.GetLatestData(jobItem);
  7715. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_VOLR_DATA: //量比
  7716. return this.SymbolData.GetVolRateData(jobItem);
  7717. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_FINONE:
  7718. return this.SymbolData.GetFinOne(jobItem);
  7719. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_FINVALUE:
  7720. return this.SymbolData.GetFinValue(jobItem);
  7721. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_FINANCE:
  7722. return this.SymbolData.GetFinance(jobItem);
  7723. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_GPJYVALUE:
  7724. return this.SymbolData.GetGPJYValue(jobItem);
  7725. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_VARIANT: //CAPITAL, TOTALCAPITAL
  7726. return this.SymbolData.GetVariantData(jobItem);
  7727. case JS_EXECUTE_JOB_ID.JOB_CUSTOM_VARIANT_DATA:
  7728. return this.SymbolData.GetCustomVariantData(jobItem);
  7729. case JS_EXECUTE_JOB_ID.JOB_CUSTOM_FUNCTION_DATA:
  7730. return this.SymbolData.GetCustomFunctionData(jobItem);
  7731. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BALANCE:
  7732. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_RATE:
  7733. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_BALANCE: //买入信息-融资余额
  7734. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_AMOUNT: //买入信息-买入额
  7735. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_REPAY: //买入信息-偿还额
  7736. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_BUY_NET: //买入信息-融资净买入
  7737. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_BALANCE: //卖出信息-融券余量
  7738. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_VOLUME: //卖出信息-卖出量
  7739. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_REPAY: //卖出信息-偿还量
  7740. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_MARGIN_SELL_NET: //卖出信息-融券净卖出
  7741. return this.SymbolData.GetMarginData(jobItem.ID);
  7742. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_NEGATIVE: //负面新闻
  7743. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_RESEARCH: //机构调研
  7744. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_INTERACT: //互动易
  7745. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE: //股东增持
  7746. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_HOLDERCHANGE2: //股东减持
  7747. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_TRUSTHOLDER: //信托持股
  7748. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_BLOCKTRADING: //大宗交易
  7749. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_COMPANYNEWS: //官网新闻
  7750. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_TOPMANAGERS: //高管要闻
  7751. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_NEWS_ANALYSIS_PLEDGE: //股权质押
  7752. return this.SymbolData.GetNewsAnalysisData(jobItem.ID);
  7753. case JS_EXECUTE_JOB_ID.JOB_DOWNLOAD_CUSTOM_API_DATA:
  7754. return this.SymbolData.DownloadCustomAPIData(jobItem);
  7755. case JS_EXECUTE_JOB_ID.JOB_RUN_SCRIPT:
  7756. return this.Run();
  7757. }
  7758. }
  7759. this.ReadSymbolData=function(name,node)
  7760. {
  7761. switch(name)
  7762. {
  7763. case 'CLOSE':
  7764. case 'C':
  7765. case 'VOL':
  7766. case 'V':
  7767. case 'OPEN':
  7768. case 'O':
  7769. case 'HIGH':
  7770. case 'H':
  7771. case 'LOW':
  7772. case 'L':
  7773. case 'AMOUNT':
  7774. case 'VOLINSTK':
  7775. return this.SymbolData.GetSymbolCacheData(name);
  7776. case 'VOLR':
  7777. return this.SymbolData.GetVolRateCacheData(node);
  7778. //大盘数据
  7779. case 'INDEXA':
  7780. case 'INDEXC':
  7781. case 'INDEXH':
  7782. case 'INDEXO':
  7783. case 'INDEXV':
  7784. case 'INDEXL':
  7785. case 'INDEXADV':
  7786. case 'INDEXDEC':
  7787. return this.SymbolData.GetIndexCacheData(name);
  7788. case 'CURRBARSCOUNT':
  7789. return this.SymbolData.GetCurrBarsCount();
  7790. case 'ISLASTBAR':
  7791. return this.SymbolData.GetIsLastBar();
  7792. case "TOTALCAPITAL":
  7793. case 'CAPITAL':
  7794. case 'EXCHANGE':
  7795. case "HYBLOCK":
  7796. case "DYBLOCK":
  7797. case "GNBLOCK":
  7798. case "FGBLOCK":
  7799. case "ZSBLOCK":
  7800. case "ZHBLOCK":
  7801. case "ZDBLOCK":
  7802. case "HYZSCODE":
  7803. case "GNBLOCKNUM":
  7804. case "FGBLOCKNUM":
  7805. case "ZSBLOCKNUM":
  7806. case "ZHBLOCKNUM":
  7807. case "ZDBLOCKNUM":
  7808. case "HYSYL":
  7809. case "HYSJL":
  7810. return this.SymbolData.GetStockCacheData({ VariantName:name, Node:node });
  7811. case 'SETCODE':
  7812. return this.SymbolData.SETCODE();
  7813. case 'CODE':
  7814. return this.SymbolData.GetSymbol();
  7815. case 'STKNAME':
  7816. return this.SymbolData.GetName();
  7817. case 'TIME':
  7818. return this.SymbolData.TIME();
  7819. case 'DATE':
  7820. return this.SymbolData.DATE();
  7821. case 'YEAR':
  7822. return this.SymbolData.YEAR();
  7823. case 'MONTH':
  7824. return this.SymbolData.MONTH();
  7825. case 'WEEK':
  7826. return this.SymbolData.WEEK();
  7827. case 'PERIOD':
  7828. return this.SymbolData.PERIOD();
  7829. case 'DRAWNULL':
  7830. return this.SymbolData.GetDrawNull();
  7831. }
  7832. }
  7833. this.ReadCustomVariant=function(name,node)
  7834. {
  7835. return this.SymbolData.GetStockCacheData({ VariantName:name, Node:node });
  7836. }
  7837. //读取变量
  7838. this.ReadVariable=function(name,node)
  7839. {
  7840. if (this.ConstVarTable.has(name))
  7841. {
  7842. let data=this.ConstVarTable.get(name);
  7843. if (data==null) //动态加载,用到再加载
  7844. {
  7845. data=this.ReadSymbolData(name,node);
  7846. this.ConstVarTable.set(name,data);
  7847. }
  7848. return data;
  7849. }
  7850. if (g_JSComplierResource.IsCustomVariant(name)) return this.ReadCustomVariant(name,node); //读取自定义变量
  7851. if (this.VarTable.has(name)) return this.VarTable.get(name);
  7852. this.ThrowUnexpectedNode(node, '变量'+name+'不存在');
  7853. return null;
  7854. }
  7855. this.ReadMemberVariable = function (node)
  7856. {
  7857. var obj = node.Object;
  7858. var member = node.Property;
  7859. let maiObj;
  7860. if (obj.Type == Syntax.BinaryExpression || obj.Type == Syntax.LogicalExpression)
  7861. maiObj = this.VisitBinaryExpression(obj);
  7862. else if (obj.Type == Syntax.CallExpression)
  7863. maiObj = this.VisitCallExpression(obj);
  7864. else
  7865. maiObj = this.GetNodeValue(obj);
  7866. if (!maiObj) return null;
  7867. var value = maiObj[member.Name];
  7868. if (value) return value;
  7869. return null;
  7870. }
  7871. //单数据转成数组 个数和历史数据一致
  7872. this.SingleDataToArrayData = function (value)
  7873. {
  7874. let count = this.SymbolData.Data.Data.length;
  7875. let result = [];
  7876. for (let i = 0; i < count; ++i)
  7877. {
  7878. result[i] = value;
  7879. }
  7880. return result;
  7881. }
  7882. this.RunAST=function()
  7883. {
  7884. //预定义的变量
  7885. for(let i in this.Arguments)
  7886. {
  7887. let item =this.Arguments[i];
  7888. this.VarTable.set(item.Name,item.Value);
  7889. }
  7890. if (!this.AST) this.ThrowError();
  7891. if (!this.AST.Body) this.ThrowError();
  7892. for(let i in this.AST.Body)
  7893. {
  7894. let item =this.AST.Body[i];
  7895. this.VisitNode(item);
  7896. //输出变量
  7897. if (item.Type==Syntax.ExpressionStatement && item.Expression)
  7898. {
  7899. if (item.Expression.Type==Syntax.AssignmentExpression && item.Expression.Operator==':' && item.Expression.Left)
  7900. {
  7901. let assignmentItem=item.Expression;
  7902. let varName=assignmentItem.Left.Name;
  7903. let outVar=this.VarTable.get(varName);
  7904. var type=0;
  7905. if (!Array.isArray(outVar))
  7906. {
  7907. if (typeof (outVar) == 'string')
  7908. {
  7909. var floatValue=parseFloat(outVar);
  7910. if (IFrameSplitOperator.IsNumber(floatValue))
  7911. {
  7912. outVar=this.SingleDataToArrayData(floatValue);
  7913. }
  7914. else
  7915. {
  7916. outVar=this.SingleDataToArrayData(outVar);
  7917. type=1001;
  7918. }
  7919. }
  7920. else outVar = this.SingleDataToArrayData(outVar);
  7921. }
  7922. this.OutVarTable.push({Name:varName, Data:outVar,Type:type});
  7923. }
  7924. else if (item.Expression.Type==Syntax.CallExpression)
  7925. {
  7926. let callItem=item.Expression;
  7927. if (this.Draw.IsDrawFunction(callItem.Callee.Name))
  7928. {
  7929. let draw=callItem.Draw;
  7930. draw.Name=callItem.Callee.Name;
  7931. this.OutVarTable.push({Name:draw.Name, Draw:draw, Type:1});
  7932. }
  7933. else
  7934. {
  7935. let outVar=callItem.Out;
  7936. varName=`__temp_c_${callItem.Callee.Name}_${i}__`;
  7937. var type=0;
  7938. if (!Array.isArray(outVar)) outVar=this.SingleDataToArrayData(outVar);
  7939. this.OutVarTable.push({Name:varName, Data:outVar,Type:type,NoneName:true});
  7940. }
  7941. }
  7942. else if (item.Expression.Type==Syntax.Identifier)
  7943. {
  7944. let varName=item.Expression.Name;
  7945. let outVar=this.ReadVariable(varName,item.Expression);
  7946. var type=0;
  7947. if (!Array.isArray(outVar))
  7948. {
  7949. if (typeof(outVar)=='string') outVar=this.SingleDataToArrayData(parseFloat(outVar));
  7950. else outVar=this.SingleDataToArrayData(outVar);
  7951. }
  7952. varName="__temp_i_"+i+"__";
  7953. this.OutVarTable.push({Name:varName, Data:outVar, Type:type, NoneName:true});
  7954. }
  7955. else if (item.Expression.Type==Syntax.BinaryExpression)
  7956. {
  7957. var varName="__temp_b_"+i+"__";
  7958. let outVar=item.Expression.Out;
  7959. var type=0;
  7960. if (!Array.isArray(outVar)) outVar=this.SingleDataToArrayData(outVar);
  7961. this.OutVarTable.push({Name:varName, Data:outVar,Type:type, NoneName:true});
  7962. }
  7963. else if (item.Expression.Type==Syntax.LogicalExpression) //逻辑语句 如 T1 AND T2
  7964. {
  7965. var varName="__temp_l_"+i+"__";
  7966. let outVar=item.Expression.Out;
  7967. var type=0;
  7968. if (!Array.isArray(outVar)) outVar=this.SingleDataToArrayData(outVar);
  7969. this.OutVarTable.push({Name:varName, Data:outVar,Type:type, NoneName:true});
  7970. }
  7971. else if (item.Expression.Type==Syntax.SequenceExpression)
  7972. {
  7973. let varName;
  7974. let draw;
  7975. let color;
  7976. let lineWidth;
  7977. let colorStick=false;
  7978. let pointDot=false;
  7979. let circleDot=false;
  7980. let lineStick=false;
  7981. let stick=false;
  7982. let volStick=false;
  7983. let isShow = true;
  7984. let isExData = false;
  7985. let isDotLine = false;
  7986. let isOverlayLine = false; //叠加线
  7987. let isNoneName=false;
  7988. var isShowTitle=true;
  7989. //显示在位置之上,对于DRAWTEXT和DRAWNUMBER等函数有用,放在语句的最后面(不能与LINETHICK等函数共用),比如:
  7990. //DRAWNUMBER(CLOSE>OPEN,HIGH,CLOSE),DRAWABOVE;
  7991. var isDrawAbove=false;
  7992. for(let j in item.Expression.Expression)
  7993. {
  7994. let itemExpression=item.Expression.Expression[j];
  7995. if (itemExpression.Type==Syntax.AssignmentExpression && itemExpression.Operator==':' && itemExpression.Left)
  7996. {
  7997. varName = itemExpression.Left.Name;
  7998. let varValue = this.VarTable.get(varName);
  7999. if (!Array.isArray(varValue))
  8000. {
  8001. varValue = this.SingleDataToArrayData(varValue);
  8002. this.VarTable.set(varName, varValue); //把常量放到变量表里
  8003. }
  8004. }
  8005. else if (itemExpression.Type==Syntax.Identifier)
  8006. {
  8007. let value=itemExpression.Name;
  8008. if (value==='COLORSTICK') colorStick=true;
  8009. else if (value==='POINTDOT') pointDot=true;
  8010. else if (value==='CIRCLEDOT') circleDot=true;
  8011. else if (value == 'DOTLINE') isDotLine = true;
  8012. else if (value==='LINESTICK') lineStick=true;
  8013. else if (value==='STICK') stick=true;
  8014. else if (value==='VOLSTICK') volStick=true;
  8015. else if (value==="DRAWABOVE") isDrawAbove=true;
  8016. else if (value.indexOf('COLOR')==0) color=value;
  8017. else if (value.indexOf('LINETHICK')==0) lineWidth=value;
  8018. else if (value.indexOf('NODRAW') == 0) isShow = false;
  8019. else if (value.indexOf('EXDATA') == 0) isExData = true; //扩展数据, 不显示再图形里面
  8020. else if (value.indexOf('LINEOVERLAY') == 0) isOverlayLine = true;
  8021. else if (value.indexOf("NOTEXT")==0 || value.indexOf("NOTITLE")==0) isShowTitle=false; //标题不显示
  8022. else
  8023. {
  8024. varName=itemExpression.Name;
  8025. let varValue=this.ReadVariable(varName,itemExpression);
  8026. if (!Array.isArray(varValue)) varValue=this.SingleDataToArrayData(varValue);
  8027. varName="__temp_si_"+i+"__";
  8028. isNoneName=true;
  8029. this.VarTable.set(varName,varValue); //放到变量表里
  8030. }
  8031. }
  8032. else if (itemExpression.Type == Syntax.Literal) //常量
  8033. {
  8034. let aryValue = this.SingleDataToArrayData(itemExpression.Value);
  8035. varName = itemExpression.Value.toString();
  8036. this.VarTable.set(varName, aryValue); //把常量放到变量表里
  8037. }
  8038. else if (itemExpression.Type==Syntax.CallExpression)
  8039. {
  8040. if (this.Draw.IsDrawFunction(itemExpression.Callee.Name))
  8041. {
  8042. draw=itemExpression.Draw;
  8043. draw.Name=itemExpression.Callee.Name;
  8044. }
  8045. else
  8046. {
  8047. let varValue=itemExpression.Out;
  8048. varName=`__temp_sc_${itemExpression.Callee.Name}_${i}__`;
  8049. isNoneName=true;
  8050. this.VarTable.set(varName,varValue);
  8051. }
  8052. }
  8053. else if (itemExpression.Type==Syntax.BinaryExpression)
  8054. {
  8055. varName="__temp_sb_"+i+"__";
  8056. let aryValue=itemExpression.Out;
  8057. isNoneName=true;
  8058. this.VarTable.set(varName,aryValue);
  8059. }
  8060. }
  8061. if (pointDot && varName) //圆点
  8062. {
  8063. let outVar=this.VarTable.get(varName);
  8064. let value={Name:varName, Data:outVar, Radius:g_JSChartResource.POINTDOT.Radius, Type:3};
  8065. if (color) value.Color=color;
  8066. if (lineWidth) value.LineWidth = lineWidth;
  8067. this.OutVarTable.push(value);
  8068. }
  8069. else if (circleDot && varName) //圆点
  8070. {
  8071. let outVar=this.VarTable.get(varName);
  8072. let value={Name:varName, Data:outVar, Radius:g_JSChartResource.CIRCLEDOT.Radius, Type:3};
  8073. if (color) value.Color=color;
  8074. if (lineWidth) value.LineWidth = lineWidth;
  8075. this.OutVarTable.push(value);
  8076. }
  8077. else if (lineStick && varName) //LINESTICK 同时画出柱状线和指标线
  8078. {
  8079. let outVar=this.VarTable.get(varName);
  8080. let value={Name:varName, Data:outVar, Type:4};
  8081. if (color) value.Color=color;
  8082. if (lineWidth) value.LineWidth=lineWidth;
  8083. this.OutVarTable.push(value);
  8084. }
  8085. else if (stick && varName) //STICK 画柱状线
  8086. {
  8087. let outVar=this.VarTable.get(varName);
  8088. let value={Name:varName, Data:outVar, Type:5};
  8089. if (color) value.Color=color;
  8090. if (lineWidth) value.LineWidth=lineWidth;
  8091. this.OutVarTable.push(value);
  8092. }
  8093. else if (volStick && varName) //VOLSTICK 画彩色柱状线
  8094. {
  8095. let outVar=this.VarTable.get(varName);
  8096. let value={Name:varName, Data:outVar, Type:6};
  8097. if (color) value.Color=color;
  8098. this.OutVarTable.push(value);
  8099. }
  8100. else if (colorStick && varName) //CYW: SUM(VAR4,10)/10000, COLORSTICK; 画上下柱子
  8101. {
  8102. let outVar=this.VarTable.get(varName);
  8103. let value={Name:varName, Data:outVar, Color:color, Type:2};
  8104. if (lineWidth) value.LineWidth=lineWidth;
  8105. if (color) value.Color=color;
  8106. this.OutVarTable.push(value);
  8107. }
  8108. else if (varName && color)
  8109. {
  8110. let outVar=this.VarTable.get(varName);
  8111. let value={Name:varName, Data:outVar, Color:color, Type:0};
  8112. if (lineWidth) value.LineWidth=lineWidth;
  8113. if (isShow == false) value.IsShow = false;
  8114. if (isExData == true) value.IsExData = true;
  8115. if (isDotLine == true) value.IsDotLine = true;
  8116. if (isOverlayLine == true) value.IsOverlayLine = true;
  8117. if (isNoneName==true) value.NoneName=true;
  8118. if (isShowTitle==false) value.IsShowTitle=false;
  8119. this.OutVarTable.push(value);
  8120. }
  8121. else if (draw)
  8122. {
  8123. var outVar = { Name: draw.Name, Draw: draw, Type: 1 };
  8124. if (color) outVar.Color = color;
  8125. if (lineWidth) outVar.LineWidth = lineWidth;
  8126. if (isDrawAbove) outVar.IsDrawAbove=true;
  8127. this.OutVarTable.push(outVar);
  8128. }
  8129. else if (varName)
  8130. {
  8131. let outVar = this.VarTable.get(varName);
  8132. let value = { Name: varName, Data: outVar, Type: 0 };
  8133. if (color) value.Color = color;
  8134. if (lineWidth) value.LineWidth = lineWidth;
  8135. if (isShow == false) value.IsShow = false;
  8136. if (isExData == true) value.IsExData = true;
  8137. if (isDotLine == true) value.IsDotLine = true;
  8138. if (isOverlayLine == true) value.IsOverlayLine = true;
  8139. if (isShowTitle==false) value.IsShowTitle=false;
  8140. this.OutVarTable.push(value);
  8141. }
  8142. }
  8143. }
  8144. }
  8145. JSConsole.Complier.Log('[JSExecute::Run]', this.VarTable);
  8146. return this.OutVarTable;
  8147. }
  8148. this.Run=function()
  8149. {
  8150. let data=this.RunAST();//执行脚本
  8151. JSConsole.Complier.Log('[JSComplier.Run] execute finish', data);
  8152. if (this.UpdateUICallback)
  8153. {
  8154. JSConsole.Complier.Log('[JSComplier.Run] invoke UpdateUICallback.');
  8155. this.UpdateUICallback(data,this.CallbackParam);
  8156. }
  8157. }
  8158. this.VisitNode=function(node)
  8159. {
  8160. switch(node.Type)
  8161. {
  8162. case Syntax.SequenceExpression:
  8163. this.VisitSequenceExpression(node);
  8164. break;
  8165. case Syntax.ExpressionStatement:
  8166. this.VisitNode(node.Expression);
  8167. break;
  8168. case Syntax.AssignmentExpression:
  8169. this.VisitAssignmentExpression(node);
  8170. break;
  8171. case Syntax.BinaryExpression:
  8172. case Syntax.LogicalExpression:
  8173. this.VisitBinaryExpression(node);
  8174. break;
  8175. case Syntax.CallExpression:
  8176. this.VisitCallExpression(node);
  8177. break;
  8178. }
  8179. }
  8180. this.VisitSequenceExpression=function(node)
  8181. {
  8182. for(let i in node.Expression)
  8183. {
  8184. let item =node.Expression[i];
  8185. this.VisitNode(item);
  8186. }
  8187. }
  8188. //函数调用
  8189. this.VisitCallExpression=function(node)
  8190. {
  8191. let funcName=node.Callee.Name;
  8192. let args=[];
  8193. for(let i in node.Arguments)
  8194. {
  8195. let item=node.Arguments[i];
  8196. let value;
  8197. if (item.Type==Syntax.BinaryExpression || item.Type==Syntax.LogicalExpression)
  8198. value=this.VisitBinaryExpression(item);
  8199. else if (item.Type==Syntax.CallExpression)
  8200. value=this.VisitCallExpression(item);
  8201. else
  8202. value=this.GetNodeValue(item);
  8203. args.push(value);
  8204. }
  8205. //if (JS_EXECUTE_DEBUG_LOG) JSConsole.Complier.Log('[JSExecute::VisitCallExpression]' , funcName, '(', args.toString() ,')');
  8206. if (g_JSComplierResource.IsCustomFunction(funcName)) //自定义函数
  8207. {
  8208. var data=this.Algorithm.CallCustomFunction(funcName, args, this.SymbolData, node);
  8209. node.Out=[];
  8210. node.Draw=null;
  8211. if (data)
  8212. {
  8213. if (data.Out) node.Out=data.Out;
  8214. if (data.Draw) node.Draw=data.Draw;
  8215. }
  8216. return node.Out;
  8217. }
  8218. switch(funcName)
  8219. {
  8220. case 'DYNAINFO': //行情最新数据
  8221. node.Out=this.SymbolData.GetLatestCacheData(args[0]);
  8222. break;
  8223. case 'STICKLINE':
  8224. node.Draw=this.Draw.STICKLINE(args[0],args[1],args[2],args[3],args[4]);
  8225. node.Out=[];
  8226. break;
  8227. case 'DRAWTEXT':
  8228. node.Draw=this.Draw.DRAWTEXT(args[0],args[1],args[2]);
  8229. node.Out=[];
  8230. break;
  8231. case 'SUPERDRAWTEXT':
  8232. node.Draw = this.Draw.SUPERDRAWTEXT(args[0], args[1], args[2], args[3], args[4]);
  8233. node.Out = [];
  8234. break;
  8235. case 'DRAWTEXT_FIX':
  8236. node.Draw=this.Draw.DRAWTEXT_FIX(args[0],args[1],args[2],args[3],args[4]);
  8237. node.Out=[];
  8238. break;
  8239. case 'DRAWICON':
  8240. node.Draw = this.Draw.DRAWICON(args[0], args[1], args[2]);
  8241. node.Out = [];
  8242. break;
  8243. case 'DRAWLINE':
  8244. node.Draw=this.Draw.DRAWLINE(args[0],args[1],args[2],args[3],args[4]);
  8245. node.Out=node.Draw.DrawData;
  8246. break;
  8247. case 'DRAWBAND':
  8248. node.Draw=this.Draw.DRAWBAND(args[0],args[1],args[2],args[3]);
  8249. node.Out=[];
  8250. break;
  8251. case 'DRAWKLINE':
  8252. node.Draw = this.Draw.DRAWKLINE(args[0], args[1], args[2], args[3]);
  8253. node.Out = [];
  8254. break;
  8255. case 'DRAWKLINE_IF':
  8256. node.Draw = this.Draw.DRAWKLINE_IF(args[0], args[1], args[2], args[3], args[4]);
  8257. node.Out = [];
  8258. break;
  8259. case 'PLOYLINE':
  8260. case 'POLYLINE':
  8261. node.Draw = this.Draw.POLYLINE(args[0], args[1]);
  8262. node.Out = node.Draw.DrawData;
  8263. break;
  8264. case 'DRAWNUMBER':
  8265. node.Draw = this.Draw.DRAWNUMBER(args[0], args[1], args[2]);
  8266. node.Out = node.Draw.DrawData.Value;
  8267. break;
  8268. case 'RGB':
  8269. node.Out = this.Draw.RGB(args[0], args[1], args[2]);
  8270. break;
  8271. case 'RGBA':
  8272. node.Out = this.Draw.RGBA(args[0], args[1], args[2],args[3]);
  8273. break;
  8274. case 'DRAWRECTREL':
  8275. node.Draw = this.Draw.DRAWRECTREL(args[0], args[1], args[2], args[3], args[4]);
  8276. node.Out = [];
  8277. break;
  8278. case 'DRAWGBK':
  8279. node.Draw=this.Draw.DRAWGBK(args[0],args[1],args[2],args[3]);
  8280. node.Out=[];
  8281. break;
  8282. case 'DRAWGBK2':
  8283. node.Draw=this.Draw.DRAWGBK2(args[0],args[1],args[2],args[3]);
  8284. node.Out=[];
  8285. break;
  8286. case 'CODELIKE':
  8287. node.Out=this.SymbolData.CODELIKE(args[0]);
  8288. break;
  8289. case 'NAMELIKE':
  8290. node.Out = this.SymbolData.NAMELIKE(args[1]);
  8291. break;
  8292. case 'REFDATE':
  8293. node.Out = this.SymbolData.REFDATE(args[0], args[1]);
  8294. break;
  8295. case 'FINANCE':
  8296. node.Out=this.SymbolData.GetStockCacheData( {FunctionName:funcName, Args:args, ArgCount:1, Node:node } );
  8297. break;
  8298. case "FINVALUE":
  8299. node.Out=this.SymbolData.GetStockCacheData( {FunctionName:funcName, Args:args, ArgCount:1, Node:node } );
  8300. break;
  8301. case "FINONE":
  8302. node.Out=this.SymbolData.GetStockCacheData( {FunctionName:funcName, Args:args, ArgCount:3, Node:node } );
  8303. break;
  8304. case "GPJYVALUE":
  8305. node.Out=this.SymbolData.GetStockCacheData( {FunctionName:funcName, Args:args, ArgCount:3, Node:node } );
  8306. break;
  8307. case "MARGIN":
  8308. node.Out = this.SymbolData.GetMarginCacheData(args[0], node);
  8309. break;
  8310. case "NEWS":
  8311. node.Out = this.SymbolData.GetNewsAnalysisCacheData(args[0], node);
  8312. break;
  8313. case 'UPCOUNT':
  8314. case 'DOWNCOUNT':
  8315. node.Out = this.SymbolData.GetIndexIncreaseCacheData(funcName, args[0], node);
  8316. break;
  8317. case 'LOADAPIDATA':
  8318. node.Out = this.SymbolData.GetCustomApiData(args);
  8319. break;
  8320. case "INBLOCK":
  8321. node.Out=this.SymbolData.IsInBlock(args[0],node);
  8322. break;
  8323. default:
  8324. node.Out=this.Algorithm.CallFunction(funcName, args,node);
  8325. break;
  8326. }
  8327. return node.Out;
  8328. }
  8329. //赋值
  8330. this.VisitAssignmentExpression=function(node)
  8331. {
  8332. let left=node.Left;
  8333. if (left.Type!=Syntax.Identifier) this.ThrowUnexpectedNode(node);
  8334. let varName=left.Name;
  8335. let right=node.Right;
  8336. let value=null;
  8337. if (right.Type==Syntax.BinaryExpression || right.Type==Syntax.LogicalExpression)
  8338. value=this.VisitBinaryExpression(right);
  8339. else if (right.Type==Syntax.CallExpression)
  8340. value=this.VisitCallExpression(right);
  8341. else if (right.Type==Syntax.Literal)
  8342. value=right.Value;
  8343. else if (right.Type==Syntax.Identifier) //右值是变量
  8344. value=this.ReadVariable(right.Name,right);
  8345. else if (right.Type == Syntax.MemberExpression)
  8346. value = this.ReadMemberVariable(right);
  8347. if (JS_EXECUTE_DEBUG_LOG) JSConsole.Complier.Log('[JSExecute::VisitAssignmentExpression]' , varName, ' = ',value);
  8348. this.VarTable.set(varName,value);
  8349. }
  8350. //逻辑运算
  8351. this.VisitBinaryExpression=function(node)
  8352. {
  8353. let stack=[];
  8354. stack.push(node);
  8355. let temp=null;
  8356. while(stack.length!=0)
  8357. {
  8358. temp=stack[stack.length-1];
  8359. if (temp.Left && node!=temp.Left && node!=temp.Right)
  8360. {
  8361. stack.push(temp.Left);
  8362. }
  8363. else if (temp.Right && node!=temp.Right)
  8364. {
  8365. stack.push(temp.Right);
  8366. }
  8367. else
  8368. {
  8369. let value=stack.pop();
  8370. if (value.Type==Syntax.BinaryExpression) //只遍历操作符就可以
  8371. {
  8372. let leftValue=this.GetNodeValue(value.Left);
  8373. let rightValue=this.GetNodeValue(value.Right);
  8374. if (JS_EXECUTE_DEBUG_LOG) JSConsole.Complier.Log('[JSExecute::VisitBinaryExpression] BinaryExpression',value , leftValue, rightValue);
  8375. value.Out=null; //保存中间值
  8376. switch(value.Operator)
  8377. {
  8378. case '-':
  8379. value.Out=this.Algorithm.Subtract(leftValue,rightValue);
  8380. break;
  8381. case '*':
  8382. value.Out=this.Algorithm.Multiply(leftValue,rightValue);
  8383. break;
  8384. case '/':
  8385. value.Out=this.Algorithm.Divide(leftValue,rightValue)
  8386. break;
  8387. case '+':
  8388. value.Out=this.Algorithm.Add(leftValue,rightValue);
  8389. break;
  8390. case '>':
  8391. value.Out=this.Algorithm.GT(leftValue,rightValue);
  8392. break;
  8393. case '>=':
  8394. value.Out=this.Algorithm.GTE(leftValue,rightValue);
  8395. break;
  8396. case '<':
  8397. value.Out=this.Algorithm.LT(leftValue,rightValue);
  8398. break;
  8399. case '<=':
  8400. value.Out=this.Algorithm.LTE(leftValue,rightValue);
  8401. break;
  8402. case '==':
  8403. case '=':
  8404. value.Out=this.Algorithm.EQ(leftValue,rightValue);
  8405. break;
  8406. case '!=':
  8407. case '<>':
  8408. value.Out = this.Algorithm.NEQ(leftValue, rightValue);
  8409. break;
  8410. }
  8411. if (JS_EXECUTE_DEBUG_LOG) JSConsole.Complier.Log('[JSExecute::VisitBinaryExpression] BinaryExpression',value);
  8412. }
  8413. else if (value.Type==Syntax.LogicalExpression)
  8414. {
  8415. let leftValue=this.GetNodeValue(value.Left);
  8416. let rightValue=this.GetNodeValue(value.Right);
  8417. if (JS_EXECUTE_DEBUG_LOG) JSConsole.Complier.Log('[JSExecute::VisitBinaryExpression] LogicalExpression',value , leftValue, rightValue);
  8418. value.Out=null; //保存中间值
  8419. switch(value.Operator)
  8420. {
  8421. case '&&':
  8422. case 'AND':
  8423. value.Out=this.Algorithm.And(leftValue,rightValue);
  8424. break;
  8425. case '||':
  8426. case 'OR':
  8427. value.Out=this.Algorithm.Or(leftValue,rightValue);
  8428. break;
  8429. }
  8430. if (JS_EXECUTE_DEBUG_LOG) JSConsole.Complier.Log('[JSExecute::VisitBinaryExpression] LogicalExpression',value);
  8431. }
  8432. node=temp;
  8433. }
  8434. }
  8435. return node.Out;
  8436. }
  8437. this.GetNodeValue=function(node)
  8438. {
  8439. switch(node.Type)
  8440. {
  8441. case Syntax.Literal: //数字
  8442. return node.Value;
  8443. case Syntax.UnaryExpression:
  8444. if (node.Operator=='-')
  8445. {
  8446. let value=this.GetNodeValue(node.Argument);
  8447. return this.Algorithm.Subtract(0,value);
  8448. }
  8449. return node.Argument.Value;
  8450. case Syntax.Identifier:
  8451. let value=this.ReadVariable(node.Name,node);
  8452. return value;
  8453. case Syntax.BinaryExpression:
  8454. case Syntax.LogicalExpression:
  8455. return node.Out;
  8456. case Syntax.CallExpression:
  8457. return this.VisitCallExpression(node);
  8458. default:
  8459. this.ThrowUnexpectedNode(node);
  8460. }
  8461. }
  8462. this.ThrowUnexpectedNode=function(node,message)
  8463. {
  8464. let marker=node.Marker;
  8465. let msg=message || "执行异常";
  8466. return this.ErrorHandler.ThrowError(marker.Index,marker.Line,marker.Column,msg);
  8467. }
  8468. this.ThrowError=function()
  8469. {
  8470. }
  8471. }
  8472. //对外导出类
  8473. function JSComplier()
  8474. {
  8475. }
  8476. //词法分析
  8477. JSComplier.Tokenize=function(code)
  8478. {
  8479. JSConsole.Complier.Log('[JSComplier.Tokenize]', code);
  8480. let tokenizer=new Tokenizer(code);
  8481. let tokens=[];
  8482. try
  8483. {
  8484. while(true)
  8485. {
  8486. let token=tokenizer.GetNextToken();
  8487. if (!token) break;
  8488. tokens.push(token);
  8489. }
  8490. }
  8491. catch(e)
  8492. {
  8493. }
  8494. return tokens;
  8495. }
  8496. //语法解析 生成抽象语法树(Abstract Syntax Tree)
  8497. JSComplier.Parse=function(code)
  8498. {
  8499. JSConsole.Complier.Log('[JSComplier.Parse]',code);
  8500. let parser=new JSParser(code);
  8501. parser.Initialize();
  8502. let program=parser.ParseScript();
  8503. let ast=program;
  8504. return ast;
  8505. }
  8506. /*
  8507. 执行
  8508. option.Symbol=股票代码
  8509. option.Name=股票名称
  8510. option.Data=这个股票的ChartData
  8511. option.Right=复权
  8512. option.MaxReqeustDataCount=请求数据的最大个数
  8513. */
  8514. function timeout(ms) {
  8515. return new Promise((resolve) => {
  8516. setTimeout(resolve, ms);
  8517. });
  8518. }
  8519. JSComplier.Execute=function(code,option,errorCallback)
  8520. {
  8521. //异步调用
  8522. var asyncExecute= function()
  8523. {
  8524. try
  8525. {
  8526. JSConsole.Complier.Log('[JSComplier.Execute] code ',code);
  8527. JSConsole.Complier.Log('[JSComplier.Execute] parser .....');
  8528. let parser=new JSParser(code);
  8529. parser.Initialize();
  8530. let program=parser.ParseScript();
  8531. let ast=program;
  8532. JSConsole.Complier.Log('[JSComplier.Execute] parser finish.', ast);
  8533. JSConsole.Complier.Log('[JSComplier.Execute] execute .....');
  8534. let execute=new JSExecute(ast,option);
  8535. execute.JobList=parser.Node.GetDataJobList();
  8536. execute.JobList.push({ID:JS_EXECUTE_JOB_ID.JOB_RUN_SCRIPT});
  8537. let result=execute.Execute();
  8538. }catch(error)
  8539. {
  8540. JSConsole.Complier.Log(error);
  8541. if (errorCallback) errorCallback(error);
  8542. }
  8543. }
  8544. asyncExecute();
  8545. JSConsole.Complier.Log('[JSComplier.Execute] async execute.');
  8546. }
  8547. JSComplier.SetDomain = function (domain, cacheDomain)
  8548. {
  8549. if (domain) g_JSComplierResource.Domain = domain;
  8550. if (cacheDomain) g_JSComplierResource.CacheDomain = cacheDomain;
  8551. }
  8552. JSComplier.AddFunction=function(obj) //添加函数 { Name:函数名, Description:描述信息, IsDownload:是否需要下载数据, Invoke:函数执行(可选) }
  8553. {
  8554. if (!obj || !obj.Name) return;
  8555. var ID=obj.Name.toUpperCase();
  8556. g_JSComplierResource.CustomFunction.Data.set(ID, obj);
  8557. }
  8558. JSComplier.AddVariant=function(obj) //{ Name:变量名, Description:描述信息 }
  8559. {
  8560. if (!obj || !obj.Name) return;
  8561. var ID=obj.Name.toUpperCase();
  8562. g_JSComplierResource.CustomVariant.Data.set(ID, obj);
  8563. }
  8564. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8565. //
  8566. //数据下载
  8567. function DownloadFinanceData(obj)
  8568. {
  8569. this.Url=obj.Url;
  8570. this.RealtimeUrl=obj.RealtimeUrl;
  8571. this.Job=obj.Job;
  8572. this.Symbol=obj.Symbol;
  8573. this.Args=obj.Args;
  8574. this.DataKey=obj.DataKey;
  8575. this.RecvCallback=obj.Callback;
  8576. this.ErrorCallback=obj.ErrorCallback;
  8577. this.Download=function()
  8578. {
  8579. var id=this.Args[0];
  8580. switch(id)
  8581. {
  8582. case 1: //FINANCE(1) 总股本(随时间可能有变化) 股
  8583. case 7: //FINANCE(7) 流通股本(随时间可能有变化) 股
  8584. case "EXCHANGE": //换手率
  8585. this.DownloadHistoryData(id);
  8586. break;
  8587. case 9: //FINANCE(9) 资产负债率
  8588. case 18: //FINANCE(18) 每股公积金
  8589. case 30: //FINANCE(30) 净利润
  8590. case 32: //FINANCE(32) 每股未分配利润
  8591. case 33: //FINANCE(33) 每股收益(折算为全年收益),对于沪深品种有效
  8592. case 34: //FINANCE(34) 每股净资产
  8593. case 38: //FINANCE(38) 每股收益(最近一期季报)
  8594. case 40: //FINANCE(40) 流通市值
  8595. case 41: //FINANCE(41) 总市值
  8596. case 42: //FINANCE(42) 上市的天数
  8597. case 43: //FINANCE(43) 利润同比
  8598. case "CAPITAL":
  8599. case "TOTALCAPITAL":
  8600. //定制
  8601. case 100: //股东人数
  8602. this.DownloadRealtimeData(id);
  8603. break;
  8604. default:
  8605. this.DownloadRealtimeData(id);
  8606. break;
  8607. }
  8608. }
  8609. //最新一期数据
  8610. this.DownloadRealtimeData=function(id)
  8611. {
  8612. var self=this;
  8613. var fieldList=this.GetFieldList();
  8614. if (!fieldList)
  8615. {
  8616. if (this.Job.FunctionName2) message=`${this.Job.FunctionName2} can't support.`;
  8617. else if (this.Job.FunctionName) message=`${this.Job.FunctionName}(${this.Args[0]}) can't support.`;
  8618. else message=`${this.Args[0]} can't support.`;
  8619. this.ErrorCallback(message);
  8620. self.RecvCallback(null, self.Job, self.DataKey);
  8621. return;
  8622. }
  8623. //请求数据
  8624. wx.request({
  8625. url: this.RealtimeUrl,
  8626. data:
  8627. {
  8628. "field": fieldList,
  8629. "symbol": [this.Symbol],
  8630. "condition":[ ] ,
  8631. "start": 0,
  8632. "end": 10
  8633. },
  8634. method: 'POST',
  8635. dataType: "json",
  8636. async:true,
  8637. success: function (recvData)
  8638. {
  8639. var data=self.RealtimeDataToHQChartData(recvData.data);
  8640. self.RecvCallback(data, self.Job, self.DataKey);
  8641. }
  8642. });
  8643. }
  8644. //历史数据
  8645. this.DownloadHistoryData=function(id)
  8646. {
  8647. var self=this;
  8648. var fieldList=this.GetFieldList();
  8649. if (!fieldList)
  8650. {
  8651. message=`${this.Job.FunctionName}(${this.Args[0]}) can't support.`;
  8652. this.ErrorCallback(message);
  8653. self.RecvCallback(null, self.Job, self.DataKey);
  8654. return;
  8655. }
  8656. //请求数据
  8657. wx.request({
  8658. url: this.Url,
  8659. data:
  8660. {
  8661. "field": fieldList,
  8662. "symbol": [this.Symbol],
  8663. "condition":[ ] ,
  8664. "start": 0,
  8665. "end": 200
  8666. },
  8667. method: 'POST',
  8668. dataType: "json",
  8669. async:true,
  8670. success: function (recvData)
  8671. {
  8672. var data=self.ToHQChartData(recvData.data);
  8673. if (data) //排序
  8674. data.sort(function (a, b) { return (a.Date - b.Date) });
  8675. self.RecvCallback(data, self.Job, self.DataKey);
  8676. }
  8677. });
  8678. }
  8679. this.GetFieldList=function()
  8680. {
  8681. var id=this.Args[0];
  8682. switch(id)
  8683. {
  8684. case 1:
  8685. return ["capital.total", "capital.date"];
  8686. case 7:
  8687. return ["capital.a", "capital.date"];
  8688. case "EXCHANGE":
  8689. return ["capital.a", "capital.date"];
  8690. case 9:
  8691. return ["finance.peruprofit","symbol","date"];
  8692. case 18:
  8693. return ["finance.percreserve","symbol","date"];
  8694. case 30:
  8695. return ["finance.nprofit","symbol","date"];
  8696. case 32:
  8697. return ["finance.peruprofit","symbol","date"];
  8698. case 33:
  8699. return ["finance.persearning","symbol","date"];
  8700. case 34:
  8701. return ["finance.pernetasset","symbol","date"];
  8702. case 38:
  8703. return ["finance.persearning","symbol","date"];
  8704. case 40:
  8705. return ["capital.a", "capital.date","symbol","date", "price"];
  8706. case 41:
  8707. return ["capital.total", "capital.date","symbol","date","price"];
  8708. case "CAPITAL":
  8709. return ["capital.a", "capital.date","symbol","date"];
  8710. case "TOTALCAPITAL":
  8711. return ["capital.total", "capital.date","symbol","date"];
  8712. case 42:
  8713. return ["company.releasedate","symbol","date"];
  8714. case 43:
  8715. return ["dividendyield","symbol","date"];
  8716. case 100:
  8717. return ["shareholder","symbol","date"]
  8718. default:
  8719. return null;
  8720. }
  8721. }
  8722. //最新报告期数据
  8723. this.RealtimeDataToHQChartData=function(recvData,id)
  8724. {
  8725. if (!recvData.stock || recvData.stock.length!=1) return null;
  8726. var stock=recvData.stock[0];
  8727. var id=this.Args[0];
  8728. var date=stock.date;
  8729. switch(id)
  8730. {
  8731. case 9:
  8732. if (!stock.finance) return null;
  8733. return { Date:date, Value:stock.finance.peruprofit };
  8734. case 18:
  8735. if (!stock.finance) return null;
  8736. return { Date:date, Value:stock.finance.percreserve };
  8737. case 30:
  8738. if (!stock.finance) return null;
  8739. return { Date:date, Value:stock.finance.nprofit };
  8740. case 32:
  8741. if (!stock.finance) return null;
  8742. return { Date:date, Value:stock.finance.peruprofit };
  8743. case 33:
  8744. if (!stock.finance) return null;
  8745. return { Date:date, Value:stock.finance.persearning };
  8746. case 34:
  8747. if (!stock.finance) return null;
  8748. return { Date:date, Value:stock.finance.pernetasset };
  8749. case 38:
  8750. if (!stock.finance) return null;
  8751. return { Date:date, Value:stock.finance.persearning };
  8752. case 40: //FINANCE(40) 流通市值
  8753. if (!stock.capital) return null;
  8754. return { Date:date, Value:stock.capital.a*stock.price }; //流通股*最新价格
  8755. case 41: //FINANCE(41) 总市值
  8756. if (!stock.capital) return null;
  8757. return { Date:date, Value:stock.capital.total*stock.price }; //总股本*最新价格
  8758. case 42: //FINANCE(42) 上市的天数
  8759. if (!stock.company) return null;
  8760. {
  8761. var releaseDate=stock.company.releasedate;
  8762. var year=parseInt(releaseDate/10000);
  8763. var month=parseInt((releaseDate%10000)/100);
  8764. var day=releaseDate%100;
  8765. var firstDate=new Date(year, month-1, day);
  8766. var nowDate=new Date();
  8767. var days=parseInt((nowDate.getTime()-firstDate.getTime())/(1000 * 60 * 60 * 24));
  8768. return { Date:date, Value:days+1 };
  8769. }
  8770. case 43:
  8771. if (!stock.dividendyield) return null;
  8772. return { Date:date, Value:stock.dividendyield.quarter4 };
  8773. case 100:
  8774. if (!stock.shareholder) return null;
  8775. return { Date:date, Value:stock.shareholder.count };
  8776. case "CAPITAL":
  8777. if (!stock.capital) return null;
  8778. return { Date:date, Value:stock.capital.a/100 }; //当前流通股本 手
  8779. case "TOTALCAPITAL":
  8780. if (!stock.capital) return null;
  8781. return { Date:date, Value:stock.capital.total/100 }; //当前流通股本 手
  8782. }
  8783. }
  8784. //历史数据转
  8785. this.ToHQChartData=function(recvData)
  8786. {
  8787. if (!recvData.stock || recvData.stock.length!=1) return null;
  8788. var aryData=[];
  8789. var setDate=new Set(); //有重复数据 去掉
  8790. var stock=recvData.stock[0];
  8791. var id=this.Args[0];
  8792. for(var i in stock.stockday)
  8793. {
  8794. var item=stock.stockday[i];
  8795. var hqchartItem=this.ToHQChartItemData(item,id);
  8796. if (hqchartItem && !setDate.has(hqchartItem.Date))
  8797. {
  8798. aryData.push(hqchartItem);
  8799. setDate.add(hqchartItem.Date);
  8800. }
  8801. }
  8802. return aryData;
  8803. }
  8804. this.ToHQChartItemData=function(item, id)
  8805. {
  8806. if (!item) return null;
  8807. var date=item.date;
  8808. switch(id)
  8809. {
  8810. case 1:
  8811. if (!item.capital) return null;
  8812. return { Date:date, Value:item.capital.total };
  8813. case 7:
  8814. case "EXCHANGE": //换手率 历史流通股本
  8815. if (!item.capital) return null;
  8816. return { Date:date, Value:item.capital.a };
  8817. default:
  8818. return null;
  8819. }
  8820. }
  8821. }
  8822. //////////////////////////////////////////////////////////////////////////////////////////////
  8823. //内置财务数据下载
  8824. //
  8825. function DownloadFinValueData(obj)
  8826. {
  8827. this.Url=obj.Url;
  8828. this.Job=obj.Job;
  8829. this.Symbol=obj.Symbol;
  8830. this.Args=obj.Args;
  8831. this.DataKey=obj.DataKey;
  8832. this.RecvCallback=obj.Callback;
  8833. this.ErrorCallback=obj.ErrorCallback;
  8834. this.Download=function()
  8835. {
  8836. var self=this;
  8837. var fieldList=this.GetFieldList();
  8838. if (!fieldList)
  8839. {
  8840. message=`${this.Job.FunctionName}(${this.Args[0]}) can't support.`;
  8841. this.ErrorCallback(message);
  8842. self.RecvCallback(null, self.Job, self.DataKey);
  8843. return;
  8844. }
  8845. //请求数据
  8846. wx.request({
  8847. url: this.Url,
  8848. data:
  8849. {
  8850. "field": fieldList,
  8851. "symbol": [this.Symbol],
  8852. "condition":[ {"item":["finance","doc","exists","true"]}] ,
  8853. "start": 0,
  8854. "end": 200
  8855. },
  8856. method: 'POST',
  8857. dataType: "json",
  8858. async:true,
  8859. success: function (recvData)
  8860. {
  8861. var data=self.ToHQChartData(recvData.data);
  8862. if (data) //排序
  8863. data.sort(function (a, b) { return (a.Date - b.Date) });
  8864. self.RecvCallback(data, self.Job, self.DataKey);
  8865. }
  8866. });
  8867. }
  8868. this.ToHQChartData=function(recvData)
  8869. {
  8870. if (!recvData.stock || recvData.stock.length!=1) return null;
  8871. var aryData=[];
  8872. var setDate=new Set(); //有重复数据 去掉
  8873. var stock=recvData.stock[0];
  8874. for(var i in stock.stockday)
  8875. {
  8876. var item=stock.stockday[i];
  8877. if (item.announcement1)
  8878. {
  8879. var hqchartItem=this.ToHQChartItemData(item.announcement1, item.finance1, item);
  8880. if (hqchartItem && !setDate.has(hqchartItem.Date))
  8881. {
  8882. aryData.push(hqchartItem);
  8883. setDate.add(hqchartItem.Date);
  8884. }
  8885. }
  8886. if (item.announcement2)
  8887. {
  8888. var hqchartItem=this.ToHQChartItemData(item.announcement2, item.finance2, item);
  8889. if (hqchartItem && !setDate.has(hqchartItem.Date))
  8890. {
  8891. aryData.push(hqchartItem);
  8892. setDate.add(hqchartItem.Date);
  8893. }
  8894. }
  8895. if (item.announcement3)
  8896. {
  8897. var hqchartItem=this.ToHQChartItemData(item.announcement3, item.finance3, item);
  8898. if (hqchartItem && !setDate.has(hqchartItem.Date))
  8899. {
  8900. aryData.push(hqchartItem);
  8901. setDate.add(hqchartItem.Date);
  8902. }
  8903. }
  8904. if (item.announcement4)
  8905. {
  8906. var hqchartItem=this.ToHQChartItemData(item.announcement4, item.finance4, item);
  8907. if (hqchartItem && !setDate.has(hqchartItem.Date))
  8908. {
  8909. aryData.push(hqchartItem);
  8910. setDate.add(hqchartItem.Date);
  8911. }
  8912. }
  8913. }
  8914. return aryData;
  8915. }
  8916. //{ Date:日期 , Value:数值 }
  8917. this.ToHQChartItemData=function(announcement, finance, sourceItem)
  8918. {
  8919. var id=this.Args[0];
  8920. var date=announcement.year*10000;
  8921. var quarter=announcement.quarter;
  8922. switch(quarter)
  8923. {
  8924. case 1:
  8925. date+=331;
  8926. break;
  8927. case 2:
  8928. date+=630;
  8929. break;
  8930. case 3:
  8931. date+=930;
  8932. break;
  8933. case 4:
  8934. date+=1231;
  8935. break;
  8936. default:
  8937. return null;
  8938. }
  8939. var result={ Date:date, Value:0 };
  8940. switch(id)
  8941. {
  8942. case 0:
  8943. result.Value=date%1000000; //0--返回报告期(YYMMDD格式),150930表示为2015年第三季
  8944. break;
  8945. case 1:
  8946. result.Value=finance.persearning;
  8947. break;
  8948. case 3:
  8949. result.Value=finance.peruprofit;
  8950. break;
  8951. case 4:
  8952. result.Value=finance.pernetasset;
  8953. break;
  8954. case 5:
  8955. result.Value=finance.percreserve;
  8956. break;
  8957. case 6:
  8958. result.Value=finance.woewa;
  8959. break;
  8960. case 7:
  8961. result.Value=finance.perccfo;
  8962. break;
  8963. case 8:
  8964. result.Value=finance.monetaryfunds;
  8965. break;
  8966. case 11:
  8967. result.Value=finance.areceivable;
  8968. break;
  8969. }
  8970. return result;
  8971. }
  8972. this.GetFieldList=function()
  8973. {
  8974. var id=this.Args[0];
  8975. switch(id)
  8976. {
  8977. case 0:
  8978. return ["finance.date"];
  8979. case 1: //persearning 每股收益
  8980. return ["finance.persearning"];
  8981. case 3: //peruprofit 每股未分配利润
  8982. return ["finance.peruprofit"];
  8983. case 4: //pernetasset 每股净资产
  8984. return ["finance.pernetasset"];
  8985. case 5: //percreserve 每股资本公积金
  8986. return ["finance.percreserve"];
  8987. case 6: //woewa 加权平均净资产收益
  8988. return ["finance.woewa"];
  8989. case 7: //perccfo 每股经营性现金流
  8990. return ["finance.perccfo"];
  8991. case 8: //monetaryfunds 货币资金
  8992. return ["finance.monetaryfunds"];
  8993. case 11: //areceivable 应收账款
  8994. return ["finance.areceivable"];
  8995. default:
  8996. return null;
  8997. }
  8998. }
  8999. }
  9000. /////////////////////////////////////////////////////////
  9001. // 内置财务数据下载 某一期的数据
  9002. //
  9003. function DownloadFinOneData(obj)
  9004. {
  9005. this.newMethod=DownloadFinValueData; //派生
  9006. this.newMethod(obj);
  9007. delete this.newMethod;
  9008. this.Download=function()
  9009. {
  9010. var self=this;
  9011. var fieldList=this.GetFieldList();
  9012. if (!fieldList)
  9013. {
  9014. message=`${this.Job.FunctionName}(${this.Args[0]}, ${this.Args[1]}, ${this.Args[2]}) can't support.`;
  9015. this.ErrorCallback(message);
  9016. self.RecvCallback(null, self.Job, self.DataKey);
  9017. return;
  9018. }
  9019. var aryCondition=[ {"item":["finance","doc","exists","true"] } ];
  9020. var year=this.Args[1];
  9021. var month=this.Args[2];
  9022. var dataIndex=0;
  9023. var dataEnd=3;
  9024. var preYear=null;
  9025. if (year==0 && month==0) //如果Y和MMDD都为0,表示最新的财报;
  9026. {
  9027. }
  9028. else if (year==0 && month<300) //如果Y为0,MMDD为小于300的数字,表示最近一期向前推MMDD期的数据,如果是331,630,930,1231这些,表示最近一期的对应季报的数据;
  9029. {
  9030. dataIndex=month;
  9031. dataEnd=200;
  9032. }
  9033. else if (month==0 && year<1000) //如果Y为0,MMDD为小于300的数字,表示最近一期向前推MMDD期的数据,如果是331,630,930,1231这些,表示最近一期的对应季报的数据;
  9034. {
  9035. preYear=year;
  9036. }
  9037. else if (year>1909)
  9038. {
  9039. if (month==331)
  9040. {
  9041. aryCondition=
  9042. [
  9043. {"item":["announcement1.year","int32","eq",year]},
  9044. {"item":["finance1","doc","exists","true"]}
  9045. ];
  9046. fieldList.push("announcement1.year");
  9047. fieldList.push("announcement1.quarter");
  9048. }
  9049. else if (month==630)
  9050. {
  9051. aryCondition=
  9052. [
  9053. {"item":["announcement2.year","int32","eq",year]},
  9054. {"item":["finance2","doc","exists","true"]}
  9055. ];
  9056. fieldList.push("announcement2.year");
  9057. fieldList.push("announcement2.quarter");
  9058. }
  9059. else if (month==930)
  9060. {
  9061. aryCondition=
  9062. [
  9063. {"item":["announcement3.year","int32","eq",year]},
  9064. {"item":["finance3","doc","exists","true"]}
  9065. ];
  9066. fieldList.push("announcement4.year");
  9067. fieldList.push("announcement4.quarter");
  9068. }
  9069. else
  9070. {
  9071. aryCondition=
  9072. [
  9073. {"item":["announcement4.year","int32","eq",year]},
  9074. {"item":["finance4","doc","exists","true"]}
  9075. ];
  9076. fieldList.push("announcement4.year");
  9077. fieldList.push("announcement4.quarter");
  9078. }
  9079. }
  9080. //请求数据
  9081. wx.request({
  9082. url: this.Url,
  9083. data:
  9084. {
  9085. "field": fieldList,
  9086. "symbol": [this.Symbol],
  9087. "condition":aryCondition,
  9088. "start": 0,
  9089. "end": dataEnd
  9090. },
  9091. method: 'POST',
  9092. dataType: "json",
  9093. async:true,
  9094. success: function (recvData)
  9095. {
  9096. var data=self.ToHQChartData(recvData.data);
  9097. var result=null;
  9098. if (data && data.length>0)
  9099. {
  9100. data.sort(function (a, b) { return (b.Date-a.Date) });
  9101. if (preYear==null)
  9102. result=data[dataIndex]; //返回一个数据
  9103. else
  9104. result=self.GetPreYearData(data, preYear);
  9105. }
  9106. self.RecvCallback(result, self.Job, self.DataKey);
  9107. }
  9108. });
  9109. }
  9110. this.GetPreYearData=function(data, preYear)
  9111. {
  9112. //331,630,930,1231这些,表示最近一期的对应季报的数据;
  9113. if (preYear==331 || preYear==630|| preYear==930 || preYear==1231)
  9114. {
  9115. for(var i in data)
  9116. {
  9117. var item=data[i];
  9118. if (item.Date%10000==preYear) return item;
  9119. }
  9120. }
  9121. else
  9122. {
  9123. //如果MMDD为0,Y为一数字,表示最近一期向前推Y年的同期数据;
  9124. var month=data[0].Date%1000;
  9125. for(var i=1, j=0; i<data.length ;++i)
  9126. {
  9127. var item=data[i];
  9128. if (item.Date%10000==month)
  9129. {
  9130. ++j;
  9131. if (j==preYear) return item;
  9132. }
  9133. }
  9134. return null;
  9135. }
  9136. }
  9137. }
  9138. function DownloadGPJYValue(obj)
  9139. {
  9140. this.Url=obj.Url;
  9141. this.RealtimeUrl=obj.RealtimeUrl;
  9142. this.Job=obj.Job;
  9143. this.Symbol=obj.Symbol;
  9144. this.Args=obj.Args;
  9145. this.DataKey=obj.DataKey;
  9146. this.RecvCallback=obj.Callback;
  9147. this.ErrorCallback=obj.ErrorCallback;
  9148. this.Download=function()
  9149. {
  9150. var self=this;
  9151. var fieldList=this.GetFieldList();
  9152. if (!fieldList)
  9153. {
  9154. message=`${this.Job.FunctionName}(${this.Args[0]}, ${this.Args[1]}, ${this.Args[2]}) can't support.`;
  9155. this.ErrorCallback(message);
  9156. self.RecvCallback(null, self.Job, self.DataKey, true);
  9157. return;
  9158. }
  9159. //请求数据
  9160. wx.request({
  9161. url: this.Url,
  9162. data:
  9163. {
  9164. "field": fieldList,
  9165. "symbol": [this.Symbol],
  9166. "orderfield":"date",
  9167. "order":-1,
  9168. "start":0,
  9169. "end":5
  9170. },
  9171. method: 'POST',
  9172. dataType: "json",
  9173. async:true,
  9174. success: function (recvData)
  9175. {
  9176. var data=self.ToHQChartData(recvData.data);
  9177. if (data && data.length>0)
  9178. {
  9179. data.sort(function (a, b) { return (a.Date-b.Date) });
  9180. }
  9181. self.RecvCallback(data, self.Job, self.DataKey);
  9182. }
  9183. });
  9184. }
  9185. this.GetFieldList=function()
  9186. {
  9187. var id=this.Args[0];
  9188. switch(id)
  9189. {
  9190. case 1: //1--股东人数 股东户数(户)
  9191. return ["shareholder", "date", "symbol"];
  9192. case 2: //2--龙虎榜 买入总计(万元) 卖出总计(万元)
  9193. return ["tradedetail.buy","tradedetail.sell", "date", "symbol"];
  9194. case 3: //3--融资融券1 融资余额(万元) 融券余量(股)
  9195. return ["margin","date", "symbol"];
  9196. case 4: //4--大宗交易 成交均价(元) 成交额(万元)
  9197. return ["blocktrading.amount","blocktrading.price","date", "symbol"]
  9198. default:
  9199. return null;
  9200. }
  9201. }
  9202. this.ToHQChartData=function(recvData)
  9203. {
  9204. if (!recvData.stock || recvData.stock.length!=1) return null;
  9205. var aryData=[];
  9206. var setDate=new Set(); //有重复数据 去掉
  9207. var stock=recvData.stock[0];
  9208. var id=this.Args[0];
  9209. var subID=this.Args[1];
  9210. for(var i in stock.stockday)
  9211. {
  9212. var item=stock.stockday[i];
  9213. var hqchartItem=this.ToHQChartItemData(item,id,subID);
  9214. if (hqchartItem && !setDate.has(hqchartItem.Date))
  9215. {
  9216. aryData.push(hqchartItem);
  9217. setDate.add(hqchartItem.Date);
  9218. }
  9219. }
  9220. return aryData;
  9221. }
  9222. this.ToHQChartItemData=function(item, id, subID)
  9223. {
  9224. if (!item) return null;
  9225. var date=item.date;
  9226. switch(id)
  9227. {
  9228. case 1:
  9229. if (!item.shareholder) return null;
  9230. return { Date:date, Value:item.shareholder.count };
  9231. case 2:
  9232. if (!item.tradedetail && item.tradedetail[0]) return null;
  9233. if (subID==0)
  9234. return { Date:date, Value:item.tradedetail[0].buy };
  9235. else
  9236. return { Date:date, Value:item.tradedetail[0].sell };
  9237. case 3:
  9238. if (!item.margin) return null;
  9239. if (subID==0)
  9240. {
  9241. if (item.margin.buy)
  9242. return { Date:date, Value:item.margin.buy.balance };
  9243. }
  9244. else
  9245. {
  9246. if (item.margin.sell)
  9247. return { Date:date, Value:item.margin.sell.balance };
  9248. }
  9249. return null;
  9250. case 4:
  9251. if (!item.blocktrading) return null;
  9252. if (subID==0)
  9253. return { Date:date, Value:item.blocktrading.price };
  9254. else
  9255. return { Date:date, Value:item.blocktrading.amount };
  9256. default:
  9257. return null;
  9258. }
  9259. }
  9260. }
  9261. function DownloadGroupData(obj)
  9262. {
  9263. this.Url=obj.Url;
  9264. this.RealtimeUrl=obj.RealtimeUrl;
  9265. this.Job=obj.Job;
  9266. this.Symbol=obj.Symbol;
  9267. this.Args=obj.Args;
  9268. this.DataKey=obj.DataKey;
  9269. this.RecvCallback=obj.Callback;
  9270. this.ErrorCallback=obj.ErrorCallback;
  9271. this.Download=function()
  9272. {
  9273. var varName=this.Args[0];
  9274. switch(varName)
  9275. {
  9276. case "HYBLOCK":
  9277. case "DYBLOCK":
  9278. case "GNBLOCK":
  9279. this.DownloadGroupName(varName);
  9280. break;
  9281. }
  9282. }
  9283. this.DownloadGroupName=function(blockType)
  9284. {
  9285. var self=this;
  9286. var field=["name","symbol"];
  9287. if (blockType=="HYBLOCK") field.push("industry");
  9288. else if (blockType=="DYBLOCK") field.push("region");
  9289. else if (blockType=="GNBLOCK") field.push("concept");
  9290. wx.request({
  9291. url: self.RealtimeUrl,
  9292. data:
  9293. {
  9294. "field": field,
  9295. "symbol": [this.Symbol]
  9296. },
  9297. method:"post",
  9298. dataType: "json",
  9299. async:true,
  9300. success: function (recvData)
  9301. {
  9302. var data=self.RecvGroupName(recvData.data);
  9303. self.RecvCallback(data, self.Job, self.DataKey, 1);
  9304. },
  9305. error: function(request)
  9306. {
  9307. self.ErrorCallback(request);
  9308. }
  9309. });
  9310. }
  9311. this.RecvGroupName=function(recvData)
  9312. {
  9313. if (!recvData.stock || recvData.stock.length!=1) return null;
  9314. var stock=recvData.stock[0];
  9315. var varName=this.Args[0];
  9316. var value=null;
  9317. if (varName=="HYBLOCK")
  9318. {
  9319. var industry=stock.industry;
  9320. if (!industry) return null;
  9321. var value;
  9322. for(var i in industry)
  9323. {
  9324. var item=industry[i];
  9325. value=item.name;
  9326. }
  9327. }
  9328. else if (varName=="DYBLOCK")
  9329. {
  9330. var region=stock.region;
  9331. if (!region) return null;
  9332. for(var i in region)
  9333. {
  9334. var item=region[i];
  9335. value=item.name;
  9336. }
  9337. }
  9338. else if (varName=="GNBLOCK")
  9339. {
  9340. var concept=stock.concept;
  9341. if (!concept) return null;
  9342. value="";
  9343. for(var i in concept)
  9344. {
  9345. var item=concept[i];
  9346. if (value.length>0) value+=' ';
  9347. value+=item.name;
  9348. }
  9349. }
  9350. return { Value:value };
  9351. }
  9352. }
  9353. /* 测试例子
  9354. var code1='VARHIGH:IF(VAR1<=REF(HH,-1),REF(H,BARSLAST(VAR1>=REF(HH,1))),DRAWNULL),COLORYELLOW;';
  9355. var code2='VAR1=((SMA(MAX((CLOSE - LC),0),3,1) / SMA(ABS((CLOSE - LC)),3,1)) * 100);';
  9356. var code3='mm1=1-2*-9+20;';
  9357. JSConsole.Complier.Log(code1+code2)
  9358. var tokens=JSComplier.Tokenize(code1+code2);
  9359. var ast=JSComplier.Parse(code2+code1);
  9360. JSConsole.Complier.Log(ast);
  9361. */
  9362. module.exports =
  9363. {
  9364. JSCommonComplier:
  9365. {
  9366. JSComplier: JSComplier,
  9367. },
  9368. //单个类导出
  9369. JSCommonComplier_ErrorHandler: ErrorHandler,
  9370. JSCommonComplier_JSComplier:JSComplier,
  9371. JSCommonComplier_JSParser:JSParser,
  9372. JSCommonComplier_Syntax:Syntax,
  9373. JS_EXECUTE_JOB_ID:JS_EXECUTE_JOB_ID,
  9374. g_JSComplierResource:g_JSComplierResource,
  9375. };