Hiki iā ʻoe ke heluhelu e pili ana i ke ʻano o ka waihona KDB+ a me ka ʻōlelo hoʻolālā Q, a me ko lākou mau ikaika a me nā nāwaliwali i kaʻu pou mua. a pōkole ma ka hoʻolauna. Ma kēia ʻatikala, e hoʻokō mākou i kahi lawelawe ma Q e hana i kahi kahawai ʻikepili e hiki mai ana a helu i nā hana hoʻohui like ʻole i kēlā me kēia minuke i ka "manawa maoli" (ʻo ia hoʻi, loaʻa ka manawa e helu ai i nā mea āpau ma mua o ka pūʻulu ʻikepili aʻe). ʻO ka hiʻohiʻona nui o Q, ʻo ia ka ʻōlelo vector, e ʻae iā mākou e hana ʻaʻole ma luna o nā mea hoʻokahi, akā ma nā ʻāpana o ia mau mea, nā ʻāpana o nā arrays, a me nā mea paʻakikī ʻē aʻe. Ua kaulana nā ʻōlelo e like me Q a me kāna mau ʻōlelo pili, K, J, a me APL, no ko lākou pōkole. ʻO ka manawa pinepine, hiki ke kākau ʻia kahi papahana e lawe i kekahi mau pale o ke code ma kahi ʻōlelo maʻamau e like me Java i kekahi mau laina. ʻO kēia ka mea aʻu e makemake ai e hōʻike i kēia ʻatikala.

Hōʻike
ʻO KDB+ kahi waihona kolamu i hoʻolālā ʻia no nā puke nui loa o ka ʻikepili i hoʻonohonoho ʻia ma ke ʻano kikoʻī (ma mua o ka manawa). Hoʻohana nui ʻia i nā ʻoihana kālā e like me nā panakō, nā kālā hoʻopukapuka, a me nā hui ʻinikua. ʻO Q ka ʻōlelo kūloko o KDB+, e ʻae ana i ka hana kūpono me kēia ʻikepili. ʻO kā Q's philosophy ka pōkole a me ka maikaʻi, e kaumaha ana i ka maopopo. ʻO kēia no ka mea paʻakikī ke hoʻomaopopo ʻana i ka ʻōlelo vector-based, ʻoiai ka pōkole a me ka waiwai e ʻae i ka ʻāpana nui o ka papahana e hōʻike ʻia ma ka pale hoʻokahi, e maʻalahi ka hoʻomaopopo ʻana.
Ma kēia ʻatikala, e hoʻokō mākou i kahi papahana piha ma Q, a makemake paha ʻoe e hoʻāʻo. No ka hana ʻana i kēia, pono ʻoe iā Q ponoʻī. Hiki iā ʻoe ke hoʻoiho i ka mana 32-bit manuahi mai ka pūnaewele kx - Ma laila, inā makemake ʻoe, e ʻike pū ʻoe i ka ʻike kuhikuhi ma Q, kahi puke a me nā ʻatikala like ʻole e pili ana i kēia kumuhana.
Ka hoʻokumu ʻana i ka pilikia
Aia kekahi kumu e hoʻouna i ka papa ʻikepili i kēlā me kēia 25 milliseconds. Ma muli o ka hoʻohana nui ʻia ʻana o KDB+ i ke kālā, manaʻo mākou he papa kālepa me nā kolamu aʻe: manawa (manawa i milliseconds), sym (hōʻailona ʻoihana ma ke kumukūʻai kūʻai - IBM, AAPL,…), kumukūʻai (ke kumu kūʻai i kūʻai ʻia ai nā ʻāpana), a me ka nui (ka nui o ke kālepa). Ua koho 'ia ka manawa 25-milikona; ʻaʻole liʻiliʻi ʻaʻole nui loa. ʻO kona hele ʻana, ʻo ia ka mea i hoʻopaʻa ʻia ka ʻikepili i hiki mai i ka lawelawe. E maʻalahi ka hoʻokō ʻana i ka buffering ma ka ʻaoʻao lawelawe, e komo pū me ka buffering dynamic e pili ana i ka ukana o kēia manawa, akā no ka maʻalahi, e paʻa mākou me kahi manawa paʻa.
Pono ka lawelawe e helu i kahi pūʻulu o nā hana hōʻuluʻulu — kumu kūʻai kiʻekiʻe, kumu kūʻai avg, nui nui, a me nā ʻike pono ʻē aʻe—i kēlā me kēia minuke no kēlā me kēia hōʻailona e komo mai ana mai ke kolamu sym. No ka maʻalahi, manaʻo mākou e hiki ke helu ʻia nā hana a pau, ʻo ia hoʻi, no ka loaʻa ʻana o kahi waiwai hou, ua lawa nā helu ʻelua - ka waiwai kahiko a me ka waiwai e hiki mai ana. No ka laʻana, loaʻa kēia waiwai i ka hana max, awelika, a me ka huina, akā ʻaʻole ka hana waena.
E manaʻo mākou ua kauoha ʻia ke kahawai ʻikepili e hiki mai ana e ka manawa. E ʻae kēia iā mākou e hana me ka minuke hope loa. I ka hoʻomaʻamaʻa ʻana, lawa ia e hiki ke hana me nā minuke o kēia manawa a me nā minuke i hala inā ua lohi nā mea hou. No ka maʻalahi, ʻaʻole mākou e noʻonoʻo i kēia hihia.
Nā hana hoʻohui
Aia ma lalo nā hana hoʻohui pono. Ua hoʻokomo au i nā mea he nui e hiki ai ke hoʻonui i ka ukana lawelawe:
- kiʻekiʻe - kumu kūʻai kiʻekiʻe - kumu kūʻai kiʻekiʻe i kēlā me kēia minuke.
- haʻahaʻa - kumu kūʻai min - kumu kūʻai liʻiliʻi i kēlā me kēia minuke.
- ke kumu kūʻai mua - ke kumu kūʻai mua - ke kumu kūʻai mua i kēlā me kēia minuke.
- ke kumu kūʻai hope - ke kumu kūʻai hope loa i kēlā me kēia minuke.
- firstSize - ka nui mua - ka nui kālepa mua i kēlā me kēia minuke.
- lastSize - ka nui hope - ka nui kālepa hope loa i kēlā me kēia minuke.
- numTrades - helu i - helu o nā kālepa i kēlā me kēia minuke.
- ka nui - ka nui o ka nui - ka huina o ka nui o ke kālepa i kēlā me kēia minuke.
- pvolume - huina kumu kūʻai - huina o nā kumukūʻai i kēlā me kēia minuke, koi ʻia no ka avgPrice.
- huli - huina kumukūʻai * nui - ka nui o nā hana i kēlā me kēia minuke.
- avgPrice - pvolume%numTrades - kumu kūʻai maʻamau i kēlā me kēia minuke.
- avgSize - volume%numTrades - ka nui kālepa maʻamau i kēlā me kēia minuke.
- vwap - huli%volume - kumu kūʻai maʻamau i kēlā me kēia minuke i kaupaona ʻia e ka nui kālepa.
- cumVolume - huina nui - hōʻiliʻili nui o nā hana i ka manawa holoʻokoʻa.
E kūkākūkā kākou i hoʻokahi wahi i ʻike ʻole ʻia: pehea e hoʻomaka ai i kēia mau kolamu i ka manawa mua a no kēlā me kēia minuke ma hope. ʻO kekahi mau kolamu, e like me ka muaPrice, pono e hoʻomaka i ka null i kēlā me kēia manawa; ʻaʻole maopopo ko lākou waiwai. ʻO nā mea ʻē aʻe, e like me ka leo, pono e hoʻonohonoho mau ʻia i ka 0. Aia kekahi mau kolamu e koi ana i kahi ala hoʻohui - no ka laʻana, pono e kope ʻia ka cumVolume mai ka minuke mua a hoʻonoho i ka 0 no ka minuke mua. E wehewehe mākou i kēia mau ʻāpana me ka hoʻohana ʻana i ke ʻano ʻikepili puke wehewehe (e like me kahi moʻolelo):
// 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 объяснен ниже
Ua hoʻohui au i ka sym a me ka manawa i ka puke wehewehe ʻōlelo no ka maʻalahi. I kēia manawa ʻo initWith kahi lālani i hoʻomākaukau ʻia mai ka papaʻaina i hōʻuluʻulu ʻia, kahi e waiho ʻia ai ka sym kūpono a me ka manawa. Hiki iā ʻoe ke hoʻohana iā ia e hoʻohui i nā lālani hou i ka papaʻaina.
Pono mākou i nā aggCols i ka hana ʻana i ka hana aggregate. Pono e hoʻohuli ʻia ka papa inoa ma muli o ke ʻano o ka loiloi hōʻike ma Q (mai ka ʻākau a i ka hema). ʻO ka pahuhopu e hōʻoia i ka loaʻa ʻana o ka loiloi mai ke kiʻekiʻe a hiki i ka cumVolume, no ka mea, pili kekahi mau kolamu i nā kolamu mua.
ʻO nā kolamu e pono e kope ʻia i ka minuke hou mai ka mea ma mua, ua hoʻohui ʻia ke kolamu sym no ka maʻalahi:
rollColumns:`sym`cumVolume;
I kēia manawa, e hoʻokaʻawale i nā kolamu i nā hui e pili ana i ke ʻano o ka hoʻonui ʻana. Hiki ke hoʻokaʻawale ʻia nā ʻano ʻekolu:
- Accumulators (volume, turnover, ..) - pono mākou e hoʻohui i ka waiwai komo i ka mea mua.
- Me kahi kikoʻī kūikawā (kiʻekiʻe, haʻahaʻa, ..) - lawe ʻia ka waiwai mua i ka minuke mai ka ʻikepili e hiki mai ana, ua helu ʻia ke koena me ka hoʻohana ʻana i ka hana.
- Hoʻohana mau ʻia ke koena me ka hoʻohana ʻana i ka hana.
E wehewehe i nā ʻano like ʻole no kēia mau papa:
accumulatorCols:`numTrades`volume`pvolume`turnover;
specialCols:`high`low`firstPrice`firstSize;
Kauoha helu
E hōʻano hou mākou i ka papa ʻaina ma nā ʻanuʻu ʻelua. No ka maikaʻi, e hōʻemi mua mākou i ka papa hoʻokomo i loaʻa i hoʻokahi lālani no kēlā me kēia hōʻailona a me nā minuke. ʻO ka ʻoiaʻiʻo ʻo kā mākou mau hana āpau he hoʻonui a hui pū ʻia ʻaʻole e loli ka hopena me kēia hana hou. Hiki iā mākou ke hōʻemi i ka papaʻaina me ka hoʻohana ʻana i kahi ʻōlelo koho:
select high:max price, low:min price … by sym,time.minute from table
He drawback kēia ʻano hana: ʻo ka hoʻonohonoho o nā kolamu helu i hoʻonohonoho mua ʻia. ʻO ka mea pōmaikaʻi, hoʻokomo pū ʻo Q i ke koho ma ke ʻano he hana e ʻae i nā manaʻo hoʻopaʻapaʻa dynamically:
?[table;whereClause;byClause;selectClause]
ʻAʻole au e wehewehe kikoʻī i ke ʻano hoʻopaʻapaʻa; i kā mākou hihia, ʻo nā huaʻōlelo nontrivial wale nō nā huaʻōlelo na a koho, a he mau puke wehewehe ʻōlelo o nā kolamu! No laila, hiki ke wehewehe ʻia ka hana compression penei:
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];
No ka akaka, ua hoʻohana au i ka hana parse, e hoʻololi ana i kahi kaula i loaʻa ka huaʻōlelo Q i kahi waiwai e hiki ke hāʻawi ʻia i ka hana eval a koi ʻia i ka hana koho. E hoʻomaopopo hoʻi ua wehewehe ʻia ka preprocess ma ke ʻano he projection (ʻo ia hoʻi, kahi hana me nā manaʻo wehewehe hapa) o ka hana koho; ua nalowale hoʻokahi manaʻo (ka papaʻaina). Inā mākou e hoʻopili i ka preprocess i kahi papaʻaina, loaʻa iā mākou kahi pākaukau paʻa.
ʻO ka hana ʻelua ʻo ka hōʻano hou ʻana i ka pākaukau i hui ʻia. E kākau mua i ka algorithm ma 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];
…
Ma Q, he mea maʻamau ka hoʻohana ʻana i ka palapala ʻāina/hōʻemi i nā hana ma kahi o nā puka lou. Akā, no ka mea he ʻōlelo vector ʻo Q a hiki iā mākou ke hoʻopili palekana i nā hana āpau i nā hōʻailona a pau i ka manawa hoʻokahi, hiki iā mākou, ma ke ʻano he hoʻohālikelike mua, e hoʻopau loa i ka loop ma ka hana ʻana i nā hana ma nā hōʻailona a pau i ka manawa hoʻokahi:
idx:calcIdx inputTable;
row:aggTable idx;
aggTable[idx;`high]: row[`high] | inputTable`high;
aggTable[idx;`volume]: row[`volume] + inputTable`volume;
…
Akā hiki iā mākou ke hele i mua. Loaʻa iā Q kahi mea hoʻohana kūʻokoʻa a ikaika loa - ka mea hoʻohana maʻamau. Hāʻawi ia iā ʻoe e hoʻololi i kahi hoʻonohonoho o nā waiwai i loko o kahi hoʻolālā data paʻakikī me ka hoʻohana ʻana i kahi papa inoa o nā kuhikuhi, nā hana, a me nā hoʻopaʻapaʻa. I kā mākou hihia, ʻano like kēia:
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;…)];
ʻO ka mea pōʻino, ʻo ka hāʻawi ʻana i ka papaʻaina he papa inoa o nā lālani, ʻaʻole nā kolamu, a pono e hoʻololi i ka matrix (papa inoa o nā kolamu i kahi papa inoa o nā lālani) me ka hoʻohana ʻana i ka hana flip. No ka papaʻaina nui, he pipiʻi kēia, no laila, hoʻohana mākou i kahi hana maʻamau i kēlā me kēia kolamu me ka hoʻohana ʻana i ka hana palapala (e like me ka apostrophe):
.[aggTable;;:;]'[(idx;)each aggCols; (row[`high] | inputTable`high;row[`volume] + inputTable`volume;…)];
Hoʻohana hou mākou i ka projection function. E hoʻomaopopo hoʻi ma Q, he hana hoʻi ka hana ʻana i ka papa inoa, a hiki iā mākou ke kapa iā ia me ka hoʻohana ʻana i kēlā me kēia(palapala palapala) e kiʻi i kahi papa inoa o nā papa inoa.
No ka pale ʻana i kahi hoʻonohonoho paʻa o nā kolamu i helu ʻia, e hana mākou i ka ʻōlelo ma luna me ka ikaika. ʻO ka mea mua, e wehewehe i nā hana no ka helu ʻana i kēlā me kēia kolamu, me ka hoʻohana ʻana i ka lālani a me nā ʻokoʻa inp e kuhikuhi i ka ʻikepili i hōʻuluʻulu ʻia a hoʻokomo:
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");
He kūikawā kekahi mau kolamu; ʻAʻole pono e helu ʻia ko lākou waiwai mua e ka hana. Hiki iā mākou ke hoʻoholo ʻo ia ka mua ma ka lālani [`numTrades] kolamu—inā he 0, a laila ʻo ka mua ka waiwai. Loaʻa iā Q kahi hana koho—?[Boolean list;list1;list2]—ʻo ia ka mea e koho ai i kahi waiwai mai ka papa inoa 1 a i ʻole 2 ma muli o ke kūlana o ka pane mua:
// high -> ?[isFirst;inp`high;row[`high]|inp`high]
// @ - тоже обобщенное присваивание для случая когда индекс неглубокий
@[`aggExpression;specialCols;{[x;y]"?[isFirst;inp`",y,";",x,"]"};string specialCols];
Ma ʻaneʻi ua kāhea wau i kahi hana maʻamau me kaʻu hana (ka ʻōlelo ma nā pale pale). Ua hala i ka waiwai o kēia manawa (ka hoʻopaʻapaʻa mua) a me kahi hoʻopaʻapaʻa hou, aʻu i hāʻawi ai i ka ʻehā.
E hoʻohui kaʻawale i nā mea ʻōlelo hoʻonaʻauao pākahi, no ka mea, lawelawe like lākou:
// volume -> row[`volume]+inp`volume
aggExpression[accumulatorCols]:{"row[`",x,"]+inp`",x } each string accumulatorCols;
He hana maʻamau kēia e nā kūlana Q, akā hāʻawi wau i kahi papa inoa o nā waiwai i ka manawa hoʻokahi. ʻO ka hope, e hana kākou i ka hana nui:
// ":",/: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),")]}";
Me kēia ʻōlelo, hana au i kahi hana mai kahi kaula i loaʻa ka ʻōlelo aʻu i hāʻawi ai ma luna. Penei ka hopena:
{[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])]}
Hoʻohuli ʻia ke ʻano o ka loiloi o nā kolamu, ʻoiai ma Q ka papa o ka loiloi he ʻākau a hema.
I kēia manawa, ʻelua mau hana nui e pono ai no ka hoʻopili ʻana, ʻo ka mea wale nō i koe e hoʻohui i kahi ʻoihana liʻiliʻi a mākaukau ka lawelawe.
Nā ʻanuʻu hope
Loaʻa iā mākou nā hana preprocess a updateAgg e hana i nā hana āpau. Akā pono mākou e hōʻoia i nā hoʻololi kūpono ma waena o nā minuke a helu i nā kuhikuhi no ka hoʻohui. ʻO ka mea mua, e wehewehe i ka hana 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
}
E wehewehe pū mākou i kahi hana ʻōwili e hoʻololi i ka minuke o kēia manawa:
roll:{[tm]
if[currTime>tm; :init[]]; // если перевалили за полночь, то просто вызовем init
rollCache,::offset _ rollColumns#tradeAgg; // обновим кэш – взять roll колонки из aggTable, обрезать, вставить в rollCache
offset::count tradeAgg;
currSyms::`u#`$();
}
Pono mākou i kahi hana e hoʻohui i nā huaʻōlelo hou:
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)];
}
A ʻo ka hope, ʻo ka hana upd (ka inoa kuʻuna o kēia hana no nā lawelawe Q), i kāhea ʻia e ka mea kūʻai aku e hoʻohui i ka ʻikepili:
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]; // обновим агрегированную таблицу. Функция ? ищет индекс элементов списка справа в списке слева.
};
ʻo ia wale nō. Eia ka code piha no kā mākou lawelawe, e like me ka mea i ʻōlelo ʻia, he mau laina wale nō:
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];
};
Hoʻoponopono
E ho'āʻo kākou i ka hana o ka lawelawe. No ka hana ʻana i kēia, e hoʻolauna iā ia i kahi kaʻina kaʻawale (e kau i ke code ma ka faila service.q) a kāhea i ka hana init:
q service.q –p 5566
q)init[]
Ma kahi console ʻē aʻe, e hoʻomaka i kahi kaʻina Q lua a hoʻohui i ka mea mua:
h:hopen `:host:5566
h:hopen 5566 // если оба на одном хосте
ʻO ka mea mua, e hana kākou i papa inoa o nā huaʻōlelo—10000 o lākou—a hoʻohui i kahi hana e hoʻohua ai i ka papaʻaina. Ma ka console lua:
syms:`IBM`AAPL`GOOG,-9997?`8
rnd:{[n;t] ([] sym:n?syms; time:t+asc n#til 25; price:n?10f; size:n?10)}
Ua hoʻohui au i ʻekolu mau hōʻailona maoli i ka papa inoa i mea e maʻalahi ai ka ʻimi ʻana iā lākou ma ka papaʻaina. Hoʻokumu ka hana rnd i ka papaʻaina maʻamau me nā lālani n, kahi o nā manawa mai ka t a i ka t+25 milliseconds.
I kēia manawa hiki iā ʻoe ke hoʻouna i ka ʻikepili i ka lawelawe (e hoʻohui i nā hola he ʻumi mua):
{h (`upd;`trade;rnd[10000;x])} each `time$00:00 + til 60*10
Hiki iā ʻoe ke nānā i ka lawelawe i hōʻano hou ʻia ka papaʻaina:
c 25 200
select from tradeAgg where sym=`AAPL
-20#select from tradeAgg where sym=`AAPL
Hualoaʻa:
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|2919I kēia manawa, e hoʻāʻo kāua e hoʻoholo i ka nui o ka ʻikepili i hiki i ka lawelawe ke hana i kēlā me kēia minuke. I mea hoʻomanaʻo, hoʻonoho mākou i ka manawa hoʻonui i 25 milliseconds. No laila, pono ka lawelawe (ma ka awelika) e hoʻohou i loko o ka liʻiliʻi 20 milliseconds e hāʻawi i nā mea hoʻohana i ka manawa e noi ai i ka ʻikepili. E hoʻokomo i kēia ma ke kaʻina hana ʻelua:
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)}
ʻO 4800 ʻelua mau minuke. Hiki iā ʻoe ke hoʻāʻo e holo mua no nā lālani 1000 i kēlā me kēia 25 milliseconds:
start 1000
I koʻu hihia, ʻo ka hopena e pili ana i ʻelua mau milliseconds no ka hoʻonui. No laila e hoʻonui koke au i ka helu o nā lālani i 10.000:
start 10000
Hualoaʻa:
min| 00:00:00.004
avg| 9.191458
med| 9f
max| 00:00:00.030
Eia hou, ʻaʻohe mea kūikawā, akā he 24 miliona lālani i kēlā me kēia minuke, 400,000 i kekona. Ua lohi wale ka mea hou no ka 25 milliseconds ʻelima mau manawa, ʻike ʻia ma muli o ka loli minuke. E hoʻonui i kēlā i 100.000:
start 100000
Hualoaʻa:
min| 00:00:00.013
avg| 25.11083
med| 24f
max| 00:00:00.108
q)sum times
00:02:00.532
E like me kā mākou e ʻike ai, ʻaʻole paʻa ka lawelawe, akā ke hoʻomau nei ʻo ia e noho mau. ʻO kēia nui o ka ʻikepili (240 miliona lālani i kēlā me kēia minuke) he nui loa; i ia mau hihia, he mea maʻamau ka hoʻomaka ʻana i kekahi mau clones (a i ʻole he mau kakini) o ka lawelawe, kēlā me kēia hana i kahi ʻāpana o nā huaʻōlelo. Eia nō naʻe, he mea kupanaha ka hopena no kahi ʻōlelo unuhi i kālele nui ʻia i ka mālama ʻikepili.
E noʻonoʻo paha kekahi no ke aha e ulu ai ka manawa me ka nui o kēlā me kēia mea hou. ʻO ke kumu, ʻo ka hana hoʻopiʻi he hana C, ʻoi aku ka maikaʻi ma mua o ka updateAgg. E hoʻomaka ana i kahi nui hoʻonui (ma kahi o 10.000), hiki i ka updateAgg ke kaupaku, a ma hope o ia, kūʻokoʻa kona manawa hoʻokō i ka nui o ka hoʻonui. Ma muli o ka Q pre-step e hiki ai i ka lawelawe ke hoʻoheheʻe i nā nui o ka ʻikepili. Hōʻike kēia i ke koʻikoʻi o ke koho ʻana i ka algorithm kūpono i ka wā e hana ai me ka ʻikepili nui. ʻO kekahi mea e noʻonoʻo pono ai ka mālama ʻana i ka ʻikepili i ka hoʻomanaʻo. Inā ʻaʻole mālama ʻia ka ʻikepili i ka columnarly a i ʻole i kauoha ʻia i ka manawa, e hālāwai mākou i kahi mea i kapa ʻia ʻo TLB cache miss—ʻo ka loaʻa ʻole o kahi helu ʻaoʻao hoʻomanaʻo i ka cache address o ka mea hana. He 30 paha ka lōʻihi o ka huli ʻana i ka helu wahi inā ʻaʻole i hoʻopōmaikaʻi ʻia, a i ka hihia o ka ʻikepili hoʻopuehu, hiki i kēia ke hoʻolohi i ka lawelawe i nā manawa he nui.
hopena
Ma kēia ʻatikala, ua hōʻike au he kūpono ʻo KDB+ a me Q ʻaʻole wale no ka mālama ʻana i nā pūʻulu ʻikepili nui a hiki ke komo maʻalahi iā lākou ma o nā ʻōlelo i koho ʻia, akā no ka hana ʻana i nā lawelawe hoʻoili ʻikepili hiki ke hana i nā haneli miliona o nā lālani / gigabytes o ka ʻikepili ma kahi kaʻina Q hoʻokahi. ʻO ka ʻōlelo Q ponoʻī e ʻae i ka hoʻokō ʻokoʻa a me ka maikaʻi o ka hoʻokō ʻana i nā algorithm hoʻoili ʻikepili ma muli o kona ʻano vector, ka unuhi ʻōlelo SQL i kūkulu ʻia, a me kahi hoʻonohonoho holomua o nā hana waihona.
Makemake au e kuhikuhi ʻo ka mea i luna nei he laʻana wale nō ia o nā mana o Q; he mau hiʻohiʻona ʻē aʻe kekahi. No ka laʻana, kahi protocol IPC maʻalahi loa e holoi i nā palena ma waena o nā kaʻina Q pākahi a hiki i nā haneli o kēia mau kaʻina e hoʻopili ʻia i kahi pūnaewele hoʻokahi, hiki ke hoʻolōʻihi i nā kaukani o nā kikowaena a puni ka honua.
Source: www.habr.com
