Q語言聪姿,量化分析利器kdb+

前言

由于項目組里的老大工程能力實在太強碴萧,各種技術棧玩得6到飛起,于是我們也跟著開闊了不少視野末购。業(yè)務的一些特性也導致允許我們嘗試一些最新的技術來完成工作內容破喻。剛進來的時候接觸clojure,這種lisp方言盟榴,開始我是抗拒的曹质。具有一定的入門門檻,開始時常城娉。看幾個函數(shù)處理邏輯羽德,要花個半天的時間。再加上逆天的可擴展性極強的宏特性迅办,老實說我是崩潰的玩般。(不過后期熟練后用起來,寫業(yè)務接口真的是好簡潔的說礼饱,,究驴,基于jvm的好處是要啥有啥镊绪,,洒忧,這里按下不表蝴韭。)

倘若要談起編程功底,編碼能力啥的熙侍,語言這種東西實在是浮于表面榄鉴,大佬眼中對于“世界上最好的語言”這種爭論常常是不屑一顧的,因為什么東西都能在他們手里玩出花兒來蛉抓。(為了不顯得過于低端庆尘,當然不能討論語言啊)
但是,最近開始用kdb+,搭配的Q 語言巷送,實在是把三觀毀得天崩地裂驶忌,以前還覺得clojure非常難懂,現(xiàn)在看來笑跛,真是年輕人啊付魔,又傻又胖又稚嫩。飞蹂。几苍。

說下業(yè)務場景:
現(xiàn)在有一張業(yè)務明細表,字段若干(100左右),量級百萬左右陈哑,經(jīng)常需要查看某條ID的明細數(shù)據(jù)妻坝,某個列的透視情況伸眶,多個列的透視情況等等,頁面上需要多個列的組合group顯示等等(其實就是excel中的各種透視操作)惠勒。這種數(shù)據(jù)量級上事實上mysql就能夠解決赚抡,但是因為頁面上可視化拖拽會導致拼出的sql比較復雜,且對字段優(yōu)化不佳的情況下也會導致查詢時間偏長纠屋。這種對于列的頻繁操作的場景涂臣,再加上量級不大,老大拍板說售担,那就玩下kdb+吧~
折騰這東西期間各種顛覆三觀赁遗,,覺得還是有必要撕破偽裝的假面族铆,誠實的回到一個低端程序員岩四,來討論下語言。哥攘。剖煌。

KDB+ 簡介

kdb+ 號稱 最強的內存數(shù)據(jù)庫之一。列式存儲的特性逝淹,使得對于某個列的統(tǒng)計分析操作異常方便耕姊。全球頂尖的投行,高盛栅葡,摩根茉兰,國內的國信等證券公司也開始使用,在延遲性上有著苛刻要求的金融領域欣簇,kdb+可謂一家獨大规脸。當然在優(yōu)秀的性能背后,超高的費用也是必不可少的熊咽,貌似單核價格在3w+美刀以上?...
kdb+:

  1. 單體架構莫鸭,輕松支持 billion以上數(shù)據(jù)
  2. 分布式擴展,無性能損耗
  3. 超低延遲+高并發(fā)支持
  4. 列式存儲+內存數(shù)據(jù)庫
  5. 靈活的Q語言横殴,內置非常多的統(tǒng)計計算方法黔龟。

等等等。滥玷。氏身。
當然官方也提供了32位免費版,單進程支持最大4G內存惑畴。實用中80萬數(shù)據(jù)蛋欣,100+列,在無任何優(yōu)化的情況下如贷,內存占用大概是200+M陷虎。(kdb+還會對數(shù)據(jù)進行壓縮等)所以單進程支持500~1000萬數(shù)據(jù)應該不是大問題到踏。
在個人研究一些歷史股票數(shù)據(jù)時,利用q/kdb+來跑一些簡單的量化策略尚猿,還是非常方便的窝稿。

Q語言 基礎

Q 數(shù)據(jù)類型

Q語言有的數(shù)據(jù)類型,跟其他語言不相上下凿掂,也就是基本的int long,double,string伴榔。但是在表現(xiàn)形式上,兩者有著巨大的生殖隔離...

基本數(shù)據(jù)類型

Q語言 使用 數(shù)字+字符 來表示一個數(shù)據(jù)類型庄萎】耍基礎的有如下幾個數(shù)據(jù)類型(只列出一些基礎的數(shù)據(jù)類型瓷马,詳細可查官方reference)

數(shù)字 字符 占用字節(jié)大小 q數(shù)據(jù)類型 對應java數(shù)據(jù)類型
0 l list
1 b 1 boolean Boolean
4 x 1 byte Byte
5 h 2 short Short
6 i 4 int Integer
7 j 8 long Long
8 e 4 real Float
9 f 8 float Double
10 c 1 char Charater
11 s symbol String
14 d 4 date Date
15 z 8 datetime TimeStamp
16 n 8 timespan TimeSpan
19 t 4 time Time

a:6 /定義 a = 6 (q中數(shù)字默認定義為Long類型)
type a
\表示注釋開始
輸出 -7h 链烈。負號表示這是a 變量是一個atom值憎茂,表示只有一個值,跟 list類型相反忍捡。
查表 集漾,7表示為long類型,h 表示type的輸出類型 是short,查表砸脊,h對應類型為short帆竹。
注釋結束/
b:1.2
type b / 輸出 -9h 。即b是一個atom值脓规,值類型為我們通常用的Double形

想要定義特定類型的數(shù)據(jù),也非常的簡單险领,只需在 值前面加上 對應的 類型字符+"$"侨舆。

int2:`i$2
type int2  /輸出 -6h。

char 與symbol:
q語言中symbol就是我們常理解 string類型绢陌,用 ` 開始挨下。
char類型則用 雙引號 "" 表示。(有點反常理的樣子....)

c:"h"
cs:"hello world"
type c / 輸出 -10h脐湾。 表示這個是單個的值臭笆,值的類型為char
type cs / 輸出 10h,正號表示這是個list,且是個char類型的list秤掌。

假如想要定義一個有多個字符的字符串(而不是char list)愁铺,就得使用 symbol

s:`hello /type s 輸出 -11h。 表示為單個的string闻鉴。
space: `$("hello world")  / string類型中包含空格會解析錯誤茵乱,得使用類型轉換將 char list轉為 symbol....

date 日期時間等
q語言中針對日期時間操作非常簡單方便且強大。(kdb+本意也是為股票證券等時序數(shù)據(jù)而準備的孟岛,畢竟每毫秒鐘就幾千萬上下...)

日期類型一般限制與 1709.01.01 ~ 2290.12.31 任何日期操作的結果值則不會有這個限制...
日期格式在kdb+存儲為 yyyy.mm.dd形式瓶竭,日期值以2000.01.01為相對"坐標"督勺。即任何一個date形式的值,都可以轉為int類型斤贰,其值的結果就是相對于 2000.01.01的相對天數(shù)

dt:2000.01.02
`int $ dt / 輸出 1智哀,表示與2000.01.01相差為1天。在此日期之前荧恍,則值為負數(shù)

time 類型就是一天中的時分秒毫秒瓷叫。time類型在kdb+表示為32位的int,表示相對于今天0點0分0毫秒的相對值块饺。最小單位為毫秒赞辩。因此,int 和time類型也能夠輕松轉換授艰,時間操作上也輕松方便辨嗽。

mtime: `time $ 60000
/以毫秒為最小單位,則mtime表示 第一個分鐘淮腾。mtime = 00:01:00.000
mtime - 30000 / 00:00:30.000 時間可以直接 + - * %
mtime * 2 / 00:02:00.000

當然datetime 形式就是 date+time合并在一起糟需。
q語言中還提供了 分鐘秒等類型

list

q中的list 與python的list概念上并沒有太大的差別,都可以認為是多個元素的集合體谷朝。支持多重嵌套
q語言中生成 list主要由幾種方法

ali: 1 2 3 4 /直接賦值,ali 為 list洲押,list中元素為1,2,3,4
ali:(1 2 3 4)/ 同上
ali: enlist 1 2 3 4 / 同上
/其他的如 # take操作符等等。

dict 字典

dict 字典也是一種常見的數(shù)據(jù)類型圆凰,key杈帐,value格式存儲,支持多重嵌套

dict:`a`b`c!1 2 3 / 使用感嘆號!定義一個字典 ,即{"a":1,"b":2,"c":3}

不太相同的是专钉,q中允許一個字典包含相同的key值挑童,但使用key 查找時,只會命中第一個出現(xiàn)該key的值跃须。

dict:`a`b`a`c!10 20 30 20

[圖片上傳失敗...(image-ddad66-1536989081986)]
查找 key為a 的值時站叼,只會命中第一個key出現(xiàn)的值,更新也只會更新第一個key的值菇民。
刪除則會把所有相同的key都刪掉.

table

table 是q中的"一等"數(shù)據(jù)結構尽楔。
table 可以認為是字典的集合。將字典轉置一下第练,就可以當成table阔馋。

dict:`a`b`c!(1 2 3; 1 2 3;1 2 3)
a| 1 2 3

b| 1 2 3
c| 1 2 3
/dict 的key,a b c 的值都為 1 2 3。
/將dict 的key value 九十度轉換一下娇掏,就變成了table垦缅。dict 的key 變成了table 的header,dict 的value變成了table每行的值驹碍。
table:flip dict
a b c
-----
1 1 1
2 2 2
3 3 3

table 的每一列就是一個key value格式的字典壁涎。因此也認為table是列式的凡恍。

table `a /取 a 列的所有值. 
1 2 3
table[0] /取table的第一行。返回一個字典怔球。
a| 1
b| 1
c| 1

keyed /unkeyed

table 除了可以通過 轉置一下字典獲得外嚼酝,還能使用table的標準定義

unkey:([]name:`a`b`c; val:1 2 3)
name val
--------
a    1  
b    2  
c    3

keyed:([name:`a`b`c] val:1 2 3)
name| val
----| ---
a   | 1  
b   | 2  
c   | 3
/keyed 與unkeyed的展示上區(qū)別是 name 和val 之間多了一個豎條分隔。

table 分為 keyed 和unkeyed竟坛。在定義上的區(qū)別是闽巩,中括號[] 中是否有定義列。
unkeyd table 就是 list,list里面的值為為一個字典担汤。如 (d1 d2 d3 d4)涎跨。d1 到d4 是四個不同的字典,字典的key充當table的列名崭歧,字典的每個值分別對應table同一行的值隅很。
unkey table 可以通過 對列名獲取整個列的值。也可以利用index下標(因為是一個list)率碾,如叔营,table[0],返回一個字典所宰,也即{"d1":d1_val0,"d2",d2_val0,"d3":d3_val0,"d4":d4_val0}

keyed table與unkey table 不同绒尊,keyed table 其實是存成了一個字典,字典的key 為中括號[] 定義的值仔粥。因此也與字典一樣婴谱,允許擁有相同的key值,但只會針對第一個出現(xiàn)的key值做操作躯泰。
因為 keyed table存成了字典谭羔,只能通過[]中的key進行獲取,無法通過列名稱獲取整列的值斟冕。這里的[]中定義的值有點像mysql中的主鍵,每次獲取一行的信息通過主鍵獲取缅阳。(不過這里允許主鍵重復)

unkey `val /操作合法磕蛇,取val 這一列的值。返回一個list

unkey[0] /操作合法十办。取表的第一行數(shù)據(jù),返回一個dict
name| `a
val | 1

unkey `val /操作不合法秀撇。
unkey[0] /操作不合法

keyed `a /操作合法,取表中主鍵為 a的行記錄 返回 val| 1

針對 table的操作向族,更多時候是使用類sql的方式進行操作呵燕,后面會找個時間記錄下這部分

數(shù)據(jù)基本操作

Q 語言基本操作符

operator desc
+ - * % 加 減 乘 除
& | &(最大) |(最小)
= <> 相等/不等 件相,一個一個比較再扭,若操作數(shù)是list氧苍,則每個atom一一比較
~ 比較,與 = 不同,將操作數(shù)看成一個整體比較
:: 別名泛范,可看是是一個引用让虐。

Q 執(zhí)行順序 與操作符優(yōu)先級

Q語言在執(zhí)行順序是從右到左,剛接觸的時候,這一點可能會非常的不習慣罢荡,再加上本身的是 一種vector language,當參數(shù)是標量和參數(shù)是向量時赡突,常常會有不一樣的效果,特別是操作符有各種前綴区赵,中綴惭缰,后綴用法,這也常被人詬病笼才,天書一樣的表達方式漱受。

Q語言不存在操作符優(yōu)先級

重溫下三種表達式:前綴表達式(prefix),中綴表達式(infix),后綴表達式(postfix)
下面簡單列舉兩個常見運算,三種式子 是等價的患整。

中綴表達式 前綴表達式 后綴表達式 desc
A * B + C / D A B * C D / + + * A B / C D A 乘B拜效,C除以D,結果相加
A * (B + C) / D A B C + * D / / * A + B C D B加C各谚,乘A紧憾,除以D

其中 中綴表達式(infix),是最符合人類閱讀習慣的昌渤,操作符之間也是有優(yōu)先級的赴穗。Q語言中為了追求解析速度,拋棄了操作符之間的優(yōu)先級膀息,這種情況下般眉,解釋器不用等到完整得讀到整個語句,便可以執(zhí)行潜支。
例如 A * B + C
由于 Q 語言是從右往左執(zhí)行的甸赃,所以 先讀到 B + C ,馬上就eval求值冗酿,假如要加上操作符優(yōu)先級的話埠对,得整行讀完,
A * B + C裁替,發(fā)現(xiàn) * 優(yōu)先級 比 + 高项玛,先執(zhí)行 A * B,再加上C。
去掉操作符優(yōu)先級的最大好處就是提高了解析速度弱判。金融領域每一個小的速度提升都是非常重要的襟沮。

2 * 3 + 4
/輸出值為 14. 從右到左執(zhí)行。無操作符優(yōu)先級

原子操作符的擴展性

+ - * % mod 等操作時,當操作數(shù)為list時开伏,默認會自動將操作符一個一個作用于list中的每個元素膀跌。

100+ 1 2 3
/ 1 2 3,為list, 加號 為list每一個元素都加上100硅则,返回 101 102 103
l:(1 2 3; 4 5)
100+l
/l  是一個 嵌套的list淹父,list中第一個list為 1 2 3,第二個list為 4 5怎虫。加法嵌套的為每一個list中的元素都加上100.返回結果為(101 102 103;104 105)

比較符 = 與 ~ 的區(qū)別.

= 與 ~ 都可以用來 比較兩個操作數(shù)是否相等暑认。不同的是,當 = 的兩邊操作數(shù)為list時大审,會輸出 一對一的比較結果蘸际。而~則將 兩邊操作數(shù)當成一個整體比較。

= ~
atomic,原子的單個的進行比較徒扶,當操作數(shù)為list時粮彤,輸出list中對應是否相等 non-atomic,將操作數(shù)當成一個整體進行比較
操作數(shù)兩邊可以為整數(shù)姜骡,字符导坟,日期等,兩兩相互兼容圈澈,symbol值則只能與symbol值對比 對操作數(shù)為類型要求
"abc" = "abd" /輸出 110b惫周。 1代表比較結果為相等,0則反之康栈。

0 = 2000.01.01 /輸出 1b 前面提到過递递,日期格式以 2000.01.01 為 坐標。因為 2000.01.01 可以與 0 直接比較

1 = 00:00:00.001 /輸出 1b啥么, 同理登舞,time類型存成語每天0點的offset值,因此也能與整數(shù)進行直接悬荣。

42="*" /輸出1b菠秒, 字符 * 在ascii中存儲值為 42,因此與整數(shù) 42相等

`b = "b" /執(zhí)行異常氯迂,symbol值也就是string 在使用 = 比較時践叠,兩邊值類型必須都是symbol類型。

"abc" ~ "abd" /輸出 0b囚戚, ~ 將兩邊參數(shù) 看成一個整體酵熙,此語句將 兩個char list進行比較轧简。內容不相同驰坊,則返回 0b。

(1 2;3 4)~(1;2 3 4) /輸出 0b,兩個list 結構不同哮独,

(1; 2 3 4)~(1; (2; 3; 4)) /輸出 1b,兩個list 相同

相對于 ~ 操作符的不同拳芙,下面有幾個 atomic的操作符察藐,在list 情況下,同樣是一對一的比較舟扎。
> 大于
< 小于
>= 大于等于
<= 小于等于
| 取最大值
& 取最小值分飞。

"abc" <= "aef" /輸出 100b
12 32 | 3 44 / 輸出 12 44
"accg" & "abed" /輸出 "abcd",對于兩個 char list中睹限,一一比較譬猫,取最小值。

Q語言中簡單的數(shù)據(jù)類型和操作規(guī)則就先介紹到這羡疗,下次介紹下 list染服,dict 與 function的一些用法與特性~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叨恨,隨后出現(xiàn)的幾起案子柳刮,更是在濱河造成了極大的恐慌,老刑警劉巖痒钝,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秉颗,死亡現(xiàn)場離奇詭異,居然都是意外死亡送矩,警方通過查閱死者的電腦和手機蚕甥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來益愈,“玉大人梢灭,你說我怎么就攤上這事≌羝洌” “怎么了敏释?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摸袁。 經(jīng)常有香客問我钥顽,道長,這世上最難降的妖魔是什么靠汁? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任蜂大,我火速辦了婚禮,結果婚禮上蝶怔,老公的妹妹穿的比我還像新娘奶浦。我一直安慰自己,他們只是感情好踢星,可當我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布澳叉。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪成洗。 梳的紋絲不亂的頭發(fā)上五督,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天,我揣著相機與錄音瓶殃,去河邊找鬼充包。 笑死,一個胖子當著我的面吹牛遥椿,可吹牛的內容都是我干的基矮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼冠场,長吁一口氣:“原來是場噩夢啊……” “哼愈捅!你這毒婦竟也來了?” 一聲冷哼從身側響起慈鸠,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蓝谨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后青团,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體譬巫,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年督笆,在試婚紗的時候發(fā)現(xiàn)自己被綠了芦昔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡娃肿,死狀恐怖咕缎,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情料扰,我是刑警寧澤凭豪,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站晒杈,受9級特大地震影響嫂伞,放射性物質發(fā)生泄漏。R本人自食惡果不足惜拯钻,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一帖努、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧粪般,春花似錦拼余、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寡润。三九已至,卻和暖如春舅柜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背躲惰。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工致份, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人础拨。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓氮块,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诡宗。 傳聞我的和親對象是個殘疾皇子滔蝉,可洞房花燭夜當晚...
    茶點故事閱讀 45,446評論 2 359

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)塔沃,斷路器蝠引,智...
    卡卡羅2017閱讀 134,695評論 18 139
  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,440評論 0 17
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    Joyyx閱讀 8,328評論 0 16
  • 十二月的瑞典已經(jīng)進入全年最為黑暗的階段蛀柴,少有的幾個小時白晝也多陰雨螃概,于是家家戶戶窗前都怪氣彩燈,香燭徹夜高燒抵御黑...
    竹影M閱讀 354評論 0 3
  • 楊力豪閱讀 173評論 0 0