์‹ค์‹œ๊ฐ„ ์„œ๋น„์Šค ์˜ˆ์‹œ๋ฅผ ํ†ตํ•œ Q, KDB+ ์–ธ์–ด์˜ ํŠน์ง•

์ด์ „ ๊ธ€์—์„œ KDB+ ๊ธฐ๋ฐ˜, Q ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๊ฐ€ ๋ฌด์—‡์ธ์ง€, ์ด๋“ค์˜ ๊ฐ•์ ๊ณผ ์•ฝ์ ์€ ๋ฌด์—‡์ธ์ง€ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์‚ฌ ๊ทธ๋ฆฌ๊ณ  ๊ฐ„๋žตํ•˜๊ฒŒ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ๋“ค์–ด์˜ค๋Š” ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  "์‹ค์‹œ๊ฐ„" ๋ชจ๋“œ์—์„œ ๋งค๋ถ„๋งˆ๋‹ค ๋‹ค์–‘ํ•œ ์ง‘๊ณ„ ํ•จ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ์„œ๋น„์Šค๋ฅผ Q์— ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค(์ฆ‰, ๋ฐ์ดํ„ฐ์˜ ๋‹ค์Œ ๋ถ€๋ถ„ ์ด์ „์— ๋ชจ๋“  ๊ฒƒ์„ ๊ณ„์‚ฐํ•  ์‹œ๊ฐ„์ด ์žˆ์Œ). Q์˜ ์ฃผ์š” ํŠน์ง•์€ ๋‹จ์ผ ๊ฐœ์ฒด๊ฐ€ ์•„๋‹Œ ๋ฐฐ์—ด, ๋ฐฐ์—ด ๋ฐฐ์—ด ๋ฐ ๊ธฐํƒ€ ๋ณต์žกํ•œ ๊ฐœ์ฒด๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒกํ„ฐ ์–ธ์–ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Q์™€ ๊ทธ ์นœ์ฒ™์ธ K, J, APL๊ณผ ๊ฐ™์€ ์–ธ์–ด๋Š” ๊ฐ„๊ฒฐํ•จ์œผ๋กœ ์œ ๋ช…ํ•ฉ๋‹ˆ๋‹ค. Java์™€ ๊ฐ™์€ ์นœ์ˆ™ํ•œ ์–ธ์–ด๋กœ ์—ฌ๋Ÿฌ ํ™”๋ฉด์˜ ์ฝ”๋“œ๋ฅผ ์ฐจ์ง€ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๋ช‡ ์ค„๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ œ๊ฐ€ ์ด ๊ธ€์—์„œ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‹ค์‹œ๊ฐ„ ์„œ๋น„์Šค ์˜ˆ์‹œ๋ฅผ ํ†ตํ•œ Q, KDB+ ์–ธ์–ด์˜ ํŠน์ง•

์†Œ๊ฐœ

KDB+๋Š” ํŠน์ • ๋ฐฉ์‹(์ฃผ๋กœ ์‹œ๊ฐ„ ๊ธฐ์ค€)์œผ๋กœ ์ •๋ ฌ๋œ ๋งค์šฐ ๋งŽ์€ ์–‘์˜ ๋ฐ์ดํ„ฐ์— ์ดˆ์ ์„ ๋งž์ถ˜ ์—ด ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ์€ํ–‰, ํˆฌ์ž ๊ธฐ๊ธˆ, ๋ณดํ—˜ ํšŒ์‚ฌ ๋“ฑ ๊ธˆ์œต ๊ธฐ๊ด€์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. Q ์–ธ์–ด๋Š” ์ด ๋ฐ์ดํ„ฐ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” KDB+์˜ ๋‚ด๋ถ€ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. Q ์ด๋ฐ์˜ฌ๋กœ๊ธฐ๋Š” ๊ฐ„๊ฒฐ์„ฑ๊ณผ ํšจ์œจ์„ฑ์„ ์ถ”๊ตฌํ•˜๋Š” ๋ฐ˜๋ฉด ๋ช…ํ™•์„ฑ์€ ํฌ์ƒ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฒกํ„ฐ ์–ธ์–ด๊ฐ€ ์–ด๋–ค ๊ฒฝ์šฐ์—๋„ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šธ ๊ฒƒ์ด๋ผ๋Š” ์‚ฌ์‹ค์— ์˜ํ•ด ์ •๋‹นํ™”๋˜๋ฉฐ, ๋…น์Œ์˜ ๊ฐ„๊ฒฐํ•จ๊ณผ ํ’๋ถ€ํ•จ์„ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋žจ์˜ ํ›จ์”ฌ ๋” ๋งŽ์€ ๋ถ€๋ถ„์„ ํ•œ ํ™”๋ฉด์—์„œ ๋ณผ ์ˆ˜ ์žˆ์–ด ๊ถ๊ทน์ ์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.

์ด ๊ธฐ์‚ฌ์—์„œ๋Š” Q์—์„œ ์™„์ „ํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌํ˜„ํ•˜๊ณ  ์ด๋ฅผ ์‹œํ—˜ํ•ด ๋ณด๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ์‹ค์ œ Q๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. kx ํšŒ์‚ฌ ์›น์‚ฌ์ดํŠธ์—์„œ ๋ฌด๋ฃŒ 32๋น„ํŠธ ๋ฒ„์ „์„ ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. www.kx.com. ๊ด€์‹ฌ์ด ์žˆ์œผ์‹œ๋ฉด ์ฑ… Q์— ๋Œ€ํ•œ ์ฐธ๊ณ  ์ •๋ณด๋ฅผ ์ฐพ์•„๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Q ํ•„์‚ฌ์ž๋ฅผ ์œ„ํ•œ ์ด ์ฃผ์ œ์— ๊ด€ํ•œ ๋‹ค์–‘ํ•œ ๊ธฐ์‚ฌ.

๋ฌธ์ œ ์„ฑ๋ช…

25๋ฐ€๋ฆฌ์ดˆ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ํ…Œ์ด๋ธ”์„ ๋ณด๋‚ด๋Š” ์†Œ์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. KDB+๋Š” ์ฃผ๋กœ ๊ธˆ์œต์—์„œ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ์ด๊ฒƒ์ด ๊ฑฐ๋ž˜(๊ฑฐ๋ž˜) ํ…Œ์ด๋ธ”์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋‹ค์Œ ์—ด์ด ์žˆ์Šต๋‹ˆ๋‹ค: time(๋ฐ€๋ฆฌ์ดˆ ๋‹จ์œ„์˜ ์‹œ๊ฐ„), Sym(์ฆ๊ถŒ๊ฑฐ๋ž˜์†Œ์˜ ํšŒ์‚ฌ ์ง€์ • - IBM, AAPL,โ€ฆ), ๊ฐ€๊ฒฉ(์ฃผ์‹์„ ๊ตฌ๋งคํ•œ ๊ฐ€๊ฒฉ), ๊ทœ๋ชจ(๊ฑฐ๋ž˜ ๊ทœ๋ชจ). 25๋ฐ€๋ฆฌ์ดˆ ๊ฐ„๊ฒฉ์€ ์ž„์˜์ ์ด๋ฉฐ ๋„ˆ๋ฌด ์ž‘์ง€๋„ ๊ธธ์ง€๋„ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ ์กด์žฌ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ด๋ฏธ ๋ฒ„ํผ๋ง๋œ ์„œ๋น„์Šค๋กœ ์ œ๊ณต๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ๋กœ๋“œ์— ๋”ฐ๋ฅธ ๋™์  ๋ฒ„ํผ๋ง์„ ํฌํ•จํ•˜์—ฌ ์„œ๋น„์Šค ์ธก์—์„œ ๋ฒ„ํผ๋ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ์ง€๋งŒ ๋‹จ์ˆœํ™”๋ฅผ ์œ„ํ•ด ๊ณ ์ •๋œ ๊ฐ„๊ฒฉ์— ์ค‘์ ์„ ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค.

์„œ๋น„์Šค๋Š” ์ตœ๋Œ€ ๊ฐ€๊ฒฉ, ํ‰๊ท  ๊ฐ€๊ฒฉ, ํ•ฉ๊ณ„ ํฌ๊ธฐ ๋“ฑ ์ง‘๊ณ„ ํ•จ์ˆ˜ ์ง‘ํ•ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ Sym ์—ด์—์„œ ๋“ค์–ด์˜ค๋Š” ๊ฐ ๊ธฐํ˜ธ์— ๋Œ€ํ•ด ๋งค๋ถ„ ๊ณ„์‚ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์œ ์šฉํ•œ ์ •๋ณด. ๋‹จ์ˆœํ™”๋ฅผ ์œ„ํ•ด ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ์ฆ๋ถ„์‹์œผ๋กœ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๊ฐ’์„ ์–ป์œผ๋ ค๋ฉด ์ด์ „ ๊ฐ’๊ณผ ๋“ค์–ด์˜ค๋Š” ๊ฐ’์ด๋ผ๋Š” ๋‘ ์ˆซ์ž๋ฅผ ์•„๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด max,average,sum ํ•จ์ˆ˜์—๋Š” ์ด ์†์„ฑ์ด ์žˆ์ง€๋งŒ median ํ•จ์ˆ˜์—๋Š” ์—†์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋“ค์–ด์˜ค๋Š” ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์ด ์‹œ๊ฐ„ ์ˆœ์„œ๋Œ€๋กœ ์ง„ํ–‰๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์šฐ๋ฆฌ์—๊ฒŒ ๋งˆ์ง€๋ง‰ ์ˆœ๊ฐ„์—๋งŒ ์ผํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ผ๋ถ€ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋Šฆ์–ด์ง€๋Š” ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•ด ํ˜„์žฌ ๋ฐ ์ด์ „ ๋ถ„์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœํ™”๋ฅผ ์œ„ํ•ด ์ด ๊ฒฝ์šฐ๋Š” ๊ณ ๋ คํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.

์ง‘๊ณ„ ํ•จ์ˆ˜

ํ•„์š”ํ•œ ์ง‘๊ณ„ ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์„œ๋น„์Šค ๋ถ€ํ•˜๋ฅผ ๋Š˜๋ฆฌ๊ธฐ ์œ„ํ•ด ๊ฐ€๋Šฅํ•œ ํ•œ ๋งŽ์€ ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋†’์Œ โ€“ ์ตœ๋Œ€ ๊ฐ€๊ฒฉ โ€“ ๋ถ„๋‹น ์ตœ๋Œ€ ๊ฐ€๊ฒฉ.
  • ์ตœ์ €๊ฐ€ โ€“ ์ตœ์ € ๊ฐ€๊ฒฉ โ€“ ๋ถ„๋‹น ์ตœ์ € ๊ฐ€๊ฒฉ.
  • firstPrice โ€“ ์ฒซ ๋ฒˆ์งธ ๊ฐ€๊ฒฉ โ€“ ๋ถ„๋‹น ์ฒซ ๋ฒˆ์งธ ๊ฐ€๊ฒฉ์ž…๋‹ˆ๋‹ค.
  • lastPrice โ€“ ๋งˆ์ง€๋ง‰ ๊ฐ€๊ฒฉ โ€“ ๋ถ„๋‹น ๋งˆ์ง€๋ง‰ ๊ฐ€๊ฒฉ.
  • firstSize โ€“ ์ฒซ ๋ฒˆ์งธ ํฌ๊ธฐ โ€“ ๋ถ„๋‹น ์ฒซ ๋ฒˆ์งธ ๊ฑฐ๋ž˜ ํฌ๊ธฐ.
  • lastSize โ€“ ๋งˆ์ง€๋ง‰ ํฌ๊ธฐ โ€” XNUMX๋ถ„ ๋™์•ˆ์˜ ๋งˆ์ง€๋ง‰ ๊ฑฐ๋ž˜ ํฌ๊ธฐ์ž…๋‹ˆ๋‹ค.
  • numTrades โ€“ count i โ€“ ๋ถ„๋‹น ๊ฑฐ๋ž˜ ์ˆ˜.
  • ๊ฑฐ๋ž˜๋Ÿ‰ - ํ•ฉ๊ณ„ ํฌ๊ธฐ - ๋ถ„๋‹น ๊ฑฐ๋ž˜ ํฌ๊ธฐ์˜ ํ•ฉ๊ณ„์ž…๋‹ˆ๋‹ค.
  • pvolume โ€“ ํ•ฉ๊ณ„ ๊ฐ€๊ฒฉ โ€“ avgPrice์— ํ•„์š”ํ•œ ๋ถ„๋‹น ๊ฐ€๊ฒฉ ํ•ฉ๊ณ„์ž…๋‹ˆ๋‹ค.
  • โ€“ ์ด ํšŒ์ „์œจ ๊ฐ€๊ฒฉ*ํฌ๊ธฐ โ€“ ๋ถ„๋‹น ์ด ๊ฑฐ๋ž˜๋Ÿ‰.
  • avgPrice โ€“ pvolume%numTrades โ€“ ๋ถ„๋‹น ํ‰๊ท  ๊ฐ€๊ฒฉ.
  • avgSize โ€“ ๋ณผ๋ฅจ%numTrades โ€“ ๋ถ„๋‹น ํ‰๊ท  ๊ฑฐ๋ž˜ ๊ทœ๋ชจ.
  • vwap โ€“ ๋งค์ถœ์•ก%๋ณผ๋ฅจ โ€“ ๊ฑฐ๋ž˜ ๊ทœ๋ชจ์— ๋”ฐ๋ฅธ ๋ถ„๋‹น ํ‰๊ท  ๊ฐ€๊ฒฉ.
  • cumVolume โ€“ ์ด๋Ÿ‰ โ€“ ์ „์ฒด ์‹œ๊ฐ„ ๋™์•ˆ ๋ˆ„์ ๋œ ํŠธ๋žœ์žญ์…˜ ํฌ๊ธฐ์ž…๋‹ˆ๋‹ค.

๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ํ•œ ๊ฐ€์ง€ ์‚ฌํ•ญ, ์ฆ‰ ์ฒ˜์Œ์œผ๋กœ ๊ทธ๋ฆฌ๊ณ  ์ดํ›„์˜ ๋งค ์ˆœ๊ฐ„๋งˆ๋‹ค ์ด๋Ÿฌํ•œ ์—ด์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ฆ‰์‹œ ๋…ผ์˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. firstPrice ์œ ํ˜•์˜ ์ผ๋ถ€ ์—ด์€ ๋งค๋ฒˆ null๋กœ ์ดˆ๊ธฐํ™”๋˜์–ด์•ผ ํ•˜๋ฉฐ ํ•ด๋‹น ๊ฐ’์€ ์ •์˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ณผ๋ฅจ ์œ ํ˜•์€ ํ•ญ์ƒ 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์˜ ํ‘œํ˜„์‹์ด ํ‰๊ฐ€๋˜๋Š” ์ˆœ์„œ(์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ์œผ๋กœ)๋กœ ์ธํ•ด ๋ชฉ๋ก์ด ๋ฐ˜์ „๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ์—ด์€ ์ด์ „ ์—ด์— ์ข…์†๋˜๋ฏ€๋กœ ๊ณ„์‚ฐ์ด ๋†’์€ ๊ฒƒ์—์„œ cumVolume์œผ๋กœ ์ง„ํ–‰๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค.

์ด์ „ ๋ถ„์—์„œ ์ƒˆ ๋ถ„์œผ๋กœ ๋ณต์‚ฌํ•ด์•ผ ํ•˜๋Š” ์—ด์—๋Š” ํŽธ์˜๋ฅผ ์œ„ํ•ด ๊ธฐํ˜ธ ์—ด์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

rollColumns:`sym`cumVolume;

์ด์ œ ์—…๋ฐ์ดํŠธ ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ์—ด์„ ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์„ธ ๊ฐ€์ง€ ์œ ํ˜•์„ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋ˆ„์‚ฐ๊ธฐ(๋ณผ๋ฅจ, ํšŒ์ „์œจ,..) โ€“ ์ด์ „ ๊ฐ’์— ๋“ค์–ด์˜ค๋Š” ๊ฐ’์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  2. ํŠน์ˆ˜ ์ง€์ (๋†’์Œ, ๋‚ฎ์Œ, ..)์˜ ๊ฒฝ์šฐ ๋ถ„๋‹น ์ฒซ ๋ฒˆ์งธ ๊ฐ’์€ ์ˆ˜์‹  ๋ฐ์ดํ„ฐ์—์„œ ๊ฐ€์ ธ์˜ค๊ณ  ๋‚˜๋จธ์ง€๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค.
  3. ๋‚˜๋จธ์ง€. ํ•ญ์ƒ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

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

๊ณ„์‚ฐ ์ˆœ์„œ

์ง‘๊ณ„๋œ ํ…Œ์ด๋ธ”์€ ๋‘ ๋‹จ๊ณ„์— ๊ฑธ์ณ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค. ํšจ์œจ์„ฑ์„ ์œ„ํ•ด ๋จผ์ € ๊ฐ ๋ฌธ์ž ๋ฐ ๋ถ„์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ํ–‰๋งŒ ์žˆ๋„๋ก ์ˆ˜์‹  ํ…Œ์ด๋ธ”์„ ์ถ•์†Œํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์ด ์ฆ๋ถ„์ ์ด๊ณ  ์—ฐ๊ด€์ ์ด๋ผ๋Š” ์‚ฌ์‹ค์€ ์ด ์ถ”๊ฐ€ ๋‹จ๊ณ„์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Œ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ด๋ธ”์„ ์ถ•์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

select high:max price, low:min price โ€ฆ by sym,time.minute from table

์ด ๋ฐฉ๋ฒ•์—๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณ„์‚ฐ๋œ ์—ด ์ง‘ํ•ฉ์ด ๋ฏธ๋ฆฌ ์ •์˜๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ Q์—์„œ๋Š” select๊ฐ€ ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ ์ธ์ˆ˜๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋กœ๋„ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.

?[table;whereClause;byClause;selectClause]

์ธ์ˆ˜ ํ˜•์‹์— ๋Œ€ํ•ด์„œ๋Š” ์ž์„ธํžˆ ์„ค๋ช…ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ by ๋ฐ select ํ‘œํ˜„์‹๋งŒ ์ค‘์š”ํ•˜๋ฉฐ columns!expressions ํ˜•์‹์˜ ์‚ฌ์ „์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ถ•์†Œ ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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 ํ‘œํ˜„์‹์ด ํฌํ•จ๋œ ๋ฌธ์ž์—ด์„ eval ํ•จ์ˆ˜์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ณ  ํ•จ์ˆ˜ select์— ํ•„์š”ํ•œ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ตฌ๋ฌธ ๋ถ„์„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ „์ฒ˜๋ฆฌ๋Š” select ํ•จ์ˆ˜์˜ ํˆฌ์˜(์ฆ‰, ๋ถ€๋ถ„์ ์œผ๋กœ ์ •์˜๋œ ์ธ์ˆ˜๊ฐ€ ์žˆ๋Š” ํ•จ์ˆ˜)์œผ๋กœ ์ •์˜๋˜๋ฉฐ ์ธ์ˆ˜ ํ•˜๋‚˜(ํ…Œ์ด๋ธ”)๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”์— ์ „์ฒ˜๋ฆฌ๋ฅผ ์ ์šฉํ•˜๋ฉด ์••์ถ•๋œ ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ์ง‘๊ณ„๋œ ํ…Œ์ด๋ธ”์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋จผ์ € ์˜์‚ฌ ์ฝ”๋“œ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

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์—์„œ๋Š” ๋ฃจํ”„ ๋Œ€์‹  ๋งต/๋ฆฌ๋“€์Šค ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ 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;โ€ฆ)];

์•ˆํƒ€๊น๊ฒŒ๋„ ํ…Œ์ด๋ธ”์— ํ• ๋‹นํ•˜๋ ค๋ฉด ์—ด์ด ์•„๋‹Œ ํ–‰ ๋ชฉ๋ก์ด ํ•„์š”ํ•˜๋ฉฐ ๋’ค์ง‘๊ธฐ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ–‰๋ ฌ(์—ด ๋ชฉ๋ก์„ ํ–‰ ๋ชฉ๋ก์œผ๋กœ)์„ ๋ฐ”๊ฟ”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํฐ ํ…Œ์ด๋ธ”์˜ ๊ฒฝ์šฐ ๋น„์šฉ์ด ๋งŽ์ด ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์‹  map ํ•จ์ˆ˜(์•„ํฌ์ŠคํŠธ๋กœํ”ผ์ฒ˜๋Ÿผ ๋ณด์ž„)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ์—ด์— ๊ฐœ๋ณ„์ ์œผ๋กœ ์ผ๋ฐ˜ํ™”๋œ ํ• ๋‹น์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

์šฐ๋ฆฌ๋Š” ๋‹ค์‹œ ํ•จ์ˆ˜ ํˆฌ์˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ Q์—์„œ ๋ชฉ๋ก์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๋„ ํ•จ์ˆ˜์ด๋ฉฐ ๋ชฉ๋ก์˜ ๋ชฉ๋ก์„ ์–ป๊ธฐ ์œ„ํ•ด ๊ฐ๊ฐ(map) ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณ„์‚ฐ๋œ ์—ด ์ง‘ํ•ฉ์ด ๊ณ ์ •๋˜์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์œ„ ์‹์„ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋จผ์ € ์ง‘๊ณ„๋œ ๋ฐ์ดํ„ฐ์™€ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•ด row ๋ฐ inp ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ์—ด์„ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

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");

์ผ๋ถ€ ์—ด์€ ํŠน๋ณ„ํ•˜๋ฏ€๋กœ ํ•ด๋‹น ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ๊ฐ’์€ ํ•จ์ˆ˜๋กœ ๊ณ„์‚ฐ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. row[`numTrades] ์—ด์„ ํ†ตํ•ด ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์ž„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 0์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ ๊ฐ’์ด ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค. Q์—๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜์˜ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋ชฉ๋ก 1 ๋˜๋Š” 2์—์„œ ๊ฐ’์„ ์„ ํƒํ•˜๋Š” ์„ ํƒ ๊ธฐ๋Šฅ์ธ ?[Boolean list;list1;list2]๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

// high -> ?[isFirst;inp`high;row[`high]|inp`high]
// @ - ั‚ะพะถะต ะพะฑะพะฑั‰ะตะฝะฝะพะต ะฟั€ะธัะฒะฐะธะฒะฐะฝะธะต ะดะปั ัะปัƒั‡ะฐั ะบะพะณะดะฐ ะธะฝะดะตะบั ะฝะตะณะปัƒะฑะพะบะธะน
@[`aggExpression;specialCols;{[x;y]"?[isFirst;inp`",y,";",x,"]"};string specialCols];

์—ฌ๊ธฐ์„œ๋Š” ๋‚ด ํ•จ์ˆ˜(์ค‘๊ด„ํ˜ธ ์•ˆ์˜ ํ‘œํ˜„์‹)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ฐ˜ํ™”๋œ ํ• ๋‹น์„ ํ˜ธ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ฐ’(์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜)๊ณผ ์ถ”๊ฐ€ ์ธ์ˆ˜๋ฅผ ์ˆ˜์‹ ํ•˜๋ฉฐ, ์ด๋ฅผ ๋„ค ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋Šฅ์ด ๋™์ผํ•˜๋ฏ€๋กœ ๋ฐฐํ„ฐ๋ฆฌ ์Šคํ”ผ์ปค๋ฅผ ๋ณ„๋„๋กœ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

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

์ด๋Š” Q ๊ธฐ์ค€์œผ๋กœ๋Š” ์ผ๋ฐ˜์ ์ธ ํ• ๋‹น์ธ๋ฐ, ๊ฐ’ ๋ชฉ๋ก์„ ํ•œ๋ฒˆ์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ main ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

// ":",/: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์—์„œ๋Š” ํ‰๊ฐ€ ์ˆœ์„œ๊ฐ€ ์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ์ด๋ฏ€๋กœ ์—ด ํ‰๊ฐ€ ์ˆœ์„œ๊ฐ€ ๋ฐ˜์ „๋ฉ๋‹ˆ๋‹ค.

์ด์ œ ๊ณ„์‚ฐ์— ํ•„์š”ํ•œ ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๊ธฐ๋Šฅ์ด ์žˆ์œผ๋ฏ€๋กœ ์•ฝ๊ฐ„์˜ ์ธํ”„๋ผ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ์„œ๋น„์Šค๊ฐ€ ์ค€๋น„๋ฉ๋‹ˆ๋‹ค.

์ตœ์ข… ๋‹จ๊ณ„

๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ „์ฒ˜๋ฆฌ ๋ฐ updateAgg ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ถ„ ๋‹จ์œ„๋กœ ์˜ฌ๋ฐ”๋ฅธ ์ „ํ™˜์„ ๋ณด์žฅํ•˜๊ณ  ์ง‘๊ณ„๋ฅผ ์œ„ํ•œ ์ธ๋ฑ์Šค๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋จผ์ € 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
 }

๋˜ํ•œ ํ˜„์žฌ ๋ถ„์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋กค ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

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)];
 }

๋งˆ์ง€๋ง‰์œผ๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ถœํ•˜๋Š” upd ํ•จ์ˆ˜(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];
 };

ํ…Œ์ŠคํŠธ

์„œ๋น„์Šค ์„ฑ๋Šฅ์„ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ๋ณ„๋„์˜ ํ”„๋กœ์„ธ์Šค์—์„œ ์‹คํ–‰ํ•˜๊ณ (์ฝ”๋“œ๋ฅผ service.q ํŒŒ์ผ์— ๋„ฃ์Œ) init ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

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๋ฐ€๋ฆฌ์ดˆ๊นŒ์ง€ ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์„œ๋น„์Šค์— ๋ฐ์ดํ„ฐ ์ „์†ก์„ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ฒ˜์Œ XNUMX์‹œ๊ฐ„ ์ถ”๊ฐ€).

{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๋ฐ€๋ฆฌ์ดˆ๋งˆ๋‹ค XNUMX๊ฐœ ํ–‰์— ๋Œ€ํ•ด ๋จผ์ € ์‹คํ–‰ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

start 1000

์ œ ๊ฒฝ์šฐ ๊ฒฐ๊ณผ๋Š” ์—…๋ฐ์ดํŠธ๋‹น ์•ฝ 10.000๋ฐ€๋ฆฌ์ดˆ ์ •๋„์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฆ‰์‹œ ํ–‰ ์ˆ˜๋ฅผ XNUMX๊ฐœ๋กœ ๋Š˜๋ฆฝ๋‹ˆ๋‹ค.

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์–ต XNUMX์ฒœ๋งŒ ํ–‰)์€ ๋งค์šฐ ํฌ๋ฉฐ, ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์„œ๋น„์Šค์˜ ์—ฌ๋Ÿฌ ํด๋ก (์‹ฌ์ง€์–ด ์ˆ˜์‹ญ ๊ฐœ์˜ ํด๋ก )์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋ฉฐ ๊ฐ ์„œ๋น„์Šค๋Š” ๋ฌธ์ž์˜ ์ผ๋ถ€๋งŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ฃผ๋กœ ๋ฐ์ดํ„ฐ ์ €์žฅ์— ์ดˆ์ ์„ ๋งž์ถ˜ ํ•ด์„ ์–ธ์–ด์˜ ๊ฒฐ๊ณผ๋Š” ์ธ์ƒ์ ์ž…๋‹ˆ๋‹ค.

๊ฐ ์—…๋ฐ์ดํŠธ์˜ ํฌ๊ธฐ์— ๋”ฐ๋ผ ์‹œ๊ฐ„์ด ๋น„์„ ํ˜•์ ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•œ ์˜๋ฌธ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ์ถ•์†Œ ํ•จ์ˆ˜๊ฐ€ ์‹ค์ œ๋กœ๋Š” updateAgg๋ณด๋‹ค ํ›จ์”ฌ ํšจ์œจ์ ์ธ C ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํŠน์ • ์—…๋ฐ์ดํŠธ ํฌ๊ธฐ(์•ฝ 10.000)๋ถ€ํ„ฐ updateAgg๊ฐ€ ์ตœ๋Œ€์น˜์— ๋„๋‹ฌํ•˜๋ฉด ์‹คํ–‰ ์‹œ๊ฐ„์€ ์—…๋ฐ์ดํŠธ ํฌ๊ธฐ์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์„œ๋น„์Šค๊ฐ€ ์ด๋Ÿฌํ•œ ์–‘์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์˜ˆ๋น„ ๋‹จ๊ณ„ Q ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋น…๋ฐ์ดํ„ฐ ์ž‘์—… ์‹œ ์˜ฌ๋ฐ”๋ฅธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ์š”์ ์€ ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ์—ด ํ˜•์‹์œผ๋กœ ์ €์žฅ๋˜์ง€ ์•Š๊ฑฐ๋‚˜ ์‹œ๊ฐ„๋ณ„๋กœ ์ •๋ ฌ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ TLB ์บ์‹œ ๋ฏธ์Šค(ํ”„๋กœ์„ธ์„œ ์ฃผ์†Œ ์บ์‹œ์— ๋ฉ”๋ชจ๋ฆฌ ํŽ˜์ด์ง€ ์ฃผ์†Œ๊ฐ€ ์—†์Œ)์™€ ๊ฐ™์€ ํ˜„์ƒ์— ์ต์ˆ™ํ•ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฃผ์†Œ ๊ฒ€์ƒ‰์— ์‹คํŒจํ•  ๊ฒฝ์šฐ ์•ฝ 30๋ฐฐ ์ •๋„์˜ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜๋ฉฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ํฉ์–ด์ง€๋ฉด ์„œ๋น„์Šค ์†๋„๊ฐ€ ๋ช‡ ๋ฐฐ๋กœ ๋Š๋ ค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” KDB+์™€ Q ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  select๋ฅผ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ˆ˜์–ต ํ–‰/๊ธฐ๊ฐ€๋ฐ”์ดํŠธ ๊ทœ๋ชจ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ์—๋„ ์ ํ•ฉํ•˜๋‹ค๋Š” ์ ์„ ๋ณด์—ฌ์ฃผ์—ˆ๋‹ค. ํ•˜๋‚˜์˜ ๋‹จ์ผ Q ํ”„๋กœ์„ธ์Šค. Q ์–ธ์–ด ์ž์ฒด๋Š” ๋ฒกํ„ฐ ํŠน์„ฑ, ๋‚ด์žฅ๋œ SQL ์–ธ์–ด ํ•ด์„๊ธฐ ๋ฐ ๋งค์šฐ ์„ฑ๊ณต์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ธฐ๋Šฅ ์„ธํŠธ๋กœ ์ธํ•ด ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์™€ ๊ด€๋ จ๋œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋งค์šฐ ๊ฐ„๊ฒฐํ•˜๊ณ  ํšจ์œจ์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด์šฉ์€ Q๊ฐ€ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์˜ ์ผ๋ถ€์ผ ๋ฟ์ด๋ฉฐ ๋‹ค๋ฅธ ๊ณ ์œ ํ•œ ๊ธฐ๋Šฅ๋„ ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐœ๋ณ„ Q ํ”„๋กœ์„ธ์Šค ์‚ฌ์ด์˜ ๊ฒฝ๊ณ„๋ฅผ ์ง€์šฐ๊ณ  ์ˆ˜๋ฐฑ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹จ์ผ ๋„คํŠธ์›Œํฌ๋กœ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•œ IPC ํ”„๋กœํ† ์ฝœ์€ ์ „ ์„ธ๊ณ„ ์—ฌ๋Ÿฌ ์ง€์—ญ์— ์žˆ๋Š” ์ˆ˜์‹ญ ๊ฐœ์˜ ์„œ๋ฒ„์— ์œ„์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€