áµá KDB+ áá°ášáµá£ ášQ áá®áá«ááá ááá áá á¥áá°ááᣠá ááµáᬠááµá¥ áá á¥áá«á¬ á¥á áµááá¶áœ á¥áá³á ááá ᥠáµáœááá ᢠá¥á á ááá¢á«á áá á á áá©á¢ á á ááá¹ ááµá¥ áá¢áá ášááᥠá¥ášáµ ášáá«áµá¬áµ á¥á á ášá°ááá á "á¥ááá°á áá" ááá³ (áááµá ášáá£á© ášááᥠááá á ááµ áááá ááá áááµááµ áá ááášáá) ášáá«áááá á áááááµá á Q áá á¥áá°áá¥á«ááᢠášQ ááá ááœá³ á áá á ááá®áœ á³ááá á á¥ááá³ážáᣠá á°á°á«á áµááµá®áœ á¥á ááᜠááµá¥áµá¥ ááá®áœ á¥áá²á á© ášáá«áµáœáá ášá¬áá°á ááá ááᢠá¥áᰠ᪠á¥á ááá¶á¹ K, J, APL á«á ááááᜠá á áá á áááá á³áááᜠáážá. á¥á áá á¥áá° áá« á£á á áá³áá ááá á áá«á³ ášá®áµ áµááªá ášááá áá®áá«á á á¥ááµ ááµáá®áœ ááµá¥ áá»áá£ážá ááœááᢠá áá áœáá ááµá¥ áá³ášáµ ášááááá áá áá ááá¢

ááá¢á«
KDB+ á á°áá°á ááááµ (á áááááµ á áá) á ášáá°á áá á áá á«á°á®áš ášá ááµ á³á³á€á ááᢠá ááááµ á áááááºá«á á°áááµ - á£áá®áœ, ášá¢áášáµáµáááµ áááµ, ášá¢áá¹á«ááµ á©á£áá«áᜠááµá¥ á¥á á áá áááá. ášQ ááá ášKDB+ ááµá£á ááá á²áá ášáá ááᥠáá á á¥ááµ á¥áá²á°á© á«áµáœááá³áᢠᚠQ ááá®á° ááá á áá á¥á á áá¥áá á²áá áááœááµ áá ááµáá¥áµááµ ááᢠáá ášá°ášááá á á ááááá ááá³ ášá¬áá°á áááá ááášá³áµ á áµážá᪠á¥áá°ááá á¥á ášáášá»á á ááááµ á¥á á¥ááœáá ášáá®áá«áá á á£á áµáá ááá á á ááµ áá« áᜠáá á¥áá²á«á© á«áµáœááá³á ᣠáá á á áášášá» ááášá³áµ ááá á«á°ááááá¢
á áá áœáá ááµá¥ á Q ááµá¥ ášá°áá áá®áá«á á¥áá°áá¥á«áá á¥á áááá©áµ ááœááᢠáá áá áááµášá áµáááááá Q á«áµááááá³á áá 32-á¢áµ áµáªáµ á kx á©á£áá« áµáš-áᜠáá ááášáµ ááœáá - . á¥áá«, ááááµ á«ááµ, á ááœáá Q áá ášááá³ášáªá« áášá á«ááá á¥á á áá áááµ áá ášá°áá«á© áœáááœ.
ášáœáá© ááá
á áš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
