Azonao atao ny mamaky momba ny fototra KDB +, ny fiteny fandaharana Q, ny tanjany sy ny fahalemeny ao amin'ny teo aloha.
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 -
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:
- Accumulators (volony, turnover, ..) - tsy maintsy ampiana ny sanda miditra amin'ny teo aloha.
- 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.
- 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