áľá KDB+ áá°á¨áľáŁ á¨Q ááŽááŤááá ááá áá áĽáá°ááᣠá ááľáᏠááľáĽ áá áĽááŤáŹ áĽá áľáááśá˝ áĽááłá ááá ἠáľá˝ááá
á˘
ááá˘áŤ
KDB+ á á°áá°á ááááľ (á áááááľ á áá) á á¨áá°á áá á áá áŤá°áŽá¨ á¨á ááľ áłáłá¤á ááᢠá ááááľ á áááááşáŤá á°áááľ - áŁááŽá˝, á¨á˘áá¨áľáľáááľ áááľ, á¨á˘áášáŤááľ áŠáŁááŤáá˝ ááľáĽ áĽá á áá áááá. á¨Q ááá á¨KDB+ ááľáŁá ááá á˛áá á¨áá ááἠáá á áĽááľ áĽáá˛á°áŠ áŤáľá˝áááłáᢠᨠQ áááŽá° ááá á áá áĽá á ááĽáá á˛áá ááá˝ááľ áá ááľááĽáľááľ ááᢠáá á¨á°á¨ááá á á ááááá áááł á¨áŹáá°á áááá ááá¨áłáľ á áľá¸á᪠áĽáá°ááá áĽá á¨áá¨áťá á ááááľ áĽá áĽáá˝áá á¨ááŽááŤáá á áŁá áľáá ááá á á ááľ á፠áá˝ áá áĽáá˛áŤáŠ áŤáľá˝áááłá ᣠáá á á áá¨á¨áť ááá¨áłáľ ááá áŤá°ááááá˘
á áá
á˝áá ááľáĽ á Q ááľáĽ á¨á°áá ááŽááŤá áĽáá°ááĽáŤáá áĽá ááááŠáľ áá˝ááᢠáá
áá áááľá¨á áľáááááá Q áŤáľáááááłá áá 32-á˘áľ áľáŞáľ á kx áŠáŁá፠áľá¨-áá˝ áá ááá¨áľ áá˝áá -
á¨á˝áአááá
á á¨25 ááá°á¨ááľ áá¨á áŤáá á áá á¨áĽ á¨ááá ááá á áᢠKDB+ á ááááľ á áááááľ ááľáĽ áĽá á áá á¨ááá áľááá, áá á¨ááĽááśá˝ á°áá á¨áĽ áá áĽáá áĽááááłáá, áĽáąá á¨áá¨á°ááľ áááśá˝ á ááľ: áá (áá á ááá°á¨ááśá˝), á˛á (á á áá˛áŽá áááἠáá á¨áŠáŁááŤá áľáŤá -) IBM, AAPL,âŚ), áá (á áá˛áŽááš á¨á°ááá áľ áá), áá á (á¨ááĽááą áá á). ᨠ25 ááá°á¨ááľ ááá°áľ á¨áááá° áá, á áŁá áľáá˝ áĽá á¨á á á áá°áá. á¨áĽáą ááááľ áááľ ááᥠááľááá áá° á°áŤáá á áááááľ áááŁá áááľ ááᢠá áá áŁáá áááľ áá á áááľá¨áľ á°áááá ááá¨áŚá˝á á¨áᎠá á áááááľ á áŠá áááľá áá°áá á ááá áááá ᣠáá áááá ᣠáĽá á áá ááá°áľ áá áĽáá°áŠáŤááá˘
á áááááą á¨á˛á á ááľ ááĽáŤááłááą á¨áᢠááááľ á á¨á°ááá ááá á á áá áľ á¨áá áá፠á°ááŁáŤáľ - á¨áá°á ááᣠá ááŤá ááᣠáľáá áá áᣠááá°. á áá áá¨á. ááááááľ, ááá á°ááŁáŤáľ á áĽáľááľ áá°á áĽáá°áá˝á áĽááááłáá, áááľá. á á˛áľ áĽá´áľ áááááľ áááľ ááĽáŽá˝á ááá á á áá - á áŽáá áĽá á᪠áĽá´áśá˝. áááłáᣠá°ááŁáŤáśáš á¨áá°áᣠá ááŤáᣠáľáá áá ááĽá¨áľ á áá¸áᣠáá ááŤá¨ááá á°ááŁá áá á¨áááá˘
áĽáá˛áá á¨áá˘á á¨ááἠáĽá¨áľ á¨áłáá áá áá áĽáá áĽááááłááᢠáá á áá¨á¨áťá á°áá áĽáť áááľáŤáľ áĽáľá áá°á áá. á á°ááŁá ᣠá ááłááľ ááááá˝ áááá°á á¨áá á¨á áá áĽá á¨áá°ááľ á°áááá˝ áá ááĽáŤáľ ááťá á á ááᢠááááááľ, áá áá ááłá á áááá¨áľá.
á¨ááááľ á°ááŁáŤáľ
á¨áááááľ á¨áá°áá á°ááŁáŤáľ á¨áá á áłá˝ á°áááá¨ááᢠá á áááááą áá á¸ááá ááá¨áá á á°áťá áá á áĽááášá ááľááá-
- á¨áá°á - á¨áá°á áá - á¨áá°á áá á á°áá.
- áá á°á - áá á°á áá - áá á°á áá á á°áá.
- firstPrice - á¨ááááŞáŤ áá - á¨ááááŞáŤá áá á á°áá.
- á¨áá¨á¨áť áá - á¨áá¨á¨áťá áá - á¨áá¨á¨áťá áá á á°áá.
- á¨ááááŞáŤ áá á - á¨ááááŞáŤ áá á - á¨ááááŞáŤá á¨áááľ áá á á á°ááá˘
- á¨áá¨á¨áťá áá á - á¨áá¨á¨áťá áá á - á¨áá¨á¨áťá á¨áááľ áá á á á°áá ááľáĽá˘
- numTrades - ááĽáŠ i - á¨áááśá˝ áĽááľ á á°ááá˘
- áá á - áľáá áá á - á¨áááľ áá áá˝ áľáá á á°áá.
- pvolume - áľáá áá - á¨áá áľáá á á°ááᣠáá ááŤá áá áŤáľááááá˘
- - áľáá áááŞáŤ áá * áá á - á á ááá á¨ááĽááśá˝ áá á á á°ááá˘
- á ááŤá áá - pvolume%numTrades - á ááŤá áá á á°ááá˘
- á ááŤá áá á - áá á%numTrades - á ááŤá á¨áááľ áá á á á°ááá˘
- vwap - á¨ááá¨áŞáŤ% áá á - á ááŤá áá á á°áá á ááĽááľ áá á áááááá˘
- áľáá - áľáá áá á - á á á ááá áá á¨á°á áŤáá á¨ááĽááśá˝ áá áá˘
áá˛áŤáá á ááľ ááá˝ áŤááá ááĽáĽ áĽáááŤá - áĽááá á á ááśá˝ áááááŞáŤ áá áĽá ááĽáŤááłááą ááŁá á°áá áĽáá´áľ ááľááá áĽáá°ááťáᢠá ááłááľ á¨á áá°á áá ááááľ á ááśá˝ á áĽáŤááłááą áá áĽáá˛áťáŠ áááá á ááŁá¸áᤠááá¸á áŤáá°ááḠááᢠááá˝ á¨áľáá˝ ááááśá˝ áááá áá° 0 áááá á ááŁá¸á. á á°á¨ááŞá á¨á°áŁáᨠá ááŤá¨áĽá á¨áá áá áááśá˝ á á - áááłá, cumVolume áŤááá á°áá áá áłáľ á áá áľ, áĽá áááááŞáŤ áá áá° 0 á°ááá áˇá. áĽááá á áá áááááá˝ á¨áááá áááąá ááἠá áá áá áĽááľáááĽ. ááááľ (á¨áááἠáá á°ááłáłá)
// 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 ОйŃŃŃнон ниМо
ááááťá¸áľ áá° áááá -áááą áá á˛á áĽá áá á¨ááŹáŤááᣠá áá initWith á¨áá¨á¨áťá á¨á°á áŤáá á á¨á´á áá ááá á¨áá ááľáá ááᣠáĽáąá áľáááááá á˛á áĽá áá ááááááľ áááŤáᢠá á˛áľ á¨áľáá˝á áá° á á¨á´á ááá¨áá áá ááá áľ áá˝áá.
á¨áá°áá á°ááŁáá áľáááĽá aggCols áŤáľáááááᢠá Q ááľáĽ áŤá á áŁáŁáá˝ á áááááá áľ á á°á á°á¨á°á (á¨áá áá° ááŤ) áááአáááá ἠá áá áľá˘ áᥠáľááą á¨á¨áá°á áá° áľáá áľáá˝ áááąá áá¨ááἠááᣠááááŤáąá á ááłááľ áááśá˝ á ááľáááš áá áľáááá°á¨áąá˘
áŤááá á°áá áá° á á˛áľ á°áá áá áłáľ á¨ááŤáľáááá¸á á ááśá˝áŁ áááá˝ á˛áŁá á¨á˛á á ááľ á°á¨ááŻáá˘
rollColumns:`sym`cumVolume;
á áá áááśášá áĽáá´áľ áááá áĽááłááŁá¸á á áĄáľá áĽáá¨áááá¸áᢠáśáľáľ ááááśá˝á ááá¨áľ ááťáá-
- Accumulators (áľáá˝, áááŞáŤ, ..) - ááŞáá áĽá´áľ áá° ááłáá áá¨áá á ááĽá.
- á áአááĽáĽ (á¨áá°á, áá á°á, ..) - á á°áá ááľáĽ á¨ááááŞáŤá áĽá´áľ á¨áá˘á áá¨á ááá°áłá, á¨á°ááŠáľ á°áá á°ááŁáŠá á áá áá áá°áá.
- áĽá¨ááľ áááá á°ááŁáá á áá áá áá°ááá˘
ááĽááá áááá˝ á°ááááŽá˝á áĽáááá˝áĄ-
accumulatorCols:`numTrades`volume`pvolume`turnover;
specialCols:`high`low`firstPrice`firstSize;
áľááľ á á°á á°á¨á°á
á¨á°ááá°áá á°áá á¨áĽ á áááľ á°á¨ááá˝ áĽááááááá. ááá¤áłááᾠᣠááĽáŤááłááą ááá áĽá á°áá á ááľ á¨áľá áĽáť áĽáá˛áá á ááááŞáŤ ááŞáá á á¨á´á áĽááááłááᢠááá á¨áĽá á°ááŁáŤáśá˝ áá¨áá áĽá á°áŁáŁáŞ áááá¸á á¨áá á°á¨á᪠áĽááá áá¤áľ áĽáá°ááááἠááľáľá áá°áŁá. áá¨áĽá á áá áá á á¨á´ááá ááááľ áá˝áá-
select high:max price, low:min price ⌠by sym,time.minute from table
áá áá´ ááłáľ á áá - á¨á°á°á áááśá˝ áľáĽáľáĽ á áľááľá á°ááľáá. áĽáá° áĽáľá ááᣠá Qᣠáá¨áĽ á á°áááá á¨á°áá አáá᪠áĽá´áśá˝á áá°áŤáľ á¨ááľá˝áá áľ á°ááŁá áá á°á°ááĽáŻáá˘
?[table;whereClause;byClause;selectClause]
á¨ááááŠá ááááľ á áááá á áááá˝áᤠá áĽá áááł á áááážá˝á ááá¨áĽ áĽá ááá¨áĽ ááá áŤááá áááá áĽáá á¨á á˝ áááśá˝ áááá -áááľ ááá á ááŁá¸á! áľááá á¨ááááľ á°ááŁá áĽáá°áá¨á°áá áááá áá˝áá-
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];
ááá áááľá¨áᣠá¨áá°áá°á á°ááŁá á°á áááŠáᣠáĽáąá á¨Q á áááá˝ áá ááĽá¨ááá áá° á˘áŤá á°ááŁá áá°ááá á¨áá˝á áĽá á á°ááŁáŠ áá¨áĽ ááľáĽ áá° ááááá áĽá´áľ ááááŤáᢠáĽáá˛áá á áľá-áá°áą áĽáá° áľáá ፠(áááľá á á¨áá á¨á°áááš áá᪠áĽá´áśá˝ áŤáá á°ááŁá) á¨ááá¨áĽ á°ááŁá á°áĽá áĽáá°áááá˝ áἠáá á ᣠá ááľ áá᪠áĽá´áľ (á°áá á¨áĄ) áááľááᢠá á á¨á´á áá á áľá-áá°áľá á°ááŁáŤá áŤá°á¨áá, á¨áłáá á á¨á´á áĽááááá.
ááá°áá á°á¨á á¨á°ááá°áá á°áá á¨áĽ áááá áá. ááááŞáŤ á áááŞááá á 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];
âŚ
á Q ááľáĽ ᨠloops ááá á¨áŤááł / á¨ááááľ á°ááŁáŤáľá áá áá á¨á°ááá° áá. ááá áá Q á¨áŹáá°á ááá áľááá áĽá áááá áŚááŹá˝áá˝ á á ááľ áá á ááá ááááśá˝ áá á ááá áá°áá á áľáááá˝á á ááááŞáŤ áááłáááľ áááá ááááśá˝á á á ááľ áá á áá¨ááá áŤá áá ááľá¨á áĽáá˝áááá˘
idx:calcIdx inputTable;
row:aggTable idx;
aggTable[idx;`high]: row[`high] | inputTable`high;
aggTable[idx;`volume]: row[`volume] + inputTable`volume;
âŚ
áá á¨á áá áááľ áĽáá˝ááá, Q áአáĽá áĽá á á áŁá áááá áŚááŹá°á á áá - á á ááá á¨áá°áŁ áŚááŹá°á. á¨áá¨á á áááá˝á ᣠá°ááŁáŽá˝á áĽá áá᪠áĽá´áśá˝á á áá áá ááľáĽáľáĽ á áá á¨ááἠááá á ááľáĽ á¨áĽá´áśá˝á áľáĽáľáĽ áĽáá˛ááአáŤáľá˝áááłáᢠá áĽá áááł, áá áááľáá:
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;âŚ)];
áĽáá° á áááłá°á áá áá° á á¨á´á áááá°áĽ á¨á ááśá˝ áłááá á¨á¨áľáá˝ áááá áŤáľáááááłá áĽá ááľáŞááľ (á¨á ááśá˝ áááá áá° á¨áľáá˝ áááá) á¨áááá ἠá°ááŁáŠá á áá áá ááľá°ááá á ááĽááľá˘ áá ááľáá á á¨á´á ááľ áááŁáľááá á ááľáŠ á¨áŤááłáá á°ááŁá (á ááľáľáŽá á¨áááľááá) á áá áá ááĽáŤááłááą á ááľ á ááľá á á ááá áá°áŁ áá¨áĽáť áĽáá°ááĽáŤááá˘
.[aggTable;;:;]'[(idx;)each aggCols; (row[`high] | inputTable`high;row[`volume] + inputTable`volume;âŚ)];
áĽáá°áá á¨á°ááŁá áľáá ፠áĽáá áááá. áĽáá˛áá á Q ááľáĽ áááá ááá á áĽáá˛á á°ááŁá áááá áĽá á¨ááááŽá˝á áááá áááááľ á¨áĽáŤááłááąá(áŤááł) á°ááŁá á áá áá ááá áŤá áĽáá˝áááá˘
á¨á°á°á áááśá˝ áľáĽáľáĽ áŤáá°áľá°áŤá¨á áááá¸áá ááá¨áááĽ, á¨áá áŤááá á áááá˝ á á°ááááááľ áĽáááĽáŤáá. á¨á¨áľá áĽá á¨á˘áá á°ááááŽá˝á á áá áá áĽáŤááłááąá áááľ áááľááľ ááááŞáŤ á°ááŁáŤáľá áĽááááá¸ááĄ
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");
á ááłááľ áááśá˝ áአáá¸áᣠá¨ááááŞáŤ áĽá´áłá¸á á á°ááŁáŠ ááá á á¨áá áľáᢠá á¨áľá[`numTrades] á ááľ á¨ááááŞáŤá áááá ááááľá áĽáá˝ááá - 0 á¨áŤá áĽá´áą ááááŞáŤ ááᢠQ á¨á°áá¨á á°ááŁá á áá - ?[Boolean list;list1;list2] - á¨áááአ1 ááá 2 áĽá´áľá á¨áááá á á ááááŞáŤá áá᪠áĽá´áľ áá áŁáá áááłáĄ-
// high -> ?[isFirst;inp`high;row[`high]|inp`high]
// @ - ŃОМо ОйОйŃоннОо ĐżŃиŃваиванио Đ´ĐťŃ ŃĐťŃŃĐ°Ń ĐşĐžĐłĐ´Đ° Đ¸Đ˝Đ´ĐľĐşŃ Đ˝ĐľĐłĐťŃйОкиК
@[`aggExpression;specialCols;{[x;y]"?[isFirst;inp`",y,";",x,"]"};string specialCols];
áĽáá áá á¨á°ááŁáŹ áá á ááľ á á ááá áľáŤ á ááťáá (á áĽáá á ááá˝ ááľáĽ áŤá ááááŤ)ᢠá¨á ááá áá (á¨ááááŞáŤáá áá᪠áĽá´áľ) áĽá á°á¨á᪠áá᪠áĽá´áľ ááá áá, á 4 á áá¤áľ ááľáĽ á áááá.
á°ááŁáŤáą ááĽááą á ááľ á áááľ áľááá á¨áŁáľáŞ áľáá˝ áááŤáá˝á áá¨áĽáť áĽáá¨áááĄ-
// volume -> row[`volume]+inp`volume
aggExpression[accumulatorCols]:{"row[`",x,"]+inp`",x } each string accumulatorCols;
áá á Q á°á¨ááá˝ á¨á°ááá° á°ááŁá ááᣠáá á á ááľ áá á¨áĽá´áśá˝á áááá áĽá¨áá°áĽáŠ ááᢠá áá¨á¨áťá áááá á°ááŁá áĽááá ááĄ-
// ":",/: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),")]}";
á áá á áááá˝áŁ á¨áá á¨á°á ááľá á áááá˝ á¨áŤá á°ááŁáá á á°ááááááľ á¨á ááľ ááĽá¨ááá áĽááĽáŤááᢠáá¤áąá áá á áááľááá˘
{[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])]}
á¨áááľ áááá á á°á á°á¨á°á á¨á°ááá á áá ááááŤáąá á Q ááľáĽ á¨áááá á á°á á°á¨á°á á¨áá áá° á፠ááá˘
á áá ááľááśá˝ á áľááá á¨áá áááľ áá á°ááŁáŤáľ á áá, áľáá˝ áá á¨á° áááľ áá¨á áĽáť áŤáľááááá áĽá á áááááą ááá áá.
á¨áá¨á¨áť á°á¨ááá˝
áááá áľáŤ á¨áá°áŠ á¨Agg á°ááŁáŤáľá áááá áĽá áááá á ááĽáᢠáá á ááá á á°áááá˝ ááľáĽ áľáááááá á˝ááá áá¨ááἠáĽá á¨áá°áá á˘áá´ááśá˝á ááľááľ áŤáľááááᢠá ááááŞáŤ ᣠá¨ááá˘áŤ á°ááŁáŠá áĽáááááá-
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
}
áĽáá˛áá á¨á ááá á°áá á¨áááá¨áá á¨áĽá áá á°ááŁá áĽáááááááĄ
roll:{[tm]
if[currTime>tm; :init[]]; // ĐľŃНи поŃоваНиНи Са пОНнОŃŃ, ŃĐž ĐżŃĐžŃŃĐž вŃСОвоП init
rollCache,::offset _ rollColumns#tradeAgg; // ОйнОвиП ĐşŃŃ â вСŃŃŃ roll кОНОнки иС aggTable, ОйŃоСаŃŃ, вŃŃавиŃŃ Đ˛ rollCache
offset::count tradeAgg;
currSyms::`u#`$();
}
á á˛áľ ááááá˝á ááá¨áá á°ááŁá áŤáľááááááĄ-
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)];
}
áĽá á áá¨á¨áťá ᣠá¨á°áťáťáá á°ááŁá (á¨áá á°ááŁá áQ á áááááśá˝ áŁá áá áľá) ᣠáá á ááἠááá¨áá á á°áá áá áá áŤáá˘
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]; // ОйнОвиП Đ°ĐłŃогиŃОваннŃŃ ŃайНиŃŃ. ФŃнкŃĐ¸Ń ? иŃĐľŃ Đ¸Đ˝Đ´ĐľĐşŃ ŃНоПонŃОв ŃпиŃка ŃĐżŃава в ŃпиŃко ŃНова.
};
ááźá áá. á ááŁá áá áá á¨áľ ááá á¨á áááááłá˝á áŽáľ áĽááľ ááľááŽá˝ áĽáť á áá˘
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];
};
áá¨áŤ
á¨á áááááąá á ááťá¸á áĽáááľá˝á˘ áá áá áááľá¨á á á°áᨠáá°áľ ááľáĽ áĽááľáŹá°á (áŽáąá á á áááááľ.q ááá ááľáĽ áĽááľááá á) áĽá á¨ááá˘áŤ á°ááŁáŠá áá°áááĄ
q service.q âp 5566
q)init[]
á áá áŽááśá ááľáĽ ááá°ááá á¨Q áá°áľ áááአáĽá á¨ááááŞáŤá áá áááááĄ
h:hopen `:host:5566
h:hopen 5566 // ĐľŃНи Ойа на ОднОП Ń
ĐžŃŃĐľ
á ááááŞáŤ ᣠá¨ááááśá˝á áááá - 10000 áááĽáŤáŽá˝ áĽááá á áĽá á¨áááá° á°áá á¨áĽ áááá á á°ááŁá áĽáá¨ááᢠá ááá°áá áŽááśá ááľáĽáĄ-
syms:`IBM`AAPL`GOOG,-9997?`8
rnd:{[n;t] ([] sym:n?syms; time:t+asc n#til 25; price:n?10f; size:n?10)}
á á áá á¨áĄ ááľáĽ ááááá ááá áááľá¨á áŚáľáľ áĽááá°á ááááśá˝á áá° áááአá¨ááŹáŤááᢠᨠrnd á°ááŁá n á¨áľáá˝ áŤáá á¨áááá° á°áá á¨áĽ áááĽáŤáᣠá°ááąá ᨠt áĽáľá¨ t +25 ááá°á¨ááľ áááŤáŤáá˘
á áá áá° á áááááą ááἠáááá ááá¨á áá˝áá (á¨ááááŞáŤáášá á áľá á°ááśá˝ áá¨ááŠ)
{h (`upd;`trade;rnd[10000;x])} each `time$00:00 + til 60*10
á á áááááą ááľáĽ á áá á¨áĄ áĽáá°á°ááá áá¨ááἠáá˝áááĄ-
c 25 200
select from tradeAgg where sym=`AAPL
-20#select from tradeAgg where sym=`AAPL
áá¤áľ:
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
á áááááą á á°áá áá áŤá á ááἠáĽáá°ááŤáľáŹáľ áááá á áá á¨áááľ áá¨áŤá áĽááľááᢠá¨ááá ááá°áąá áá° 25 ááá°á¨ááśá˝ áĽááłáááá ááľáłááľá ᢠá áá áá á¨áľ á°á áááá˝ áá¨áá áĽáá˛á áá áá áááľá áľ á áááááą (á á ááŤá) á˘áŤááľ 20 ááá°á¨ááľ á á ááľ ááťáťáŤ ááľáĽ ááá á á áá áľá˘ á ááá°áá áá°áľ ááľáĽ á¨áá¨á°ááá á áľááŁ:
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 áááľ á°áá ááᢠá ááááŞáŤ á1000 á¨áľáá˝ á á¨25 ááá°á¨ááľ áááŽáĽ ááá¨á áľá˝ááá áĄ-
start 1000
á áĽá áááł áá¤áą á á ááľ ááá áá° áááľ ááá°á¨ááśá˝ á áŤáŁá˘ ááᢠáľááá áá˛áŤáá á¨á¨áľáá˝á ááĽá áá° 10.000 áĽá¨ááŤáááĄ
start 10000
áá¤áľ:
min| 00:00:00.004
avg| 9.191458
med| 9f
max| 00:00:00.030
á áľáá, ááá áአááá á¨áá, áá áá 24 áááŽá ááľááŽá˝ á á°áá, 400 áşá á á°á¨ááľ. á¨25 ááá°á¨ááśá˝ á ááᣠáááá á¨ááá°á 5 áá áĽáť ááᣠáá á á°ááá á˛áá¨á áááľááᢠáá° 100.000 áĽáá¨áááĄ-
start 100000
áá¤áľ:
min| 00:00:00.013
avg| 25.11083
med| 24f
max| 00:00:00.108
q)sum times
00:02:00.532
áĽáá°áááá¨áąáľ ᣠá áááááą á ááá áááá áá˝áá ᣠááá áá á áá áá áááá¨áľ á˝ááᢠáĽáá˛á ááááą á¨áá¨á áá á (á 240 áááŽá á¨áľáá˝ á á°áá) áĽá á á áŁá áľáá áá ᣠá áĽáá°áá ááááľ áááłáὠᣠá¨á áááááąá á ááŤáł áááá˝ (ááá á á°ááá á¨ááá አáááá˝) ááľááá á¨á°ááá° áá ᣠáĽáŤááłááąá á¨ááááášá ááá áĽáť áŤáľáŹáłáᢠá ááá áá¤áą á ááááľ á áá¨á áá¨ááť áá áŤá°áŽá¨ áá°á°á¨áá ááá á áľá°áá ááá˘
á¨áĽáŤááłááą ááťáťáŤ áá á áá áá ááá ááĽá°á áŤááá áŤáľáá á¨ááá áĽáŤá áááł áá˝ááᢠááááŤáą á¨áá˝áááá á°ááŁá á áĽáááą á¨C á°ááŁá á˛áá áá á ᨠupdateAgg á¨á áá áááŁá ááᢠá¨á°áá°á á¨ááá áá á (10.000 á áŤáŁá˘) ááᎠᣠupdateAgg áŁáŞáŤá áá áá°ááłá áĽá á¨á፠á¨ááľáá¸á፠áá á áááá áá á áá á¨á°á፠á áá°ááᢠá á áľá á°á¨á Q ááááŤáľ áá á áááááą áĽáá°áá áŤá áá áá˝á áááá¨áľ á¨áťááᢠáá á¨áľáá ááἠáá á˛á°áŤ áľáááááá áľáá° ááá ááá¨áĽ áá áŤá á á áľááá áĽáá°áá áŤááá. ááá ááĽáĽ á áá á°á¨ áľááľáł ááľáĽ áŤáá áľáááá á¨ááἠáá¨ááť áá. ááᥠá á áááą áŤáá°á¨áḠááá á áá áŤááłáá áĽáá° TLB cache miss - á á áááŁáŁáŞá á¨á áľáŤáť áá¸á፠ááľáĽ á¨áá á°á¨ áľááľáł áá˝ á áľáŤáť á ááááŠá áĽááááááᢠá áľáŤáť áááá áŤáá°áłáŤ 30 áá áŤá á áá¨ááá áĽá áá¨áá á¨á°á áłá°á á áááááąá áĽá áá ááŤááá¨á áá˝ááá˘
áá°áá°ááŤ
á áá á˝áá ááľáĽ KDB+ áĽá Q áłáłá¤á áľáá áá¨áá ááá¨áá¸áľ áĽá á ááá á á°áá¨á á ááááľ áááááľ áĽáť áłááá á ááś áááŽáá˝ á¨ááá á á¨áľáá˝/áááŁááľ áłáł á ááľáĽ áĽááłá ááá¨áľ á¨áá˝á á¨áá¨á ááááŁá áŞáŤ á áááááśá˝á áááá á ááš áááá¸áá á áłááťááᢠá ááľ áá á Q áá°áľ . á¨Q áááá á áŤáą á áŹáá°á á°ááĽáŽáᣠá áĽáŽ á á°á°áŤá á¨SQL áᏠá áľá°ááá áĽá á áŁá á¨á°áłáŤ á¨á¤á°-ááťá ááľ á°ááŁáŤáľ áľáĽáľáĽ ááááŤáľ á¨áá¨á áááá áŞáŤ áá á¨á°áŤáŤá áľáá° áááŽá˝á áĽá á á áŁá á áá áĽá áááŁá á°ááŁáŤá áááľá¨á áŤáľá˝ááá˘
á¨áá
á áá áŤáá Q ááľá¨á á¨áá˝áá á áŤá áĽáť áĽáá°áá á áľá°ááŤááᣠááá˝ áአáŁá
áŞáŤáľá á ááľá˘ áááłáᣠáĽá
á á áŁá ááá á¨áá á¨á ááᲠááŽáśáŽá á ááá°áĽ Q áá°áśá˝ ááŤá¨á áŤááá áľáá á á¨áá°áá áĽá á ááśáá˝ á¨ááá አáá°áśá˝á áá° á ááľ á ááłá¨ áá¨áĽ áĽáá˛áŤáá
áą á¨ááŤáľá˝áááľáŁ áá
á á á°ááŤáŠ á¨á áá áááá˝ á ááá á á°ááá á¨ááá አá ááááŽá˝ áá ááááá˘
ááá: hab.com