Endri-javatra amin'ny fiteny Q sy KDB+ mampiasa ny ohatra amin'ny serivisy amin'ny fotoana tena izy

Azonao atao ny mamaky momba ny fototra KDB +, ny fiteny fandaharana Q, ny tanjany sy ny fahalemeny ao amin'ny teo aloha. lahatsoratra ary fohy ao amin'ny teny fampidirana. Ao amin'ny lahatsoratra, dia hampihatra serivisy amin'ny Q izay handrindra ny onjam-peo ho avy ary hanao kajy ny asa fanangonam-bokatra isan-minitra amin'ny fomba "tena izy" (izany hoe, hanana fotoana handinihana ny zava-drehetra alohan'ny ampahany amin'ny data manaraka). Ny singa fototra amin'ny Q dia ny fiteny vector izay ahafahanao miasa tsy amin'ny zavatra tokana, fa amin'ny arrays, arrays ary zavatra sarotra hafa. Ny fiteny toa ny Q sy ny havany K, J, APL dia malaza amin'ny fahafohezan-tenany. Matetika, programa iray izay maka efijery maromaro amin'ny fiteny mahazatra toa an'i Java dia azo soratana amin'ny andalana vitsivitsy. Izany no tiako haseho ato amin'ity lahatsoratra ity.

Endri-javatra amin'ny fiteny Q sy KDB+ mampiasa ny ohatra amin'ny serivisy amin'ny fotoana tena izy

fampidirana

KDB+ dia angon-drakitra tsanganana mifantoka amin'ny angon-drakitra be dia be, voalamina amin'ny fomba manokana (indrindra amin'ny fotoana). Izy io dia ampiasaina indrindra amin'ny andrim-panjakana - banky, vola fampiasam-bola, orinasa fiantohana. Ny fiteny Q dia fiteny anatiny an'ny KDB+ izay ahafahanao miasa tsara amin'ity data ity. Ny ideolojia Q dia fahafoizan-tena sy fahombiazana, raha toa ka atao sorona ny mazava. Manamarina izany ny zava-misy fa ny fiteny vΓ©ctor dia ho sarotra takarina na ahoana na ahoana, ary ny hafohezana sy ny haren'ny fandraisam-peo dia ahafahanao mahita ampahany lehibe kokoa amin'ny fandaharana amin'ny efijery iray, izay manamora ny fahazoana azy amin'ny farany.

Amin'ity lahatsoratra ity dia mametraka programa feno ao amin'ny Q izahay ary mety te hanandrana izany ianao. Mba hanaovana izany dia mila ny tena Q. Azonao atao ny misintona ny kinova 32-bit maimaim-poana amin'ny tranokala kx orinasa - www.kx.com. Ao, raha liana ianao, dia hahita fampahalalana momba ny Q, ilay boky Q Ho an'ny maty ary lahatsoratra samihafa momba ity lohahevitra ity.

Fanambarana olana

Misy loharano iray mandefa latabatra misy angona isaky ny 25 milisegondra. Satria ny KDB+ dia ampiasaina voalohany indrindra amin'ny fitantanam-bola, dia hoheverintsika fa tabilaon'ny fifampiraharahana (varotra), izay misy tsanganana manaraka ireto: fotoana (fotoana amin'ny milisegondra), sym (fanendrena orinasa amin'ny fifanakalozana - IBM, AAPL,…), vidiny (ny vidiny nividianana ny ampahany), ny habeny (ny haben'ny varotra). Ny elanelana 25 milisegondra dia tsy misy dikany, tsy kely loatra ary tsy lava loatra. Ny fisiany dia midika fa ny angon-drakitra dia tonga amin'ny serivisy efa buffered. Mora ny mampihatra buffering eo amin'ny lafiny serivisy, anisan'izany ny buffering mavitrika miankina amin'ny entana ankehitriny, fa ho an'ny fahatsorana dia hifantoka amin'ny elanelana raikitra isika.

Ny serivisy dia tsy maintsy manisa isa-minitra ho an'ny mari-pamantarana miditra avy amin'ny tsanganana sym andiana asa manangom-bokatra - vidiny max, vidiny salan'isa, haben'ny vola, sns. fampahalalana mahasoa. Ho an'ny fahatsorana, dia hihevitra isika fa ny fiasa rehetra dia azo atao kajy tsikelikely, i.e. mba hahazoana sanda vaovao, dia ampy ny mahafantatra isa roa - ny taloha sy ny soatoavina miditra. Ohatra, ny fonctions max, average, sum dia manana an'io fananana io, fa ny median function dia tsy.

Heverintsika ihany koa fa ny fikorianan'ny data miditra dia voabaiko ny fotoana. Izany dia hanome antsika fahafahana hiasa amin'ny minitra farany. Amin'ny fampiharana dia ampy ny miasa miaraka amin'ny minitra ankehitriny sy teo aloha raha toa ka tara ny fanavaozana sasany. Ho an'ny fahatsorana dia tsy hojerentsika ity tranga ity.

Fandraisana anjara

Ny asa fanangonam-bokatra ilaina dia voatanisa etsy ambany. Naka betsaka tamin'izy ireo aho mba hampitombo ny enta-mavesatra amin'ny serivisy:

  • avo - vidiny ambony indrindra - vidiny ambony indrindra isa-minitra.
  • ambany - min vidiny - vidiny ambany indrindra isa-minitra.
  • Prix ​​voalohany - vidiny voalohany - vidiny voalohany isa-minitra.
  • faranyPrice - vidiny farany - vidiny farany isa-minitra.
  • firstSize - habe voalohany - habe varotra voalohany isa-minitra.
  • lastSize - last size - habe varotra farany ao anatin'ny iray minitra.
  • numTrades - manisa i - isan'ny varotra isa-minitra.
  • volume - total size - fitambaran'ny haben'ny varotra isa-minitra.
  • pvolume – vola vidina – fitambaran'ny vidiny isa-minitra, ilaina amin'ny avgPrice.
  • - ny vidin'ny fihodinana * habe - ny totalin'ny varotra isa-minitra.
  • avgPrice – pvolume%numTrades – vidiny antonony isa-minitra.
  • avgSize – volume%numTrades – antonony varotra isan-minitra.
  • vwap - turnover%volume - vidiny antonony isa-minitra lanjaina amin'ny haben'ny varotra.
  • cumVolume – volam-bola – habe voaangona nandritra ny fotoana rehetra.

Andeha hodinihintsika avy hatrany ny teboka iray tsy mazava - ny fomba hanombohana ireo tsanganana ireo amin'ny voalohany sy isaky ny minitra manaraka. Ny tsanganana sasany amin'ny karazana FirstPrice dia tsy maintsy atomboka amin'ny null isaky ny mandeha; tsy voafaritra ny sandany. Ny karazana volume hafa dia tsy maintsy apetraka amin'ny 0 foana. Misy ihany koa ny tsanganana izay mitaky fomba fiasa mitambatra - ohatra, ny cumVolume dia tsy maintsy adika amin'ny minitra teo aloha, ary ny voalohany dia apetraka amin'ny 0. Andao apetraka ireo mason-tsivana rehetra ireo amin'ny fampiasana ny angona rakibolana. karazana (mitovy amin'ny rakitra):

// list ! list – ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ, 0n – float null, 0N – long null, `sym – Ρ‚ΠΈΠΏ символ, `sym1`sym2 – список символов
initWith:`sym`time`high`low`firstPrice`lastPrice`firstSize`lastSize`numTrades`volume`pvolume`turnover`avgPrice`avgSize`vwap`cumVolume!(`;00:00;0n;0n;0n;0n;0N;0N;0;0;0.0;0.0;0n;0n;0n;0);
aggCols:reverse key[initWith] except `sym`time; // список всСх вычисляСмых ΠΊΠΎΠ»ΠΎΠ½ΠΎΠΊ, reverse объяснСн Π½ΠΈΠΆΠ΅

Nanampy sym sy fotoana tao amin'ny rakibolana aho mba hahamora kokoa, ankehitriny ny initWith dia tsipika efa vita avy amin'ny latabatra aggregate farany, izay mbola mametraka ny sym sy ny fotoana marina. Azonao ampiasaina izany mba hanampiana andalana vaovao amin'ny latabatra.

Mila aggCols isika rehefa mamorona asa fanangonana. Tsy maintsy avadika ny lisitra noho ny filaharan'ny fanombanana ny teny ao amin'ny Q (avy eo ankavanana miankavia). Ny tanjona dia ny hiantohana fa ny kajy dia miainga avy any ambony mankany amin'ny cumVolume, satria ny tsanganana sasany dia miankina amin'ny teo aloha.

Tsanganana mila adika amin'ny minitra vaovao avy amin'ny teo aloha, ampiana ny tsanganana sym mba hahamora kokoa:

rollColumns:`sym`cumVolume;

Andeha hozaraina ho vondrona ny tsanganana araka ny tokony hanavaozana azy. Misy karazany telo azo avahana:

  1. Accumulators (volony, turnover, ..) - tsy maintsy ampiana ny sanda miditra amin'ny teo aloha.
  2. Miaraka amin'ny teboka manokana (avo, ambany, ..) - ny sanda voalohany amin'ny minitra dia nalaina avy amin'ny angon-drakitra miditra, ny ambiny dia kajy amin'ny fampiasana ny asa.
  3. Fitsaharana. Kajy foana amin'ny fampiasana asa iray.

Andeha hofaritana ny variables ho an'ireto kilasy ireto:

accumulatorCols:`numTrades`volume`pvolume`turnover;
specialCols:`high`low`firstPrice`firstSize;

Filaharana kajy

Havaozinay amin'ny dingana roa ny latabatra mitambatra. Ho an'ny fahombiazana dia ahena aloha ny latabatra miditra ka tsy misy afa-tsy andalana iray isaky ny toetra sy minitra. Ny zava-misy fa ny asantsika rehetra dia mitombo sy mifandray dia miantoka fa tsy hiova ny vokatr'io dingana fanampiny io. Azonao atao ny mampihena ny latabatra amin'ny fampiasana ny Select:

select high:max price, low:min price … by sym,time.minute from table

Ity fomba ity dia manana fatiantoka - ny andiana tsanganana kajy dia efa voafaritra mialoha. Soa ihany, ao amin'ny Q, Select dia ampiharina ihany koa ho toy ny asa izay ahafahanao manolo hevitra dynamically noforonina:

?[table;whereClause;byClause;selectClause]

Tsy holazaiko amin'ny an-tsipiriany ny endrik'ireo tohan-kevitra, raha ny eto amintsika, ny fanehoan-kevitra amin'ny alalan'ny sy voafantina ihany no tsy misy dikany ary tokony ho diksionera amin'ny tsanganana! Noho izany dia azo faritana toy izao manaraka izao ny fiasan'ny shrinking:

selExpression:`high`low`firstPrice`lastPrice`firstSize`lastSize`numTrades`volume`pvolume`turnover!parse each ("max price";"min price";"first price";"last price";"first size";"last size";"count i";"sum size";"sum price";"sum price*size"); // each это функция map Π² Q для ΠΎΠ΄Π½ΠΎΠ³ΠΎ списка
preprocess:?[;();`sym`time!`sym`time.minute;selExpression];

Mba hanazavana dia nampiasa ny fonction parse aho, izay mamadika tady miaraka amin'ny fanehoana Q ho sanda azo ampitaina amin'ny asa eval ary takiana amin'ny fisafidianana asa. Mariho ihany koa fa ny preprocess dia faritana ho projection (izany hoe, asa miaraka amin'ny tohan-kevitra voafaritra ampahany) amin'ny asa voafantina, tsy misy hevitra iray (ny latabatra). Raha mampihatra preprocess amin'ny latabatra isika dia hahazo latabatra voaporitra.

Ny dingana faharoa dia ny fanavaozana ny latabatra mitambatra. Andeha aloha hanoratra ny algorithm amin'ny pseudocode:

for each sym in inputTable
  idx: row index in agg table for sym+currentTime;
  aggTable[idx;`high]: aggTable[idx;`high] | inputTable[sym;`high];
  aggTable[idx;`volume]: aggTable[idx;`volume] + inputTable[sym;`volume];
  …

Ao amin'ny Q, mahazatra ny mampiasa sari-tany / fampihenana ny asa fa tsy loop. Fa satria ny Q dia fiteny vetaveta ary azontsika atao mora foana ny mampihatra ny asa rehetra amin'ny marika rehetra indray mandeha, dia amin'ny fanombanana voalohany dia azontsika atao tsy misy loop mihitsy, manao asa amin'ny marika rehetra indray mandeha:

idx:calcIdx inputTable;
row:aggTable idx;
aggTable[idx;`high]: row[`high] | inputTable`high;
aggTable[idx;`volume]: row[`volume] + inputTable`volume;
…

Saingy afaka mandroso bebe kokoa isika, manana mpandraharaha tokana sy mahery vaika i Q - ilay mpandraharaha fanendrena ankapobeny. Mamela anao hanova sanda maromaro amin'ny rafitra angon-drakitra sarotra amin'ny alΓ lan'ny lisitry ny indices, fiasa ary tohan-kevitra. Amin'ny tranga misy antsika dia toa izao:

idx:calcIdx inputTable;
rows:aggTable idx;
// .[target;(idx0;idx1;..);function;argument] ~ target[idx 0;idx 1;…]: function[target[idx 0;idx 1;…];argument], Π² нашСм случаС функция – это присваиваниС
.[aggTable;(idx;aggCols);:;flip (row[`high] | inputTable`high;row[`volume] + inputTable`volume;…)];

Indrisy anefa, raha hanendry latabatra ianao dia mila lisitry ny andalana, fa tsy tsanganana, ary tsy maintsy mamadika ny matrix (lisitra tsanganana mankany amin'ny lisitry ny andalana) ianao amin'ny fampiasana ny flip function. Lafo izany ho an'ny latabatra lehibe iray, noho izany dia mampihatra fanendrena ankapobe amin'ny tsanganana tsirairay isika, amin'ny fampiasana ny fiasan'ny sarintany (izay mitovy amin'ny apostrophe):

.[aggTable;;:;]'[(idx;)each aggCols; (row[`high] | inputTable`high;row[`volume] + inputTable`volume;…)];

Mampiasa projection indray izahay. Mariho ihany koa fa ao amin'ny Q, ny famoronana lisitra dia asa iray ihany koa ary azontsika atao ny miantso azy io amin'ny fampiasana ny fiasa tsirairay (sarintany) hahazoana lisitry ny lisitra.

Mba hahazoana antoka fa tsy raikitra ny fitambaran'ny tsanganana kajy, dia hamorona ny fomba fiteny etsy ambony isika. Andeha aloha hamaritana ny asa kajy ny tsanganana tsirairay, amin'ny fampiasana ny row sy inp variables hanondroana ny angona natambatra sy fampidirana:

aggExpression:`high`low`firstPrice`lastPrice`firstSize`lastSize`avgPrice`avgSize`vwap`cumVolume!
 ("row[`high]|inp`high";"row[`low]&inp`low";"row`firstPrice";"inp`lastPrice";"row`firstSize";"inp`lastSize";"pvolume%numTrades";"volume%numTrades";"turnover%volume";"row[`cumVolume]+inp`volume");

Ny tsanganana sasany dia miavaka; ny sandany voalohany dia tsy tokony kajy amin'ny asa. Azontsika atao ny mamaritra fa io no voalohany amin'ny tsanganana [`numTrades] - raha misy 0, dia ny sanda no voalohany. Q dia manana asa mifantina - ?[Boolean list;list1;list2] - izay mifidy sanda avy amin'ny lisitra 1 na 2 miankina amin'ny fepetra ao amin'ny tohan-kevitra voalohany:

// high -> ?[isFirst;inp`high;row[`high]|inp`high]
// @ - Ρ‚ΠΎΠΆΠ΅ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½ΠΎΠ΅ присваиваниС для случая ΠΊΠΎΠ³Π΄Π° индСкс Π½Π΅Π³Π»ΡƒΠ±ΠΎΠΊΠΈΠΉ
@[`aggExpression;specialCols;{[x;y]"?[isFirst;inp`",y,";",x,"]"};string specialCols];

Eto aho dia niantso andraikitra ankapobe miaraka amin'ny asako (fitenenana amin'ny braces olioly). Mahazo ny sanda ankehitriny (ny tohan-kevitra voalohany) sy ny tohan-kevitra fanampiny, izay ampitaiko amin'ny paramètre faha-4.

Andao ampio mitokana ny mpandahateny bateria, satria mitovy amin'izy ireo ny fiasa:

// volume -> row[`volume]+inp`volume
aggExpression[accumulatorCols]:{"row[`",x,"]+inp`",x } each string accumulatorCols;

Fanendrena mahazatra amin'ny fenitry Q izany, fa manome lisitry ny soatoavina aho indray mandeha. Farany, andao hamorona ny asa fototra:

// ":",/:aggExprs ~ map[{":",x};aggExpr] => ":row[`high]|inp`high" присвоим вычислСнноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ зависят ΠΎΡ‚ ΡƒΠΆΠ΅ вычислСнных Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ
// string[cols],'exprs ~ map[,;string[cols];exprs] => "high:row[`high]|inp`high" Π·Π°Π²Π΅Ρ€ΡˆΠΈΠΌ созданиС присваивания. ,’ Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Ρ‹Π²Π°Π΅Ρ‚ΡΡ ΠΊΠ°ΠΊ map[concat]
// ";" sv exprs – String from Vector (sv), соСдиняСт список строк вставляя β€œ;” посрСдинС
updateAgg:value "{[aggTable;idx;inp] row:aggTable idx; isFirst_0=row`numTrades; .[aggTable;;:;]'[(idx;)each aggCols;(",(";"sv string[aggCols],'":",/:aggExpression aggCols),")]}";

Miaraka amin'io fomba fiteny io dia mamorona asa avy amin'ny tady misy ny fomba fiteny nomeko etsy ambony aho. Ho toy izao ny vokatra:

{[aggTable;idx;inp] rows:aggTable idx; isFirst_0=row`numTrades; .[aggTable;;:;]'[(idx;)each aggCols ;(cumVolume:row[`cumVolume]+inp`cumVolume;… ; high:?[isFirst;inp`high;row[`high]|inp`high])]}

Mivadika ny filaharan'ny fanombanana tsanganana satria ao amin'ny Q ny filaharana fanombanana dia miankavanana miankavia.

Manana asa roa lehibe ilaina amin'ny kajy isika izao, mila ampiana fotodrafitrasa kely fotsiny isika dia vonona ny serivisy.

Dingana farany

Manana fiasa mialoha sy fanavaozanaAgg izahay izay manao ny asa rehetra. Saingy mbola ilaina ny miantoka ny fifindrana marina amin'ny alΓ lan'ny minitra sy ny kajy ny indeksan'ny fanangonana. Voalohany indrindra, andeha hofaritana ny asa init:

init:{
  tradeAgg:: 0#enlist[initWith]; // создаСм ΠΏΡƒΡΡ‚ΡƒΡŽ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ, enlist ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Π² Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ, Π° 0# ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Π²Π·ΡΡ‚ΡŒ 0 элСмСнтов ΠΈΠ· Π½Π΅Π΅
  currTime::00:00; // Π½Π°Ρ‡Π½Π΅ΠΌ с 0, :: ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ присваиваниС Π² Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ
  currSyms::`u#`symbol$(); // `u# - ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ список Π² Π΄Π΅Ρ€Π΅Π²ΠΎ, для ускорСния поиска элСмСнтов
  offset::0; // индСкс Π² tradeAgg, Π³Π΄Π΅ начинаСтся тСкущая ΠΌΠΈΠ½ΡƒΡ‚Π° 
  rollCache:: `sym xkey update `u#sym from rollColumns#tradeAgg; // кэш для послСдних Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ roll ΠΊΠΎΠ»ΠΎΠ½ΠΎΠΊ, Ρ‚Π°Π±Π»ΠΈΡ†Π° с ΠΊΠ»ΡŽΡ‡ΠΎΠΌ sym
 }

Hofaritantsika ihany koa ny fiasan'ny horonana, izay hanova ny minitra ankehitriny:

roll:{[tm]
  if[currTime>tm; :init[]]; // Ссли ΠΏΠ΅Ρ€Π΅Π²Π°Π»ΠΈΠ»ΠΈ Π·Π° ΠΏΠΎΠ»Π½ΠΎΡ‡ΡŒ, Ρ‚ΠΎ просто Π²Ρ‹Π·ΠΎΠ²Π΅ΠΌ init
  rollCache,::offset _ rollColumns#tradeAgg; // ΠΎΠ±Π½ΠΎΠ²ΠΈΠΌ кэш – Π²Π·ΡΡ‚ΡŒ roll ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ ΠΈΠ· aggTable, ΠΎΠ±Ρ€Π΅Π·Π°Ρ‚ΡŒ, Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π² rollCache
  offset::count tradeAgg;
  currSyms::`u#`$();
 }

Mila fiasa isika mba hanampiana tarehintsoratra vaovao:

addSyms:{[syms]
  currSyms,::syms; // Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² список извСстных
  // Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ sym, time ΠΈ rollColumns воспользовавшись ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½Ρ‹ΠΌ присваиваниСм.
  // Ѐункция ^ подставляСт значСния ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для roll ΠΊΠΎΠ»ΠΎΠ½ΠΎΠΊ, Ссли символа Π½Π΅Ρ‚ Π² кэшС. value flip table Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ список ΠΊΠΎΠ»ΠΎΠ½ΠΎΠΊ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅.
  `tradeAgg upsert @[count[syms]#enlist initWith;`sym`time,cols rc;:;(syms;currTime), (initWith cols rc)^value flip rc:rollCache ([] sym: syms)];
 }

Ary farany, ny asa upd (ny anarana nentim-paharazana ho an'ity asa ity ho an'ny serivisy Q), izay antsoin'ny mpanjifa hanampy data:

upd:{[tblName;data] // tblName Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ, Π½ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ сСрвис ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ нСсколько Ρ‚Π°Π±Π»ΠΈΡ† 
  tm:exec distinct time from data:() xkey preprocess data; // preprocess & calc time
  updMinute[data] each tm; // Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π΄Π°Π½Π½Ρ‹Π΅ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΌΠΈΠ½ΡƒΡ‚Ρ‹
};
updMinute:{[data;tm]
  if[tm<>currTime; roll tm; currTime::tm]; // помСняСм ΠΌΠΈΠ½ΡƒΡ‚Ρƒ, Ссли Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ
  data:select from data where time=tm; // Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡ
  if[count msyms:syms where not (syms:data`sym)in currSyms; addSyms msyms]; // Π½ΠΎΠ²Ρ‹Π΅ символы
  updateAgg[`tradeAgg;offset+currSyms?syms;data]; // ΠΎΠ±Π½ΠΎΠ²ΠΈΠΌ Π°Π³Ρ€Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ. Ѐункция ? ΠΈΡ‰Π΅Ρ‚ индСкс элСмСнтов списка справа Π² спискС слСва.
 };

Izay ihany. Ity ny code fenon'ny serivisinay, araka ny nampanantenaina, andalana vitsivitsy monja:

initWith:`sym`time`high`low`firstPrice`lastPrice`firstSize`lastSize`numTrades`volume`pvolume`turnover`avgPrice`avgSize`vwap`cumVolume!(`;00:00;0n;0n;0n;0n;0N;0N;0;0;0.0;0.0;0n;0n;0n;0);
aggCols:reverse key[initWith] except `sym`time;
rollColumns:`sym`cumVolume;

accumulatorCols:`numTrades`volume`pvolume`turnover;
specialCols:`high`low`firstPrice`firstSize;

selExpression:`high`low`firstPrice`lastPrice`firstSize`lastSize`numTrades`volume`pvolume`turnover!parse each ("max price";"min price";"first price";"last price";"first size";"last size";"count i";"sum size";"sum price";"sum price*size");
preprocess:?[;();`sym`time!`sym`time.minute;selExpression];

aggExpression:`high`low`firstPrice`lastPrice`firstSize`lastSize`avgPrice`avgSize`vwap`cumVolume!("row[`high]|inp`high";"row[`low]&inp`low";"row`firstPrice";"inp`lastPrice";"row`firstSize";"inp`lastSize";"pvolume%numTrades";"volume%numTrades";"turnover%volume";"row[`cumVolume]+inp`volume");
@[`aggExpression;specialCols;{"?[isFirst;inp`",y,";",x,"]"};string specialCols];
aggExpression[accumulatorCols]:{"row[`",x,"]+inp`",x } each string accumulatorCols;
updateAgg:value "{[aggTable;idx;inp] row:aggTable idx; isFirst_0=row`numTrades; .[aggTable;;:;]'[(idx;)each aggCols;(",(";"sv string[aggCols],'":",/:aggExpression aggCols),")]}"; / '

init:{
  tradeAgg::0#enlist[initWith];
  currTime::00:00;
  currSyms::`u#`symbol$();
  offset::0;
  rollCache:: `sym xkey update `u#sym from rollColumns#tradeAgg;
 };
roll:{[tm]
  if[currTime>tm; :init[]];
  rollCache,::offset _ rollColumns#tradeAgg;
  offset::count tradeAgg;
  currSyms::`u#`$();
 };
addSyms:{[syms]
  currSyms,::syms;
  `tradeAgg upsert @[count[syms]#enlist initWith;`sym`time,cols rc;:;(syms;currTime),(initWith cols rc)^value flip rc:rollCache ([] sym: syms)];
 };

upd:{[tblName;data] updMinute[data] each exec distinct time from data:() xkey preprocess data};
updMinute:{[data;tm]
  if[tm<>currTime; roll tm; currTime::tm];
  data:select from data where time=tm;
  if[count msyms:syms where not (syms:data`sym)in currSyms; addSyms msyms];
  updateAgg[`tradeAgg;offset+currSyms?syms;data];
 };

fitiliana

Andeha hojerentsika ny fahombiazan'ny serivisy. Mba hanaovana izany, andao hatao amin'ny dingana mitokana (apetraho ao amin'ny rakitra service.q ny code) ary antsoy ny asa init:

q service.q –p 5566

q)init[]

Ao amin'ny console hafa, atombohy ny dingana Q faharoa ary mifandray amin'ny voalohany:

h:hopen `:host:5566
h:hopen 5566 // Ссли ΠΎΠ±Π° Π½Π° ΠΎΠ΄Π½ΠΎΠΌ хостС

Voalohany, andao hamorona lisitry ny marika - tapa-10000 ary ampio asa iray hamoronana latabatra kisendrasendra. Ao amin'ny console faharoa:

syms:`IBM`AAPL`GOOG,-9997?`8
rnd:{[n;t] ([] sym:n?syms; time:t+asc n#til 25; price:n?10f; size:n?10)}

Nanampy marika telo tena izy tamin'ny lisitra aho mba hanamora ny fitadiavana azy ireo eo amin'ny latabatra. Ny asa rnd dia mamorona latabatra kisendrasendra misy laharana n, izay miovaova ny fotoana manomboka amin'ny t ka hatramin'ny t+25 milliseconds.

Afaka manandrana mandefa data amin'ny serivisy ianao izao (ampio ny adiny folo voalohany):

{h (`upd;`trade;rnd[10000;x])} each `time$00:00 + til 60*10

Azonao atao ny manamarina amin'ny serivisy fa nohavaozina ny latabatra:

c 25 200
select from tradeAgg where sym=`AAPL
-20#select from tradeAgg where sym=`AAPL

vokany:

sym|time|high|low|firstPrice|lastPrice|firstSize|lastSize|numTrades|volume|pvolume|turnover|avgPrice|avgSize|vwap|cumVolume
--|--|--|--|--|--------------------------------
AAPL|09:27|9.258904|9.258904|9.258904|9.258904|8|8|1|8|9.258904|74.07123|9.258904|8|9.258904|2888
AAPL|09:28|9.068162|9.068162|9.068162|9.068162|7|7|1|7|9.068162|63.47713|9.068162|7|9.068162|2895
AAPL|09:31|4.680449|0.2011121|1.620827|0.2011121|1|5|4|14|9.569556|36.84342|2.392389|3.5|2.631673|2909
AAPL|09:33|2.812535|2.812535|2.812535|2.812535|6|6|1|6|2.812535|16.87521|2.812535|6|2.812535|2915
AAPL|09:34|5.099025|5.099025|5.099025|5.099025|4|4|1|4|5.099025|20.3961|5.099025|4|5.099025|2919

Andeha isika izao hanao fitiliana enta-mavesatra hahitana hoe ohatrinona ny angona azon'ny serivisy atao isa-minitra. MamelΓ  ahy hampahatsiahy anao fa nametraka ny elanelam-potoana fanavaozana ho 25 milliseconds. Noho izany, ny serivisy dia tsy maintsy (amin'ny salanisa) miditra ao anatin'ny 20 milisegondra farafahakeliny isaky ny fanavaozana mba hanomezana fotoana ny mpampiasa hangataka data. Ampidiro ireto manaraka ireto amin'ny dingana faharoa:

tm:10:00:00.000
stressTest:{[n] 1 string[tm]," "; times,::h ({st:.z.T; upd[`trade;x]; .z.T-st};rnd[n;tm]); tm+:25}
start:{[n] times::(); do[4800;stressTest[n]]; -1 " "; `min`avg`med`max!(min times;avg times;med times;max times)}

4800 dia roa minitra. Azonao atao ny manandrana mihazakazaka voalohany ho an'ny laharana 1000 isaky ny 25 milisegondra:

start 1000

Raha ny amiko, manodidina ny roa milliseconds isaky ny fanavaozana ny valiny. Noho izany dia hampitombo avy hatrany ny isan'ny andalana ho 10.000 aho:

start 10000

vokany:

min| 00:00:00.004
avg| 9.191458
med| 9f
max| 00:00:00.030

Indray, tsy misy zavatra manokana, fa andalana 24 tapitrisa isa-minitra, 400 arivo isan-tsegondra. Nandritra ny 25 milisegondra mahery dia nihena in-5 fotsiny ny fanavaozana, toa rehefa niova ny minitra. Andao hampitomboina ho 100.000:

start 100000

vokany:

min| 00:00:00.013
avg| 25.11083
med| 24f
max| 00:00:00.108
q)sum times
00:02:00.532

Araka ny hitanao dia zara raha afaka miatrika ny serivisy, saingy na izany aza dia mahavita mijanona. Ny habetsaky ny angon-drakitra toy izany (240 tapitrisa andalana isa-minitra) dia tena lehibe; amin'ny tranga toy izany dia mahazatra ny manangana clones maromaro (na clones am-polony aza) amin'ny serivisy, ary ny tsirairay amin'izy ireo dia tsy manao afa-tsy ampahany amin'ny endri-tsoratra. Na izany aza, mahavariana ny vokatra ho an'ny fiteny voadika izay mifantoka indrindra amin'ny fitahirizana angon-drakitra.

Mety hipoitra ny fanontaniana hoe nahoana ny fotoana no mitombo tsy misy tsipika miaraka amin'ny haben'ny fanavaozana tsirairay. Ny antony dia ny fiasan'ny shrink dia tena asa C, izay mahomby kokoa noho ny updateAgg. Manomboka amin'ny haben'ny fanavaozana sasany (manodidina ny 10.000), ny updateAgg dia mahatratra ny valindrihana ary avy eo ny fotoana famonoana dia tsy miankina amin'ny haben'ny fanavaozana. Noho ny dingana savaranonando Q no ahafahan'ny serivisy mandevona angon-drakitra toy izany. Izany dia manasongadina ny maha-zava-dehibe ny fisafidianana ny algorithm tsara rehefa miasa amin'ny angona lehibe. Ny teboka iray hafa dia ny fitahirizana marina ny angona ao amin'ny fitadidiana. Raha tsy voatahiry an-jorony ny angon-drakitra na tsy voabaiko ara-potoana, dia ho zatra amin'ny zavatra toy ny TLB cache miss - ny tsy fisian'ny pejin'ny fahatsiarovana ao amin'ny cache adiresin'ny processeur. Ny fitadiavana adiresy dia maharitra in-30 eo ho eo raha tsy mahomby, ary raha miparitaka ny angona dia mety hampiadana ny serivisy imbetsaka izany.

famaranana

Ato amin'ity lahatsoratra ity, nasehoko fa ny angon-drakitra KDB + sy Q dia mety tsy amin'ny fitahirizana angon-drakitra lehibe sy ny fidirana mora amin'izany amin'ny alΓ lan'ny fifantenana, fa koa amin'ny famoronana serivisy fanodinana data izay afaka mandevona andalana / gigabytes an-jatony tapitrisa na dia amin'ny dingana Q tokana. Ny fiteny Q mihitsy dia mamela ny fampiharana algorithm amin'ny fomba fohy sy mahomby mifandraika amin'ny fanodinana angon-drakitra noho ny toetrany vector, mpandika teny SQL naorina ao anatiny ary andiana famakiam-boky tena mahomby.

Marihiko fa ampahany fotsiny amin'ny zavatra azon'i Q atao io etsy ambony io, manana endri-javatra miavaka hafa koa izy. Ohatra, protocole IPC tena tsotra izay mamafa ny sisin-tany eo amin'ny fizotran'ny Q tsirairay ary ahafahanao manambatra an-jatony amin'ireo dingana ireo ho tambajotra tokana, izay azo jerena amin'ny mpizara am-polony any amin'ny faritra samihafa eto amin'izao tontolo izao.

Source: www.habr.com

Add a comment