์‹ค์‹œ๊ฐ„ ์„œ๋น„์Šค๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด 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 For Mortals ์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ๊ธฐ์‚ฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ ์„ฑ๋ช…

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

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

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

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

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

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

๋ฐ”๋กœ ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ์  ํ•˜๋‚˜๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์ด๋Ÿฌํ•œ ์—ด์„ ์ฒ˜์Œ๊ณผ ์ดํ›„ ๋งค ๋ถ„๋งˆ๋‹ค ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. firstPrice ์œ ํ˜•์˜ ์ผ๋ถ€ ์—ด์€ ๋งค๋ฒˆ null ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•˜๋ฉฐ, ๊ทธ ๊ฐ’์€ ์ •์˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. volume ์œ ํ˜•์˜ ๋‹ค๋ฅธ ์—ด์€ ํ•ญ์ƒ 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 ะพะฑัŠััะฝะตะฝ ะฝะธะถะต

ํŽธ์˜๋ฅผ ์œ„ํ•ด ์‚ฌ์ „์— sym๊ณผ time์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ initWith๋Š” ์ตœ์ข… ์ง‘๊ณ„ ํ…Œ์ด๋ธ”์—์„œ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ง„ ์ค„์ด๋ฉฐ, ์˜ฌ๋ฐ”๋ฅธ sym๊ณผ time์„ ์„ค์ •ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ด๋ธ”์— ์ƒˆ ํ–‰์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง‘๊ณ„ ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•  ๋•Œ aggCols๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Q์˜ ํ‘œํ˜„์‹ ๊ณ„์‚ฐ ์ˆœ์„œ(์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ)์˜ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜์ „ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ์—ด์ด ์ด์ „ ์—ด์— ์ข…์†๋˜๋ฏ€๋กœ, ๊ณ„์‚ฐ์ด high์—์„œ cumVolume์œผ๋กœ ์ง„ํ–‰๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค.

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

rollColumns:`sym`cumVolume;

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

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

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

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

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

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

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

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

?[table;whereClause;byClause;selectClause]

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

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

๋ช…ํ™•์„ฑ์„ ์œ„ํ•ด, parse ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” Q ํ‘œํ˜„์‹์ด ํฌํ•จ๋œ ๋ฌธ์ž์—ด์„ eval ํ•จ์ˆ˜์— ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ select ํ•จ์ˆ˜์— ํ•„์š”ํ•œ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, preprocess ํ•จ์ˆ˜๋Š” select ํ•จ์ˆ˜์˜ ํ”„๋กœ์ ์…˜(์ฆ‰, ์ธ์ˆ˜๊ฐ€ ๋ถ€๋ถ„์ ์œผ๋กœ ์ง€์ •๋œ ํ•จ์ˆ˜)์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ธ์ˆ˜ ํ•˜๋‚˜(ํ…Œ์ด๋ธ”)๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”์— preprocess ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜๋ฉด ์••์ถ•๋œ ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

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

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;โ€ฆ)];

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

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

ํ•จ์ˆ˜ ํˆฌ์˜์„ ๋‹ค์‹œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ Q์—์„œ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๋„ ํ•จ์ˆ˜์ด๋ฉฐ, each(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์—์„œ ๊ฐ’์„ ์„ ํƒํ•˜๋Š” select ํ•จ์ˆ˜(?[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์—์„œ๋Š” ํ‰๊ฐ€ ์ˆœ์„œ๊ฐ€ ์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ์œผ๋กœ ๋ฐ”๋€Œ๋ฏ€๋กœ ์—ด์˜ ํ‰๊ฐ€ ์ˆœ์„œ๋Š” ๋ฐ˜๋Œ€์ž…๋‹ˆ๋‹ค.

์ด์ œ ์ปดํ“จํŒ…์— ํ•„์š”ํ•œ ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๊ธฐ๋Šฅ์ด ๊ฐ–์ถฐ์กŒ๊ณ , ์ธํ”„๋ผ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ์„œ๋น„์Šค๊ฐ€ ์ค€๋น„๋ฉ๋‹ˆ๋‹ค.

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

๋ชจ๋“  ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” preprocess ํ•จ์ˆ˜์™€ 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๋ฐ€๋ฆฌ์ดˆ๊นŒ์ง€ ๋ณ€ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์„œ๋น„์Šค๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ฒ˜์Œ 10์‹œ๊ฐ„์„ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค).

{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๊ฐœ๋กœ ๋Š˜๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

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๋Š” ๋‹ค๋ฅธ ๊ณ ์œ ํ•œ ๊ธฐ๋Šฅ๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐœ๋ณ„ Q ํ”„๋กœ์„ธ์Šค ๊ฐ„์˜ ๊ฒฝ๊ณ„๋ฅผ ์—†์• ๊ณ  ์ˆ˜๋ฐฑ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹จ์ผ ๋„คํŠธ์›Œํฌ๋กœ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•œ IPC ํ”„๋กœํ† ์ฝœ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋„คํŠธ์›Œํฌ๋Š” ์ „ ์„ธ๊ณ„ ์ˆ˜์‹ญ ๊ฐœ์˜ ์„œ๋ฒ„์— ๋ถ„์‚ฐ ๋ฐฐ์น˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

DDoS ๋ณดํ˜ธ, VPS VDS ์„œ๋ฒ„๊ฐ€ ์žˆ๋Š” ์‚ฌ์ดํŠธ๋ฅผ ์œ„ํ•œ ์•ˆ์ •์ ์ธ ํ˜ธ์ŠคํŒ… ๊ตฌ์ž… ๐Ÿ”ฅ DDoS ๊ณต๊ฒฉ ๋ฐฉ์ง€ ๊ธฐ๋Šฅ์ด ํƒ‘์žฌ๋œ ์•ˆ์ •์ ์ธ ์›น์‚ฌ์ดํŠธ ํ˜ธ์ŠคํŒ…, VPS ๋ฐ VDS ์„œ๋ฒ„๋ฅผ ๊ตฌ๋งคํ•˜์„ธ์š” | ProHoster