Compare commits
1526 Commits
v0.5.0
...
backtest_i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ac9dd7221 | ||
|
|
7efec6bbc4 | ||
|
|
3fa48d7017 | ||
|
|
4f2d6b0d84 | ||
|
|
3943b7001f | ||
|
|
2593185721 | ||
|
|
7a884fa9f2 | ||
|
|
d929d4bb21 | ||
|
|
e54b019ee2 | ||
|
|
426b98a3bc | ||
|
|
82f8ff9066 | ||
|
|
31e9d529de | ||
|
|
5fa56703ae | ||
|
|
c6bb11fe56 | ||
|
|
3d7ebd1fe0 | ||
|
|
7313b4dad0 | ||
|
|
b70caff522 | ||
|
|
96b422a906 | ||
|
|
64130d9407 | ||
|
|
a58bc03a8e | ||
|
|
f537222ce3 | ||
|
|
c427c64845 | ||
|
|
22ff8fdc44 | ||
|
|
4efb0a75c1 | ||
|
|
052aad7982 | ||
|
|
12f05c7182 | ||
|
|
ac08468330 | ||
|
|
df9745f134 | ||
|
|
2e49a5f7c0 | ||
|
|
3ab5721448 | ||
|
|
6a94b45503 | ||
|
|
7c31012b50 | ||
|
|
334b92ace7 | ||
|
|
9a175d7507 | ||
|
|
17ea44e0cf | ||
|
|
c0ce712be9 | ||
|
|
8e81a017c1 | ||
|
|
706727988c | ||
|
|
e99224e5c2 | ||
|
|
8c8d1336de | ||
|
|
d01de411a8 | ||
|
|
28fe4d4bb4 | ||
|
|
873129aa9b | ||
|
|
3a152f9b8b | ||
|
|
2b75b41a08 | ||
|
|
00d17f0a52 | ||
|
|
6bec33e854 | ||
|
|
48a860c8b7 | ||
|
|
4099050935 | ||
|
|
3760a18a8d | ||
|
|
8cf6ed3564 | ||
|
|
92055d64ec | ||
|
|
b9809a4c33 | ||
|
|
fc243fd29b | ||
|
|
b6a8bd5b80 | ||
|
|
6ee0fe366c | ||
|
|
55b6ff123e | ||
|
|
45ea4bae4e | ||
|
|
17d472cf01 | ||
|
|
c500a01226 | ||
|
|
114c38b4c3 | ||
|
|
414c3082c0 | ||
|
|
3fc2f8c93c | ||
|
|
66ff3e5bf6 | ||
|
|
8ff68a182e | ||
|
|
a105ef1d76 | ||
|
|
d02965ea70 | ||
|
|
b8d1e08010 | ||
|
|
163e3c6266 | ||
|
|
6203e4c09e | ||
|
|
51709c20d8 | ||
|
|
28c99c77be | ||
|
|
bb5cdfe050 | ||
|
|
fb21c591bb | ||
|
|
5279e71423 | ||
|
|
f35254c288 | ||
|
|
5e82c18cb2 | ||
|
|
2759e8c28d | ||
|
|
2461575d30 | ||
|
|
867667531d | ||
|
|
0fc52333b7 | ||
|
|
ab9b6dc47a | ||
|
|
4c5a4d5cd7 | ||
|
|
e84cc23589 | ||
|
|
707399a245 | ||
|
|
6e88ccca88 | ||
|
|
ee5f3de800 | ||
|
|
3605cd7b96 | ||
|
|
d1cbf4c3d9 | ||
|
|
6011a21308 | ||
|
|
76a05f37a9 | ||
|
|
c99494eb76 | ||
|
|
e8126b0c39 | ||
|
|
88d2f9263e | ||
|
|
f71b0c1189 | ||
|
|
919380597b | ||
|
|
4da3f3b104 | ||
|
|
9446116642 | ||
|
|
5003e49197 | ||
|
|
5f0ee6ce68 | ||
|
|
9a74471ab6 | ||
|
|
d39c8de800 | ||
|
|
43a8f502ed | ||
|
|
7ee4a207bc | ||
|
|
25f54ddaeb | ||
|
|
d9ad8ff791 | ||
|
|
13a9b7cea0 | ||
|
|
9c326fd398 | ||
|
|
f111e34bd2 | ||
|
|
be0d9e6a22 | ||
|
|
e134c358fd | ||
|
|
16b954866f | ||
|
|
f7d7f1a223 | ||
|
|
8eb7a1fddc | ||
|
|
222c2fd21a | ||
|
|
f67b99a30e | ||
|
|
2da6a8c770 | ||
|
|
8f4d320832 | ||
|
|
e2739ac72c | ||
|
|
19d15ddc38 | ||
|
|
12af8f304b | ||
|
|
25b771ddf1 | ||
|
|
1158472489 | ||
|
|
84d2cb3226 | ||
|
|
509bfcb02e | ||
|
|
309dfa36cc | ||
|
|
6608a40965 | ||
|
|
735153a50d | ||
|
|
3e75cead93 | ||
|
|
6697f209d4 | ||
|
|
05b9fb5a47 | ||
|
|
7c858803f0 | ||
|
|
74e1ee6921 | ||
|
|
e3b57b1901 | ||
|
|
82a5223166 | ||
|
|
398131cff7 | ||
|
|
8e87950292 | ||
|
|
e71e2f941c | ||
|
|
0483406c12 | ||
|
|
3ff1d91d61 | ||
|
|
f5db0e1b05 | ||
|
|
0f2d85d098 | ||
|
|
5c2ddac7f0 | ||
|
|
da1f4db968 | ||
|
|
a7c41b6969 | ||
|
|
5b7b48e376 | ||
|
|
4f9f978909 | ||
|
|
319a2f38cc | ||
|
|
a2c38c979e | ||
|
|
07655f2d5b | ||
|
|
9303415666 | ||
|
|
73f5cc0a2b | ||
|
|
05d28469ad | ||
|
|
ab3c4a2c05 | ||
|
|
c1992b1bb1 | ||
|
|
e817413769 | ||
|
|
0b607da690 | ||
|
|
0d41ca26ab | ||
|
|
ba1c575aa9 | ||
|
|
66971d5f0d | ||
|
|
fcca242807 | ||
|
|
4924717276 | ||
|
|
c202a4b1e6 | ||
|
|
dc6859bdd9 | ||
|
|
a6f9dde006 | ||
|
|
bdebe12cf2 | ||
|
|
1d22ee56d3 | ||
|
|
e88c45e13c | ||
|
|
103d3034bf | ||
|
|
4ffb05ae59 | ||
|
|
6dcbf51298 | ||
|
|
9d732e9646 | ||
|
|
a8ea66b83e | ||
|
|
9e6f4ec578 | ||
|
|
301e0477ec | ||
|
|
0ec6b87d39 | ||
|
|
d445f28e5f | ||
|
|
bbba9600a1 | ||
|
|
2c8a3ded08 | ||
|
|
3810a4cd33 | ||
|
|
48af7126b6 | ||
|
|
025b1dcff9 | ||
|
|
29e66b2dea | ||
|
|
698e59ac72 | ||
|
|
e006ef40ad | ||
|
|
59d4bc9394 | ||
|
|
b07e0bffb1 | ||
|
|
161343018f | ||
|
|
bee031af68 | ||
|
|
35840606a8 | ||
|
|
2df9b6e076 | ||
|
|
0c3eaf3f16 | ||
|
|
2eee064eb8 | ||
|
|
096ef5a62b | ||
|
|
dd0eebed53 | ||
|
|
7b20abeda1 | ||
|
|
10c182e2b0 | ||
|
|
83d4387e9f | ||
|
|
5519420efd | ||
|
|
eb3c5b3088 | ||
|
|
f03df874bf | ||
|
|
8fa22bd2e1 | ||
|
|
d1c8d885aa | ||
|
|
bf7732e284 | ||
|
|
9bf8c999e6 | ||
|
|
4e862f7d1f | ||
|
|
3f5334ab39 | ||
|
|
62583ea6ec | ||
|
|
92f2891664 | ||
|
|
c97a96363d | ||
|
|
25ff62f542 | ||
|
|
2023f714c9 | ||
|
|
f8a2b0533b | ||
|
|
3183a232df | ||
|
|
8b715268bd | ||
|
|
28cb827a23 | ||
|
|
b723f14619 | ||
|
|
47535ba530 | ||
|
|
4a62e02fca | ||
|
|
572181ef5d | ||
|
|
ed12c7fca3 | ||
|
|
5f50614dbc | ||
|
|
7738f39546 | ||
|
|
d70e5a4f88 | ||
|
|
2b8d4dc3c2 | ||
|
|
6ad52e8cf5 | ||
|
|
567841e1c6 | ||
|
|
110141ddac | ||
|
|
65b44349cd | ||
|
|
3b8087677c | ||
|
|
5241b2f918 | ||
|
|
344f4f69d2 | ||
|
|
f295497e2c | ||
|
|
aae4b02ab8 | ||
|
|
d907817ce9 | ||
|
|
4ec41ea0e7 | ||
|
|
870f834577 | ||
|
|
94b456714d | ||
|
|
cfcd9fb1f8 | ||
|
|
457dcaa466 | ||
|
|
3c740fc2de | ||
|
|
571d27cba7 | ||
|
|
831773a0d6 | ||
|
|
6d91f28474 | ||
|
|
be8653c505 | ||
|
|
7b9e338a0d | ||
|
|
0646e53d24 | ||
|
|
ca14e36f7a | ||
|
|
9b38e62f21 | ||
|
|
4c4b30ebec | ||
|
|
a8974ce535 | ||
|
|
79026e5390 | ||
|
|
4610e16ac2 | ||
|
|
b504cc6ac8 | ||
|
|
c29e5b2621 | ||
|
|
d5059e609f | ||
|
|
215f7e0d22 | ||
|
|
45bde7527e | ||
|
|
155019ba35 | ||
|
|
ece7b662e2 | ||
|
|
80f5426693 | ||
|
|
cbd52b7905 | ||
|
|
17d8b8a7cc | ||
|
|
eada8640b9 | ||
|
|
32ae6e4259 | ||
|
|
5c5379e09d | ||
|
|
e8f5a1e491 | ||
|
|
0c946cffd6 | ||
|
|
1fb50d521b | ||
|
|
8c743a46c7 | ||
|
|
93796bdcef | ||
|
|
267ee3555d | ||
|
|
8b28575dad | ||
|
|
4488c3b625 | ||
|
|
bd6080b8f5 | ||
|
|
cbe7c5285a | ||
|
|
85c75a6639 | ||
|
|
d1b8ed9613 | ||
|
|
d6984a3f2d | ||
|
|
e42aa67f52 | ||
|
|
4e41e9c8f2 | ||
|
|
6fd50a5bfa | ||
|
|
dd8231edeb | ||
|
|
03d6facbd2 | ||
|
|
354f7e68c2 | ||
|
|
e214557e3a | ||
|
|
bdac9f4dda | ||
|
|
cb72857710 | ||
|
|
82645233e7 | ||
|
|
dafef0ac08 | ||
|
|
1cb43ea69b | ||
|
|
7ca9cf79f7 | ||
|
|
e063d3536c | ||
|
|
35f090a6e4 | ||
|
|
ace7484304 | ||
|
|
7048bef7c6 | ||
|
|
50c0e99f98 | ||
|
|
9b74a19b14 | ||
|
|
ecf2f24d59 | ||
|
|
ef7fe8aa75 | ||
|
|
2d4f0e80f9 | ||
|
|
946c9392a1 | ||
|
|
8dd5788bac | ||
|
|
8b85b9eee7 | ||
|
|
2b4a493617 | ||
|
|
a401f1eafe | ||
|
|
24d5a3127b | ||
|
|
bbf5d1bbbb | ||
|
|
b242d6e1e1 | ||
|
|
8d1b1979d9 | ||
|
|
9985befe69 | ||
|
|
b523b27d5a | ||
|
|
0b83fb3564 | ||
|
|
d96f7a67c6 | ||
|
|
a7862387a2 | ||
|
|
c4c438249c | ||
|
|
90bbf2b7c6 | ||
|
|
e1b6f310c9 | ||
|
|
20d566ceee | ||
|
|
8e8bba1a96 | ||
|
|
27f0db669f | ||
|
|
72c9593aa7 | ||
|
|
c907d8deb4 | ||
|
|
e78cdd4a08 | ||
|
|
9b91758aed | ||
|
|
b41267fa59 | ||
|
|
b68294da93 | ||
|
|
4f384d37ce | ||
|
|
284d96761b | ||
|
|
8709dde65b | ||
|
|
d66733c358 | ||
|
|
9cf574b697 | ||
|
|
107e40f3ee | ||
|
|
b6564cd760 | ||
|
|
1517a9eb91 | ||
|
|
4837ba8db3 | ||
|
|
2ab4a9adb3 | ||
|
|
8d0b673341 | ||
|
|
8ebdb1e873 | ||
|
|
39340fbf06 | ||
|
|
0e277723a3 | ||
|
|
1418417034 | ||
|
|
b261f7b501 | ||
|
|
bab50e8837 | ||
|
|
0eee4a0f2e | ||
|
|
21eb71d4a9 | ||
|
|
583fbbef3c | ||
|
|
d226ac8c32 | ||
|
|
ab97e82484 | ||
|
|
7525854bed | ||
|
|
56cf43da44 | ||
|
|
46714adf4c | ||
|
|
4ac6e6e246 | ||
|
|
99fb49650a | ||
|
|
985fd0816c | ||
|
|
d0f54343c7 | ||
|
|
a3679e6758 | ||
|
|
b6c31540e8 | ||
|
|
a4f6e04199 | ||
|
|
0aee46ee79 | ||
|
|
9c8d423a86 | ||
|
|
b4efbd53b2 | ||
|
|
5a50d7c952 | ||
|
|
0fe8b281ba | ||
|
|
5331ab93f8 | ||
|
|
64582e9d46 | ||
|
|
9e0e2ff736 | ||
|
|
9e45528165 | ||
|
|
f78e90171b | ||
|
|
973c4137e4 | ||
|
|
730f6258d6 | ||
|
|
5850490b24 | ||
|
|
d4b36bdab4 | ||
|
|
40416d8c30 | ||
|
|
567e42840c | ||
|
|
65ddca133f | ||
|
|
d199256d34 | ||
|
|
073fe4668e | ||
|
|
89d53853e5 | ||
|
|
bb6c1572ca | ||
|
|
4c4e77b11f | ||
|
|
38c7b7303a | ||
|
|
02d0eedd68 | ||
|
|
5a3dde93a8 | ||
|
|
177f6a59d2 | ||
|
|
492a62a569 | ||
|
|
9a44fbf9c1 | ||
|
|
03eb0882de | ||
|
|
a845a2271b | ||
|
|
ba021f6007 | ||
|
|
7d9544fb91 | ||
|
|
12b7be333d | ||
|
|
ed54f1213c | ||
|
|
76be5d50e5 | ||
|
|
554b9c7826 | ||
|
|
6f150f3fd6 | ||
|
|
a06fa2bc44 | ||
|
|
46d253b457 | ||
|
|
1581ef12ac | ||
|
|
c43805eff6 | ||
|
|
8aee853a11 | ||
|
|
2a0d991d9b | ||
|
|
1320e53f81 | ||
|
|
bf02fc23f8 | ||
|
|
f5ac6230e1 | ||
|
|
8222795ac4 | ||
|
|
616a742db7 | ||
|
|
811d2c975e | ||
|
|
2314405613 | ||
|
|
cc8339acd9 | ||
|
|
d515efb46e | ||
|
|
6272ce108f | ||
|
|
64896745d0 | ||
|
|
3200bb88c8 | ||
|
|
b2fe2385d5 | ||
|
|
4d48c96d30 | ||
|
|
83535bff6a | ||
|
|
a8e96e59f8 | ||
|
|
449e3f40c8 | ||
|
|
04fff8ca36 | ||
|
|
a183d8a631 | ||
|
|
8d05cd2daf | ||
|
|
231bdf8608 | ||
|
|
a46d99a2be | ||
|
|
bf16e1ab47 | ||
|
|
ab6b88ce14 | ||
|
|
94ab4bbf3f | ||
|
|
cdc59a78f0 | ||
|
|
d3dac068df | ||
|
|
60e082e446 | ||
|
|
4ff0c4fb0f | ||
|
|
b3eece155f | ||
|
|
02e34eb9e9 | ||
|
|
bf3b757294 | ||
|
|
96e393b599 | ||
|
|
029b63c9dd | ||
|
|
c26bee126b | ||
|
|
3033fdf4b7 | ||
|
|
ef11a9d95c | ||
|
|
98eacf8f88 | ||
|
|
43cad1ec27 | ||
|
|
e7aa7ffcdd | ||
|
|
ed3c9d9212 | ||
|
|
2f3fbae73b | ||
|
|
e409bee9b9 | ||
|
|
7ceec37848 | ||
|
|
6a636546c4 | ||
|
|
4085b447aa | ||
|
|
c12c861b7a | ||
|
|
2ad61f12b3 | ||
|
|
0a4e241608 | ||
|
|
ca0363ded8 | ||
|
|
5a382d7e99 | ||
|
|
9b431bc503 | ||
|
|
cbbf6cd822 | ||
|
|
928bae08f4 | ||
|
|
c65fc226bd | ||
|
|
114162693f | ||
|
|
b884c8c571 | ||
|
|
6222940b9c | ||
|
|
bb0c555803 | ||
|
|
5da33562dd | ||
|
|
ee74489c37 | ||
|
|
75fcb3800d | ||
|
|
0c6e505455 | ||
|
|
a467e10974 | ||
|
|
6dfbf00a23 | ||
|
|
b24af7fff6 | ||
|
|
db3aa8b887 | ||
|
|
ae32d79549 | ||
|
|
a80369b80a | ||
|
|
369177acf9 | ||
|
|
2ac5ceb4de | ||
|
|
602f78b568 | ||
|
|
669f6bd6f5 | ||
|
|
3d71fd1966 | ||
|
|
b887d2ec32 | ||
|
|
8e6c744a1b | ||
|
|
9e296a8a4e | ||
|
|
4ba4512619 | ||
|
|
26d75b71b0 | ||
|
|
dda509da0b | ||
|
|
2fa7ef32fb | ||
|
|
c72ee9091e | ||
|
|
19eda8f4f0 | ||
|
|
d08146c30f | ||
|
|
8c3a08b18d | ||
|
|
142a9dca3c | ||
|
|
41ab130807 | ||
|
|
8f67010b58 | ||
|
|
a986379deb | ||
|
|
eaa719df17 | ||
|
|
aef3f186c1 | ||
|
|
ebd01e0de5 | ||
|
|
ea60e608ba | ||
|
|
f51e04a1cc | ||
|
|
de2658a8db | ||
|
|
d71a666904 | ||
|
|
8b15ffc027 | ||
|
|
f15ca39df8 | ||
|
|
bd37f5d953 | ||
|
|
c703dabcc7 | ||
|
|
07eaada31e | ||
|
|
76c5c5d1b6 | ||
|
|
b8e64dc526 | ||
|
|
df7c882fe3 | ||
|
|
621cb243c2 | ||
|
|
9bd77bd89f | ||
|
|
c43a0b208d | ||
|
|
8ba5e93d04 | ||
|
|
370b6aad74 | ||
|
|
f5ded06a15 | ||
|
|
4c232610f1 | ||
|
|
81bd2ca8fb | ||
|
|
143c257fa2 | ||
|
|
724f9ba8d2 | ||
|
|
aa1f9b464b | ||
|
|
d2daba99d3 | ||
|
|
1c605e505a | ||
|
|
060a32e0f6 | ||
|
|
08edb92461 | ||
|
|
bec65ddf94 | ||
|
|
9dfd001f6f | ||
|
|
95a4a98de8 | ||
|
|
d4639b7df9 | ||
|
|
f7d30960c1 | ||
|
|
bc3eada02d | ||
|
|
7540ecde11 | ||
|
|
846c64f6c6 | ||
|
|
84c56f13bd | ||
|
|
1c99fb35da | ||
|
|
5bc2b96346 | ||
|
|
ae339506b3 | ||
|
|
e30df11a0b | ||
|
|
d297a493b8 | ||
|
|
ee269b0914 | ||
|
|
2a2d2cf709 | ||
|
|
5eb9dfff16 | ||
|
|
694ae34027 | ||
|
|
51b649ec39 | ||
|
|
a109df3f46 | ||
|
|
ca92cb980c | ||
|
|
f58c61a2e0 | ||
|
|
2b7ffa100f | ||
|
|
67c5740c83 | ||
|
|
f404a031f3 | ||
|
|
49cdaf8f5d | ||
|
|
86a6f565e8 | ||
|
|
6f669348a8 | ||
|
|
40cf83e557 | ||
|
|
fa4511cb0a | ||
|
|
45c6dfc5da | ||
|
|
36ab078fbd | ||
|
|
5a7f9ef720 | ||
|
|
8b8d21107c | ||
|
|
eab19de080 | ||
|
|
42f510024c | ||
|
|
5a7eecabee | ||
|
|
8920c1967f | ||
|
|
0058f7d0dc | ||
|
|
9a74fe34f6 | ||
|
|
e15ea06122 | ||
|
|
319396c815 | ||
|
|
af0053eb17 | ||
|
|
b14efa1129 | ||
|
|
50be7a9171 | ||
|
|
e410caaa8f | ||
|
|
fbff4c271a | ||
|
|
39deb7d27f | ||
|
|
ee91503973 | ||
|
|
de0a0c083d | ||
|
|
8adfafa6aa | ||
|
|
aafaff45d2 | ||
|
|
8979d786a9 | ||
|
|
971d6a2847 | ||
|
|
6a05d4e255 | ||
|
|
cbf1fa721e | ||
|
|
4ebf684794 | ||
|
|
f4bfe8e619 | ||
|
|
cec318fbfe | ||
|
|
78bb8882cd | ||
|
|
848d953226 | ||
|
|
a3a2b5ae0b | ||
|
|
941c980d06 | ||
|
|
fe190dec4b | ||
|
|
5095b2a470 | ||
|
|
317357b50d | ||
|
|
b15e5e33fd | ||
|
|
cca43cf102 | ||
|
|
a366c11d67 | ||
|
|
18bf4b5477 | ||
|
|
c20eb5c8a6 | ||
|
|
71605794a2 | ||
|
|
1dbb561744 | ||
|
|
cb42e99bee | ||
|
|
431a9c92c1 | ||
|
|
bd7a1c11b9 | ||
|
|
70fc58104b | ||
|
|
edcd7b1ff9 | ||
|
|
3724273d73 | ||
|
|
544365f3a9 | ||
|
|
bed1175e24 | ||
|
|
70c84cbc77 | ||
|
|
da59b35c0a | ||
|
|
eae94d1ee8 | ||
|
|
1f2d2c9b69 | ||
|
|
b6df11b6b4 | ||
|
|
ae57110f64 | ||
|
|
7a2203f116 | ||
|
|
023603479c | ||
|
|
f8da79b802 | ||
|
|
136830bc2b | ||
|
|
45f78676ea | ||
|
|
1074284666 | ||
|
|
d18c367497 | ||
|
|
8743576f72 | ||
|
|
fb7f84f31e | ||
|
|
31bc85bf86 | ||
|
|
968930e85f | ||
|
|
4b66304978 | ||
|
|
253378a44e | ||
|
|
f809f0a063 | ||
|
|
0386df7b16 | ||
|
|
8a2e7b62af | ||
|
|
9d04ae4676 | ||
|
|
9b8acd9a82 | ||
|
|
ee45a7833e | ||
|
|
d395c904f2 | ||
|
|
9bf819e653 | ||
|
|
46cd57688e | ||
|
|
0387eaf7ab | ||
|
|
4ee0240c24 | ||
|
|
5f60d18dfe | ||
|
|
194217fb07 | ||
|
|
d6ff764bb2 | ||
|
|
9cc3b18e4e | ||
|
|
56eaacd931 | ||
|
|
e119c8576c | ||
|
|
68246b3b6d | ||
|
|
a04c6bd6c9 | ||
|
|
efe134e9f4 | ||
|
|
4ec300787e | ||
|
|
3886022669 | ||
|
|
8264033a72 | ||
|
|
4861552d28 | ||
|
|
834f9bd9b8 | ||
|
|
f6dc25b229 | ||
|
|
1fcfe8e4ba | ||
|
|
b1a28358ad | ||
|
|
1ca3c6a61c | ||
|
|
e3739bb980 | ||
|
|
419629e4d2 | ||
|
|
e490e83a16 | ||
|
|
fda144e66f | ||
|
|
4dc10d27e0 | ||
|
|
0a0c6a3185 | ||
|
|
d66d4ec93d | ||
|
|
4b56a4e907 | ||
|
|
7370d5af9e | ||
|
|
c6b67cb8fe | ||
|
|
3bf6c7f95f | ||
|
|
1ad237f89f | ||
|
|
2b74b4dfa4 | ||
|
|
598ee875a0 | ||
|
|
d3a1e03a11 | ||
|
|
84d5318bda | ||
|
|
ba56e4071e | ||
|
|
d3160e9439 | ||
|
|
06c90d654d | ||
|
|
f72771cc81 | ||
|
|
8abdd63869 | ||
|
|
38f35658e7 | ||
|
|
d245242f2f | ||
|
|
45f73361e3 | ||
|
|
6ef204f190 | ||
|
|
dad18074ac | ||
|
|
3cf84f8859 | ||
|
|
0403237232 | ||
|
|
689774c6be | ||
|
|
d78e42e2fe | ||
|
|
4de628c736 | ||
|
|
023c1fedfe | ||
|
|
9be6866972 | ||
|
|
be55e0e3fe | ||
|
|
619a3bb25d | ||
|
|
4bd2cd4611 | ||
|
|
aa552fdb20 | ||
|
|
5520463395 | ||
|
|
872ddc6f95 | ||
|
|
88b0871c12 | ||
|
|
d4aa681652 | ||
|
|
34f0be2836 | ||
|
|
447fed8e54 | ||
|
|
4cb74d77d1 | ||
|
|
b0fd0d2395 | ||
|
|
6559d44c7d | ||
|
|
9f57681032 | ||
|
|
d33041dc24 | ||
|
|
5953365af3 | ||
|
|
e3730b32d7 | ||
|
|
08b44ed727 | ||
|
|
83fb482f1e | ||
|
|
734bb9ee3c | ||
|
|
d47e35d64e | ||
|
|
0bc49dab60 | ||
|
|
646d899f8d | ||
|
|
07434da8b0 | ||
|
|
53a6b72ce5 | ||
|
|
a51dafcb4c | ||
|
|
8362780e22 | ||
|
|
358de88602 | ||
|
|
32a7be9964 | ||
|
|
d5f9395e51 | ||
|
|
4e7a147759 | ||
|
|
1344c40598 | ||
|
|
1d2b2f4f01 | ||
|
|
373f6e0900 | ||
|
|
ba64758c24 | ||
|
|
abddcfccdf | ||
|
|
6d5381f9b1 | ||
|
|
e4e8a4abcd | ||
|
|
e41373b8ad | ||
|
|
9d84d389ab | ||
|
|
6d8aa215d6 | ||
|
|
0969c3e7e0 | ||
|
|
5de7870f9b | ||
|
|
44a7dc004d | ||
|
|
5f8d0e0436 | ||
|
|
4fbb5a03c1 | ||
|
|
0cffb87cbc | ||
|
|
df56e3bdf9 | ||
|
|
1d435248e2 | ||
|
|
593553f573 | ||
|
|
d38b8d6001 | ||
|
|
db59713d36 | ||
|
|
67fbdafe76 | ||
|
|
42be8ac312 | ||
|
|
0df88c07f6 | ||
|
|
f6b019dcec | ||
|
|
e626264d5a | ||
|
|
b99de068f8 | ||
|
|
e8beaa5257 | ||
|
|
0ef7c8e0e6 | ||
|
|
48f0fc147f | ||
|
|
cda96be8c3 | ||
|
|
f6ed175070 | ||
|
|
2ca2071d95 | ||
|
|
0054a4db2a | ||
|
|
e2f58274ba | ||
|
|
119fe90570 | ||
|
|
e2817ab87c | ||
|
|
2e37033e35 | ||
|
|
105fe1d3ed | ||
|
|
78bc2c8748 | ||
|
|
83dbdfb45e | ||
|
|
81987bb143 | ||
|
|
53cf89d7c2 | ||
|
|
8b9065c166 | ||
|
|
6a305c73ae | ||
|
|
7022675d00 | ||
|
|
2f9af1af8f | ||
|
|
fc89fec46d | ||
|
|
c6675be792 | ||
|
|
351d598c9f | ||
|
|
81b86f8022 | ||
|
|
4d5a30b30b | ||
|
|
79c1142d3e | ||
|
|
e061443560 | ||
|
|
03ef918dd8 | ||
|
|
ca48345b29 | ||
|
|
def132e140 | ||
|
|
7bed3b4c2e | ||
|
|
4266492a34 | ||
|
|
91eef93386 | ||
|
|
a244f87f95 | ||
|
|
9df0361262 | ||
|
|
6bcd88973b | ||
|
|
d13c9ae018 | ||
|
|
11412727ef | ||
|
|
73b7107ee8 | ||
|
|
91fd53ab4d | ||
|
|
aab5c5b311 | ||
|
|
dc86a6abc5 | ||
|
|
a62d1a1b36 | ||
|
|
5015d218ff | ||
|
|
6f034ccb5d | ||
|
|
07eef18337 | ||
|
|
f277a66582 | ||
|
|
49697b1f15 | ||
|
|
131f0e2e67 | ||
|
|
b14a559a52 | ||
|
|
b115ca5353 | ||
|
|
b40bfb1ea5 | ||
|
|
4f980a0266 | ||
|
|
19d93744f3 | ||
|
|
e327f404e3 | ||
|
|
452fb8f013 | ||
|
|
c4d6e00470 | ||
|
|
0f3e3d206b | ||
|
|
83c6e74783 | ||
|
|
2bff6eb781 | ||
|
|
ee7eb79277 | ||
|
|
592db903b3 | ||
|
|
34b7da1dd8 | ||
|
|
2882929c5d | ||
|
|
fd2c1ba1ed | ||
|
|
05cf0e1edc | ||
|
|
229a39d0d3 | ||
|
|
a9a70dfddf | ||
|
|
b8cf229b05 | ||
|
|
7258340e0c | ||
|
|
b84156fde8 | ||
|
|
d1d70616a3 | ||
|
|
5378d261b4 | ||
|
|
a1fb10f7cf | ||
|
|
dbc8ca7379 | ||
|
|
c48b4c9971 | ||
|
|
b592669d1f | ||
|
|
0bcaab3a5a | ||
|
|
1de4def444 | ||
|
|
ee4692a355 | ||
|
|
6e2ce6f1dc | ||
|
|
c4733f601f | ||
|
|
82353b20e1 | ||
|
|
51baf57b40 | ||
|
|
3082f6ac1b | ||
|
|
db80b620d8 | ||
|
|
6e56396217 | ||
|
|
24024d51c7 | ||
|
|
a96f0c2e5f | ||
|
|
1e5cf1c174 | ||
|
|
719074d306 | ||
|
|
70575e8a1c | ||
|
|
ce60097722 | ||
|
|
1a990fdd25 | ||
|
|
527718a440 | ||
|
|
d3caea60ee | ||
|
|
f947a2fdef | ||
|
|
dc4aa67503 | ||
|
|
37871389b9 | ||
|
|
2f9d45e03a | ||
|
|
b8647c13c7 | ||
|
|
164687d54b | ||
|
|
58f74cfd84 | ||
|
|
f7d3e56561 | ||
|
|
42f882504e | ||
|
|
9448a6e2c7 | ||
|
|
2cc057e438 | ||
|
|
b2e2142594 | ||
|
|
4000518698 | ||
|
|
fa8f1cba06 | ||
|
|
a72911e4f8 | ||
|
|
cd5b721bc6 | ||
|
|
42590972e4 | ||
|
|
d27dc8bab8 | ||
|
|
50d5fcf61e | ||
|
|
77830a546e | ||
|
|
83237ba4ed | ||
|
|
04b916c8ae | ||
|
|
b90bd66ac6 | ||
|
|
63d05e4a1a | ||
|
|
0b11dc5167 | ||
|
|
9c2653f125 | ||
|
|
7b01c5cae7 | ||
|
|
988b42e159 | ||
|
|
12c8bfa545 | ||
|
|
c948385e76 | ||
|
|
07b905c153 | ||
|
|
0192f28bf4 | ||
|
|
cbf97f56a4 | ||
|
|
d702c8bcb1 | ||
|
|
b84686b215 | ||
|
|
6a670828a5 | ||
|
|
ca6c2ffc27 | ||
|
|
914637b3ef | ||
|
|
d8da94de10 | ||
|
|
477a548fe9 | ||
|
|
35af9ad954 | ||
|
|
8a91e7d34d | ||
|
|
4ed8b8e233 | ||
|
|
c71b645777 | ||
|
|
f2ffb80a0b | ||
|
|
cda1d4be40 | ||
|
|
fc1431cd4e | ||
|
|
06158fb621 | ||
|
|
1e2e02368c | ||
|
|
d87d29aca9 | ||
|
|
005da6306c | ||
|
|
090b68e44e | ||
|
|
bf748ba4b7 | ||
|
|
0da9b909f6 | ||
|
|
5f87fc32ad | ||
|
|
97d354fa73 | ||
|
|
a87fb5a68c | ||
|
|
835b47a7e7 | ||
|
|
802dac81c9 | ||
|
|
bdc70c192a | ||
|
|
213f809148 | ||
|
|
f3fd5e0773 | ||
|
|
decf74cbdf | ||
|
|
b4a92d55f8 | ||
|
|
ebc31b9bdb | ||
|
|
56ebe9bf36 | ||
|
|
ddd68fc761 | ||
|
|
fd5c68a7d1 | ||
|
|
8c3ec164ff | ||
|
|
acdc469e39 | ||
|
|
f50463aca9 | ||
|
|
c0e7cbc983 | ||
|
|
828993b397 | ||
|
|
8ef89b4fa8 | ||
|
|
76cf9dad99 | ||
|
|
f3eb02a0bd | ||
|
|
ffa68fd010 | ||
|
|
f6dd006c35 | ||
|
|
8c29105bca | ||
|
|
948b829ff4 | ||
|
|
304a0c3d7a | ||
|
|
02dea2aeb6 | ||
|
|
6fc4f2b249 | ||
|
|
2a5f06ee9e | ||
|
|
7f9216dc90 | ||
|
|
263ccdfe6f | ||
|
|
1a8f1bfc57 | ||
|
|
9dc11a9e3c | ||
|
|
3bdd54308b | ||
|
|
1b569d371d | ||
|
|
36e5c601de | ||
|
|
ae45711e2b | ||
|
|
bcc47aa4cb | ||
|
|
ee94634b23 | ||
|
|
2016ebbbb2 | ||
|
|
1eaf09cce1 | ||
|
|
7579f4b4c0 | ||
|
|
1a1c45981c | ||
|
|
e4ecea55e4 | ||
|
|
58616fced9 | ||
|
|
8e9ca22b07 | ||
|
|
6a145df87c | ||
|
|
06dbd02b99 | ||
|
|
ffedb6382f | ||
|
|
3f9f295a87 | ||
|
|
84d77f4585 | ||
|
|
afdf58b4fa | ||
|
|
2b6d16feb1 | ||
|
|
0a86a6f392 | ||
|
|
5da5ad4b9f | ||
|
|
dd07810b66 | ||
|
|
a762248d98 | ||
|
|
80c9a47e51 | ||
|
|
784e73bceb | ||
|
|
5ad1b4cc33 | ||
|
|
e85646762c | ||
|
|
fc81a39317 | ||
|
|
d44c5bb2b2 | ||
|
|
c622d3f6f8 | ||
|
|
6daaa79519 | ||
|
|
3dda2cb379 | ||
|
|
4fcfde7cfb | ||
|
|
3403c00b6b | ||
|
|
ecdfe49fd1 | ||
|
|
cc214a3462 | ||
|
|
65d8af41e7 | ||
|
|
0e0970f06e | ||
|
|
917261dbf6 | ||
|
|
6a9105e065 | ||
|
|
570bb272eb | ||
|
|
0524a47cf4 | ||
|
|
9abc0b0d4f | ||
|
|
fe60e40927 | ||
|
|
740c297618 | ||
|
|
b4a088efe8 | ||
|
|
b34890772f | ||
|
|
054ffa29f6 | ||
|
|
74e08c9e37 | ||
|
|
ea96c9e22d | ||
|
|
86e7c44c6b | ||
|
|
64cf2e2df8 | ||
|
|
4361a4049a | ||
|
|
231f37376b | ||
|
|
328cdeda4a | ||
|
|
4dbc8e52ec | ||
|
|
ba447d3448 | ||
|
|
df556532d0 | ||
|
|
18e040f506 | ||
|
|
aefc98b1d7 | ||
|
|
46c8d791ac | ||
|
|
afcd91a2d0 | ||
|
|
4a30d9d1ec | ||
|
|
2da2e9bd9e | ||
|
|
3e6877ff0f | ||
|
|
a0f32036a6 | ||
|
|
d8f36df7f4 | ||
|
|
cb3b6c5bde | ||
|
|
b11712fa54 | ||
|
|
660edeb94f | ||
|
|
95de4088df | ||
|
|
e8d7a22651 | ||
|
|
4a62b929ad | ||
|
|
5efe82fb56 | ||
|
|
40bbafcaab | ||
|
|
4c4f0f3c5e | ||
|
|
ae0e0eca3d | ||
|
|
7e37fa710a | ||
|
|
e0c460c33c | ||
|
|
53f501ac19 | ||
|
|
132df027a5 | ||
|
|
7d97fd39ce | ||
|
|
995fa98fc6 | ||
|
|
824de921d1 | ||
|
|
66d9bd1a68 | ||
|
|
1c0bb2f827 | ||
|
|
ea018ed4dc | ||
|
|
f3f1867b14 | ||
|
|
8bbfd8810c | ||
|
|
3f84c3768a | ||
|
|
7372a3a598 | ||
|
|
4b4cd38ca6 | ||
|
|
7d40ba753a | ||
|
|
9b60214e0c | ||
|
|
f7e775f941 | ||
|
|
aefbf3b5f1 | ||
|
|
3f85af05e5 | ||
|
|
192c2dc5ef | ||
|
|
911edd7839 | ||
|
|
3d47dd78c8 | ||
|
|
8f6ab0af54 | ||
|
|
cb0b6fcdaa | ||
|
|
6b8824dd29 | ||
|
|
c217e7c479 | ||
|
|
ea4fe1577b | ||
|
|
1bab07e419 | ||
|
|
422d1d8c93 | ||
|
|
c8f9b1162d | ||
|
|
e2bdef7ffe | ||
|
|
e49b590322 | ||
|
|
9d19294f15 | ||
|
|
b0e7a85601 | ||
|
|
8ea45802df | ||
|
|
bba94d72dc | ||
|
|
d6dd423dc2 | ||
|
|
c10955d026 | ||
|
|
d642c7b6ea | ||
|
|
9307bcc8d1 | ||
|
|
99f3820e42 | ||
|
|
b04d2c39c8 | ||
|
|
0cdc5e125a | ||
|
|
2de812f262 | ||
|
|
16450c2876 | ||
|
|
729b57e4a7 | ||
|
|
87cc52cd05 | ||
|
|
0be57d51be | ||
|
|
9c482ebbe2 | ||
|
|
eb67f1037a | ||
|
|
59282c8965 | ||
|
|
03ab67ad5c | ||
|
|
e2d862bfb2 | ||
|
|
936d5abb1f | ||
|
|
7296780149 | ||
|
|
97c053ba73 | ||
|
|
2c5864204e | ||
|
|
6562c9aaa4 | ||
|
|
85a217c121 | ||
|
|
f156280a51 | ||
|
|
e8eb034a97 | ||
|
|
7763cf5a5c | ||
|
|
053736c0ea | ||
|
|
74ac230edb | ||
|
|
303021cd47 | ||
|
|
c0f1696adb | ||
|
|
361d168890 | ||
|
|
73669de392 | ||
|
|
89ec87e45b | ||
|
|
15cdfeb121 | ||
|
|
1bbd026195 | ||
|
|
a5c098de92 | ||
|
|
a63ba3e819 | ||
|
|
56e579e20f | ||
|
|
2873813562 | ||
|
|
a8ac56a82f | ||
|
|
6ef339b1ec | ||
|
|
579caa757c | ||
|
|
a1e579ff39 | ||
|
|
217019a640 | ||
|
|
c14404afe1 | ||
|
|
4596a7e000 | ||
|
|
ec40845513 | ||
|
|
dcfa8110e8 | ||
|
|
666e1ffcbd | ||
|
|
70fb760830 | ||
|
|
4a748525bc | ||
|
|
fb4a2e65cc | ||
|
|
71ad651514 | ||
|
|
65a9a72a88 | ||
|
|
ec0d7838ac | ||
|
|
752f17e51e | ||
|
|
8d42092a7e | ||
|
|
412c9eee2e | ||
|
|
abb90ca2f6 | ||
|
|
a7c6aea386 | ||
|
|
a88697151a | ||
|
|
d2107c9957 | ||
|
|
65902e424c | ||
|
|
bf8de72605 | ||
|
|
60f62482b7 | ||
|
|
d2d865fb7a | ||
|
|
5d5f8c8868 | ||
|
|
d093afd684 | ||
|
|
46396c229a | ||
|
|
eef90c7901 | ||
|
|
895b1e7944 | ||
|
|
2fb7774927 | ||
|
|
86b0b63771 | ||
|
|
99adc514a5 | ||
|
|
07fb9031c6 | ||
|
|
f237a344c3 | ||
|
|
2cb888c8b9 | ||
|
|
ab762b3cd7 | ||
|
|
703ae5d4aa | ||
|
|
91c3dfddf5 | ||
|
|
745b93138d | ||
|
|
7f385345bb | ||
|
|
d109d3d44e | ||
|
|
a2603fe27a | ||
|
|
e5590de2a4 | ||
|
|
77884db3a5 | ||
|
|
dc54836990 | ||
|
|
bb5f3cb33d | ||
|
|
d488a503b2 | ||
|
|
620e325da1 | ||
|
|
e0dad0e85a | ||
|
|
d6ff62b48c | ||
|
|
fa391e9658 | ||
|
|
29f12e857f | ||
|
|
1877ad8c39 | ||
|
|
4caddb24ad | ||
|
|
4f61d43d14 | ||
|
|
a939445da3 | ||
|
|
a3983bba6b | ||
|
|
19f9fc1b9b | ||
|
|
b3657d1c8f | ||
|
|
89f907bf6c | ||
|
|
0fb0109f9c | ||
|
|
33f50b3cee | ||
|
|
fdf0f9a182 | ||
|
|
30ab4a8d8b | ||
|
|
e333b78650 | ||
|
|
1aeff4f1e2 | ||
|
|
680e8f9260 | ||
|
|
3f47a282cc | ||
|
|
05afeb820a | ||
|
|
22c3806672 | ||
|
|
627fc628e0 | ||
|
|
ac96dde4c9 | ||
|
|
eaa9f1a80d | ||
|
|
d820d5b8f6 | ||
|
|
cde5c59b7e | ||
|
|
dc8bf6f077 | ||
|
|
4f69ab6ed8 | ||
|
|
aa2b28386a | ||
|
|
6fc4ff0a62 | ||
|
|
47cbfdc50c | ||
|
|
d7fc90ddcd | ||
|
|
c52b84b3fe | ||
|
|
1353e81b5b | ||
|
|
c5a3b74a96 | ||
|
|
b89c191e6f | ||
|
|
bebce24a7c | ||
|
|
7952d79932 | ||
|
|
0824e0e65c | ||
|
|
c49aaacb9b | ||
|
|
f0454667f3 | ||
|
|
be2173d839 | ||
|
|
1b78152715 | ||
|
|
10747a3219 | ||
|
|
8b281957b0 | ||
|
|
b3afcc67d4 | ||
|
|
f05df04320 | ||
|
|
f8101214eb | ||
|
|
2311af5e47 | ||
|
|
e4e730bada | ||
|
|
c62f3164a2 | ||
|
|
a9c1f8c2a0 | ||
|
|
80b01cb6a6 | ||
|
|
ae757a4b51 | ||
|
|
8b275a6006 | ||
|
|
c31bf61278 | ||
|
|
a144a9c3c6 | ||
|
|
c8355f9f18 | ||
|
|
55acac9fd5 | ||
|
|
a4f76b3922 | ||
|
|
e27290c8a0 | ||
|
|
11564f6457 | ||
|
|
6fb19eb58d | ||
|
|
13c2c41d23 | ||
|
|
d5adc4934b | ||
|
|
ad21092375 | ||
|
|
6b4156ab9f | ||
|
|
ca0a689362 | ||
|
|
5796363ecf | ||
|
|
814ecbb488 | ||
|
|
b0c09c0d6a | ||
|
|
f5ec219135 | ||
|
|
293c405593 | ||
|
|
e25fc3b243 | ||
|
|
dae28139da | ||
|
|
07c1ca69a7 | ||
|
|
38cfb22cba | ||
|
|
52c7076917 | ||
|
|
6b053137fd | ||
|
|
47f416f1dc | ||
|
|
0fbf401c98 | ||
|
|
22dc7139da | ||
|
|
ab98f44345 | ||
|
|
99efaadd38 | ||
|
|
2fd982a98f | ||
|
|
0f8f9453bd | ||
|
|
36b11676bf | ||
|
|
7d092f39c8 | ||
|
|
3a3937aa42 | ||
|
|
e2935f214a | ||
|
|
f7e375ae68 | ||
|
|
056951605b | ||
|
|
a108f753d5 | ||
|
|
667f69ef8f | ||
|
|
50f6ca7df3 | ||
|
|
e04bebde62 | ||
|
|
96e8ce920a | ||
|
|
191691b61c | ||
|
|
1454bb2b0c | ||
|
|
7a5153f7c7 | ||
|
|
28b11886dd | ||
|
|
305b9372c7 | ||
|
|
e8bb5061b0 | ||
|
|
85f9d5594e | ||
|
|
f42661f2d4 | ||
|
|
2a17062421 | ||
|
|
398f67f8d8 | ||
|
|
5102566aad | ||
|
|
45192413f9 | ||
|
|
37cc51465c | ||
|
|
d0ca52f3fd | ||
|
|
21eb86e5cb | ||
|
|
f185f48185 | ||
|
|
87cee85cea | ||
|
|
5be847909f | ||
|
|
991f14a5b9 | ||
|
|
f84cb64332 | ||
|
|
27f19c1f1b | ||
|
|
d780daaa87 | ||
|
|
b5722a56b4 | ||
|
|
8b71127e2b | ||
|
|
130a7043dd | ||
|
|
1f6d6e0e30 | ||
|
|
b6726628c4 | ||
|
|
cb6370ba9b | ||
|
|
515c627659 | ||
|
|
a371bf757b | ||
|
|
c516ec89e1 | ||
|
|
587d92f9ef | ||
|
|
0024b43103 | ||
|
|
6ca72167ee | ||
|
|
233ef71775 | ||
|
|
538106f1b8 | ||
|
|
7201334733 | ||
|
|
0bb7457520 | ||
|
|
510be10a87 | ||
|
|
5581cc42bf | ||
|
|
939154b4a5 | ||
|
|
65e3ad3779 | ||
|
|
f0d7eaf7f4 | ||
|
|
2952641d3f | ||
|
|
5c1a818488 | ||
|
|
9d3be6d894 | ||
|
|
1134d58b31 | ||
|
|
068ad4ba90 | ||
|
|
9b7251d8d4 | ||
|
|
e986f2c731 | ||
|
|
c2c96a817f | ||
|
|
93323ed6b3 | ||
|
|
c897ecac33 | ||
|
|
80fb24d8c3 | ||
|
|
47cf46f0c2 | ||
|
|
25177b6dad | ||
|
|
7f1f86488c | ||
|
|
64b7748033 | ||
|
|
2c403943b2 | ||
|
|
5c25f97e64 | ||
|
|
a99db6a1dc | ||
|
|
05599d1de8 | ||
|
|
33a40c290f | ||
|
|
62ea2f89ae | ||
|
|
8c4bc5be65 | ||
|
|
53620d4c08 | ||
|
|
d3480602c3 | ||
|
|
b31480a06a | ||
|
|
ca1a0875e4 | ||
|
|
cd7c81cfd0 | ||
|
|
c14a99a735 | ||
|
|
88b6fc4818 | ||
|
|
5ac90f25b3 | ||
|
|
1e46ad2fbe | ||
|
|
3520d3b108 | ||
|
|
fcbafde741 | ||
|
|
6b90c6d066 | ||
|
|
dad09e91cf | ||
|
|
e59f9e43a8 | ||
|
|
610535de51 | ||
|
|
991c6195bd | ||
|
|
0e2c2fcd7f | ||
|
|
8ed01d5c8e | ||
|
|
b4671746c2 | ||
|
|
5059bba51e | ||
|
|
db9758575b | ||
|
|
dfa8bc10a5 | ||
|
|
e819879232 | ||
|
|
67e7fdf80b | ||
|
|
73b280754d | ||
|
|
de68649eea | ||
|
|
e5e402197a | ||
|
|
93ce9a4cb2 | ||
|
|
acae9087e9 | ||
|
|
e2485bcf2b | ||
|
|
641e7f38bc | ||
|
|
7f9f54faf4 | ||
|
|
5729b2242e | ||
|
|
0112d06ed5 | ||
|
|
6ded0d50c7 | ||
|
|
f536241a5f | ||
|
|
e3a5d1fc50 | ||
|
|
71ba15c097 | ||
|
|
27b573c7d6 | ||
|
|
0c3f50e426 | ||
|
|
aed566fa00 | ||
|
|
bac16060ff | ||
|
|
8958656222 | ||
|
|
f11c3ab483 | ||
|
|
c8d7d3ea2a | ||
|
|
f0d75cc189 | ||
|
|
ae60546fe9 | ||
|
|
220208f28c | ||
|
|
89977320e3 | ||
|
|
e5923333f5 | ||
|
|
a0fe6941d2 | ||
|
|
f476ada22d | ||
|
|
c22bd73f67 | ||
|
|
5aa48524d6 | ||
|
|
38e76a6e40 | ||
|
|
5107d46568 | ||
|
|
3bcb01d45f | ||
|
|
547697ddc6 | ||
|
|
75d779ebe8 | ||
|
|
0f433571f6 | ||
|
|
6610b7110a | ||
|
|
11dc307a96 | ||
|
|
c91698287a | ||
|
|
aa971e017a | ||
|
|
df406d58a5 | ||
|
|
21c0dae03c | ||
|
|
a8ad2120c9 | ||
|
|
4a0394ce05 | ||
|
|
7152f8321b | ||
|
|
1f62cfe0af | ||
|
|
6f2b51cf55 | ||
|
|
74f6dc8d02 | ||
|
|
afcfa0a478 | ||
|
|
d019183af9 | ||
|
|
00277699c7 | ||
|
|
7b2a9a15e3 | ||
|
|
9eb58ad366 | ||
|
|
6be6b95414 | ||
|
|
94407da25f | ||
|
|
c6d557c33e | ||
|
|
ae300592a0 | ||
|
|
77bfeadb65 | ||
|
|
87bf5cb01a | ||
|
|
dfc9351096 | ||
|
|
e6a902c659 | ||
|
|
d8414b949a | ||
|
|
58bd2339c0 | ||
|
|
64ed43b791 | ||
|
|
a8b46dd41d | ||
|
|
0afe57f2fe | ||
|
|
90d41e4022 | ||
|
|
3e04ded750 | ||
|
|
42867264f3 | ||
|
|
c06914eb39 | ||
|
|
7a79028a72 | ||
|
|
ea5f14ce12 | ||
|
|
138ab10c1a | ||
|
|
59745486f5 | ||
|
|
4f4a7679ce | ||
|
|
b32f6a8bb1 | ||
|
|
16f2b5d821 | ||
|
|
dc6874a11c | ||
|
|
4f86712579 | ||
|
|
54a256d3bc | ||
|
|
063bfd4621 | ||
|
|
d45aa86fb5 | ||
|
|
52c0c4b7a8 | ||
|
|
e2d89f44fb | ||
|
|
ad6c2e759f | ||
|
|
9c2dbaa94e | ||
|
|
b839733ec7 | ||
|
|
722655ad13 | ||
|
|
3e0f8571d3 | ||
|
|
490910b994 | ||
|
|
1a8ef55dc7 | ||
|
|
307661398f | ||
|
|
21a24f9893 | ||
|
|
2f42a59c3d | ||
|
|
004e2f557b | ||
|
|
b1c6b216fe | ||
|
|
633af182f4 | ||
|
|
853410c16e | ||
|
|
9a826eefa3 | ||
|
|
eead71fcb5 | ||
|
|
1556be6798 | ||
|
|
65a009acb2 | ||
|
|
e37950d636 | ||
|
|
918a2b8a38 | ||
|
|
b6867c6161 | ||
|
|
8a0135d79a | ||
|
|
371da2a74c | ||
|
|
661b3bffcc | ||
|
|
b077d848f4 | ||
|
|
5f9c8be33d | ||
|
|
91019edcb8 | ||
|
|
a12ae596ec | ||
|
|
c59058b47d | ||
|
|
9dc357bc81 | ||
|
|
72b5d9abfa | ||
|
|
e7657bbd3a | ||
|
|
da9d1c8ac6 | ||
|
|
490dbd908b | ||
|
|
60d0cfcf64 | ||
|
|
a50c9008b8 | ||
|
|
1a9ee6cef8 | ||
|
|
aee507d5dd | ||
|
|
393584e535 | ||
|
|
5bca9d892a | ||
|
|
10066ecf79 | ||
|
|
d4091a8711 | ||
|
|
77e2f25f7b | ||
|
|
54d5e1fbdc | ||
|
|
59047df699 | ||
|
|
eda0c81bfb | ||
|
|
916d9d363e | ||
|
|
992983ff4c | ||
|
|
cbc9111082 | ||
|
|
04fbe8d2f8 | ||
|
|
97164f8f5d | ||
|
|
7c6e5e822c | ||
|
|
143f3f985b | ||
|
|
660847a3c8 | ||
|
|
c8c3575aab | ||
|
|
5256d18c5b | ||
|
|
d6b1e111d4 | ||
|
|
17db49d0ae | ||
|
|
c470d3e82a | ||
|
|
6a3fe77d6a | ||
|
|
4dfe26da54 | ||
|
|
63962a8ff4 | ||
|
|
80f7c4f81e | ||
|
|
1f23eb9a30 | ||
|
|
9637dc540e | ||
|
|
7ce485f2b7 | ||
|
|
2c3e286a8a | ||
|
|
e5c7d634eb | ||
|
|
5c2f218cfb | ||
|
|
34ce3ad9bf | ||
|
|
6c401d17b8 | ||
|
|
b332321e90 | ||
|
|
71743af1fc | ||
|
|
d7a8ec8b3a | ||
|
|
044ee3cb99 | ||
|
|
d976391a74 | ||
|
|
76137308ab | ||
|
|
5bd8db724e | ||
|
|
9458df0883 | ||
|
|
4ea485681b | ||
|
|
3b05c07c05 | ||
|
|
1c3627cc1d | ||
|
|
2c4b31b274 | ||
|
|
e22e98ddc9 | ||
|
|
8d76a99ee0 | ||
|
|
3c9f3acf79 | ||
|
|
c0b0920d73 | ||
|
|
e3eb965f5c | ||
|
|
17f38a40fe | ||
|
|
6ae77b5524 | ||
|
|
71cd874fe3 | ||
|
|
1235b9c5c3 | ||
|
|
dbe8bedf63 | ||
|
|
4ba2ba8e9e | ||
|
|
ad0afc111c | ||
|
|
621b6058b9 | ||
|
|
9eb3d3a416 | ||
|
|
5b80ebaf40 | ||
|
|
0c5ac3cc9b | ||
|
|
63acfb3a97 | ||
|
|
3994d6bf5d | ||
|
|
d02ccd0340 | ||
|
|
1680d0f8ff | ||
|
|
3ca4dc8ee0 | ||
|
|
727a6d33b2 | ||
|
|
18aeb0d48d | ||
|
|
2bca76ebee | ||
|
|
c825c99c2c | ||
|
|
0aa57252de | ||
|
|
2a50a02331 | ||
|
|
29f0814d83 | ||
|
|
247dde2d26 | ||
|
|
0e8a4a3eb5 | ||
|
|
fc7b968571 | ||
|
|
40b9203df2 | ||
|
|
8ec4e9b5e4 | ||
|
|
9f5e18fc3e | ||
|
|
900e284696 | ||
|
|
c539d81223 | ||
|
|
3557fac1ae | ||
|
|
9556d1ce38 | ||
|
|
b2749d2e08 | ||
|
|
2572284d20 | ||
|
|
be37ca5690 | ||
|
|
0895cf5c75 |
12
.deepsource.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
version = 1
|
||||
|
||||
test_patterns = ["tests/test_*.py"]
|
||||
|
||||
exclude_patterns = ["examples/**"]
|
||||
|
||||
[[analyzers]]
|
||||
name = "python"
|
||||
enabled = true
|
||||
|
||||
[analyzers.meta]
|
||||
runtime_version = "3.x.x"
|
||||
41
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: "\U0001F41B Bug Report"
|
||||
about: Submit a bug report to help us improve Qlib
|
||||
labels: bug
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Bug Description
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
## To Reproduce
|
||||
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1.
|
||||
1.
|
||||
1.
|
||||
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
## Screenshot
|
||||
|
||||
<!-- A screenshot of the error message or anything shouldn't appear-->
|
||||
|
||||
## Environment
|
||||
|
||||
**Note**: User could run `cd scripts && python collect_info.py all` under project directory to get system information
|
||||
and paste them here directly.
|
||||
|
||||
- Qlib version:
|
||||
- Python version:
|
||||
- OS (`Windows`, `Linux`, `MacOS`):
|
||||
- Commit number (optional, please provide it if you are using the dev version):
|
||||
|
||||
## Additional Notes
|
||||
|
||||
<!-- Add any other information about the problem here. -->
|
||||
9
.github/ISSUE_TEMPLATE/documentation.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
name: "\U0001F4D6 Documentation"
|
||||
about: Report an issue related to documentation
|
||||
|
||||
---
|
||||
|
||||
## 📖 Documentation
|
||||
|
||||
<!-- Please specify whether it's tutorial part or API reference part, and describe it.-->
|
||||
25
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: "\U0001F31FFeature Request"
|
||||
about: Request for a new Qlib feature
|
||||
labels: enhancement
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Feature Description
|
||||
<!-- A clear and concise description of the feature proposal -->
|
||||
|
||||
## Motivation
|
||||
|
||||
1. Application scenario
|
||||
2. Related works (Papers, Github repos etc.):
|
||||
3. Any other relevant and important information:
|
||||
|
||||
<!-- Please describe why the feature is important. -->
|
||||
|
||||
## Alternatives
|
||||
|
||||
<!-- A short description of any alternative solutions or features you've considered. -->
|
||||
|
||||
## Additional Notes
|
||||
|
||||
<!-- Add any other context or screenshots about the feature request here. -->
|
||||
10
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: "❓Questions & Help"
|
||||
about: Have some questions? We can offer help.
|
||||
labels: question
|
||||
|
||||
---
|
||||
|
||||
## ❓ Questions and Help
|
||||
|
||||
We sincerely suggest you to carefully read the [documentation](http://qlib.readthedocs.io/) of our library as well as the official [paper](https://arxiv.org/abs/2009.11189). After that, if you still feel puzzled, please describe the question clearly under this issue.
|
||||
24
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--- Provide a general summary of your changes in the Title above -->
|
||||
|
||||
## Description
|
||||
<!--- Describe your changes in detail -->
|
||||
|
||||
## Motivation and Context
|
||||
<!--- Are there any related issues? If so, please put the link here. -->
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
|
||||
## How Has This Been Tested?
|
||||
- [ ] Pass the test by running: `pytest qlib/tests/test_all_pipeline.py` under upper directory of `qlib`.
|
||||
- [ ] If you are adding a new feature, test on your own test scripts.
|
||||
|
||||
<!--- **ATTENTION**: If you are adding a new feature, please make sure your codes are **correctly tested**. If our test scripts do not cover your cases, please provide your own test scripts under the `tests` folder and test them. More information about test scripts can be found [here](https://docs.python.org/3/library/unittest.html#basic-example), or you could refer to those we provide under the `tests` folder. -->
|
||||
|
||||
## Screenshots of Test Results (if appropriate):
|
||||
1. Pipeline test:
|
||||
2. Your own tests:
|
||||
|
||||
## Types of changes
|
||||
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
||||
- [ ] Fix bugs
|
||||
- [ ] Add new feature
|
||||
- [ ] Update documentation
|
||||
649
.github/brew_install.sh
vendored
Normal file
@@ -0,0 +1,649 @@
|
||||
#!/bin/bash
|
||||
set -u
|
||||
|
||||
# First check if the OS is Linux.
|
||||
if [[ "$(uname)" = "Linux" ]]; then
|
||||
HOMEBREW_ON_LINUX=1
|
||||
fi
|
||||
|
||||
# On macOS, this script installs to /usr/local only.
|
||||
# On Linux, it installs to /home/linuxbrew/.linuxbrew if you have sudo access
|
||||
# and ~/.linuxbrew otherwise.
|
||||
# To install elsewhere (which is unsupported)
|
||||
# you can untar https://github.com/Homebrew/brew/tarball/master
|
||||
# anywhere you like.
|
||||
if [[ -z "${HOMEBREW_ON_LINUX-}" ]]; then
|
||||
HOMEBREW_PREFIX="/usr/local"
|
||||
HOMEBREW_REPOSITORY="/usr/local/Homebrew"
|
||||
HOMEBREW_CACHE="${HOME}/Library/Caches/Homebrew"
|
||||
|
||||
STAT="stat -f"
|
||||
CHOWN="/usr/sbin/chown"
|
||||
CHGRP="/usr/bin/chgrp"
|
||||
GROUP="admin"
|
||||
TOUCH="/usr/bin/touch"
|
||||
else
|
||||
HOMEBREW_PREFIX_DEFAULT="/home/linuxbrew/.linuxbrew"
|
||||
HOMEBREW_CACHE="${HOME}/.cache/Homebrew"
|
||||
|
||||
STAT="stat --printf"
|
||||
CHOWN="/bin/chown"
|
||||
CHGRP="/bin/chgrp"
|
||||
GROUP="$(id -gn)"
|
||||
TOUCH="/bin/touch"
|
||||
fi
|
||||
BREW_REPO="https://github.com/Homebrew/brew"
|
||||
|
||||
# TODO: bump version when new macOS is released
|
||||
MACOS_LATEST_SUPPORTED="10.15"
|
||||
# TODO: bump version when new macOS is released
|
||||
MACOS_OLDEST_SUPPORTED="10.13"
|
||||
|
||||
# For Homebrew on Linux
|
||||
REQUIRED_RUBY_VERSION=2.6 # https://github.com/Homebrew/brew/pull/6556
|
||||
REQUIRED_GLIBC_VERSION=2.13 # https://docs.brew.sh/Homebrew-on-Linux#requirements
|
||||
|
||||
# no analytics during installation
|
||||
export HOMEBREW_NO_ANALYTICS_THIS_RUN=1
|
||||
export HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT=1
|
||||
|
||||
# string formatters
|
||||
if [[ -t 1 ]]; then
|
||||
tty_escape() { printf "\033[%sm" "$1"; }
|
||||
else
|
||||
tty_escape() { :; }
|
||||
fi
|
||||
tty_mkbold() { tty_escape "1;$1"; }
|
||||
tty_underline="$(tty_escape "4;39")"
|
||||
tty_blue="$(tty_mkbold 34)"
|
||||
tty_red="$(tty_mkbold 31)"
|
||||
tty_bold="$(tty_mkbold 39)"
|
||||
tty_reset="$(tty_escape 0)"
|
||||
|
||||
have_sudo_access() {
|
||||
local -a args
|
||||
if [[ -n "${SUDO_ASKPASS-}" ]]; then
|
||||
args=("-A")
|
||||
fi
|
||||
|
||||
if [[ -z "${HAVE_SUDO_ACCESS-}" ]]; then
|
||||
if [[ -n "${args[*]-}" ]]; then
|
||||
/usr/bin/sudo "${args[@]}" -l mkdir &>/dev/null
|
||||
else
|
||||
/usr/bin/sudo -l mkdir &>/dev/null
|
||||
fi
|
||||
HAVE_SUDO_ACCESS="$?"
|
||||
fi
|
||||
|
||||
if [[ -z "${HOMEBREW_ON_LINUX-}" ]] && [[ "$HAVE_SUDO_ACCESS" -ne 0 ]]; then
|
||||
abort "Need sudo access on macOS (e.g. the user $USER to be an Administrator)!"
|
||||
fi
|
||||
|
||||
return "$HAVE_SUDO_ACCESS"
|
||||
}
|
||||
|
||||
shell_join() {
|
||||
local arg
|
||||
printf "%s" "$1"
|
||||
shift
|
||||
for arg in "$@"; do
|
||||
printf " "
|
||||
printf "%s" "${arg// /\ }"
|
||||
done
|
||||
}
|
||||
|
||||
chomp() {
|
||||
printf "%s" "${1/"$'\n'"/}"
|
||||
}
|
||||
|
||||
ohai() {
|
||||
printf "${tty_blue}==>${tty_bold} %s${tty_reset}\n" "$(shell_join "$@")"
|
||||
}
|
||||
|
||||
warn() {
|
||||
printf "${tty_red}Warning${tty_reset}: %s\n" "$(chomp "$1")"
|
||||
}
|
||||
|
||||
abort() {
|
||||
printf "%s\n" "$1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
execute() {
|
||||
if ! "$@"; then
|
||||
abort "$(printf "Failed during: %s" "$(shell_join "$@")")"
|
||||
fi
|
||||
}
|
||||
|
||||
execute_sudo() {
|
||||
local -a args=("$@")
|
||||
if [[ -n "${SUDO_ASKPASS-}" ]]; then
|
||||
args=("-A" "${args[@]}")
|
||||
fi
|
||||
if have_sudo_access; then
|
||||
ohai "/usr/bin/sudo" "${args[@]}"
|
||||
execute "/usr/bin/sudo" "${args[@]}"
|
||||
else
|
||||
ohai "${args[@]}"
|
||||
execute "${args[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
getc() {
|
||||
local save_state
|
||||
save_state=$(/bin/stty -g)
|
||||
/bin/stty raw -echo
|
||||
IFS= read -r -n 1 -d '' "$@"
|
||||
/bin/stty "$save_state"
|
||||
}
|
||||
|
||||
wait_for_user() {
|
||||
local c
|
||||
echo
|
||||
echo "Press RETURN to continue or any other key to abort"
|
||||
getc c
|
||||
# we test for \r and \n because some stuff does \r instead
|
||||
if ! [[ "$c" == $'\r' || "$c" == $'\n' ]]; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
major_minor() {
|
||||
echo "${1%%.*}.$(x="${1#*.}"; echo "${x%%.*}")"
|
||||
}
|
||||
|
||||
if [[ -z "${HOMEBREW_ON_LINUX-}" ]]; then
|
||||
macos_version="$(major_minor "$(/usr/bin/sw_vers -productVersion)")"
|
||||
fi
|
||||
|
||||
version_gt() {
|
||||
[[ "${1%.*}" -gt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -gt "${2#*.}" ]]
|
||||
}
|
||||
version_ge() {
|
||||
[[ "${1%.*}" -gt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -ge "${2#*.}" ]]
|
||||
}
|
||||
version_lt() {
|
||||
[[ "${1%.*}" -lt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -lt "${2#*.}" ]]
|
||||
}
|
||||
|
||||
should_install_command_line_tools() {
|
||||
if [[ -n "${HOMEBREW_ON_LINUX-}" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if version_gt "$macos_version" "10.13"; then
|
||||
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]]
|
||||
else
|
||||
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]] ||
|
||||
! [[ -e "/usr/include/iconv.h" ]]
|
||||
fi
|
||||
}
|
||||
|
||||
get_permission() {
|
||||
$STAT "%A" "$1"
|
||||
}
|
||||
|
||||
user_only_chmod() {
|
||||
[[ -d "$1" ]] && [[ "$(get_permission "$1")" != "755" ]]
|
||||
}
|
||||
|
||||
exists_but_not_writable() {
|
||||
[[ -e "$1" ]] && ! [[ -r "$1" && -w "$1" && -x "$1" ]]
|
||||
}
|
||||
|
||||
get_owner() {
|
||||
$STAT "%u" "$1"
|
||||
}
|
||||
|
||||
file_not_owned() {
|
||||
[[ "$(get_owner "$1")" != "$(id -u)" ]]
|
||||
}
|
||||
|
||||
get_group() {
|
||||
$STAT "%g" "$1"
|
||||
}
|
||||
|
||||
file_not_grpowned() {
|
||||
[[ " $(id -G "$USER") " != *" $(get_group "$1") "* ]]
|
||||
}
|
||||
|
||||
# Please sync with 'test_ruby()' in 'Library/Homebrew/utils/ruby.sh' from Homebrew/brew repository.
|
||||
test_ruby () {
|
||||
if [[ ! -x $1 ]]
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
|
||||
"$1" --enable-frozen-string-literal --disable=gems,did_you_mean,rubyopt -rrubygems -e \
|
||||
"abort if Gem::Version.new(RUBY_VERSION.to_s.dup).to_s.split('.').first(2) != \
|
||||
Gem::Version.new('$REQUIRED_RUBY_VERSION').to_s.split('.').first(2)" 2>/dev/null
|
||||
}
|
||||
|
||||
no_usable_ruby() {
|
||||
local ruby_exec
|
||||
IFS=$'\n' # Do word splitting on new lines only
|
||||
for ruby_exec in $(which -a ruby); do
|
||||
if test_ruby "$ruby_exec"; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
IFS=$' \t\n' # Restore IFS to its default value
|
||||
return 0
|
||||
}
|
||||
|
||||
outdated_glibc() {
|
||||
local glibc_version
|
||||
glibc_version=$(ldd --version | head -n1 | grep -o '[0-9.]*$' | grep -o '^[0-9]\+\.[0-9]\+')
|
||||
version_lt "$glibc_version" "$REQUIRED_GLIBC_VERSION"
|
||||
}
|
||||
|
||||
if [[ -n "${HOMEBREW_ON_LINUX-}" ]] && no_usable_ruby && outdated_glibc
|
||||
then
|
||||
abort "$(cat <<-EOFABORT
|
||||
Homebrew requires Ruby $REQUIRED_RUBY_VERSION which was not found on your system.
|
||||
Homebrew portable Ruby requires Glibc version $REQUIRED_GLIBC_VERSION or newer,
|
||||
and your Glibc version is too old.
|
||||
See ${tty_underline}https://docs.brew.sh/Homebrew-on-Linux#requirements${tty_reset}
|
||||
Install Ruby $REQUIRED_RUBY_VERSION and add its location to your PATH.
|
||||
EOFABORT
|
||||
)"
|
||||
fi
|
||||
|
||||
# USER isn't always set so provide a fall back for the installer and subprocesses.
|
||||
if [[ -z "${USER-}" ]]; then
|
||||
USER="$(chomp "$(id -un)")"
|
||||
export USER
|
||||
fi
|
||||
|
||||
# Invalidate sudo timestamp before exiting (if it wasn't active before).
|
||||
if ! /usr/bin/sudo -n -v 2>/dev/null; then
|
||||
trap '/usr/bin/sudo -k' EXIT
|
||||
fi
|
||||
|
||||
# Things can fail later if `pwd` doesn't exist.
|
||||
# Also sudo prints a warning message for no good reason
|
||||
cd "/usr" || exit 1
|
||||
|
||||
####################################################################### script
|
||||
if ! command -v git >/dev/null; then
|
||||
abort "$(cat <<EOABORT
|
||||
You must install Git before installing Homebrew. See:
|
||||
${tty_underline}https://docs.brew.sh/Installation${tty_reset}
|
||||
EOABORT
|
||||
)"
|
||||
fi
|
||||
|
||||
if ! command -v curl >/dev/null; then
|
||||
abort "$(cat <<EOABORT
|
||||
You must install cURL before installing Homebrew. See:
|
||||
${tty_underline}https://docs.brew.sh/Installation${tty_reset}
|
||||
EOABORT
|
||||
)"
|
||||
fi
|
||||
|
||||
if [[ -z "${HOMEBREW_ON_LINUX-}" ]]; then
|
||||
have_sudo_access
|
||||
else
|
||||
if [[ -n "${CI-}" ]] || [[ -w "$HOMEBREW_PREFIX_DEFAULT" ]] || [[ -w "/home/linuxbrew" ]] || [[ -w "/home" ]]; then
|
||||
HOMEBREW_PREFIX="$HOMEBREW_PREFIX_DEFAULT"
|
||||
else
|
||||
trap exit SIGINT
|
||||
if [[ $(/usr/bin/sudo -n -l mkdir 2>&1) != *"mkdir"* ]]; then
|
||||
ohai "Select the Homebrew installation directory"
|
||||
echo "- ${tty_bold}Enter your password${tty_reset} to install to ${tty_underline}${HOMEBREW_PREFIX_DEFAULT}${tty_reset} (${tty_bold}recommended${tty_reset})"
|
||||
echo "- ${tty_bold}Press Control-D${tty_reset} to install to ${tty_underline}$HOME/.linuxbrew${tty_reset}"
|
||||
echo "- ${tty_bold}Press Control-C${tty_reset} to cancel installation"
|
||||
fi
|
||||
if have_sudo_access; then
|
||||
HOMEBREW_PREFIX="$HOMEBREW_PREFIX_DEFAULT"
|
||||
else
|
||||
HOMEBREW_PREFIX="$HOME/.linuxbrew"
|
||||
fi
|
||||
trap - SIGINT
|
||||
fi
|
||||
HOMEBREW_REPOSITORY="${HOMEBREW_PREFIX}/Homebrew"
|
||||
fi
|
||||
|
||||
if [[ "$UID" == "0" ]]; then
|
||||
abort "Don't run this as root!"
|
||||
elif [[ -d "$HOMEBREW_PREFIX" && ! -x "$HOMEBREW_PREFIX" ]]; then
|
||||
abort "$(cat <<EOABORT
|
||||
The Homebrew prefix, ${HOMEBREW_PREFIX}, exists but is not searchable. If this is
|
||||
not intentional, please restore the default permissions and try running the
|
||||
installer again:
|
||||
sudo chmod 775 ${HOMEBREW_PREFIX}
|
||||
EOABORT
|
||||
)"
|
||||
fi
|
||||
|
||||
if [[ -z "${HOMEBREW_ON_LINUX-}" ]]; then
|
||||
if version_lt "$macos_version" "10.7"; then
|
||||
abort "$(cat <<EOABORT
|
||||
Your Mac OS X version is too old. See:
|
||||
${tty_underline}https://github.com/mistydemeo/tigerbrew${tty_reset}
|
||||
EOABORT
|
||||
)"
|
||||
elif version_lt "$macos_version" "10.10"; then
|
||||
abort "Your OS X version is too old"
|
||||
elif version_gt "$macos_version" "$MACOS_LATEST_SUPPORTED" || \
|
||||
version_lt "$macos_version" "$MACOS_OLDEST_SUPPORTED"; then
|
||||
who="We"
|
||||
what=""
|
||||
if version_gt "$macos_version" "$MACOS_LATEST_SUPPORTED"; then
|
||||
what="pre-release version"
|
||||
else
|
||||
who+=" (and Apple)"
|
||||
what="old version"
|
||||
fi
|
||||
ohai "You are using macOS ${macos_version}."
|
||||
ohai "${who} do not provide support for this ${what}."
|
||||
|
||||
echo "$(cat <<EOS
|
||||
This installation may not succeed.
|
||||
After installation, you will encounter build failures with some formulae.
|
||||
Please create pull requests instead of asking for help on Homebrew\'s GitHub,
|
||||
Discourse, Twitter or IRC. You are responsible for resolving any issues you
|
||||
experience while you are running this ${what}.
|
||||
EOS
|
||||
)
|
||||
"
|
||||
fi
|
||||
fi
|
||||
|
||||
ohai "This script will install:"
|
||||
echo "${HOMEBREW_PREFIX}/bin/brew"
|
||||
echo "${HOMEBREW_PREFIX}/share/doc/homebrew"
|
||||
echo "${HOMEBREW_PREFIX}/share/man/man1/brew.1"
|
||||
echo "${HOMEBREW_PREFIX}/share/zsh/site-functions/_brew"
|
||||
echo "${HOMEBREW_PREFIX}/etc/bash_completion.d/brew"
|
||||
echo "${HOMEBREW_REPOSITORY}"
|
||||
|
||||
# Keep relatively in sync with
|
||||
# https://github.com/Homebrew/brew/blob/master/Library/Homebrew/keg.rb
|
||||
directories=(bin etc include lib sbin share opt var
|
||||
Frameworks
|
||||
etc/bash_completion.d lib/pkgconfig
|
||||
share/aclocal share/doc share/info share/locale share/man
|
||||
share/man/man1 share/man/man2 share/man/man3 share/man/man4
|
||||
share/man/man5 share/man/man6 share/man/man7 share/man/man8
|
||||
var/log var/homebrew var/homebrew/linked
|
||||
bin/brew)
|
||||
group_chmods=()
|
||||
for dir in "${directories[@]}"; do
|
||||
if exists_but_not_writable "${HOMEBREW_PREFIX}/${dir}"; then
|
||||
group_chmods+=("${HOMEBREW_PREFIX}/${dir}")
|
||||
fi
|
||||
done
|
||||
|
||||
# zsh refuses to read from these directories if group writable
|
||||
directories=(share/zsh share/zsh/site-functions)
|
||||
zsh_dirs=()
|
||||
for dir in "${directories[@]}"; do
|
||||
zsh_dirs+=("${HOMEBREW_PREFIX}/${dir}")
|
||||
done
|
||||
|
||||
directories=(bin etc include lib sbin share var opt
|
||||
share/zsh share/zsh/site-functions
|
||||
var/homebrew var/homebrew/linked
|
||||
Cellar Caskroom Homebrew Frameworks)
|
||||
mkdirs=()
|
||||
for dir in "${directories[@]}"; do
|
||||
if ! [[ -d "${HOMEBREW_PREFIX}/${dir}" ]]; then
|
||||
mkdirs+=("${HOMEBREW_PREFIX}/${dir}")
|
||||
fi
|
||||
done
|
||||
|
||||
user_chmods=()
|
||||
if [[ "${#zsh_dirs[@]}" -gt 0 ]]; then
|
||||
for dir in "${zsh_dirs[@]}"; do
|
||||
if user_only_chmod "${dir}"; then
|
||||
user_chmods+=("${dir}")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
chmods=()
|
||||
if [[ "${#group_chmods[@]}" -gt 0 ]]; then
|
||||
chmods+=("${group_chmods[@]}")
|
||||
fi
|
||||
if [[ "${#user_chmods[@]}" -gt 0 ]]; then
|
||||
chmods+=("${user_chmods[@]}")
|
||||
fi
|
||||
|
||||
chowns=()
|
||||
chgrps=()
|
||||
if [[ "${#chmods[@]}" -gt 0 ]]; then
|
||||
for dir in "${chmods[@]}"; do
|
||||
if file_not_owned "${dir}"; then
|
||||
chowns+=("${dir}")
|
||||
fi
|
||||
if file_not_grpowned "${dir}"; then
|
||||
chgrps+=("${dir}")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${#group_chmods[@]}" -gt 0 ]]; then
|
||||
ohai "The following existing directories will be made group writable:"
|
||||
printf "%s\n" "${group_chmods[@]}"
|
||||
fi
|
||||
if [[ "${#user_chmods[@]}" -gt 0 ]]; then
|
||||
ohai "The following existing directories will be made writable by user only:"
|
||||
printf "%s\n" "${user_chmods[@]}"
|
||||
fi
|
||||
if [[ "${#chowns[@]}" -gt 0 ]]; then
|
||||
ohai "The following existing directories will have their owner set to ${tty_underline}${USER}${tty_reset}:"
|
||||
printf "%s\n" "${chowns[@]}"
|
||||
fi
|
||||
if [[ "${#chgrps[@]}" -gt 0 ]]; then
|
||||
ohai "The following existing directories will have their group set to ${tty_underline}${GROUP}${tty_reset}:"
|
||||
printf "%s\n" "${chgrps[@]}"
|
||||
fi
|
||||
if [[ "${#mkdirs[@]}" -gt 0 ]]; then
|
||||
ohai "The following new directories will be created:"
|
||||
printf "%s\n" "${mkdirs[@]}"
|
||||
fi
|
||||
|
||||
if should_install_command_line_tools; then
|
||||
ohai "The Xcode Command Line Tools will be installed."
|
||||
fi
|
||||
|
||||
if [[ -t 0 && -z "${CI-}" ]]; then
|
||||
wait_for_user
|
||||
fi
|
||||
|
||||
if [[ -d "${HOMEBREW_PREFIX}" ]]; then
|
||||
if [[ "${#chmods[@]}" -gt 0 ]]; then
|
||||
execute_sudo "/bin/chmod" "u+rwx" "${chmods[@]}"
|
||||
fi
|
||||
if [[ "${#group_chmods[@]}" -gt 0 ]]; then
|
||||
execute_sudo "/bin/chmod" "g+rwx" "${group_chmods[@]}"
|
||||
fi
|
||||
if [[ "${#user_chmods[@]}" -gt 0 ]]; then
|
||||
execute_sudo "/bin/chmod" "755" "${user_chmods[@]}"
|
||||
fi
|
||||
if [[ "${#chowns[@]}" -gt 0 ]]; then
|
||||
execute_sudo "$CHOWN" "$USER" "${chowns[@]}"
|
||||
fi
|
||||
if [[ "${#chgrps[@]}" -gt 0 ]]; then
|
||||
execute_sudo "$CHGRP" "$GROUP" "${chgrps[@]}"
|
||||
fi
|
||||
else
|
||||
execute_sudo "/bin/mkdir" "-p" "${HOMEBREW_PREFIX}"
|
||||
if [[ -z "${HOMEBREW_ON_LINUX-}" ]]; then
|
||||
execute_sudo "$CHOWN" "root:wheel" "${HOMEBREW_PREFIX}"
|
||||
else
|
||||
execute_sudo "$CHOWN" "$USER:$GROUP" "${HOMEBREW_PREFIX}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${#mkdirs[@]}" -gt 0 ]]; then
|
||||
execute_sudo "/bin/mkdir" "-p" "${mkdirs[@]}"
|
||||
execute_sudo "/bin/chmod" "g+rwx" "${mkdirs[@]}"
|
||||
execute_sudo "$CHOWN" "$USER" "${mkdirs[@]}"
|
||||
execute_sudo "$CHGRP" "$GROUP" "${mkdirs[@]}"
|
||||
fi
|
||||
|
||||
if ! [[ -d "${HOMEBREW_CACHE}" ]]; then
|
||||
if [[ -z "${HOMEBREW_ON_LINUX-}" ]]; then
|
||||
execute_sudo "/bin/mkdir" "-p" "${HOMEBREW_CACHE}"
|
||||
else
|
||||
execute "/bin/mkdir" "-p" "${HOMEBREW_CACHE}"
|
||||
fi
|
||||
fi
|
||||
if exists_but_not_writable "${HOMEBREW_CACHE}"; then
|
||||
execute_sudo "/bin/chmod" "g+rwx" "${HOMEBREW_CACHE}"
|
||||
fi
|
||||
if file_not_owned "${HOMEBREW_CACHE}"; then
|
||||
execute_sudo "$CHOWN" "$USER" "${HOMEBREW_CACHE}"
|
||||
fi
|
||||
if file_not_grpowned "${HOMEBREW_CACHE}"; then
|
||||
execute_sudo "$CHGRP" "$GROUP" "${HOMEBREW_CACHE}"
|
||||
fi
|
||||
if [[ -d "${HOMEBREW_CACHE}" ]]; then
|
||||
execute "$TOUCH" "${HOMEBREW_CACHE}/.cleaned"
|
||||
fi
|
||||
|
||||
if should_install_command_line_tools && version_ge "$macos_version" "10.13"; then
|
||||
ohai "Searching online for the Command Line Tools"
|
||||
# This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools
|
||||
clt_placeholder="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress"
|
||||
execute_sudo "$TOUCH" "$clt_placeholder"
|
||||
|
||||
clt_label_command="/usr/sbin/softwareupdate -l |
|
||||
grep -B 1 -E 'Command Line Tools' |
|
||||
awk -F'*' '/^ *\\*/ {print \$2}' |
|
||||
sed -e 's/^ *Label: //' -e 's/^ *//' |
|
||||
sort -V |
|
||||
tail -n1"
|
||||
clt_label="$(chomp "$(/bin/bash -c "$clt_label_command")")"
|
||||
|
||||
if [[ -n "$clt_label" ]]; then
|
||||
ohai "Installing $clt_label"
|
||||
execute_sudo "/usr/sbin/softwareupdate" "-i" "$clt_label"
|
||||
execute_sudo "/bin/rm" "-f" "$clt_placeholder"
|
||||
execute_sudo "/usr/bin/xcode-select" "--switch" "/Library/Developer/CommandLineTools"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Headless install may have failed, so fallback to original 'xcode-select' method
|
||||
if should_install_command_line_tools && test -t 0; then
|
||||
ohai "Installing the Command Line Tools (expect a GUI popup):"
|
||||
execute_sudo "/usr/bin/xcode-select" "--install"
|
||||
echo "Press any key when the installation has completed."
|
||||
getc
|
||||
execute_sudo "/usr/bin/xcode-select" "--switch" "/Library/Developer/CommandLineTools"
|
||||
fi
|
||||
|
||||
if [[ -z "${HOMEBREW_ON_LINUX-}" ]] && ! output="$(/usr/bin/xcrun clang 2>&1)" && [[ "$output" == *"license"* ]]; then
|
||||
abort "$(cat <<EOABORT
|
||||
You have not agreed to the Xcode license.
|
||||
Before running the installer again please agree to the license by opening
|
||||
Xcode.app or running:
|
||||
sudo xcodebuild -license
|
||||
EOABORT
|
||||
)"
|
||||
fi
|
||||
|
||||
ohai "Downloading and installing Homebrew..."
|
||||
(
|
||||
cd "${HOMEBREW_REPOSITORY}" >/dev/null || return
|
||||
|
||||
# we do it in four steps to avoid merge errors when reinstalling
|
||||
execute "git" "init" "-q"
|
||||
|
||||
# "git remote add" will fail if the remote is defined in the global config
|
||||
execute "git" "config" "remote.origin.url" "${BREW_REPO}"
|
||||
execute "git" "config" "remote.origin.fetch" "+refs/heads/*:refs/remotes/origin/*"
|
||||
|
||||
# ensure we don't munge line endings on checkout
|
||||
execute "git" "config" "core.autocrlf" "false"
|
||||
|
||||
execute "git" "fetch" "origin" "--force"
|
||||
execute "git" "fetch" "origin" "--tags" "--force"
|
||||
|
||||
execute "git" "reset" "--hard" "origin/master"
|
||||
|
||||
execute "ln" "-sf" "${HOMEBREW_REPOSITORY}/bin/brew" "${HOMEBREW_PREFIX}/bin/brew"
|
||||
|
||||
) || exit 1
|
||||
|
||||
if [[ ":${PATH}:" != *":${HOMEBREW_PREFIX}/bin:"* ]]; then
|
||||
warn "${HOMEBREW_PREFIX}/bin is not in your PATH."
|
||||
fi
|
||||
|
||||
ohai "Installation successful!"
|
||||
echo
|
||||
|
||||
# Use the shell's audible bell.
|
||||
if [[ -t 1 ]]; then
|
||||
printf "\a"
|
||||
fi
|
||||
|
||||
# Use an extra newline and bold to avoid this being missed.
|
||||
ohai "Homebrew has enabled anonymous aggregate formulae and cask analytics."
|
||||
echo "$(cat <<EOS
|
||||
${tty_bold}Read the analytics documentation (and how to opt-out) here:
|
||||
${tty_underline}https://docs.brew.sh/Analytics${tty_reset}
|
||||
No analytics data has been sent yet (or will be during this \`install\` run).
|
||||
EOS
|
||||
)
|
||||
"
|
||||
|
||||
ohai "Homebrew is run entirely by unpaid volunteers. Please consider donating:"
|
||||
echo "$(cat <<EOS
|
||||
${tty_underline}https://github.com/Homebrew/brew#donations${tty_reset}
|
||||
EOS
|
||||
)
|
||||
"
|
||||
|
||||
(
|
||||
cd "${HOMEBREW_REPOSITORY}" >/dev/null || return
|
||||
execute "git" "config" "--replace-all" "homebrew.analyticsmessage" "true"
|
||||
execute "git" "config" "--replace-all" "homebrew.caskanalyticsmessage" "true"
|
||||
) || exit 1
|
||||
|
||||
ohai "Next steps:"
|
||||
echo "- Run \`brew help\` to get started"
|
||||
echo "- Further documentation: "
|
||||
echo " ${tty_underline}https://docs.brew.sh${tty_reset}"
|
||||
|
||||
if [[ -n "${HOMEBREW_ON_LINUX-}" ]]; then
|
||||
case "$SHELL" in
|
||||
*/bash*)
|
||||
if [[ -r "$HOME/.bash_profile" ]]; then
|
||||
shell_profile="$HOME/.bash_profile"
|
||||
else
|
||||
shell_profile="$HOME/.profile"
|
||||
fi
|
||||
;;
|
||||
*/zsh*)
|
||||
shell_profile="$HOME/.zprofile"
|
||||
;;
|
||||
*)
|
||||
shell_profile="$HOME/.profile"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "- Install the Homebrew dependencies if you have sudo access:"
|
||||
|
||||
if [[ $(command -v apt-get) ]]; then
|
||||
echo " sudo apt-get install build-essential"
|
||||
elif [[ $(command -v yum) ]]; then
|
||||
echo " sudo yum groupinstall 'Development Tools'"
|
||||
elif [[ $(command -v pacman) ]]; then
|
||||
echo " sudo pacman -S base-devel"
|
||||
elif [[ $(command -v apk) ]]; then
|
||||
echo " sudo apk add build-base"
|
||||
fi
|
||||
|
||||
cat <<EOS
|
||||
See ${tty_underline}https://docs.brew.sh/linux${tty_reset} for more information
|
||||
- Add Homebrew to your ${tty_bold}PATH${tty_reset} in ${tty_underline}${shell_profile}${tty_reset}:
|
||||
echo 'eval \$(${HOMEBREW_PREFIX}/bin/brew shellenv)' >> ${shell_profile}
|
||||
eval \$(${HOMEBREW_PREFIX}/bin/brew shellenv)
|
||||
- We recommend that you install GCC:
|
||||
brew install gcc
|
||||
|
||||
EOS
|
||||
fi
|
||||
33
.github/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name-template: 'v$RESOLVED_VERSION 🌈'
|
||||
tag-template: 'v$RESOLVED_VERSION'
|
||||
categories:
|
||||
- title: '🌟 Features'
|
||||
labels:
|
||||
- 'feature'
|
||||
- 'enhancement'
|
||||
- title: '🐛 Bug Fixes'
|
||||
labels:
|
||||
- 'fix'
|
||||
- 'bugfix'
|
||||
- 'bug'
|
||||
- title: '📚 Documentation'
|
||||
label:
|
||||
- 'doc'
|
||||
- 'documentation'
|
||||
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
||||
version-resolver:
|
||||
major:
|
||||
labels:
|
||||
- 'major'
|
||||
minor:
|
||||
labels:
|
||||
- 'minor'
|
||||
patch:
|
||||
labels:
|
||||
- 'patch'
|
||||
default: patch
|
||||
template: |
|
||||
## Changes
|
||||
|
||||
$CHANGES
|
||||
63
.github/workflows/python-publish.yml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
# This workflows will upload a Python Package using Twine when a release is created
|
||||
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
|
||||
|
||||
name: Upload Python Package
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
deploy_with_bdist_wheel:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, macos-latest, macos-11]
|
||||
# not supporting 3.6 due to annotations is not supported https://stackoverflow.com/a/52890129
|
||||
python-version: [3.7, 3.8]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install setuptools wheel twine
|
||||
- name: Build wheel on Windows
|
||||
run: |
|
||||
pip install numpy
|
||||
pip install cython
|
||||
python setup.py bdist_wheel
|
||||
- name: Build and publish
|
||||
env:
|
||||
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
||||
run: |
|
||||
twine upload dist/*
|
||||
|
||||
deploy_with_manylinux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build wheel on Linux
|
||||
uses: RalfG/python-wheels-manylinux-build@v0.3.1-manylinux2010_x86_64
|
||||
with:
|
||||
# not supporting 3.6 due to annotations is not supported https://stackoverflow.com/a/52890129
|
||||
python-versions: 'cp37-cp37m cp38-cp38'
|
||||
build-requirements: 'numpy cython'
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.7
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install twine
|
||||
- name: Build and publish
|
||||
env:
|
||||
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
||||
run: |
|
||||
twine upload dist/pyqlib-*-manylinux*.whl
|
||||
16
.github/workflows/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Release Drafter
|
||||
|
||||
on:
|
||||
push:
|
||||
# branches to consider in the event; optional, defaults to all
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
update_release_draft:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Drafts your next Release notes as Pull Requests are merged into "master"
|
||||
- uses: release-drafter/release-drafter@v5.11.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
24
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0/3 * * *"
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'This issue is stale because it has been open for three months with no activity. Remove the stale label or comment on the issue otherwise this will be closed in 5 days'
|
||||
stale-pr-message: 'This PR is stale because it has been open for a year with no activity. Remove the stale label or comment on the PR otherwise this will be closed in 5 days'
|
||||
stale-issue-label: 'stale'
|
||||
stale-pr-label: 'stale'
|
||||
days-before-stale: 90
|
||||
days-before-close: 5
|
||||
operations-per-run: 100
|
||||
exempt-issue-labels: 'bug,enhancement'
|
||||
remove-stale-when-updated: true
|
||||
66
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, ubuntu-18.04, ubuntu-20.04]
|
||||
# not supporting 3.6 due to annotations is not supported https://stackoverflow.com/a/52890129
|
||||
python-version: [3.7, 3.8]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Lint with Black
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install black wheel
|
||||
black qlib -l 120 --check --diff
|
||||
|
||||
- name: Install Qlib with pip
|
||||
run: |
|
||||
pip install numpy==1.19.5 ruamel.yaml
|
||||
pip install pyqlib --ignore-installed
|
||||
|
||||
- name: Test data downloads
|
||||
run: |
|
||||
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --interval 1d --region cn
|
||||
|
||||
- name: Test workflow by config (install from pip)
|
||||
run: |
|
||||
python qlib/workflow/cli.py examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml
|
||||
python -m pip uninstall -y pyqlib
|
||||
|
||||
# Test Qlib installed from source
|
||||
- name: Install Qlib from source
|
||||
run: |
|
||||
pip install --upgrade cython jupyter jupyter_contrib_nbextensions numpy scipy scikit-learn # installing without this line will cause errors on GitHub Actions, while instsalling locally won't
|
||||
pip install -e .
|
||||
|
||||
- name: Install test dependencies
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install black pytest
|
||||
|
||||
- name: Unit tests with Pytest
|
||||
run: |
|
||||
cd tests
|
||||
python -m pytest . --durations=10
|
||||
|
||||
- name: Test workflow by config (install from source)
|
||||
run: |
|
||||
python qlib/workflow/cli.py examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml
|
||||
|
||||
75
.github/workflows/test_macos.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# There are some issues (in the downloading data phase) on MacOS when running with other tests. So we split it into an individual config.
|
||||
name: Test MacOS
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11, macos-latest]
|
||||
# not supporting 3.6 due to annotations is not supported https://stackoverflow.com/a/52890129
|
||||
python-version: [3.7, 3.8]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Lint with Black
|
||||
run: |
|
||||
cd ..
|
||||
python -m pip install pip --upgrade
|
||||
python -m pip install wheel --upgrade
|
||||
python -m pip install black
|
||||
python -m black qlib -l 120 --check --diff
|
||||
# Test Qlib installed with pip
|
||||
|
||||
- name: Install Qlib with pip
|
||||
run: |
|
||||
python -m pip install numpy==1.19.5
|
||||
python -m pip install pyqlib --ignore-installed ruamel.yaml numpy
|
||||
- name: Install Lightgbm for MacOS
|
||||
run: |
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Microsoft/qlib/main/.github/brew_install.sh)"
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install lightgbm
|
||||
# FIX MacOS error: Segmentation fault
|
||||
# reference: https://github.com/microsoft/LightGBM/issues/4229
|
||||
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/fb8323f2b170bd4ae97e1bac9bf3e2983af3fdb0/Formula/libomp.rb
|
||||
brew unlink libomp
|
||||
brew install libomp.rb
|
||||
- name: Test data downloads
|
||||
run: |
|
||||
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --interval 1d --region cn
|
||||
- name: Test workflow by config (install from pip)
|
||||
run: |
|
||||
python qlib/workflow/cli.py examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml
|
||||
python -m pip uninstall -y pyqlib
|
||||
# Test Qlib installed from source
|
||||
- name: Install Qlib from source
|
||||
run: |
|
||||
python -m pip install --upgrade cython
|
||||
python -m pip install numpy jupyter jupyter_contrib_nbextensions
|
||||
python -m pip install -U scipy scikit-learn # installing without this line will cause errors on GitHub Actions, while instsalling locally won't
|
||||
python setup.py install
|
||||
- name: Install test dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -U pyopenssl idna
|
||||
python -m pip install black pytest
|
||||
- name: Unit tests with Pytest
|
||||
run: |
|
||||
cd tests
|
||||
python -m pytest . --durations=0
|
||||
- name: Test workflow by config (install from source)
|
||||
run: |
|
||||
python qlib/workflow/cli.py examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml
|
||||
8
.gitignore
vendored
@@ -2,6 +2,7 @@
|
||||
__pycache__/
|
||||
|
||||
*.pyc
|
||||
*.pyd
|
||||
*.so
|
||||
*.ipynb
|
||||
.ipynb_checkpoints
|
||||
@@ -19,6 +20,7 @@ dist/
|
||||
.nvimrc
|
||||
.vscode
|
||||
|
||||
qlib/VERSION.txt
|
||||
qlib/data/_libs/expanding.cpp
|
||||
qlib/data/_libs/rolling.cpp
|
||||
examples/estimator/estimator_example/
|
||||
@@ -31,3 +33,9 @@ mlruns/
|
||||
|
||||
tags
|
||||
|
||||
.pytest_cache/
|
||||
.vscode/
|
||||
|
||||
*.swp
|
||||
|
||||
./pretrain
|
||||
|
||||
21
.readthedocs.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
# .readthedocs.yml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
# Build all formats
|
||||
formats: all
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
version: 3.7
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
- method: setuptools
|
||||
path: .
|
||||
29
CHANGES.rst
@@ -114,7 +114,7 @@ Version 0.4.1
|
||||
Version 0.4.2
|
||||
--------------------
|
||||
- Refactor DataHandler
|
||||
- Add ``ALPHA360`` DataHandler
|
||||
- Add ``Alpha360`` DataHandler
|
||||
|
||||
|
||||
Version 0.4.3
|
||||
@@ -150,3 +150,30 @@ Version 0.4.6
|
||||
- Some bugs are fixed
|
||||
- The default config in `Version 0.4.5` is not friendly to daily frequency data.
|
||||
- Backtest error in TopkWeightStrategy when `WithInteract=True`.
|
||||
|
||||
|
||||
Version 0.5.0
|
||||
--------------------
|
||||
- First opensource version
|
||||
- Refine the docs, code
|
||||
- Add baselines
|
||||
- public data crawler
|
||||
|
||||
|
||||
Version 0.8.0
|
||||
--------------------
|
||||
- The backtest is greatly refactored.
|
||||
- Nested decision execution framework is supported
|
||||
- There are lots of changes for daily trading, it is hard to list all of them. But a few important changes could be noticed
|
||||
- The trading limitation is more accurate;
|
||||
- In `previous version <https://github.com/microsoft/qlib/blob/v0.7.2/qlib/contrib/backtest/exchange.py#L160>`_, longing and shorting actions share the same action.
|
||||
- In `current verison <https://github.com/microsoft/qlib/blob/7c31012b507a3823117bddcc693fc64899460b2a/qlib/backtest/exchange.py#L304>`_, the trading limitation is different between loging and shorting action.
|
||||
- The constant is different when calculating annualized metrics.
|
||||
- `Current version <https://github.com/microsoft/qlib/blob/7c31012b507a3823117bddcc693fc64899460b2a/qlib/contrib/evaluate.py#L42>`_ uses more accurate constant than `previous version <https://github.com/microsoft/qlib/blob/v0.7.2/qlib/contrib/evaluate.py#L22>`_
|
||||
- `A new version <https://github.com/microsoft/qlib/blob/7c31012b507a3823117bddcc693fc64899460b2a/qlib/tests/data.py#L17>`_ of data is released. Due to the unstability of Yahoo data source, the data may be different after downloading data again.
|
||||
- Users could chec kout the backtesting results between `Current version <https://github.com/microsoft/qlib/tree/7c31012b507a3823117bddcc693fc64899460b2a/examples/benchmarks>`_ and `previous version <https://github.com/microsoft/qlib/tree/v0.7.2/examples/benchmarks>`_
|
||||
|
||||
|
||||
Other Versions
|
||||
----------------------------------
|
||||
Please refer to `Github release Notes <https://github.com/microsoft/qlib/releases>`_
|
||||
|
||||
1
MANIFEST.in
Normal file
@@ -0,0 +1 @@
|
||||
include qlib/VERSION.txt
|
||||
326
README.md
@@ -1,44 +1,86 @@
|
||||
[](https://pypi.org/project/pyqlib/#files)
|
||||
[](https://pypi.org/project/pyqlib/#files)
|
||||
[](https://pypi.org/project/pyqlib/#history)
|
||||
[](https://pypi.org/project/pyqlib/)
|
||||
[](https://github.com/microsoft/qlib/actions)
|
||||
[](https://qlib.readthedocs.io/en/latest/?badge=latest)
|
||||
[](LICENSE)
|
||||
[](https://gitter.im/Microsoft/qlib?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
<div style="align: center">
|
||||
<img src="docs/_static/img/logo/white_bg_rec+word.png" />
|
||||
</div>
|
||||
## :newspaper: **What's NEW!** :sparkling_heart:
|
||||
Recent released features
|
||||
| Feature | Status |
|
||||
| -- | ------ |
|
||||
|Temporal Routing Adaptor (TRA) | [Released](https://github.com/microsoft/qlib/pull/531) on July 30, 2021 |
|
||||
| Transformer & Localformer | [Released](https://github.com/microsoft/qlib/pull/508) on July 22, 2021 |
|
||||
| Release Qlib v0.7.0 | [Released](https://github.com/microsoft/qlib/releases/tag/v0.7.0) on July 12, 2021 |
|
||||
| TCTS Model | [Released](https://github.com/microsoft/qlib/pull/491) on July 1, 2021 |
|
||||
| Online serving and automatic model rolling | :star: [Released](https://github.com/microsoft/qlib/pull/290) on May 17, 2021 |
|
||||
| DoubleEnsemble Model | [Released](https://github.com/microsoft/qlib/pull/286) on Mar 2, 2021 |
|
||||
| High-frequency data processing example | [Released](https://github.com/microsoft/qlib/pull/257) on Feb 5, 2021 |
|
||||
| High-frequency trading example | [Part of code released](https://github.com/microsoft/qlib/pull/227) on Jan 28, 2021 |
|
||||
| High-frequency data(1min) | [Released](https://github.com/microsoft/qlib/pull/221) on Jan 27, 2021 |
|
||||
| Tabnet Model | [Released](https://github.com/microsoft/qlib/pull/205) on Jan 22, 2021 |
|
||||
|
||||
Features released before 2021 are not listed here.
|
||||
|
||||
<p align="center">
|
||||
<img src="http://fintech.msra.cn/images_v070/logo/1.png" />
|
||||
</p>
|
||||
|
||||
|
||||
Qlib is an AI-oriented quantitative investment platform, which aims to realize the potential, empower the research, and create the value of AI technologies in quantitative investment.
|
||||
|
||||
With Qlib, you can easily try your ideas to create better Quant investment strategies.
|
||||
It contains the full ML pipeline of data processing, model training, back-testing; and covers the entire chain of quantitative investment: alpha seeking, risk modeling, portfolio optimization, and order execution.
|
||||
|
||||
With Qlib, users can easily try ideas to create better Quant investment strategies.
|
||||
|
||||
For more details, please refer to our paper ["Qlib: An AI-oriented Quantitative Investment Platform"](https://arxiv.org/abs/2009.11189).
|
||||
|
||||
|
||||
- [**Plans**](#plans)
|
||||
- [Framework of Qlib](#framework-of-qlib)
|
||||
- [Quick Start](#Quick-Start)
|
||||
- [Installation](#Installation)
|
||||
- [Data Preparation](#Data-Preparation)
|
||||
- [Auto Quant Research Workflow with](#Auto-Quant-Research-Workflow)
|
||||
- [Building Customized Quant Research Workflow by Code](#Building-Customized-Quant-Research-Workflow-by-Code)
|
||||
- [More About Qlib](#More-About-Qlib)
|
||||
- [Offline mode and online mode of data server](#Offline-Mode-and-Online-Mode-of-the-Data-Server)
|
||||
- [Performance of Qlib Data Server](#Performance-of-Qlib-Data-Server)
|
||||
- [Contributing](#Contributing)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Installation](#installation)
|
||||
- [Data Preparation](#data-preparation)
|
||||
- [Auto Quant Research Workflow](#auto-quant-research-workflow)
|
||||
- [Building Customized Quant Research Workflow by Code](#building-customized-quant-research-workflow-by-code)
|
||||
- [**Quant Model(Paper) Zoo**](#quant-model-paper-zoo)
|
||||
- [Run a single model](#run-a-single-model)
|
||||
- [Run multiple models](#run-multiple-models)
|
||||
- [**Quant Dataset Zoo**](#quant-dataset-zoo)
|
||||
- [More About Qlib](#more-about-qlib)
|
||||
- [Offline Mode and Online Mode](#offline-mode-and-online-mode)
|
||||
- [Performance of Qlib Data Server](#performance-of-qlib-data-server)
|
||||
- [Related Reports](#related-reports)
|
||||
- [Contact Us](#contact-us)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
|
||||
# Plans
|
||||
New features under development(order by estimated release time).
|
||||
Your feedbacks about the features are very important.
|
||||
| Feature | Status |
|
||||
| -- | ------ |
|
||||
| Planning-based portfolio optimization | Under review: https://github.com/microsoft/qlib/pull/280 |
|
||||
| Fund data supporting and analysis | Under review: https://github.com/microsoft/qlib/pull/292 |
|
||||
| Point-in-Time database | Under review: https://github.com/microsoft/qlib/pull/343 |
|
||||
| High-frequency trading | Under review: https://github.com/microsoft/qlib/pull/408 |
|
||||
| Meta-Learning-based data selection | Initial opensource version under development |
|
||||
|
||||
# Framework of Qlib
|
||||
|
||||
<div style="align: center">
|
||||
<img src="docs/_static/img/framework.png" />
|
||||
<img src="docs/_static/img/framework.svg" />
|
||||
</div>
|
||||
|
||||
|
||||
At the module level, Qlib is a platform that consists of the above components. The components are designed as loose-coupled modules and each component could be used stand-alone.
|
||||
At the module level, Qlib is a platform that consists of the above components. The components are designed as loose-coupled modules, and each component could be used stand-alone.
|
||||
|
||||
| Name | Description |
|
||||
| ------ | ----- |
|
||||
| `Data layer` | `DataServer` focuses on providing high-performance infrastructure for users to manage and retrieve raw data. `DataEnhancement` will preprocess the data and provide the best dataset to be fed into the models. |
|
||||
| `Interday Model` | `Interday model` focuses on producing prediction scores (aka. _alpha_). Models are trained by `Model Creator` and managed by `Model Manager`. Users could choose one or multiple models for prediction. Multiple models could be combined with `Ensemble` module. |
|
||||
| `Interday Strategy` | `Portfolio Generator` will take prediction scores as input and output the orders based on the current position to achieve the target portfolio. |
|
||||
| `Intraday Trading` | `Order Executor` is responsible for executing orders output by `Interday Strategy` and returning the executed results. |
|
||||
| `Analysis` | Users could get a detailed analysis report of forecasting signals and portfolios in this part. |
|
||||
| Name | Description |
|
||||
| ------ | ----- |
|
||||
| `Infrastructure` layer | `Infrastructure` layer provides underlying support for Quant research. `DataServer` provides a high-performance infrastructure for users to manage and retrieve raw data. `Trainer` provides a flexible interface to control the training process of models, which enable algorithms to control the training process. |
|
||||
| `Workflow` layer | `Workflow` layer covers the whole workflow of quantitative investment. `Information Extractor` extracts data for models. `Forecast Model` focuses on producing all kinds of forecast signals (e.g. _alpha_, risk) for other modules. With these signals `Portfolio Generator` will generate the target portfolio and produce orders to be executed by `Order Executor`. |
|
||||
| `Interface` layer | `Interface` layer tries to present a user-friendly interface for the underlying system. `Analyser` module will provide users detailed analysis reports of forecasting signals, portfolios and execution results |
|
||||
|
||||
* The modules with hand-drawn style are under development and will be released in the future.
|
||||
* The modules with dashed borders are highly user-customizable and extendible.
|
||||
@@ -48,36 +90,98 @@ At the module level, Qlib is a platform that consists of the above components. T
|
||||
|
||||
This quick start guide tries to demonstrate
|
||||
1. It's very easy to build a complete Quant research workflow and try your ideas with _Qlib_.
|
||||
1. Though with *public data* and *simple models*, machine learning technologies **work very well** in practical Quant investment.
|
||||
2. Though with *public data* and *simple models*, machine learning technologies **work very well** in practical Quant investment.
|
||||
|
||||
Here is a quick **[demo](https://terminalizer.com/view/3f24561a4470)** shows how to install ``Qlib``, and run LightGBM with ``qrun``. **But**, please make sure you have already prepared the data following the [instruction](#data-preparation).
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
Users can easily intsall ``Qlib`` according to the following steps:
|
||||
This table demonstrates the supported Python version of `Qlib`:
|
||||
| | install with pip | install from source | plot |
|
||||
| ------------- |:---------------------:|:--------------------:|:----:|
|
||||
| Python 3.7 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Python 3.8 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Python 3.9 | :x: | :heavy_check_mark: | :x: |
|
||||
|
||||
* Before installing ``Qlib`` from source, you need to install some dependencies:
|
||||
**Note**:
|
||||
1. **Conda** is suggested for managing your Python environment.
|
||||
1. Please pay attention that installing cython in Python 3.6 will raise some error when installing ``Qlib`` from source. If users use Python 3.6 on their machines, it is recommended to *upgrade* Python to version 3.7 or use `conda`'s Python to install ``Qlib`` from source.
|
||||
1. For Python 3.9, `Qlib` supports running workflows such as training models, doing backtest and plot most of the related figures (those included in [notebook](examples/workflow_by_code.ipynb)). However, plotting for the *model performance* is not supported for now and we will fix this when the dependent packages are upgraded in the future.
|
||||
|
||||
### Install with pip
|
||||
Users can easily install ``Qlib`` by pip according to the following command.
|
||||
|
||||
```bash
|
||||
pip install pyqlib
|
||||
```
|
||||
|
||||
**Note**: pip will install the latest stable qlib. However, the main branch of qlib is in active development. If you want to test the latest scripts or functions in the main branch. Please install qlib with the methods below.
|
||||
|
||||
### Install from source
|
||||
Also, users can install the latest dev version ``Qlib`` by the source code according to the following steps:
|
||||
|
||||
* Before installing ``Qlib`` from source, users need to install some dependencies:
|
||||
|
||||
```bash
|
||||
pip install numpy
|
||||
pip install --upgrade cython
|
||||
```
|
||||
|
||||
* Clone the repository and install ``Qlib``:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/microsoft/qlib.git && cd qlib
|
||||
python setup.py install
|
||||
```
|
||||
* Clone the repository and install ``Qlib`` as follows.
|
||||
* If you haven't installed qlib by the command ``pip install pyqlib`` before:
|
||||
```bash
|
||||
git clone https://github.com/microsoft/qlib.git && cd qlib
|
||||
python setup.py install
|
||||
```
|
||||
* If you have already installed the stable version by the command ``pip install pyqlib``:
|
||||
```bash
|
||||
git clone https://github.com/microsoft/qlib.git && cd qlib
|
||||
pip install .
|
||||
```
|
||||
**Note**: **Only** the command ``pip install .`` **can** overwrite the stable version installed by ``pip install pyqlib``, while the command ``python setup.py install`` **can't**.
|
||||
|
||||
**Tips**: If you fail to install `Qlib` or run the examples in your environment, comparing your steps and the [CI workflow](.github/workflows/test.yml) may help you find the problem.
|
||||
|
||||
## Data Preparation
|
||||
Load and prepare data by running the following code:
|
||||
```bash
|
||||
python scripts/get_data.py qlib_data_cn --target_dir ~/.qlib/qlib_data/cn_data
|
||||
# get 1d data
|
||||
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn
|
||||
|
||||
# get 1min data
|
||||
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data_1min --region cn --interval 1min
|
||||
|
||||
```
|
||||
|
||||
This dataset is created by public data collected by [crawler scripts](scripts/data_collector/), which have been released in
|
||||
the same repository.
|
||||
Users could create the same dataset with it.
|
||||
Users could create the same dataset with it.
|
||||
|
||||
*Please pay **ATTENTION** that the data is collected from [Yahoo Finance](https://finance.yahoo.com/lookup), and the data might not be perfect.
|
||||
We recommend users to prepare their own data if they have a high-quality dataset. For more information, users can refer to the [related document](https://qlib.readthedocs.io/en/latest/component/data.html#converting-csv-format-into-qlib-format)*.
|
||||
|
||||
### Automatic update of daily frequency data (from yahoo finance)
|
||||
> It is recommended that users update the data manually once (--trading_date 2021-05-25) and then set it to update automatically.
|
||||
|
||||
> For more information refer to: [yahoo collector](https://github.com/microsoft/qlib/tree/main/scripts/data_collector/yahoo#automatic-update-of-daily-frequency-datafrom-yahoo-finance)
|
||||
|
||||
* Automatic update of data to the "qlib" directory each trading day(Linux)
|
||||
* use *crontab*: `crontab -e`
|
||||
* set up timed tasks:
|
||||
|
||||
```
|
||||
* * * * 1-5 python <script path> update_data_to_bin --qlib_data_1d_dir <user data dir>
|
||||
```
|
||||
* **script path**: *scripts/data_collector/yahoo/collector.py*
|
||||
|
||||
* Manual update of data
|
||||
```
|
||||
python scripts/data_collector/yahoo/collector.py update_data_to_bin --qlib_data_1d_dir <user data dir> --trading_date <start date> --end_date <end date>
|
||||
```
|
||||
* *trading_date*: start of trading day
|
||||
* *end_date*: end of trading day(not included)
|
||||
|
||||
|
||||
<!--
|
||||
- Run the initialization code and get stock data:
|
||||
@@ -107,50 +211,54 @@ Users could create the same dataset with it.
|
||||
-->
|
||||
|
||||
## Auto Quant Research Workflow
|
||||
Qlib provides a tool named `Estimator` to run the whole workflow automatically (including building dataset, training models, backtest and evaluation). You can start an auto quant research workflow and have a graphical reports analysis according to the following steps:
|
||||
Qlib provides a tool named `qrun` to run the whole workflow automatically (including building dataset, training models, backtest and evaluation). You can start an auto quant research workflow and have a graphical reports analysis according to the following steps:
|
||||
|
||||
1. Quant Research Workflow: Run `Estimator` with [estimator_config.yaml](examples/estimator/estimator_config.yaml) as following.
|
||||
1. Quant Research Workflow: Run `qrun` with lightgbm workflow config ([workflow_config_lightgbm_Alpha158.yaml](examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml) as following.
|
||||
```bash
|
||||
cd examples # Avoid running program under the directory contains `qlib`
|
||||
estimator -c estimator/estimator_config.yaml
|
||||
qrun benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml
|
||||
```
|
||||
The result of `Estimator` is as follows, please refer to please refer to [Intraday Trading](https://qlib.readthedocs.io/en/latest/component/backtest.html) for more details about the result.
|
||||
If users want to use `qrun` under debug mode, please use the following command:
|
||||
```bash
|
||||
python -m pdb qlib/workflow/cli.py examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml
|
||||
```
|
||||
The result of `qrun` is as follows, please refer to [Intraday Trading](https://qlib.readthedocs.io/en/latest/component/backtest.html) for more details about the result.
|
||||
|
||||
```bash
|
||||
|
||||
risk
|
||||
excess_return_without_cost mean 0.000605
|
||||
std 0.005481
|
||||
annualized_return 0.152373
|
||||
information_ratio 1.751319
|
||||
max_drawdown -0.059055
|
||||
excess_return_with_cost mean 0.000410
|
||||
std 0.005478
|
||||
annualized_return 0.103265
|
||||
information_ratio 1.187411
|
||||
max_drawdown -0.075024
|
||||
|
||||
|
||||
'The following are analysis results of the excess return without cost.'
|
||||
risk
|
||||
mean 0.000708
|
||||
std 0.005626
|
||||
annualized_return 0.178316
|
||||
information_ratio 1.996555
|
||||
max_drawdown -0.081806
|
||||
'The following are analysis results of the excess return with cost.'
|
||||
risk
|
||||
mean 0.000512
|
||||
std 0.005626
|
||||
annualized_return 0.128982
|
||||
information_ratio 1.444287
|
||||
max_drawdown -0.091078
|
||||
```
|
||||
Here are detailed documents for [Estimator](https://qlib.readthedocs.io/en/latest/component/estimator.html).
|
||||
Here are detailed documents for `qrun` and [workflow](https://qlib.readthedocs.io/en/latest/component/workflow.html).
|
||||
|
||||
2. Graphical Reports Analysis: Run `examples/estimator/analyze_from_estimator.ipynb` with `jupyter notebook` to get graphical reports
|
||||
2. Graphical Reports Analysis: Run `examples/workflow_by_code.ipynb` with `jupyter notebook` to get graphical reports
|
||||
- Forecasting signal (model prediction) analysis
|
||||
- Cumulative Return of groups
|
||||

|
||||

|
||||
- Return distribution
|
||||

|
||||

|
||||
- Information Coefficient (IC)
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
- Auto Correlation of forecasting signal (model prediction)
|
||||

|
||||
|
||||

|
||||
|
||||
- Portfolio analysis
|
||||
- Backtest return
|
||||

|
||||

|
||||
<!--
|
||||
- Score IC
|
||||

|
||||
@@ -161,11 +269,69 @@ Qlib provides a tool named `Estimator` to run the whole workflow automatically (
|
||||
- Rank Label
|
||||

|
||||
-->
|
||||
- [Explanation](https://qlib.readthedocs.io/en/latest/component/report.html) of above results
|
||||
|
||||
## Building Customized Quant Research Workflow by Code
|
||||
The automatic workflow may not suite the research workflow of all Quant researchers. To support a flexible Quant research workflow, Qlib also provides a modularized interface to allow researchers to build their own workflow by code. [Here](examples/train_backtest_analyze.ipynb) is a demo for customized Quant research workflow by code
|
||||
The automatic workflow may not suit the research workflow of all Quant researchers. To support a flexible Quant research workflow, Qlib also provides a modularized interface to allow researchers to build their own workflow by code. [Here](examples/workflow_by_code.ipynb) is a demo for customized Quant research workflow by code.
|
||||
|
||||
|
||||
# [Quant Model (Paper) Zoo](examples/benchmarks)
|
||||
|
||||
Here is a list of models built on `Qlib`.
|
||||
- [GBDT based on XGBoost (Tianqi Chen, et al. KDD 2016)](qlib/contrib/model/xgboost.py)
|
||||
- [GBDT based on LightGBM (Guolin Ke, et al. NIPS 2017)](qlib/contrib/model/gbdt.py)
|
||||
- [GBDT based on Catboost (Liudmila Prokhorenkova, et al. NIPS 2018)](qlib/contrib/model/catboost_model.py)
|
||||
- [MLP based on pytorch](qlib/contrib/model/pytorch_nn.py)
|
||||
- [LSTM based on pytorch (Sepp Hochreiter, et al. Neural omputation 1997)](qlib/contrib/model/pytorch_lstm.py)
|
||||
- [GRU based on pytorch (Kyunghyun Cho, et al. 2014)](qlib/contrib/model/pytorch_gru.py)
|
||||
- [ALSTM based on pytorch (Yao Qin, et al. IJCAI 2017)](qlib/contrib/model/pytorch_alstm.py)
|
||||
- [GATs based on pytorch (Petar Velickovic, et al. 2017)](qlib/contrib/model/pytorch_gats.py)
|
||||
- [SFM based on pytorch (Liheng Zhang, et al. KDD 2017)](qlib/contrib/model/pytorch_sfm.py)
|
||||
- [TFT based on tensorflow (Bryan Lim, et al. International Journal of Forecasting 2019)](examples/benchmarks/TFT/tft.py)
|
||||
- [TabNet based on pytorch (Sercan O. Arik, et al. AAAI 2019)](qlib/contrib/model/pytorch_tabnet.py)
|
||||
- [DoubleEnsemble based on LightGBM (Chuheng Zhang, et al. ICDM 2020)](qlib/contrib/model/double_ensemble.py)
|
||||
- [TCTS based on pytorch (Xueqing Wu, et al. ICML 2021)](qlib/contrib/model/pytorch_tcts.py)
|
||||
- [Transformer based on pytorch (Ashish Vaswani, et al. NeurIPS 2017)](qlib/contrib/model/pytorch_transformer.py)
|
||||
- [Localformer based on pytorch (Juyong Jiang, et al.)](qlib/contrib/model/pytorch_localformer.py)
|
||||
- [TRA based on pytorch (Hengxu, Dong, et al. KDD 2021)](qlib/contrib/model/pytorch_tra.py)
|
||||
|
||||
Your PR of new Quant models is highly welcomed.
|
||||
|
||||
The performance of each model on the `Alpha158` and `Alpha360` dataset can be found [here](examples/benchmarks/README.md).
|
||||
|
||||
## Run a single model
|
||||
All the models listed above are runnable with ``Qlib``. Users can find the config files we provide and some details about the model through the [benchmarks](examples/benchmarks) folder. More information can be retrieved at the model files listed above.
|
||||
|
||||
`Qlib` provides three different ways to run a single model, users can pick the one that fits their cases best:
|
||||
- Users can use the tool `qrun` mentioned above to run a model's workflow based from a config file.
|
||||
- Users can create a `workflow_by_code` python script based on the [one](examples/workflow_by_code.py) listed in the `examples` folder.
|
||||
|
||||
- Users can use the script [`run_all_model.py`](examples/run_all_model.py) listed in the `examples` folder to run a model. Here is an example of the specific shell command to be used: `python run_all_model.py run --models=lightgbm`, where the `--models` arguments can take any number of models listed above(the available models can be found in [benchmarks](examples/benchmarks/)). For more use cases, please refer to the file's [docstrings](examples/run_all_model.py).
|
||||
- **NOTE**: Each baseline has different environment dependencies, please make sure that your python version aligns with the requirements(e.g. TFT only supports Python 3.6~3.7 due to the limitation of `tensorflow==1.15.0`)
|
||||
|
||||
## Run multiple models
|
||||
`Qlib` also provides a script [`run_all_model.py`](examples/run_all_model.py) which can run multiple models for several iterations. (**Note**: the script only support *Linux* for now. Other OS will be supported in the future. Besides, it doesn't support parallel running the same model for multiple times as well, and this will be fixed in the future development too.)
|
||||
|
||||
The script will create a unique virtual environment for each model, and delete the environments after training. Thus, only experiment results such as `IC` and `backtest` results will be generated and stored.
|
||||
|
||||
Here is an example of running all the models for 10 iterations:
|
||||
```python
|
||||
python run_all_model.py run 10
|
||||
```
|
||||
|
||||
It also provides the API to run specific models at once. For more use cases, please refer to the file's [docstrings](examples/run_all_model.py).
|
||||
|
||||
|
||||
# Quant Dataset Zoo
|
||||
Dataset plays a very important role in Quant. Here is a list of the datasets built on `Qlib`:
|
||||
|
||||
| Dataset | US Market | China Market |
|
||||
| -- | -- | -- |
|
||||
| [Alpha360](./qlib/contrib/data/handler.py) | √ | √ |
|
||||
| [Alpha158](./qlib/contrib/data/handler.py) | √ | √ |
|
||||
|
||||
[Here](https://qlib.readthedocs.io/en/latest/advanced/alpha.html) is a tutorial to build dataset with `Qlib`.
|
||||
Your PR to build new Quant dataset is highly welcomed.
|
||||
|
||||
# More About Qlib
|
||||
The detailed documents are organized in [docs](docs/).
|
||||
@@ -183,12 +349,12 @@ Qlib is in active and continuing development. Our plan is in the roadmap, which
|
||||
|
||||
|
||||
|
||||
# Offline Mode and Online Mode of the Data Server
|
||||
The data server of Qlib can either deployed as offline mode or online mode. The default mode is offline mode.
|
||||
# Offline Mode and Online Mode
|
||||
The data server of Qlib can either deployed as `Offline` mode or `Online` mode. The default mode is offline mode.
|
||||
|
||||
Under offline mode, the data will be deployed locally.
|
||||
Under `Offline` mode, the data will be deployed locally.
|
||||
|
||||
Under online mode, the data will be deployed as a shared data service. The data and their cache will be shared by all the clients. The data retrieval performance is expected to be improved due to a higher rate of cache hits. It will consume less disk space, too. The documents of the online mode can be found in [Qlib-Server](https://qlib-server.readthedocs.io/). The online mode can be deployed automatically with [Azure CLI based scripts](https://qlib-server.readthedocs.io/en/latest/build.html#one-click-deployment-in-azure). The source code of online data server can be found in [qlib-server repository](https://github.com/microsoft/qlib-server).
|
||||
Under `Online` mode, the data will be deployed as a shared data service. The data and their cache will be shared by all the clients. The data retrieval performance is expected to be improved due to a higher rate of cache hits. It will consume less disk space, too. The documents of the online mode can be found in [Qlib-Server](https://qlib-server.readthedocs.io/). The online mode can be deployed automatically with [Azure CLI based scripts](https://qlib-server.readthedocs.io/en/latest/build.html#one-click-deployment-in-azure). The source code of online data server can be found in [Qlib-Server repository](https://github.com/microsoft/qlib-server).
|
||||
|
||||
## Performance of Qlib Data Server
|
||||
The performance of data processing is important to data-driven methods like AI technologies. As an AI-oriented platform, Qlib provides a solution for data storage and data processing. To demonstrate the performance of Qlib data server, we
|
||||
@@ -204,17 +370,39 @@ which creates a dataset (14 features/factors) from the basic OHLCV daily data of
|
||||
* `+(-)E` indicates with (out) `ExpressionCache`
|
||||
* `+(-)D` indicates with (out) `DatasetCache`
|
||||
|
||||
Most general-purpose databases take too much time on loading data. After looking into the underlying implementation, we find that data go through too many layers of interfaces and unnecessary format transformations in general-purpose database solutions.
|
||||
Most general-purpose databases take too much time to load data. After looking into the underlying implementation, we find that data go through too many layers of interfaces and unnecessary format transformations in general-purpose database solutions.
|
||||
Such overheads greatly slow down the data loading process.
|
||||
Qlib data are stored in a compact format, which is efficient to be combined into arrays for scientific computation.
|
||||
|
||||
# Related Reports
|
||||
- [Guide To Qlib: Microsoft’s AI Investment Platform](https://analyticsindiamag.com/qlib/)
|
||||
- [微软也搞AI量化平台?还是开源的!](https://mp.weixin.qq.com/s/47bP5YwxfTp2uTHjUBzJQQ)
|
||||
- [微矿Qlib:业内首个AI量化投资开源平台](https://mp.weixin.qq.com/s/vsJv7lsgjEi-ALYUz4CvtQ)
|
||||
|
||||
# Contact Us
|
||||
- If you have any issues, please create issue [here](https://github.com/microsoft/qlib/issues/new/choose) or send messages in [gitter](https://gitter.im/Microsoft/qlib).
|
||||
- If you want to make contributions to `Qlib`, please [create pull requests](https://github.com/microsoft/qlib/compare).
|
||||
- For other reasons, you are welcome to contact us by email([qlib@microsoft.com](mailto:qlib@microsoft.com)).
|
||||
- We are recruiting new members(both FTEs and interns), your resumes are welcome!
|
||||
|
||||
|
||||
Join IM discussion groups:
|
||||
|[Gitter](https://gitter.im/Microsoft/qlib)|
|
||||
|----|
|
||||
||
|
||||
|
||||
# Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
This project welcomes contributions and suggestions.
|
||||
**Here are some
|
||||
[code standards](docs/developer/code_standard.rst) when you submit a pull request.**
|
||||
|
||||
If you want to contribute to Qlib's document, you can follow the steps in the figure below.
|
||||
<p align="center">
|
||||
<img src="https://github.com/demon143/qlib/blob/main/docs/_static/img/change%20doc.gif" />
|
||||
</p>
|
||||
|
||||
|
||||
Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the right to use your contribution. For details, visit https://cla.opensource.microsoft.com.
|
||||
|
||||
|
||||
1
VERSION.txt
Normal file
@@ -0,0 +1 @@
|
||||
0.7.2.99
|
||||
153
docs/FAQ/FAQ.rst
Normal file
@@ -0,0 +1,153 @@
|
||||
|
||||
Qlib FAQ
|
||||
############
|
||||
|
||||
Qlib Frequently Asked Questions
|
||||
================================
|
||||
.. contents::
|
||||
:depth: 1
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
------
|
||||
|
||||
|
||||
1. RuntimeError: An attempt has been made to start a new process before the current process has finished its bootstrapping phase...
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
RuntimeError:
|
||||
An attempt has been made to start a new process before the
|
||||
current process has finished its bootstrapping phase.
|
||||
|
||||
This probably means that you are not using fork to start your
|
||||
child processes and you have forgotten to use the proper idiom
|
||||
in the main module:
|
||||
|
||||
if __name__ == '__main__':
|
||||
freeze_support()
|
||||
...
|
||||
|
||||
The "freeze_support()" line can be omitted if the program
|
||||
is not going to be frozen to produce an executable.
|
||||
|
||||
This is caused by the limitation of multiprocessing under windows OS. Please refer to `here <https://stackoverflow.com/a/24374798>`_ for more info.
|
||||
|
||||
**Solution**: To select a start method you use the ``D.features`` in the if __name__ == '__main__' clause of the main module. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import qlib
|
||||
from qlib.data import D
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
qlib.init()
|
||||
instruments = ["SH600000"]
|
||||
fields = ["$close", "$change"]
|
||||
df = D.features(instruments, fields, start_time='2010-01-01', end_time='2012-12-31')
|
||||
print(df.head())
|
||||
|
||||
|
||||
|
||||
2. qlib.data.cache.QlibCacheException: It sees the key(...) of the redis lock has existed in your redis db now.
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
It sees the key of the redis lock has existed in your redis db now. You can use the following command to clear your redis keys and rerun your commands
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ redis-cli
|
||||
> select 1
|
||||
> flushdb
|
||||
|
||||
If the issue is not resolved, use ``keys *`` to find if multiple keys exist. If so, try using ``flushall`` to clear all the keys.
|
||||
|
||||
.. note::
|
||||
|
||||
``qlib.config.redis_task_db`` defaults is ``1``, users can use ``qlib.init(redis_task_db=<other_db>)`` settings.
|
||||
|
||||
|
||||
Also, feel free to post a new issue in our GitHub repository. We always check each issue carefully and try our best to solve them.
|
||||
|
||||
3. ModuleNotFoundError: No module named 'qlib.data._libs.rolling'
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
#### Do not import qlib package in the repository directory in case of importing qlib from . without compiling #####
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
File "qlib/qlib/__init__.py", line 19, in init
|
||||
from .data.cache import H
|
||||
File "qlib/qlib/data/__init__.py", line 8, in <module>
|
||||
from .data import (
|
||||
File "qlib/qlib/data/data.py", line 20, in <module>
|
||||
from .cache import H
|
||||
File "qlib/qlib/data/cache.py", line 36, in <module>
|
||||
from .ops import Operators
|
||||
File "qlib/qlib/data/ops.py", line 19, in <module>
|
||||
from ._libs.rolling import rolling_slope, rolling_rsquare, rolling_resi
|
||||
ModuleNotFoundError: No module named 'qlib.data._libs.rolling'
|
||||
|
||||
- If the error occurs when importing ``qlib`` package with ``PyCharm`` IDE, users can execute the following command in the project root folder to compile Cython files and generate executable files:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python setup.py build_ext --inplace
|
||||
|
||||
- If the error occurs when importing ``qlib`` package with command ``python`` , users need to change the running directory to ensure that the script does not run in the project directory.
|
||||
|
||||
|
||||
4. BadNamespaceError: / is not a connected namespace
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
File "qlib_online.py", line 35, in <module>
|
||||
cal = D.calendar()
|
||||
File "e:\code\python\microsoft\qlib_latest\qlib\qlib\data\data.py", line 973, in calendar
|
||||
return Cal.calendar(start_time, end_time, freq, future=future)
|
||||
File "e:\code\python\microsoft\qlib_latest\qlib\qlib\data\data.py", line 798, in calendar
|
||||
self.conn.send_request(
|
||||
File "e:\code\python\microsoft\qlib_latest\qlib\qlib\data\client.py", line 101, in send_request
|
||||
self.sio.emit(request_type + "_request", request_content)
|
||||
File "G:\apps\miniconda\envs\qlib\lib\site-packages\python_socketio-5.3.0-py3.8.egg\socketio\client.py", line 369, in emit
|
||||
raise exceptions.BadNamespaceError(
|
||||
BadNamespaceError: / is not a connected namespace.
|
||||
|
||||
- The version of ``python-socketio`` in qlib needs to be the same as the version of ``python-socketio`` in qlib-server:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install -U python-socketio==<qlib-server python-socketio version>
|
||||
|
||||
|
||||
5. TypeError: send() got an unexpected keyword argument 'binary'
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
File "qlib_online.py", line 35, in <module>
|
||||
cal = D.calendar()
|
||||
File "e:\code\python\microsoft\qlib_latest\qlib\qlib\data\data.py", line 973, in calendar
|
||||
return Cal.calendar(start_time, end_time, freq, future=future)
|
||||
File "e:\code\python\microsoft\qlib_latest\qlib\qlib\data\data.py", line 798, in calendar
|
||||
self.conn.send_request(
|
||||
File "e:\code\python\microsoft\qlib_latest\qlib\qlib\data\client.py", line 101, in send_request
|
||||
self.sio.emit(request_type + "_request", request_content)
|
||||
File "G:\apps\miniconda\envs\qlib\lib\site-packages\socketio\client.py", line 263, in emit
|
||||
self._send_packet(packet.Packet(packet.EVENT, namespace=namespace,
|
||||
File "G:\apps\miniconda\envs\qlib\lib\site-packages\socketio\client.py", line 339, in _send_packet
|
||||
self.eio.send(ep, binary=binary)
|
||||
TypeError: send() got an unexpected keyword argument 'binary'
|
||||
|
||||
|
||||
- The ``python-engineio`` version needs to be compatible with the ``python-socketio`` version, reference: https://github.com/miguelgrinberg/python-socketio#version-compatibility
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install -U python-engineio==<compatible python-socketio version>
|
||||
# or
|
||||
pip install -U python-socketio==3.1.2 python-engineio==3.13.2
|
||||
12
docs/_static/demo.sh
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
git clone https://github.com/microsoft/qlib.git
|
||||
cd qlib
|
||||
ls
|
||||
pip install pyqlib
|
||||
# or
|
||||
# pip install numpy
|
||||
# pip install --upgrade cython
|
||||
# python setup.py install
|
||||
cd examples
|
||||
ls
|
||||
qrun benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml
|
||||
BIN
docs/_static/img/analysis/analysis_model_IC.png
vendored
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 37 KiB |
BIN
docs/_static/img/analysis/analysis_model_NDQ.png
vendored
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 15 KiB |
BIN
docs/_static/img/analysis/report.png
vendored
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 45 KiB |
BIN
docs/_static/img/analysis/risk_analysis_bar.png
vendored
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 48 KiB |
BIN
docs/_static/img/analysis/risk_analysis_std.png
vendored
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 44 KiB |
BIN
docs/_static/img/analysis/score_ic.png
vendored
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 93 KiB |
BIN
docs/_static/img/change doc.gif
vendored
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/_static/img/framework.png
vendored
|
Before Width: | Height: | Size: 205 KiB After Width: | Height: | Size: 208 KiB |
4
docs/_static/img/framework.svg
vendored
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
docs/_static/img/online_serving.png
vendored
Normal file
|
After Width: | Height: | Size: 440 KiB |
BIN
docs/_static/img/qrcode/gitter_qr.png
vendored
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
@@ -1,4 +1,5 @@
|
||||
.. _alpha:
|
||||
|
||||
===========================
|
||||
Building Formulaic Alphas
|
||||
===========================
|
||||
@@ -49,56 +50,37 @@ Users can use ``Data Handler`` to build formulaic alphas `MACD` in qlib:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from qlib.contrib.estimator.handler import QLibDataHandler
|
||||
>>> fields = ['(EMA($close, 12) - EMA($close, 26))/$close - EMA((EMA($close, 12) - EMA($close, 26))/$close, 9)/$close'] # MACD
|
||||
>>> names = ['MACD']
|
||||
>>> labels = ['Ref($vwap, -2)/Ref($vwap, -1) - 1'] # label
|
||||
>>> label_names = ['LABEL']
|
||||
>>> data_handler = QLibDataHandler(start_date='2010-01-01', end_date='2017-12-31', fields=fields, names=names, labels=labels, label_names=label_names)
|
||||
>>> TRAINER_CONFIG = {
|
||||
... "train_start_date": "2007-01-01",
|
||||
... "train_end_date": "2014-12-31",
|
||||
... "validate_start_date": "2015-01-01",
|
||||
... "validate_end_date": "2016-12-31",
|
||||
... "test_start_date": "2017-01-01",
|
||||
... "test_end_date": "2020-08-01",
|
||||
... }
|
||||
>>> feature_train, label_train, feature_validate, label_validate, feature_test, label_test = data_handler.get_split_data(**TRAINER_CONFIG)
|
||||
>>> print(feature_train, label_train)
|
||||
MACD
|
||||
instrument datetime
|
||||
SH600004 2012-01-04 -0.030853
|
||||
2012-01-05 -0.030452
|
||||
2012-01-06 -0.028252
|
||||
2012-01-09 -0.024507
|
||||
2012-01-10 -0.019744
|
||||
... ...
|
||||
SZ300273 2014-12-25 0.031339
|
||||
2014-12-26 0.029695
|
||||
2014-12-29 0.025577
|
||||
2014-12-30 0.020493
|
||||
2014-12-31 0.017089
|
||||
|
||||
[605882 rows x 1 columns]
|
||||
label
|
||||
instrument datetime
|
||||
SH600004 2012-01-04 0.003021
|
||||
2012-01-05 0.017434
|
||||
2012-01-06 0.015490
|
||||
2012-01-09 0.002324
|
||||
2012-01-10 -0.002542
|
||||
... ...
|
||||
SZ300273 2014-12-25 -0.032454
|
||||
2014-12-26 -0.016638
|
||||
2014-12-29 0.008263
|
||||
2014-12-30 -0.011985
|
||||
2014-12-31 0.047797
|
||||
|
||||
[605882 rows x 1 columns]
|
||||
>> from qlib.data.dataset.loader import QlibDataLoader
|
||||
>> MACD_EXP = '(EMA($close, 12) - EMA($close, 26))/$close - EMA((EMA($close, 12) - EMA($close, 26))/$close, 9)/$close'
|
||||
>> fields = [MACD_EXP] # MACD
|
||||
>> names = ['MACD']
|
||||
>> labels = ['Ref($close, -2)/Ref($close, -1) - 1'] # label
|
||||
>> label_names = ['LABEL']
|
||||
>> data_loader_config = {
|
||||
.. "feature": (fields, names),
|
||||
.. "label": (labels, label_names)
|
||||
.. }
|
||||
>> data_loader = QlibDataLoader(config=data_loader_config)
|
||||
>> df = data_loader.load(instruments='csi300', start_time='2010-01-01', end_time='2017-12-31')
|
||||
>> print(df)
|
||||
feature label
|
||||
MACD LABEL
|
||||
datetime instrument
|
||||
2010-01-04 SH600000 -0.011547 -0.019672
|
||||
SH600004 0.002745 -0.014721
|
||||
SH600006 0.010133 0.002911
|
||||
SH600008 -0.001113 0.009818
|
||||
SH600009 0.025878 -0.017758
|
||||
... ... ...
|
||||
2017-12-29 SZ300124 0.007306 -0.005074
|
||||
SZ300136 -0.013492 0.056352
|
||||
SZ300144 -0.000966 0.011853
|
||||
SZ300251 0.004383 0.021739
|
||||
SZ300315 -0.030557 0.012455
|
||||
|
||||
Reference
|
||||
===========
|
||||
|
||||
To kown more about ``Data Handler``, please refer to `Data Handler <../component/data.html>`_
|
||||
To learn more about ``Data Loader``, please refer to `Data Loader <../component/data.html#data-loader>`_
|
||||
|
||||
To kown more about ``Data Api``, please refer to `Data Api <../component/data.html>`_
|
||||
To learn more about ``Data API``, please refer to `Data API <../component/data.html>`_
|
||||
|
||||
45
docs/advanced/serial.rst
Normal file
@@ -0,0 +1,45 @@
|
||||
.. _serial:
|
||||
|
||||
=================================
|
||||
Serialization
|
||||
=================================
|
||||
.. currentmodule:: qlib
|
||||
|
||||
Introduction
|
||||
===================
|
||||
``Qlib`` supports dumping the state of ``DataHandler``, ``DataSet``, ``Processor`` and ``Model``, etc. into a disk and reloading them.
|
||||
|
||||
Serializable Class
|
||||
========================
|
||||
|
||||
``Qlib`` provides a base class ``qlib.utils.serial.Serializable``, whose state can be dumped into or loaded from disk in `pickle` format.
|
||||
When users dump the state of a ``Serializable`` instance, the attributes of the instance whose name **does not** start with `_` will be saved on the disk.
|
||||
However, users can use ``config`` method or override ``default_dump_all`` attribute to prevent this feature.
|
||||
|
||||
Users can also override ``pickle_backend`` attribute to choose a pickle backend. The supported value is "pickle" (default and common) and "dill" (dump more things such as function, more information in `here <https://pypi.org/project/dill/>`_).
|
||||
|
||||
Example
|
||||
==========================
|
||||
``Qlib``'s serializable class includes ``DataHandler``, ``DataSet``, ``Processor`` and ``Model``, etc., which are subclass of ``qlib.utils.serial.Serializable``.
|
||||
Specifically, ``qlib.data.dataset.DatasetH`` is one of them. Users can serialize ``DatasetH`` as follows.
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
##=============dump dataset=============
|
||||
dataset.to_pickle(path="dataset.pkl") # dataset is an instance of qlib.data.dataset.DatasetH
|
||||
|
||||
##=============reload dataset=============
|
||||
with open("dataset.pkl", "rb") as file_dataset:
|
||||
dataset = pickle.load(file_dataset)
|
||||
|
||||
.. note::
|
||||
Only state of ``DatasetH`` should be saved on the disk, such as some `mean` and `variance` used for data normalization, etc.
|
||||
|
||||
After reloading the ``DatasetH``, users need to reinitialize it. It means that users can reset some states of ``DatasetH`` or ``QlibDataHandler`` such as `instruments`, `start_time`, `end_time` and `segments`, etc., and generate new data according to the states (data is not state and should not be saved on the disk).
|
||||
|
||||
A more detailed example is in this `link <https://github.com/microsoft/qlib/tree/main/examples/highfreq>`_.
|
||||
|
||||
|
||||
API
|
||||
===================
|
||||
Please refer to `Serializable API <../reference/api.html#module-qlib.utils.serial.Serializable>`_.
|
||||
@@ -1,4 +1,5 @@
|
||||
.. _server:
|
||||
|
||||
=================================
|
||||
``Online`` & ``Offline`` mode
|
||||
=================================
|
||||
|
||||
89
docs/advanced/task_management.rst
Normal file
@@ -0,0 +1,89 @@
|
||||
.. _task_management:
|
||||
|
||||
=================================
|
||||
Task Management
|
||||
=================================
|
||||
.. currentmodule:: qlib
|
||||
|
||||
|
||||
Introduction
|
||||
=============
|
||||
|
||||
The `Workflow <../component/introduction.html>`_ part introduces how to run research workflow in a loosely-coupled way. But it can only execute one ``task`` when you use ``qrun``.
|
||||
To automatically generate and execute different tasks, ``Task Management`` provides a whole process including `Task Generating`_, `Task Storing`_, `Task Training`_ and `Task Collecting`_.
|
||||
With this module, users can run their ``task`` automatically at different periods, in different losses, or even by different models.
|
||||
|
||||
This whole process can be used in `Online Serving <../component/online.html>`_.
|
||||
|
||||
An example of the entire process is shown `here <https://github.com/microsoft/qlib/tree/main/examples/model_rolling/task_manager_rolling.py>`_.
|
||||
|
||||
Task Generating
|
||||
===============
|
||||
A ``task`` consists of `Model`, `Dataset`, `Record`, or anything added by users.
|
||||
The specific task template can be viewed in
|
||||
`Task Section <../component/workflow.html#task-section>`_.
|
||||
Even though the task template is fixed, users can customize their ``TaskGen`` to generate different ``task`` by task template.
|
||||
|
||||
Here is the base class of ``TaskGen``:
|
||||
|
||||
.. autoclass:: qlib.workflow.task.gen.TaskGen
|
||||
:members:
|
||||
|
||||
``Qlib`` provides a class `RollingGen <https://github.com/microsoft/qlib/tree/main/qlib/workflow/task/gen.py>`_ to generate a list of ``task`` of the dataset in different date segments.
|
||||
This class allows users to verify the effect of data from different periods on the model in one experiment. More information is `here <../reference/api.html#TaskGen>`_.
|
||||
|
||||
Task Storing
|
||||
===============
|
||||
To achieve higher efficiency and the possibility of cluster operation, ``Task Manager`` will store all tasks in `MongoDB <https://www.mongodb.com/>`_.
|
||||
``TaskManager`` can fetch undone tasks automatically and manage the lifecycle of a set of tasks with error handling.
|
||||
Users **MUST** finish the configuration of `MongoDB <https://www.mongodb.com/>`_ when using this module.
|
||||
|
||||
Users need to provide the MongoDB URL and database name for using ``TaskManager`` in `initialization <../start/initialization.html#Parameters>`_ or make a statement like this.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from qlib.config import C
|
||||
C["mongo"] = {
|
||||
"task_url" : "mongodb://localhost:27017/", # your MongoDB url
|
||||
"task_db_name" : "rolling_db" # database name
|
||||
}
|
||||
|
||||
.. autoclass:: qlib.workflow.task.manage.TaskManager
|
||||
:members:
|
||||
|
||||
More information of ``Task Manager`` can be found in `here <../reference/api.html#TaskManager>`_.
|
||||
|
||||
Task Training
|
||||
===============
|
||||
After generating and storing those ``task``, it's time to run the ``task`` which is in the *WAITING* status.
|
||||
``Qlib`` provides a method called ``run_task`` to run those ``task`` in task pool, however, users can also customize how tasks are executed.
|
||||
An easy way to get the ``task_func`` is using ``qlib.model.trainer.task_train`` directly.
|
||||
It will run the whole workflow defined by ``task``, which includes *Model*, *Dataset*, *Record*.
|
||||
|
||||
.. autofunction:: qlib.workflow.task.manage.run_task
|
||||
|
||||
Meanwhile, ``Qlib`` provides a module called ``Trainer``.
|
||||
|
||||
.. autoclass:: qlib.model.trainer.Trainer
|
||||
:members:
|
||||
|
||||
``Trainer`` will train a list of tasks and return a list of model recorders.
|
||||
``Qlib`` offer two kinds of Trainer, TrainerR is the simplest way and TrainerRM is based on TaskManager to help manager tasks lifecycle automatically.
|
||||
If you do not want to use ``Task Manager`` to manage tasks, then use TrainerR to train a list of tasks generated by ``TaskGen`` is enough.
|
||||
`Here <../reference/api.html#Trainer>`_ are the details about different ``Trainer``.
|
||||
|
||||
Task Collecting
|
||||
===============
|
||||
To collect the results of ``task`` after training, ``Qlib`` provides `Collector <../reference/api.html#Collector>`_, `Group <../reference/api.html#Group>`_ and `Ensemble <../reference/api.html#Ensemble>`_ to collect the results in a readable, expandable and loosely-coupled way.
|
||||
|
||||
`Collector <../reference/api.html#Collector>`_ can collect objects from everywhere and process them such as merging, grouping, averaging and so on. It has 2 step action including ``collect`` (collect anything in a dict) and ``process_collect`` (process collected dict).
|
||||
|
||||
`Group <../reference/api.html#Group>`_ also has 2 steps including ``group`` (can group a set of object based on `group_func` and change them to a dict) and ``reduce`` (can make a dict become an ensemble based on some rule).
|
||||
For example: {(A,B,C1): object, (A,B,C2): object} ---``group``---> {(A,B): {C1: object, C2: object}} ---``reduce``---> {(A,B): object}
|
||||
|
||||
`Ensemble <../reference/api.html#Ensemble>`_ can merge the objects in an ensemble.
|
||||
For example: {C1: object, C2: object} ---``Ensemble``---> object
|
||||
|
||||
So the hierarchy is ``Collector``'s second step corresponds to ``Group``. And ``Group``'s second step correspond to ``Ensemble``.
|
||||
|
||||
For more information, please see `Collector <../reference/api.html#Collector>`_, `Group <../reference/api.html#Group>`_ and `Ensemble <../reference/api.html#Ensemble>`_, or the `example <https://github.com/microsoft/qlib/tree/main/examples/model_rolling/task_manager_rolling.py>`_.
|
||||
@@ -1,4 +1,5 @@
|
||||
.. _backtest:
|
||||
|
||||
============================================
|
||||
Intraday Trading: Model&Strategy Testing
|
||||
============================================
|
||||
@@ -12,7 +13,7 @@ Introduction
|
||||
|
||||
.. note::
|
||||
|
||||
``Intraday Trading`` uses ``Order Executor`` to trade and execute orders output by ``Interday Strategy``. ``Order Executor`` is a component in `Qlib Framework <../introduction/introduction.html#framework>`_, which can execute orders. ``Vwap Executor`` and ``Close Executor`` is supported by ``Qlib`` now. In the future, ``Qlib`` will support ``HighFreq Executor`` also.
|
||||
``Intraday Trading`` uses ``Order Executor`` to trade and execute orders output by ``Portfolio Strategy``. ``Order Executor`` is a component in `Qlib Framework <../introduction/introduction.html#framework>`_, which can execute orders. ``VWAP Executor`` and ``Close Executor`` is supported by ``Qlib`` now. In the future, ``Qlib`` will support ``HighFreq Executor`` also.
|
||||
|
||||
|
||||
|
||||
@@ -29,36 +30,36 @@ The simple example of the default strategy is as follows.
|
||||
|
||||
from qlib.contrib.evaluate import backtest
|
||||
# pred_score is the prediction score
|
||||
report, positions = backtest(pred_score, topk=50, n_drop=0.5, verbose=False, limit_threshold=0.0095)
|
||||
report, positions = backtest(pred_score, topk=50, n_drop=0.5, limit_threshold=0.0095)
|
||||
|
||||
To know more about backtesting with a specific strategy, please refer to `Strategy <strategy.html>`_.
|
||||
To know more about backtesting with a specific ``Strategy``, please refer to `Portfolio Strategy <strategy.html>`_.
|
||||
|
||||
To know more about the prediction score `pred_score` output by ``Model``, please refer to `Interday Model: Model Training & Prediction <model.html>`_.
|
||||
To know more about the prediction score `pred_score` output by ``Forecast Model``, please refer to `Forecast Model: Model Training & Prediction <model.html>`_.
|
||||
|
||||
Prediction Score
|
||||
-----------------
|
||||
|
||||
The `prediction score` is a pandas DataFrame. Its index is <instrument(str), datetime(pd.Timestamp)> and it must
|
||||
The `prediction score` is a pandas DataFrame. Its index is <datetime(pd.Timestamp), instrument(str)> and it must
|
||||
contains a `score` column.
|
||||
|
||||
A prediction sample is shown as follows.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
instrument datetime score
|
||||
SH600000 2019-01-04 -0.505488
|
||||
SZ002531 2019-01-04 -0.320391
|
||||
SZ000999 2019-01-04 0.583808
|
||||
SZ300569 2019-01-04 0.819628
|
||||
SZ001696 2019-01-04 -0.137140
|
||||
... ...
|
||||
SZ000996 2019-04-30 -1.027618
|
||||
SH603127 2019-04-30 0.225677
|
||||
SH603126 2019-04-30 0.462443
|
||||
SH603133 2019-04-30 -0.302460
|
||||
SZ300760 2019-04-30 -0.126383
|
||||
datetime instrument score
|
||||
2019-01-04 SH600000 -0.505488
|
||||
2019-01-04 SZ002531 -0.320391
|
||||
2019-01-04 SZ000999 0.583808
|
||||
2019-01-04 SZ300569 0.819628
|
||||
2019-01-04 SZ001696 -0.137140
|
||||
... ...
|
||||
2019-04-30 SZ000996 -1.027618
|
||||
2019-04-30 SH603127 0.225677
|
||||
2019-04-30 SH603126 0.462443
|
||||
2019-04-30 SH603133 -0.302460
|
||||
2019-04-30 SZ300760 -0.126383
|
||||
|
||||
``Model`` module can make predictions, please refer to `Model <model.html>`_.
|
||||
``Forecast Model`` module can make predictions, please refer to `Forecast Model: Model Training & Prediction <model.html>`_.
|
||||
|
||||
Backtest Result
|
||||
------------------
|
||||
@@ -110,4 +111,4 @@ The backtest results are in the following form:
|
||||
Reference
|
||||
==============
|
||||
|
||||
To know more about ``Intraday Trading``, please refer to `Backtest API <../reference/api.html>`_.
|
||||
To know more about ``Intraday Trading``, please refer to `Intraday Trading <../reference/api.html#module-qlib.contrib.evaluate>`_.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
.. _data:
|
||||
|
||||
================================
|
||||
Data Layer: Data Framework&Usage
|
||||
Data Layer: Data Framework & Usage
|
||||
================================
|
||||
|
||||
Introduction
|
||||
@@ -14,7 +15,9 @@ The introduction of ``Data Layer`` includes the following parts.
|
||||
|
||||
- Data Preparation
|
||||
- Data API
|
||||
- Data Loader
|
||||
- Data Handler
|
||||
- Dataset
|
||||
- Cache
|
||||
- Data and Cache File Structure
|
||||
|
||||
@@ -26,68 +29,187 @@ Qlib Format Data
|
||||
------------------
|
||||
|
||||
We've specially designed a data structure to manage financial data, please refer to the `File storage design section in Qlib paper <https://arxiv.org/abs/2009.11189>`_ for detailed information.
|
||||
Such data will be stored with filename suffix `.bin` (We'll call them `.bin` file, `.bin` format or qlib format). `.bin` file is designed for scientific computing on finance data
|
||||
Such data will be stored with filename suffix `.bin` (We'll call them `.bin` file, `.bin` format, or qlib format). `.bin` file is designed for scientific computing on finance data.
|
||||
|
||||
``Qlib`` provides two different off-the-shelf datasets, which can be accessed through this `link <https://github.com/microsoft/qlib/blob/main/qlib/contrib/data/handler.py>`_:
|
||||
|
||||
======================== ================= ================
|
||||
Dataset US Market China Market
|
||||
======================== ================= ================
|
||||
Alpha360 √ √
|
||||
|
||||
Alpha158 √ √
|
||||
======================== ================= ================
|
||||
|
||||
Also, ``Qlib`` provides a high-frequency dataset. Users can run a high-frequency dataset example through this `link <https://github.com/microsoft/qlib/tree/main/examples/highfreq>`_.
|
||||
|
||||
Qlib Format Dataset
|
||||
--------------------
|
||||
``Qlib`` has provided an off-the-shelf dataset in `.bin` format, users could use the script ``scripts/get_data.py`` to download the dataset as follows.
|
||||
``Qlib`` has provided an off-the-shelf dataset in `.bin` format, users could use the script ``scripts/get_data.py`` to download the China-Stock dataset as follows.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python scripts/get_data.py qlib_data_cn --target_dir ~/.qlib/qlib_data/cn_data
|
||||
# download 1d
|
||||
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn
|
||||
|
||||
After running the above command, users can find china-stock data in Qlib format in the ``~/.qlib/csv_data/cn_data`` directory.
|
||||
# download 1min
|
||||
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/qlib_cn_1min --region cn --interval 1min
|
||||
|
||||
In addition to China-Stock data, ``Qlib`` also includes a US-Stock dataset, which can be downloaded with the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/us_data --region us
|
||||
|
||||
After running the above command, users can find china-stock and us-stock data in ``Qlib`` format in the ``~/.qlib/qlib_data/cn_data`` directory and ``~/.qlib/qlib_data/us_data`` directory respectively.
|
||||
|
||||
``Qlib`` also provides the scripts in ``scripts/data_collector`` to help users crawl the latest data on the Internet and convert it to qlib format.
|
||||
|
||||
When ``Qlib`` is initialized with this dataset, users could build and evaluate their own models with it. Please refer to `Initialization <../start/initialization.html>`_ for more details.
|
||||
|
||||
Automatic update of daily frequency data
|
||||
----------------------------------------
|
||||
|
||||
**It is recommended that users update the data manually once (\-\-trading_date 2021-05-25) and then set it to update automatically.**
|
||||
|
||||
For more information refer to: `yahoo collector <https://github.com/microsoft/qlib/tree/main/scripts/data_collector/yahoo#Automatic-update-of-daily-frequency-data>`_
|
||||
|
||||
- Automatic update of data to the "qlib" directory each trading day(Linux)
|
||||
- use *crontab*: `crontab -e`
|
||||
- set up timed tasks:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
* * * * 1-5 python <script path> update_data_to_bin --qlib_data_1d_dir <user data dir>
|
||||
|
||||
- **script path**: *scripts/data_collector/yahoo/collector.py*
|
||||
|
||||
- Manual update of data
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python scripts/data_collector/yahoo/collector.py update_data_to_bin --qlib_data_1d_dir <user data dir> --trading_date <start date> --end_date <end date>
|
||||
|
||||
- *trading_date*: start of trading day
|
||||
- *end_date*: end of trading day(not included)
|
||||
|
||||
|
||||
|
||||
Converting CSV Format into Qlib Format
|
||||
-------------------------------------------
|
||||
|
||||
``Qlib`` has provided the script ``scripts/dump_bin.py`` to convert data in CSV format into `.bin` files(Qlib format).
|
||||
``Qlib`` has provided the script ``scripts/dump_bin.py`` to convert **any** data in CSV format into `.bin` files (``Qlib`` format) as long as they are in the correct format.
|
||||
|
||||
Besides downloading the prepared demo data, users could download demo data directly from the Collector as follows for reference to the CSV format.
|
||||
Here are some example:
|
||||
|
||||
Users can download the china-stock data in CSV format as follows for reference to the CSV format.
|
||||
|
||||
.. code-block:: bash
|
||||
for daily data:
|
||||
.. code-block:: bash
|
||||
|
||||
python scripts/get_data.py csv_data_cn --target_dir ~/.qlib/csv_data/cn_data
|
||||
|
||||
for 1min data:
|
||||
.. code-block:: bash
|
||||
|
||||
python scripts/data_collector/yahoo/collector.py download_data --source_dir ~/.qlib/stock_data/source/cn_1min --region CN --start 2021-05-20 --end 2021-05-23 --delay 0.1 --interval 1min --limit_nums 10
|
||||
|
||||
Users can also provide their own data in CSV format. However, the CSV data **must satisfies** following criterions:
|
||||
|
||||
- CSV file is named after a specific stock *or* the CSV file includes a column of the stock name
|
||||
|
||||
- Name the CSV file after a stock: `SH600000.csv`, `AAPL.csv` (not case sensitive).
|
||||
|
||||
- CSV file includes a column of the stock name. User **must** specify the column name when dumping the data. Here is an example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python scripts/dump_bin.py dump_all ... --symbol_field_name symbol
|
||||
|
||||
where the data are in the following format:
|
||||
|
||||
.. code-block::
|
||||
|
||||
symbol,close
|
||||
SH600000,120
|
||||
|
||||
- CSV file **must** includes a column for the date, and when dumping the data, user must specify the date column name. Here is an example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python scripts/dump_bin.py dump_all ... --date_field_name date
|
||||
|
||||
where the data are in the following format:
|
||||
|
||||
.. code-block::
|
||||
|
||||
symbol,date,close,open,volume
|
||||
SH600000,2020-11-01,120,121,12300000
|
||||
SH600000,2020-11-02,123,120,12300000
|
||||
|
||||
|
||||
Supposed that users prepare their CSV format data in the directory ``~/.qlib/csv_data/my_data``, they can run the following command to start the conversion.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python scripts/dump_bin.py dump --csv_path ~/.qlib/csv_data/my_data --qlib_dir ~/.qlib/qlib_data/my_data --include_fields open,close,high,low,volume,factor
|
||||
python scripts/dump_bin.py dump_all --csv_path ~/.qlib/csv_data/my_data --qlib_dir ~/.qlib/qlib_data/my_data --include_fields open,close,high,low,volume,factor
|
||||
|
||||
For other supported parameters when dumping the data into `.bin` file, users can refer to the information by running the following commands:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python dump_bin.py dump_all --help
|
||||
|
||||
After conversion, users can find their Qlib format data in the directory `~/.qlib/qlib_data/my_data`.
|
||||
|
||||
.. note::
|
||||
|
||||
The arguments of `--include_fields` should correspond with the columns names of CSV files. The columns names of dataset provided by ``Qlib`` includes open,close,high,low,volume,factor.
|
||||
The arguments of `--include_fields` should correspond with the column names of CSV files. The columns names of dataset provided by ``Qlib`` should include open, close, high, low, volume and factor at least.
|
||||
|
||||
- `open`
|
||||
The opening price
|
||||
The adjusted opening price
|
||||
- `close`
|
||||
The closing price
|
||||
The adjusted closing price
|
||||
- `high`
|
||||
The highest price
|
||||
The adjusted highest price
|
||||
- `low`
|
||||
The lowest price
|
||||
The adjusted lowest price
|
||||
- `volume`
|
||||
The trading volume
|
||||
The adjusted trading volume
|
||||
- `factor`
|
||||
The Restoration factor
|
||||
The Restoration factor. Normally, ``factor = adjusted_price / original_price``, `adjusted price` reference: `split adjusted <https://www.investopedia.com/terms/s/splitadjusted.asp>`_
|
||||
|
||||
In the convention of `Qlib` data processing, `open, close, high, low, volume, money and factor` will be set to NaN if the stock is suspended.
|
||||
If you want to use your own alpha-factor which can't be calculate by OCHLV, like PE, EPS and so on, you could add it to the CSV files with OHCLV together and then dump it to the Qlib format data.
|
||||
|
||||
China-Stock Mode & US-Stock Mode
|
||||
Stock Pool (Market)
|
||||
--------------------------------
|
||||
|
||||
``Qlib`` defines `stock pool <https://github.com/microsoft/qlib/blob/main/examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml#L4>`_ as stock list and their date ranges. Predefined stock pools (e.g. csi300) may be imported as follows.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python collector.py --index_name CSI300 --qlib_dir <user qlib data dir> --method parse_instruments
|
||||
|
||||
|
||||
Multiple Stock Modes
|
||||
--------------------------------
|
||||
|
||||
``Qlib`` now provides two different stock modes for users: China-Stock Mode & US-Stock Mode. Here are some different settings of these two modes:
|
||||
|
||||
============== ================= ================
|
||||
Region Trade Unit Limit Threshold
|
||||
============== ================= ================
|
||||
China 100 0.099
|
||||
|
||||
US 1 None
|
||||
============== ================= ================
|
||||
|
||||
The `trade unit` defines the unit number of stocks can be used in a trade, and the `limit threshold` defines the bound set to the percentage of ups and downs of a stock.
|
||||
|
||||
- If users use ``Qlib`` in china-stock mode, china-stock data is required. Users can use ``Qlib`` in china-stock mode according to the following steps:
|
||||
- Download china-stock in qlib format, please refer to section `Qlib Format Dataset <#qlib-format-dataset>`_.
|
||||
- Initialize ``Qlib`` in china-stock mode
|
||||
Supposed that users download their Qlib format data in the directory ``~/.qlib/csv_data/cn_data``. Users only need to initialize ``Qlib`` as follows.
|
||||
Supposed that users download their Qlib format data in the directory ``~/.qlib/qlib_data/cn_data``. Users only need to initialize ``Qlib`` as follows.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -95,11 +217,10 @@ China-Stock Mode & US-Stock Mode
|
||||
qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region=REG_CN)
|
||||
|
||||
|
||||
- If users use ``Qlib`` in US-stock mode, US-stock data is required. ``Qlib`` does not provide a script to download US-stock data. Users can use ``Qlib`` in US-stock mode according to the following steps:
|
||||
- Prepare data in CSV format
|
||||
- Convert data from CSV format to Qlib format, please refer to section `Converting CSV Format into Qlib Format <#converting-csv-format-into-qlib-format>`_.
|
||||
- If users use ``Qlib`` in US-stock mode, US-stock data is required. ``Qlib`` also provides a script to download US-stock data. Users can use ``Qlib`` in US-stock mode according to the following steps:
|
||||
- Download us-stock in qlib format, please refer to section `Qlib Format Dataset <#qlib-format-dataset>`_.
|
||||
- Initialize ``Qlib`` in US-stock mode
|
||||
Supposed that users prepare their Qlib format data in the directory ``~/.qlib/csv_data/us_data``. Users only need to initialize ``Qlib`` as follows.
|
||||
Supposed that users prepare their Qlib format data in the directory ``~/.qlib/qlib_data/us_data``. Users only need to initialize ``Qlib`` as follows.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -107,6 +228,11 @@ China-Stock Mode & US-Stock Mode
|
||||
qlib.init(provider_uri='~/.qlib/qlib_data/us_data', region=REG_US)
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
PRs for new data source are highly welcome! Users could commit the code to crawl data as a PR like `the examples here <https://github.com/microsoft/qlib/tree/main/scripts>`_. And then we will use the code to create data cache on our server which other users could use directly.
|
||||
|
||||
|
||||
Data API
|
||||
========================
|
||||
|
||||
@@ -124,9 +250,10 @@ Feature
|
||||
|
||||
- `ExpressionOps`
|
||||
`ExpressionOps` will use operator for feature construction.
|
||||
To know more about ``Operator``, please refer to `Operator API <../reference/api.html>`_.
|
||||
To know more about ``Operator``, please refer to `Operator API <../reference/api.html#module-qlib.data.ops>`_.
|
||||
Also, ``Qlib`` supports users to define their own custom ``Operator``, an example has been given in ``tests/test_register_ops.py``.
|
||||
|
||||
To know more about ``Feature``, please refer to `Feature API <../reference/api.html>`_.
|
||||
To know more about ``Feature``, please refer to `Feature API <../reference/api.html#module-qlib.data.base>`_.
|
||||
|
||||
Filter
|
||||
-------------------
|
||||
@@ -139,123 +266,189 @@ Filter
|
||||
Expression dynamic instrument filter. Filter the instruments based on a certain expression. An expression rule indicating a certain feature field is required.
|
||||
|
||||
- `basic features filter`: rule_expression = '$close/$open>5'
|
||||
- `cross-sectional features filter` : rule_expression = '$rank($close)<10'
|
||||
- `cross-sectional features filter` \: rule_expression = '$rank($close)<10'
|
||||
- `time-sequence features filter`: rule_expression = '$Ref($close, 3)>100'
|
||||
|
||||
To know more about ``Filter``, please refer to `Filter API <../reference/api.html>`_.
|
||||
Here is a simple example showing how to use filter in a basic ``Qlib`` workflow configuration file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
API
|
||||
filter: &filter
|
||||
filter_type: ExpressionDFilter
|
||||
rule_expression: "Ref($close, -2) / Ref($close, -1) > 1"
|
||||
filter_start_time: 2010-01-01
|
||||
filter_end_time: 2010-01-07
|
||||
keep: False
|
||||
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2010-01-01
|
||||
end_time: 2021-01-22
|
||||
fit_start_time: 2010-01-01
|
||||
fit_end_time: 2015-12-31
|
||||
instruments: *market
|
||||
filter_pipe: [*filter]
|
||||
|
||||
To know more about ``Filter``, please refer to `Filter API <../reference/api.html#module-qlib.data.filter>`_.
|
||||
|
||||
Reference
|
||||
-------------
|
||||
|
||||
To know more about ``Data API``, please refer to `Data API <../reference/api.html>`_.
|
||||
To know more about ``Data API``, please refer to `Data API <../reference/api.html#data>`_.
|
||||
|
||||
|
||||
Data Loader
|
||||
=================
|
||||
|
||||
``Data Loader`` in ``Qlib`` is designed to load raw data from the original data source. It will be loaded and used in the ``Data Handler`` module.
|
||||
|
||||
QlibDataLoader
|
||||
---------------
|
||||
|
||||
The ``QlibDataLoader`` class in ``Qlib`` is such an interface that allows users to load raw data from the ``Qlib`` data source.
|
||||
|
||||
StaticDataLoader
|
||||
---------------
|
||||
|
||||
The ``StaticDataLoader`` class in ``Qlib`` is such an interface that allows users to load raw data from file or as provided.
|
||||
|
||||
|
||||
Interface
|
||||
------------
|
||||
|
||||
Here are some interfaces of the ``QlibDataLoader`` class:
|
||||
|
||||
.. autoclass:: qlib.data.dataset.loader.DataLoader
|
||||
:members:
|
||||
|
||||
API
|
||||
-----------
|
||||
|
||||
To know more about ``Data Loader``, please refer to `Data Loader API <../reference/api.html#module-qlib.data.dataset.loader>`_.
|
||||
|
||||
|
||||
Data Handler
|
||||
=================
|
||||
|
||||
Users can use ``Data Handler`` in an automatic workflow by ``Estimator``, refer to `Estimator <estimator.html>`_ for more details.
|
||||
The ``Data Handler`` module in ``Qlib`` is designed to handler those common data processing methods which will be used by most of the models.
|
||||
|
||||
Also, ``Data Handler`` can be used as an independent module, by which users can easily preprocess data(standardization, remove NaN, etc.) and build datasets. It is a subclass of ``qlib.contrib.estimator.handler.BaseDataHandler``, which provides some interfaces as follows.
|
||||
Users can use ``Data Handler`` in an automatic workflow by ``qrun``, refer to `Workflow: Workflow Management <workflow.html>`_ for more details.
|
||||
|
||||
Base Class & Interface
|
||||
----------------------
|
||||
|
||||
Qlib provides a base class `qlib.contrib.estimator.BaseDataHandler <../reference/api.html#class-qlib.contrib.estimator.BaseDataHandler>`_, which provides the following interfaces:
|
||||
|
||||
- `setup_feature`
|
||||
Implement the interface to load the data features.
|
||||
|
||||
- `setup_label`
|
||||
Implement the interface to load the data labels and calculate the users' labels.
|
||||
|
||||
- `setup_processed_data`
|
||||
Implement the interface for data preprocessing, such as preparing feature columns, discarding blank lines, and so on.
|
||||
|
||||
Qlib also provides two functions to help users init the data handler, users can override them for users' needs.
|
||||
|
||||
- `_init_kwargs`
|
||||
Users can init the kwargs of the data handler in this function, some kwargs may be used when init the raw df.
|
||||
Kwargs are the other attributes in data.args, like dropna_label, dropna_feature
|
||||
|
||||
- `_init_raw_df`
|
||||
Users can init the raw df, feature names, and label names of data handler in this function.
|
||||
If the index of feature df and label df are not same, users need to override this method to merge them (e.g. inner, left, right merge).
|
||||
|
||||
If users want to load features and labels by config, users can inherit ``qlib.contrib.estimator.handler.ConfigDataHandler``, ``Qlib`` also have provided some preprocess method in this subclass.
|
||||
If users want to use qlib data, `QLibDataHandler` is recommended. Users can inherit their custom class from `QLibDataHandler`, which is also a subclass of `ConfigDataHandler`.
|
||||
|
||||
|
||||
Usage
|
||||
DataHandlerLP
|
||||
--------------
|
||||
|
||||
``Data Handler`` can be used as a single module, which provides the following mehtods:
|
||||
In addition to use ``Data Handler`` in an automatic workflow with ``qrun``, ``Data Handler`` can be used as an independent module, by which users can easily preprocess data (standardization, remove NaN, etc.) and build datasets.
|
||||
|
||||
- `get_split_data`
|
||||
- According to the start and end dates, return features and labels of the pandas DataFrame type used for the 'Model'
|
||||
|
||||
- `get_rolling_data`
|
||||
- According to the start and end dates, and `rolling_period`, an iterator is returned, which can be used to traverse the features and labels used for rolling.
|
||||
In order to achieve so, ``Qlib`` provides a base class `qlib.data.dataset.DataHandlerLP <../reference/api.html#qlib.data.dataset.handler.DataHandlerLP>`_. The core idea of this class is that: we will have some leanable ``Processors`` which can learn the parameters of data processing(e.g., parameters for zscore normalization). When new data comes in, these `trained` ``Processors`` can then process the new data and thus processing real-time data in an efficient way becomes possible. More information about ``Processors`` will be listed in the next subsection.
|
||||
|
||||
|
||||
Interface
|
||||
----------------------
|
||||
|
||||
Here are some important interfaces that ``DataHandlerLP`` provides:
|
||||
|
||||
.. autoclass:: qlib.data.dataset.handler.DataHandlerLP
|
||||
:members: __init__, fetch, get_cols
|
||||
|
||||
|
||||
If users want to load features and labels by config, users can define a new handler and call the static method `parse_config_to_fields` of ``qlib.contrib.data.handler.Alpha158``.
|
||||
|
||||
Also, users can pass ``qlib.contrib.data.processor.ConfigSectionProcessor`` that provides some preprocess methods for features defined by config into the new handler.
|
||||
|
||||
|
||||
Processor
|
||||
----------
|
||||
|
||||
The ``Processor`` module in ``Qlib`` is designed to be learnable and it is responsible for handling data processing such as `normalization` and `drop none/nan features/labels`.
|
||||
|
||||
``Qlib`` provides the following ``Processors``:
|
||||
|
||||
- ``DropnaProcessor``: `processor` that drops N/A features.
|
||||
- ``DropnaLabel``: `processor` that drops N/A labels.
|
||||
- ``TanhProcess``: `processor` that uses `tanh` to process noise data.
|
||||
- ``ProcessInf``: `processor` that handles infinity values, it will be replaces by the mean of the column.
|
||||
- ``Fillna``: `processor` that handles N/A values, which will fill the N/A value by 0 or other given number.
|
||||
- ``MinMaxNorm``: `processor` that applies min-max normalization.
|
||||
- ``ZscoreNorm``: `processor` that applies z-score normalization.
|
||||
- ``RobustZScoreNorm``: `processor` that applies robust z-score normalization.
|
||||
- ``CSZScoreNorm``: `processor` that applies cross sectional z-score normalization.
|
||||
- ``CSRankNorm``: `processor` that applies cross sectional rank normalization.
|
||||
- ``CSZFillna``: `processor` that fills N/A values in a cross sectional way by the mean of the column.
|
||||
|
||||
Users can also create their own `processor` by inheriting the base class of ``Processor``. Please refer to the implementation of all the processors for more information (`Processor Link <https://github.com/microsoft/qlib/blob/main/qlib/data/dataset/processor.py>`_).
|
||||
|
||||
To know more about ``Processor``, please refer to `Processor API <../reference/api.html#module-qlib.data.dataset.processor>`_.
|
||||
|
||||
Example
|
||||
--------------
|
||||
|
||||
``Data Handler`` can be run with ``estimator`` by modifying the configuration file, and can also be used as a single module.
|
||||
``Data Handler`` can be run with ``qrun`` by modifying the configuration file, and can also be used as a single module.
|
||||
|
||||
Know more about how to run ``Data Handler`` with ``estimator``, please refer to `Estimator <estimator.html#about-data>`_.
|
||||
Know more about how to run ``Data Handler`` with ``qrun``, please refer to `Workflow: Workflow Management <workflow.html>`_
|
||||
|
||||
Qlib provides implemented data handler `QLibDataHandlerClose`. The following example shows how to run `QLibDataHandlerV1` as a single module.
|
||||
Qlib provides implemented data handler `Alpha158`. The following example shows how to run `Alpha158` as a single module.
|
||||
|
||||
.. note:: Users need to initialize ``Qlib`` with `qlib.init` first, please refer to `initialization <../start/initialization.html>`_.
|
||||
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
from qlib.contrib.estimator.handler import QLibDataHandlerClose
|
||||
from qlib.contrib.model.gbdt import LGBModel
|
||||
import qlib
|
||||
from qlib.contrib.data.handler import Alpha158
|
||||
|
||||
DATA_HANDLER_CONFIG = {
|
||||
"dropna_label": True,
|
||||
"start_date": "2007-01-01",
|
||||
"end_date": "2020-08-01",
|
||||
"market": "csi300",
|
||||
data_handler_config = {
|
||||
"start_time": "2008-01-01",
|
||||
"end_time": "2020-08-01",
|
||||
"fit_start_time": "2008-01-01",
|
||||
"fit_end_time": "2014-12-31",
|
||||
"instruments": "csi300",
|
||||
}
|
||||
|
||||
TRAINER_CONFIG = {
|
||||
"train_start_date": "2007-01-01",
|
||||
"train_end_date": "2014-12-31",
|
||||
"validate_start_date": "2015-01-01",
|
||||
"validate_end_date": "2016-12-31",
|
||||
"test_start_date": "2017-01-01",
|
||||
"test_end_date": "2020-08-01",
|
||||
}
|
||||
if __name__ == "__main__":
|
||||
qlib.init()
|
||||
h = Alpha158(**data_handler_config)
|
||||
|
||||
exampleDataHandler = QLibDataHandlerClose(**DATA_HANDLER_CONFIG)
|
||||
# get all the columns of the data
|
||||
print(h.get_cols())
|
||||
|
||||
# example of 'get_split_data'
|
||||
x_train, y_train, x_validate, y_validate, x_test, y_test = exampleDataHandler.get_split_data(**TRAINER_CONFIG)
|
||||
# fetch all the labels
|
||||
print(h.fetch(col_set="label"))
|
||||
|
||||
# example of 'get_rolling_data'
|
||||
|
||||
for (x_train, y_train, x_validate, y_validate, x_test, y_test) in exampleDataHandler.get_rolling_data(**TRAINER_CONFIG):
|
||||
print(x_train, y_train, x_validate, y_validate, x_test, y_test)
|
||||
# fetch all the features
|
||||
print(h.fetch(col_set="feature"))
|
||||
|
||||
|
||||
.. note:: (x_train, y_train, x_validate, y_validate, x_test, y_test) can be used as arguments for the ``fit``, ``predict``, and ``score`` methods of the 'Model' , please refer to `Model <model.html#Interface>`_.
|
||||
|
||||
Also, the above example has been given in ``examples.estimator.train_backtest_analyze.ipynb``.
|
||||
.. note:: In the ``Alpha158``, ``Qlib`` uses the label `Ref($close, -2)/Ref($close, -1) - 1` that means the change from T+1 to T+2, rather than `Ref($close, -1)/$close - 1`, of which the reason is that when getting the T day close price of a china stock, the stock can be bought on T+1 day and sold on T+2 day.
|
||||
|
||||
API
|
||||
---------
|
||||
|
||||
To know more about ``Data Handler``, please refer to `Data Handler API <../reference/api.html#handler>`_.
|
||||
To know more about ``Data Handler``, please refer to `Data Handler API <../reference/api.html#module-qlib.data.dataset.handler>`_.
|
||||
|
||||
|
||||
Dataset
|
||||
=================
|
||||
|
||||
The ``Dataset`` module in ``Qlib`` aims to prepare data for model training and inferencing.
|
||||
|
||||
The motivation of this module is that we want to maximize the flexibility of of different models to handle data that are suitable for themselves. This module gives the model the flexibility to process their data in an unique way. For instance, models such as ``GBDT`` may work well on data that contains `nan` or `None` value, while neural networks such as ``MLP`` will break down on such data.
|
||||
|
||||
If user's model need process its data in a different way, user could implement his own ``Dataset`` class. If the model's
|
||||
data processing is not special, ``DatasetH`` can be used directly.
|
||||
|
||||
The ``DatasetH`` class is the `dataset` with `Data Handler`. Here is the most important interface of the class:
|
||||
|
||||
.. autoclass:: qlib.data.dataset.__init__.DatasetH
|
||||
:members:
|
||||
|
||||
API
|
||||
---------
|
||||
|
||||
To know more about ``Dataset``, please refer to `Dataset API <../reference/api.html#dataset>`_.
|
||||
|
||||
|
||||
Cache
|
||||
==========
|
||||
|
||||
``Cache`` is an optional module that helps accelerate providing data by saving some frequently-used data as cache file. ``Qlib`` provides a `Memcache` class to cache the most-frequently-used data in memory, an inheritable `ExpressionCache` class and an inheritable `DatasetCache` class.
|
||||
``Cache`` is an optional module that helps accelerate providing data by saving some frequently-used data as cache file. ``Qlib`` provides a `Memcache` class to cache the most-frequently-used data in memory, an inheritable `ExpressionCache` class, and an inheritable `DatasetCache` class.
|
||||
|
||||
Global Memory Cache
|
||||
---------------------
|
||||
@@ -297,14 +490,14 @@ The following shows the details about the interfaces:
|
||||
.. autoclass:: qlib.data.cache.DatasetCache
|
||||
:members:
|
||||
|
||||
``Qlib`` has currently provided implemented disk cache `DiskDatasetCache` which inherits from `DatasetCache` . The datasets data will be stored in the disk.
|
||||
``Qlib`` has currently provided implemented disk cache `DiskDatasetCache` which inherits from `DatasetCache` . The datasets' data will be stored in the disk.
|
||||
|
||||
|
||||
|
||||
Data and Cache File Structure
|
||||
==================================
|
||||
|
||||
We've specially designed a file structure to manage data and cache, please refer to the `File storage design section in Qlib paper <https://arxiv.org/abs/2009.11189>`_ for detailed information.The file structure of data and cache is listed as follows.
|
||||
We've specially designed a file structure to manage data and cache, please refer to the `File storage design section in Qlib paper <https://arxiv.org/abs/2009.11189>`_ for detailed information. The file structure of data and cache is listed as follows.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
@@ -336,5 +529,3 @@ We've specially designed a file structure to manage data and cache, please refer
|
||||
- .index : an assorted index file recording the line index of all calendars
|
||||
- ...
|
||||
|
||||
|
||||
.. TODO: refer to paper
|
||||
|
||||
@@ -1,692 +0,0 @@
|
||||
.. _estimator:
|
||||
=================================
|
||||
Estimator: Workflow Management
|
||||
=================================
|
||||
.. currentmodule:: qlib
|
||||
|
||||
Introduction
|
||||
===================
|
||||
|
||||
The components in `Qlib Framework <../introduction/introduction.html#framework>`_ are designed in a loosely-coupled way. Users could build their own Quant research workflow with these components like `Example <https://github.com/microsoft/qlib/blob/main/examples/train_and_backtest.py>`_
|
||||
|
||||
|
||||
Besides, ``Qlib`` provides more user-friendly interfaces named ``Estimator`` to automatically run the whole workflow defined by configuration. A concrete execution of the whole workflow is called an `experiment`.
|
||||
With ``Estimator``, user can easily run an `experiment`, which includes the following steps:
|
||||
|
||||
- Data
|
||||
- Loading
|
||||
- Processing
|
||||
- Slicing
|
||||
- Model
|
||||
- Training and inference(static or rolling)
|
||||
- Saving & loading
|
||||
- Evaluation(Back-testing)
|
||||
|
||||
For each `experiment`, ``Qlib`` will capture the model training details, performance evaluation results and basic information (e.g. names, ids). The captured data will be stored in backend-storage (disk or database).
|
||||
|
||||
Complete Example
|
||||
===================
|
||||
|
||||
Before getting into details, here is a complete example of ``Estimator``, which defines the workflow in typical Quant research.
|
||||
Below is a typical config file of ``Estimator``.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
experiment:
|
||||
name: estimator_example
|
||||
observer_type: file_storage
|
||||
mode: train
|
||||
model:
|
||||
class: LGBModel
|
||||
module_path: qlib.contrib.model.gbdt
|
||||
args:
|
||||
loss: mse
|
||||
colsample_bytree: 0.8879
|
||||
learning_rate: 0.0421
|
||||
subsample: 0.8789
|
||||
lambda_l1: 205.6999
|
||||
lambda_l2: 580.9768
|
||||
max_depth: 8
|
||||
num_leaves: 210
|
||||
num_threads: 20
|
||||
data:
|
||||
class: QLibDataHandlerClose
|
||||
args:
|
||||
dropna_label: True
|
||||
filter:
|
||||
market: csi500
|
||||
trainer:
|
||||
class: StaticTrainer
|
||||
args:
|
||||
rolling_period: 360
|
||||
train_start_date: 2007-01-01
|
||||
train_end_date: 2014-12-31
|
||||
validate_start_date: 2015-01-01
|
||||
validate_end_date: 2016-12-31
|
||||
test_start_date: 2017-01-01
|
||||
test_end_date: 2020-08-01
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
args:
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
normal_backtest_args:
|
||||
verbose: False
|
||||
limit_threshold: 0.095
|
||||
account: 100000000
|
||||
benchmark: SH000905
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
qlib_data:
|
||||
# when testing, please modify the following parameters according to the specific environment
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: "cn"
|
||||
|
||||
After saving the config into `configuration.yaml`, users could start the workflow and test their ideas with a single command below.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
estimator -c configuration.yaml
|
||||
|
||||
.. note:: `estimator` will be placed in your $PATH directory when installing ``Qlib``.
|
||||
|
||||
|
||||
|
||||
Configuration File
|
||||
===================
|
||||
|
||||
Let's get into details of ``Estimator`` in this section.
|
||||
|
||||
Before using ``estimator``, users need to prepare a configuration file. The following content shows how to prepare each part of the configuration file.
|
||||
|
||||
Experiment Section
|
||||
--------------------
|
||||
|
||||
At first, the configuration file needs to contain a section named `experiment` about the basic information. This section describes how `estimator` tracks and persists current `experiment`. ``Qlib`` used `sacred`, a lightweight open-source tool, to configure, organize, generate logs, and manage experiment results. Partial behaviors of `sacred` will base on the `experiment` section.
|
||||
|
||||
Following files will be saved by `sacred` after `estimator` finish an `experiment`:
|
||||
|
||||
- `model.bin`, model binary file
|
||||
- `pred.pkl`, model prediction result file
|
||||
- `analysis.pkl`, backtest performance analysis file
|
||||
- `positions.pkl`, backtest position records file
|
||||
- `run`, the experiment information object, usually contains some meta information such as the experiment name, experiment date, etc.
|
||||
|
||||
Here is the typical configuration of `experiment section`
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
experiment:
|
||||
name: test_experiment
|
||||
observer_type: mongo
|
||||
mongo_url: mongodb://MONGO_URL
|
||||
db_name: public
|
||||
finetune: false
|
||||
exp_info_path: /home/test_user/exp_info.json
|
||||
mode: test
|
||||
loader:
|
||||
id: 677
|
||||
|
||||
|
||||
The meaning of each field is as follows:
|
||||
|
||||
- `name`
|
||||
The experiment name, str type, `sacred <https://github.com/IDSIA/sacred>_` will use this experiment name as an identifier for some important internal processes. Users can find this field in `run` object of `sacred`. The default value is `test_experiment`.
|
||||
|
||||
- `observer_type`
|
||||
Observer type, str type, there are two choices which include `file_storage` and `mongo` respectively. If `file_storage` is selected, all the above-mentioned managed contents will be stored in the `dir` directory, separated by the number of times of experiments as a subfolder. If it is `mongo`, the content will be stored in the database. The default is `file_storage`.
|
||||
|
||||
- For `file_storage` observer.
|
||||
- `dir`
|
||||
Directory URL, str type, directory for `file_storage` observer type, files captured and managed by sacred with `file_storage` observer will be saved to this directory, which is the same directory as `config.json` by default.
|
||||
|
||||
- For `mongo` observer.
|
||||
- `mongo_url`
|
||||
Database URL, str type, required if the observer type is `mongo`.
|
||||
|
||||
- `db_name`
|
||||
Database name, str type, required if the observer type is `mongo`.
|
||||
|
||||
- `finetune`
|
||||
``Estimator``'s behaviors to train models will base on this flag.
|
||||
If you just want to train models from scratch each time instead of based on existing models, please leave `finetune=false`. Otherwise please read the
|
||||
details below.
|
||||
|
||||
The following table is the processing logic for different situations.
|
||||
|
||||
========== =========================================== ==================================== =========================================== ==========================================
|
||||
. Static Rolling
|
||||
. finetune:true finetune:false finetune:true finetune:false
|
||||
========== =========================================== ==================================== =========================================== ==========================================
|
||||
Train - Need to provide model (Static or Rolling) - No need to provide model - Need to provide model (Static or Rolling) - Need to provide model (Static or Rolling)
|
||||
- The args in model section will be - The args in model section will be - The args in model section will be - The args in model section will be
|
||||
used for finetuning used for training used for finetuning used for finetuning
|
||||
- Update based on the provided model - Train model from scratch - Update based on the provided model - Based on the provided model update
|
||||
and parameters and parameters - Train model from scratch
|
||||
- **Each rolling time slice is based on** - **Train each rolling time slice**
|
||||
**a model updated from the previous** **separately**
|
||||
**time**
|
||||
Test - Model must exist, otherwise an exception will be raised.
|
||||
- For `StaticTrainer`, users need to train a model and record 'exp_info' for 'Test'.
|
||||
- For `RollingTrainer`, users need to train a set of models until the latest time, and record 'exp_info' for 'Test'.
|
||||
========== =============================================================================================================================================================================
|
||||
|
||||
.. note::
|
||||
|
||||
1. finetune parameters: share model.args parameters.
|
||||
|
||||
2. provide model: from `loader.model_index`, load the index of the model(starting from 0).
|
||||
|
||||
3. If `loader.model_index` is None:
|
||||
- In 'Static Finetune=True', if provide 'Rolling', use the last model to update.
|
||||
|
||||
- For `RollingTrainer` with Finetune=True.
|
||||
|
||||
- If `StaticTrainer` is used in loader, the model will be used for initialization for finetuning.
|
||||
|
||||
- If `RollingTrainer` is used in loader, the existing models will be used without any modification and the new models will be initialized with the model in the last period and finetune one by one.
|
||||
|
||||
|
||||
- `exp_info_path`
|
||||
save path of experiment info, str type, save the experiment info and model `prediction score` after the experiment is finished. Optional parameter, the default value is `<config_file_dir>/ex_name/exp_info.json`.
|
||||
|
||||
- `mode`
|
||||
`train` or `test`, str type.
|
||||
- `test mode` is designed for inference. Under `test mode`, it will load the model according to the parameters of `loader` and skip model training.
|
||||
- `train model` is the default value. It will train new models by default and
|
||||
Please note that when it fails to load model, it will fall back to `fit` model.
|
||||
|
||||
.. note::
|
||||
|
||||
if users choose ` test mode`, they need to make sure:
|
||||
- The loader of `test_start_date` must be less than or equal to the current `test_start_date`.
|
||||
- If other parameters of the `loader` model args are different, a warning will appear.
|
||||
|
||||
|
||||
- `loader`
|
||||
If you just want to train models from scratch each time instead of based on existing models, please ignore `loader` section. Otherwise please read the
|
||||
details below.
|
||||
|
||||
The `loader` section only works when the `mode` is `test` or `finetune` is `true`.
|
||||
|
||||
- `model_index`
|
||||
Model index, int type. The index of the loaded model in loader_models (starting at 0) for the first `finetune`. The default value is None.
|
||||
|
||||
- `exp_info_path`
|
||||
Loader model experiment info path, str type. If the field exists, the following parameters will be parsed from `exp_info_path`, and the following parameters will not work. One of this field and `id` must exist at least .
|
||||
|
||||
- `id`
|
||||
The experiment id of the model that needs to be loaded, int type. If the `mode` is `test`, this value is required. This field and `exp_info_path` must exist one.
|
||||
|
||||
- `name`
|
||||
The experiment name of the model that needs to be loaded, str type. The default value is the current experiment `name`.
|
||||
|
||||
- `observer_type`
|
||||
The experiment observer type of the model that needs to be loaded, str type. The default value is the current experiment `observer_type`.
|
||||
|
||||
.. note:: The observer type is a concept of the `sacred` module, which determines how files, standard input, and output which are managed by sacred are stored.
|
||||
|
||||
|
||||
- `file_storage`
|
||||
If `observer_type` is `file_storage`, the config may be as follows.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
experiment:
|
||||
name: test_experiment
|
||||
dir: <path to a directory> # default is dir of `config.yml`
|
||||
observer_type: file_storage
|
||||
- `mongo`
|
||||
If `observer_type` is `mongo`, the config may be as follows.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
experiment:
|
||||
name: test_experiment
|
||||
observer_type: mongo
|
||||
mongo_url: mongodb://MONGO_URL
|
||||
db_name: public
|
||||
|
||||
Users need to indicate `mongo_url` and `db_name` for a mongo observer.
|
||||
|
||||
.. note::
|
||||
|
||||
If users choose the mongo observer, they need to make sure:
|
||||
- Have an environment with the mongodb installed and a mongo database dedicated to storing the results of the experiments.
|
||||
- The python environment (the version of python and package) to run the experiments and the one to fetch the results are consistent.
|
||||
|
||||
Model Section
|
||||
-----------------
|
||||
|
||||
Users can use a specified model by configuration with hyper-parameters.
|
||||
|
||||
Custom Models
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Qlib supports custom models, but it must be a subclass of the `qlib.contrib.model.Model`, the config for a custom model may be as following.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
model:
|
||||
class: SomeModel
|
||||
module_path: /tmp/my_experment/custom_model.py
|
||||
args:
|
||||
loss: binary
|
||||
|
||||
|
||||
The class `SomeModel` should be in the module `custom_model`, and ``Qlib`` could parse the `module_path` to load the class.
|
||||
|
||||
To know more about ``Model``, please refer to `Model <model.html>`_.
|
||||
|
||||
Data Section
|
||||
-----------------
|
||||
|
||||
``Data Handler`` can be used to load raw data, prepare features and label columns, preprocess data (standardization, remove NaN, etc.), split training, validation, and test sets. It is a subclass of `qlib.contrib.estimator.handler.BaseDataHandler`.
|
||||
|
||||
Users can use the specified data handler by config as follows.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
data:
|
||||
class: QLibDataHandlerClose
|
||||
args:
|
||||
start_date: 2005-01-01
|
||||
end_date: 2018-04-30
|
||||
dropna_label: True
|
||||
filter:
|
||||
market: csi500
|
||||
filter_pipeline:
|
||||
-
|
||||
class: NameDFilter
|
||||
module_path: qlib.filter
|
||||
args:
|
||||
name_rule_re: S(?!Z3)
|
||||
fstart_time: 2018-01-01
|
||||
fend_time: 2018-12-11
|
||||
-
|
||||
class: ExpressionDFilter
|
||||
module_path: qlib.filter
|
||||
args:
|
||||
rule_expression: $open/$factor<=45
|
||||
fstart_time: 2018-01-01
|
||||
fend_time: 2018-12-11
|
||||
|
||||
- `class`
|
||||
Data handler class, str type, which should be a subclass of `qlib.contrib.estimator.handler.BaseDataHandler`, and implements 5 important interfaces for loading features, loading raw data, preprocessing raw data, slicing train, validation, and test data. The default value is `ALPHA360`. If users want to write a data handler to retrieve the data in ``Qlib``, `QlibDataHandler` is suggested.
|
||||
|
||||
- `module_path`
|
||||
The module path, str type, absolute url is also supported, indicates the path of the `class` implementation of the data processor class. The default value is `qlib.contrib.estimator.handler`.
|
||||
|
||||
- `args`
|
||||
Parameters used for ``Data Handler`` initialization.
|
||||
|
||||
- `train_start_date`
|
||||
Training start time, str type, the default value is `2005-01-01`.
|
||||
|
||||
- `start_date`
|
||||
Data start date, str type.
|
||||
|
||||
- `end_date`
|
||||
Data end date, str type. the data from start_date to end_date decides which part of data will be loaded in `datahandler`, users can only use these data in the following parts.
|
||||
|
||||
- `dropna_feature` (Optional in args)
|
||||
Drop Nan feature, bool type, the default value is False.
|
||||
|
||||
- `dropna_label` (Optional in args)
|
||||
Drop Nan label, bool type, the default value is True. Some multi-label tasks will use this.
|
||||
|
||||
- `normalize_method` (Optional in args)
|
||||
Normalize data by a given method. str type. ``Qlib`` gives two normalizing methods, `MinMax` and `Std`.
|
||||
If users want to build their own method, please override `_process_normalize_feature`.
|
||||
|
||||
- `filter`
|
||||
Dynamically filtering the stocks based on the filter pipeline.
|
||||
|
||||
- `market`
|
||||
index name, str type, the default value is `csi500`.
|
||||
|
||||
- `filter_pipeline`
|
||||
Filter rule list, list type, the default value is []. Can be customized according to users' needs.
|
||||
|
||||
- `class`
|
||||
Filter class name, str type.
|
||||
|
||||
- `module_path`
|
||||
The module path, str type.
|
||||
|
||||
- `args`
|
||||
The filter class parameters, these parameters are set according to the `class`, and all the parameters as kwargs to `class`.
|
||||
|
||||
Custom Data Handler
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Qlib support custom data handler, but it must be a subclass of the ``qlib.contrib.estimator.handler.BaseDataHandler``, the config for custom data handler may be as follows.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
data:
|
||||
class: SomeDataHandler
|
||||
module_path: /tmp/my_experment/custom_data_handler.py
|
||||
args:
|
||||
start_date: 2005-01-01
|
||||
end_date: 2018-04-30
|
||||
|
||||
The class `SomeDataHandler` should be in the module `custom_data_handler`, and ``Qlib`` could parse the `module_path` to load the class.
|
||||
|
||||
If users want to load features and labels by config, they can inherit ``qlib.contrib.estimator.handler.ConfigDataHandler``, ``Qlib`` also has provided some preprocess methods in this subclass.
|
||||
If users want to use qlib data, `QLibDataHandler` is recommended, from which users can inherit the custom class. `QLibDataHandler` is also a subclass of `ConfigDataHandler`.
|
||||
|
||||
To know more about ``Data Handler``, please refer to `Data Framework&Usage <data.html>`_.
|
||||
|
||||
Trainer Section
|
||||
-----------------
|
||||
|
||||
Users can specify the trainer ``Trainer`` by the config file, which is a subclass of ``qlib.contrib.estimator.trainer.BaseTrainer`` and implement three important interfaces for training the model, restoring the model, and getting model predictions as follows.
|
||||
|
||||
- `train`
|
||||
Implement this interface to train the model.
|
||||
|
||||
- `load`
|
||||
Implement this interface to recover the model from disk.
|
||||
|
||||
- `get_pred`
|
||||
Implement this interface to get model prediction results.
|
||||
|
||||
Qlib have provided two implemented trainer,
|
||||
|
||||
- `StaticTrainer`
|
||||
The static trainer will be trained using the training, validation, and test data of the data processor static slicing.
|
||||
|
||||
- `RollingTrainer`
|
||||
The rolling trainer will use the rolling iterator of the data processor to split data for rolling training.
|
||||
|
||||
|
||||
Users can specify `trainer` with the configuration file:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
trainer:
|
||||
class: StaticTrainer # or RollingTrainer
|
||||
args:
|
||||
rolling_period: 360
|
||||
train_start_date: 2005-01-01
|
||||
train_end_date: 2014-12-31
|
||||
validate_start_date: 2015-01-01
|
||||
validate_end_date: 2016-06-30
|
||||
test_start_date: 2016-07-01
|
||||
test_end_date: 2017-07-31
|
||||
|
||||
- `class`
|
||||
Trainer class, which should be a subclass of `qlib.contrib.estimator.trainer.BaseTrainer`, and needs to implement three important interfaces, the default value is `StaticTrainer`.
|
||||
|
||||
- `module_path`
|
||||
The module path, str type, absolute url is also supported, indicates the path of the trainer class implementation.
|
||||
|
||||
- `args`
|
||||
Parameters used for ``Trainer`` initialization.
|
||||
|
||||
- `rolling_period`
|
||||
The rolling period, integer type, indicates how many time steps need rolling when rolling the data. The default value is `60`. Only used in `RollingTrainer`.
|
||||
|
||||
- `train_start_date`
|
||||
Training start time, str type.
|
||||
|
||||
- `train_end_date`
|
||||
Training end time, str type.
|
||||
|
||||
- `validate_start_date`
|
||||
Validation start time, str type.
|
||||
|
||||
- `validate_end_date`
|
||||
Validation end time, str type.
|
||||
|
||||
- `test_start_date`
|
||||
Test start time, str type.
|
||||
|
||||
- `test_end_date`
|
||||
Test end time, str type. If `test_end_date` is `-1` or greater than the last date of the data, the last date of the data will be used as `test_end_date`.
|
||||
|
||||
Custom Trainer
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Qlib supports custom trainer, but it must be a subclass of the `qlib.contrib.estimator.trainer.BaseTrainer`, the config for a custom trainer may be as following:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
trainer:
|
||||
class: SomeTrainer
|
||||
module_path: /tmp/my_experment/custom_trainer.py
|
||||
args:
|
||||
train_start_date: 2005-01-01
|
||||
train_end_date: 2014-12-31
|
||||
validate_start_date: 2015-01-01
|
||||
validate_end_date: 2016-06-30
|
||||
test_start_date: 2016-07-01
|
||||
test_end_date: 2017-07-31
|
||||
|
||||
|
||||
The class `SomeTrainer` should be in the module `custom_trainer`, and ``Qlib`` could parse the `module_path` to load the class.
|
||||
|
||||
Strategy Section
|
||||
-----------------
|
||||
|
||||
Users can specify strategy through a config file, for example:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
strategy :
|
||||
class: TopkDropoutStrategy
|
||||
args:
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
|
||||
- `class`
|
||||
The strategy class, str type, should be a subclass of `qlib.contrib.strategy.strategy.BaseStrategy`. The default value is `TopkDropoutStrategy`.
|
||||
|
||||
- `module_path`
|
||||
The module location, str type, absolute url is also supported, and absolute path is also supported, indicates the location of the policy class implementation.
|
||||
|
||||
- `args`
|
||||
Parameters used for ``Trainer`` initialization.
|
||||
|
||||
- `topk`
|
||||
The number of stocks in the portfolio
|
||||
|
||||
- `n_drop`
|
||||
Number of stocks to be replaced in each trading date
|
||||
|
||||
Custom Strategy
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Qlib supports custom strategy, but it must be a subclass of the ``qlib.contrib.strategy.strategy.BaseStrategy``, the config for custom strategy may be as following:
|
||||
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
strategy :
|
||||
class: SomeStrategy
|
||||
module_path: /tmp/my_experment/custom_strategy.py
|
||||
|
||||
The class `SomeStrategy` should be in the module `custom_strategy`, and ``Qlib`` could parse the `module_path` to load the class.
|
||||
|
||||
To know more about ``Strategy``, please refer to `Strategy <strategy.html>`_.
|
||||
|
||||
Backtest Section
|
||||
-----------------
|
||||
|
||||
Users can specify `backtest` through a config file, for example:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
backtest :
|
||||
normal_backtest_args:
|
||||
topk: 50
|
||||
benchmark: SH000905
|
||||
account: 500000
|
||||
deal_price: close
|
||||
min_cost: 5
|
||||
subscribe_fields:
|
||||
- $close
|
||||
- $change
|
||||
- $factor
|
||||
|
||||
- `normal_backtest_args`
|
||||
Normal backtest parameters. All the parameters in this section will be passed to the ``qlib.contrib.evaluate.backtest`` function in the form of `**kwargs`.
|
||||
|
||||
- `benchmark`
|
||||
Stock index symbol, str, or list type, the default value is `None`.
|
||||
|
||||
.. note::
|
||||
|
||||
* If `benchmark` is None, it will use the average change of the day of all stocks in 'pred' as the 'bench'.
|
||||
|
||||
* If `benchmark` is list, it will use the daily average change of the stock pool in the list as the 'bench'.
|
||||
|
||||
* If `benchmark` is str, it will use the daily change as the 'bench'.
|
||||
|
||||
|
||||
- `account`
|
||||
Backtest initial cash, integer type. The `account` in `strategy` section is deprecated. It only works when `account` is not set in `backtest` section. It will be overridden by `account` in the `backtest` section. The default value is 1e9.
|
||||
|
||||
- `deal_price`
|
||||
Order transaction price field, str type, the default value is vwap.
|
||||
|
||||
- `min_cost`
|
||||
Min transaction cost, float type, the default value is 5.
|
||||
|
||||
- `subscribe_fields`
|
||||
Subscribe quote fields, array type, the default value is [`deal_price`, $close, $change, $factor].
|
||||
|
||||
|
||||
Qlib Data Section
|
||||
--------------------
|
||||
|
||||
The `qlib_data` field describes the parameters of qlib initialization.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
qlib_data:
|
||||
# when testing, please modify the following parameters according to the specific environment
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: "cn"
|
||||
|
||||
- `provider_uri`
|
||||
The local directory where the data loaded by 'get_data.py' is stored.
|
||||
- `region`
|
||||
- If region == ``qlib.config.REG_CN``, 'qlib' will be initialized in US-stock mode.
|
||||
- If region == ``qlib.config.REG_US``, 'qlib' will be initialized in china-stock mode.
|
||||
|
||||
Please refer to `Initialization <../start/initialization.html>`_.
|
||||
|
||||
Experiment Result
|
||||
===================
|
||||
|
||||
Form of Experimental Result
|
||||
----------------------------
|
||||
The result of the experiment is also the result of the ``Interdat Trading(Backtest)``, please refer to `Interday Trading <backtest.html>`_.
|
||||
|
||||
|
||||
Get Experiment Result
|
||||
----------------------------
|
||||
|
||||
Base Class & Interface
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Users can check the experiment results from file storage directly, or check the experiment results from the database, or get the experiment results through two interfaces of a base class `Fetcher` provided by ``Qlib``.
|
||||
|
||||
The `Fetcher` provides the following interface
|
||||
- `get_experiments(self, exp_name=None):`
|
||||
The interface takes one parameters. The `exp_name` is the experiment name, the default is all experiments. Users can get the returned dictionary with a list of ids and test end date as follows.
|
||||
|
||||
.. code-block:: JSON
|
||||
|
||||
{
|
||||
"ex_a": [
|
||||
{
|
||||
"id": 1,
|
||||
"test_end_date": "2017-01-01"
|
||||
}
|
||||
],
|
||||
"ex_b": [
|
||||
...
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
- `get_experiment(exp_name, exp_id, fields=None)`
|
||||
The interface takes three parameters. The first parameter is the experiment name, the second parameter is the experiment id, and the third parameter is list of fields. The default value of `fields` is None, which means all fields.
|
||||
|
||||
|
||||
.. note::
|
||||
Currently supported fields:
|
||||
['model', 'analysis', 'positions', 'report_normal', 'pred', 'task_config', 'label']
|
||||
|
||||
Users can get the returned dictionary as follows.
|
||||
|
||||
.. code-block:: JSON
|
||||
|
||||
{
|
||||
'analysis': analysis_df,
|
||||
'pred': pred_df,
|
||||
'positions': positions_dic,
|
||||
'report_normal': report_normal_df,
|
||||
}
|
||||
|
||||
Implemented `Fetcher` s & Examples
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``Qlib`` provides two implemented `Fetcher` s as follows.
|
||||
|
||||
`FileFetcher`
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The `FileFetcher` is a subclass of `Fetcher`, which could fetch files from `file_storage` observer. The following is an example:
|
||||
.. code-block:: python
|
||||
|
||||
>>> from qlib.contrib.estimator.fetcher import FileFetcher
|
||||
>>> f = FileFetcher(experiments_dir=r'./')
|
||||
>>> print(f.get_experiments())
|
||||
{
|
||||
'test_experiment': [
|
||||
{
|
||||
'id': '1',
|
||||
'config': ...
|
||||
},
|
||||
{
|
||||
'id': '2',
|
||||
'config': ...
|
||||
},
|
||||
{
|
||||
'id': '3',
|
||||
'config': ...
|
||||
}
|
||||
]
|
||||
}
|
||||
>>> print(f.get_experiment('test_experiment', '1'))
|
||||
risk
|
||||
excess_return_without_cost mean 0.000605
|
||||
std 0.005481
|
||||
annualized_return 0.152373
|
||||
information_ratio 1.751319
|
||||
max_drawdown -0.059055
|
||||
excess_return_with_cost mean 0.000410
|
||||
std 0.005478
|
||||
annualized_return 0.103265
|
||||
information_ratio 1.187411
|
||||
max_drawdown -0.075024
|
||||
|
||||
|
||||
|
||||
`MongoFetcher`
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The `FileFetcher` is a subclass of `Fetcher`, which could fetch files from `mongo` observer. Users should initialize the fetcher with `mongo_url`. The following is an example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from qlib.contrib.estimator.fetcher import MongoFetcher
|
||||
>>> f = MongoFetcher(mongo_url=..., db_name=...)
|
||||
|
||||
120
docs/component/highfreq.rst
Normal file
@@ -0,0 +1,120 @@
|
||||
.. _highfreq:
|
||||
|
||||
============================================
|
||||
Design of hierarchical order execution framework
|
||||
============================================
|
||||
.. currentmodule:: qlib
|
||||
|
||||
Introduction
|
||||
===================
|
||||
|
||||
In order to support reinforcement learning algorithms for high-frequency trading, a corresponding framework is required. None of the publicly available high-frequency trading frameworks now consider multi-layer trading mechanisms, and the currently designed algorithms cannot directly use existing frameworks.
|
||||
In addition to supporting the basic intraday multi-layer trading, the linkage with the day-ahead strategy is also a factor that affects the performance evaluation of the strategy. Different day strategies generate different order distributions and different patterns on different stocks. To verify that high-frequency trading strategies perform well on real trading orders, it is necessary to support day-frequency and high-frequency multi-level linkage trading. In addition to more accurate backtesting of high-frequency trading algorithms, if the distribution of day-frequency orders is considered when training a high-frequency trading model, the algorithm can also be optimized more for product-specific day-frequency orders.
|
||||
Therefore, innovation in the high-frequency trading framework is necessary to solve the various problems mentioned above, for which we designed a hierarchical order execution framework that can link daily-frequency and intra-day trading at different granularities.
|
||||
|
||||
.. image:: ../_static/img/framework.svg
|
||||
|
||||
The design of the framework is shown in the figure above. At each layer consists of Trading Agent and Execution Env. The Trading Agent has its own data processing module (Information Extractor), forecasting module (Forecast Model) and decision generator (Decision Generator). The trading algorithm generates the corresponding decisions by the Decision Generator based on the forecast signals output by the Forecast Module, and the decisions generated by the trading algorithm are passed to the Execution Env, which returns the execution results. Here the frequency of trading algorithm, decision content and execution environment can be customized by users (e.g. intra-day trading, daily-frequency trading, weekly-frequency trading), and the execution environment can be nested with finer-grained trading algorithm and execution environment inside (i.e. sub-workflow in the figure, e.g. daily-frequency orders can be turned into finer-grained decisions by splitting orders within the day). The hierarchical order execution framework is user-defined in terms of hierarchy division and decision frequency, making it easy for users to explore the effects of combining different levels of trading algorithms and breaking down the barriers between different levels of trading algorithm optimization.
|
||||
In addition to the innovation in the framework, the hierarchical order execution framework also takes into account various details of the real backtesting environment, minimizing the differences with the final real environment as much as possible. At the same time, the framework is designed to unify the interface between online and offline (e.g. data pre-processing level supports using the same set of code to process both offline and online data) to reduce the cost of strategy go-live as much as possible.
|
||||
|
||||
Prepare Data
|
||||
===================
|
||||
.. _data:: ../../examples/highfreq/README.md
|
||||
|
||||
|
||||
Example
|
||||
===========================
|
||||
|
||||
Here is an example of highfreq execution.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import qlib
|
||||
# init qlib
|
||||
provider_uri_day = "~/.qlib/qlib_data/cn_data"
|
||||
provider_uri_1min = "~/.qlib/qlib_data/cn_data_1min"
|
||||
provider_uri_map = {"1min": provider_uri_1min, "day": provider_uri_day}
|
||||
qlib.init(provider_uri=provider_uri_day, expression_cache=None, dataset_cache=None)
|
||||
|
||||
# data freq and backtest time
|
||||
freq = "1min"
|
||||
inst_list = D.list_instruments(D.instruments("all"), as_list=True)
|
||||
start_time = "2020-01-01"
|
||||
start_time = "2020-01-31"
|
||||
|
||||
When initializing qlib, if the default data is used, then both daily and minute frequency data need to be passed in.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# random order strategy config
|
||||
strategy_config = {
|
||||
"class": "RandomOrderStrategy",
|
||||
"module_path": "qlib.contrib.strategy.rule_strategy",
|
||||
"kwargs": {
|
||||
"trade_range": TradeRangeByTime("9:30", "15:00"),
|
||||
"sample_ratio": 1.0,
|
||||
"volume_ratio": 0.01,
|
||||
"market": market,
|
||||
},
|
||||
}
|
||||
|
||||
.. code-block:: python
|
||||
# backtest config
|
||||
backtest_config = {
|
||||
"start_time": start_time,
|
||||
"end_time": end_time,
|
||||
"account": 100000000,
|
||||
"benchmark": None,
|
||||
"exchange_kwargs": {
|
||||
"freq": freq,
|
||||
"limit_threshold": 0.095,
|
||||
"deal_price": "close",
|
||||
"open_cost": 0.0005,
|
||||
"close_cost": 0.0015,
|
||||
"min_cost": 5,
|
||||
"codes": market,
|
||||
},
|
||||
"pos_type": "InfPosition", # Position with infinitive position
|
||||
}
|
||||
|
||||
please refer to "../../qlib/backtest".
|
||||
|
||||
.. code-block:: python
|
||||
# excutor config
|
||||
executor_config = {
|
||||
"class": "NestedExecutor",
|
||||
"module_path": "qlib.backtest.executor",
|
||||
"kwargs": {
|
||||
"time_per_step": "day",
|
||||
"inner_executor": {
|
||||
"class": "SimulatorExecutor",
|
||||
"module_path": "qlib.backtest.executor",
|
||||
"kwargs": {
|
||||
"time_per_step": freq,
|
||||
"generate_portfolio_metrics": True,
|
||||
"verbose": False,
|
||||
# "verbose": True,
|
||||
"indicator_config": {
|
||||
"show_indicator": False,
|
||||
},
|
||||
},
|
||||
},
|
||||
"inner_strategy": {
|
||||
"class": "TWAPStrategy",
|
||||
"module_path": "qlib.contrib.strategy.rule_strategy",
|
||||
},
|
||||
"track_data": True,
|
||||
"generate_portfolio_metrics": True,
|
||||
"indicator_config": {
|
||||
"show_indicator": True,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
NestedExecutor represents not the innermost layer, the initialization parameters should contain inner_executor and inner_strategy. simulatorExecutor represents the current excutor is the innermost layer, the innermost strategy used here is the TWAP strategy, the framework currently also supports the VWAP strategy
|
||||
|
||||
.. code-block:: python
|
||||
# backtest
|
||||
portfolio_metrics_dict, indicator_dict = backtest(executor=executor_config, strategy=strategy_config, **backtest_config)
|
||||
|
||||
The metrics of backtest are included in the portfolio_metrics_dict and indicator_dict.
|
||||
@@ -1,170 +1,109 @@
|
||||
.. _model:
|
||||
|
||||
============================================
|
||||
Interday Model: Model Training & Prediction
|
||||
Forecast Model: Model Training & Prediction
|
||||
============================================
|
||||
|
||||
Introduction
|
||||
===================
|
||||
|
||||
``Interday Model`` is designed to make the `prediction score` about stocks. Users can use the ``Interday Model`` in an automatic workflow by ``Estimator``, please refer to `Estimator <estimator.html>`_.
|
||||
``Forecast Model`` is designed to make the `prediction score` about stocks. Users can use the ``Forecast Model`` in an automatic workflow by ``qrun``, please refer to `Workflow: Workflow Management <workflow.html>`_.
|
||||
|
||||
Because the components in ``Qlib`` are designed in a loosely-coupled way, ``Interday Model`` can be used as an independent module also.
|
||||
Because the components in ``Qlib`` are designed in a loosely-coupled way, ``Forecast Model`` can be used as an independent module also.
|
||||
|
||||
Base Class & Interface
|
||||
======================
|
||||
|
||||
``Qlib`` provides a base class `qlib.contrib.model.base.Model <../reference/api.html#module-qlib.contrib.model.base>`_ from which all models should inherit.
|
||||
``Qlib`` provides a base class `qlib.model.base.Model <../reference/api.html#module-qlib.model.base>`_ from which all models should inherit.
|
||||
|
||||
The base class provides the following interfaces:
|
||||
|
||||
- `__init__(**kwargs)`
|
||||
- Initialization.
|
||||
- If users use ``Estimator`` to start an `experiment`, the parameter of `__init__` method shoule be consistent with the hyperparameters in the configuration file.
|
||||
.. autoclass:: qlib.model.base.Model
|
||||
:members:
|
||||
|
||||
- `fit(self, x_train, y_train, x_valid, y_valid, w_train=None, w_valid=None, **kwargs)`
|
||||
- Train model.
|
||||
- Parameter:
|
||||
- `x_train`, pd.DataFrame type, train feature
|
||||
The following example explains the value of `x_train`:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
KMID KLEN KMID2 KUP KUP2
|
||||
instrument datetime
|
||||
SH600004 2012-01-04 0.000000 0.017685 0.000000 0.012862 0.727275
|
||||
2012-01-05 -0.006473 0.025890 -0.250001 0.012945 0.499998
|
||||
2012-01-06 0.008117 0.019481 0.416666 0.008117 0.416666
|
||||
2012-01-09 0.016051 0.025682 0.624998 0.006421 0.250001
|
||||
2012-01-10 0.017323 0.026772 0.647057 0.003150 0.117648
|
||||
... ... ... ... ... ...
|
||||
SZ300273 2014-12-25 -0.005295 0.038697 -0.136843 0.016293 0.421052
|
||||
2014-12-26 -0.022486 0.041701 -0.539215 0.002453 0.058824
|
||||
2014-12-29 -0.031526 0.039092 -0.806451 0.000000 0.000000
|
||||
2014-12-30 -0.010000 0.032174 -0.310811 0.013913 0.432433
|
||||
2014-12-31 0.010917 0.020087 0.543479 0.001310 0.065216
|
||||
|
||||
|
||||
`x_train` is a pandas DataFrame, whose index is MultiIndex <instrument(str), datetime(pd.Timestamp)>. Each column of `x_train` corresponds to a feature, and the column name is the feature name.
|
||||
|
||||
.. note::
|
||||
|
||||
The number and names of the columns are determined by the data handler, please refer to `Data Handler <data.html#data-handler>`_ and `Estimator Data <estimator.html#about-data>`_.
|
||||
|
||||
- `y_train`, pd.DataFrame type, train label
|
||||
The following example explains the value of `y_train`:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
LABEL
|
||||
instrument datetime
|
||||
SH600004 2012-01-04 -0.798456
|
||||
2012-01-05 -1.366716
|
||||
2012-01-06 -0.491026
|
||||
2012-01-09 0.296900
|
||||
2012-01-10 0.501426
|
||||
... ...
|
||||
SZ300273 2014-12-25 -0.465540
|
||||
2014-12-26 0.233864
|
||||
2014-12-29 0.471368
|
||||
2014-12-30 0.411914
|
||||
2014-12-31 1.342723
|
||||
|
||||
`y_train` is a pandas DataFrame, whose index is MultiIndex <instrument(str), datetime(pd.Timestamp)>. The `LABEL` column represents the value of train label.
|
||||
|
||||
.. note::
|
||||
|
||||
The number and names of the columns are determined by the ``Data Handler``, please refer to `Data Handler <data.html#data-handler>`_.
|
||||
|
||||
- `x_valid`, pd.DataFrame type, validation feature
|
||||
The format of `x_valid` is same as `x_train`
|
||||
|
||||
|
||||
- `y_valid`, pd.DataFrame type, validation label
|
||||
The format of `y_valid` is same as `y_train`
|
||||
|
||||
- `w_train`(Optional args, default is None), pd.DataFrame type, train weight
|
||||
`w_train` is a pandas DataFrame, whose shape and index is same as `x_train`. The float value in `w_train` represents the weight of the feature at the same position in `x_train`.
|
||||
|
||||
- `w_train`(Optional args, default is None), pd.DataFrame type, validation weight
|
||||
`w_train` is a pandas DataFrame, whose shape and index is the same as `x_valid`. The float value in `w_train` represents the weight of the feature at the same position in `x_train`.
|
||||
|
||||
- `predict(self, x_test, **kwargs)`
|
||||
- Predict test data 'x_test'
|
||||
- Parameter:
|
||||
- `x_test`, pd.DataFrame type, test features
|
||||
The form of `x_test` is same as `x_train` in 'fit' method.
|
||||
- Return:
|
||||
- `label`, np.ndarray type, test label
|
||||
The label of `x_test` that predicted by model.
|
||||
|
||||
- `score(self, x_test, y_test, w_test=None, **kwargs)`
|
||||
- Evaluate model with test feature/label
|
||||
- Parameter:
|
||||
- `x_test`, pd.DataFrame type, test feature
|
||||
The format of `x_test` is same as `x_train` in `fit` method.
|
||||
|
||||
- `x_test`, pd.DataFrame type, test label
|
||||
The format of `y_test` is same as `y_train` in `fit` method.
|
||||
|
||||
- `w_test`, pd.DataFrame type, test weight
|
||||
The format of `w_test` is same as `w_train` in `fit` method.
|
||||
- Return: float type, evaluation score
|
||||
|
||||
For other interfaces such as `save`, `load`, `finetune`, please refer to `Model API <../reference/api.html#module-qlib.contrib.model.base>`_.
|
||||
``Qlib`` also provides a base class `qlib.model.base.ModelFT <../reference/api.html#qlib.model.base.ModelFT>`_, which includes the method for finetuning the model.
|
||||
|
||||
For other interfaces such as `finetune`, please refer to `Model API <../reference/api.html#module-qlib.model.base>`_.
|
||||
|
||||
Example
|
||||
==================
|
||||
|
||||
``Qlib`` provides ``LightGBM`` and ``DNN`` models as the baseline, the following steps show how to run`` LightGBM`` as an independent module.
|
||||
``Qlib``'s `Model Zoo` includes models such as ``LightGBM``, ``MLP``, ``LSTM``, etc.. These models are treated as the baselines of ``Forecast Model``. The following steps show how to run`` LightGBM`` as an independent module.
|
||||
|
||||
- Initialize ``Qlib`` with `qlib.init` first, please refer to `initialization <../start/initialization.html>`_.
|
||||
- Initialize ``Qlib`` with `qlib.init` first, please refer to `Initialization <../start/initialization.html>`_.
|
||||
- Run the following code to get the `prediction score` `pred_score`
|
||||
.. code-block:: Python
|
||||
|
||||
from qlib.contrib.estimator.handler import QLibDataHandlerClose
|
||||
from qlib.contrib.model.gbdt import LGBModel
|
||||
from qlib.contrib.data.handler import Alpha158
|
||||
from qlib.utils import init_instance_by_config, flatten_dict
|
||||
from qlib.workflow import R
|
||||
from qlib.workflow.record_temp import SignalRecord, PortAnaRecord
|
||||
|
||||
DATA_HANDLER_CONFIG = {
|
||||
"dropna_label": True,
|
||||
"start_date": "2007-01-01",
|
||||
"end_date": "2020-08-01",
|
||||
"market": MARKET,
|
||||
market = "csi300"
|
||||
benchmark = "SH000300"
|
||||
|
||||
data_handler_config = {
|
||||
"start_time": "2008-01-01",
|
||||
"end_time": "2020-08-01",
|
||||
"fit_start_time": "2008-01-01",
|
||||
"fit_end_time": "2014-12-31",
|
||||
"instruments": market,
|
||||
}
|
||||
|
||||
TRAINER_CONFIG = {
|
||||
"train_start_date": "2007-01-01",
|
||||
"train_end_date": "2014-12-31",
|
||||
"validate_start_date": "2015-01-01",
|
||||
"validate_end_date": "2016-12-31",
|
||||
"test_start_date": "2017-01-01",
|
||||
"test_end_date": "2020-08-01",
|
||||
task = {
|
||||
"model": {
|
||||
"class": "LGBModel",
|
||||
"module_path": "qlib.contrib.model.gbdt",
|
||||
"kwargs": {
|
||||
"loss": "mse",
|
||||
"colsample_bytree": 0.8879,
|
||||
"learning_rate": 0.0421,
|
||||
"subsample": 0.8789,
|
||||
"lambda_l1": 205.6999,
|
||||
"lambda_l2": 580.9768,
|
||||
"max_depth": 8,
|
||||
"num_leaves": 210,
|
||||
"num_threads": 20,
|
||||
},
|
||||
},
|
||||
"dataset": {
|
||||
"class": "DatasetH",
|
||||
"module_path": "qlib.data.dataset",
|
||||
"kwargs": {
|
||||
"handler": {
|
||||
"class": "Alpha158",
|
||||
"module_path": "qlib.contrib.data.handler",
|
||||
"kwargs": data_handler_config,
|
||||
},
|
||||
"segments": {
|
||||
"train": ("2008-01-01", "2014-12-31"),
|
||||
"valid": ("2015-01-01", "2016-12-31"),
|
||||
"test": ("2017-01-01", "2020-08-01"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# model initiaiton
|
||||
model = init_instance_by_config(task["model"])
|
||||
dataset = init_instance_by_config(task["dataset"])
|
||||
|
||||
x_train, y_train, x_validate, y_validate, x_test, y_test = QLibDataHandlerClose(
|
||||
**DATA_HANDLER_CONFIG
|
||||
).get_split_data(**TRAINER_CONFIG)
|
||||
# start exp
|
||||
with R.start(experiment_name="workflow"):
|
||||
# train
|
||||
R.log_params(**flatten_dict(task))
|
||||
model.fit(dataset)
|
||||
|
||||
# prediction
|
||||
recorder = R.get_recorder()
|
||||
sr = SignalRecord(model, dataset, recorder)
|
||||
sr.generate()
|
||||
|
||||
MODEL_CONFIG = {
|
||||
"loss": "mse",
|
||||
"colsample_bytree": 0.8879,
|
||||
"learning_rate": 0.0421,
|
||||
"subsample": 0.8789,
|
||||
"lambda_l1": 205.6999,
|
||||
"lambda_l2": 580.9768,
|
||||
"max_depth": 8,
|
||||
"num_leaves": 210,
|
||||
"num_threads": 20,
|
||||
}
|
||||
# use default model
|
||||
# custom Model, refer to: TODO: Model API url
|
||||
model = LGBModel(**MODEL_CONFIG)
|
||||
model.fit(x_train, y_train, x_validate, y_validate)
|
||||
_pred = model.predict(x_test)
|
||||
pred_score = pd.DataFrame(index=_pred.index)
|
||||
pred_score["score"] = _pred.iloc(axis=1)[0]
|
||||
|
||||
.. note:: `QLibDataHandlerClose` is the data handler provided by ``Qlib``, please refer to `Data Handler <data.html#data-handler>`_.
|
||||
.. note::
|
||||
|
||||
`Alpha158` is the data handler provided by ``Qlib``, please refer to `Data Handler <data.html#data-handler>`_.
|
||||
`SignalRecord` is the `Record Template` in ``Qlib``, please refer to `Workflow <recorder.html#record-template>`_.
|
||||
|
||||
Also, the above example has been given in ``examples/train_backtest_analyze.ipynb``.
|
||||
|
||||
@@ -176,4 +115,4 @@ Qlib supports custom models. If users are interested in customizing their own mo
|
||||
|
||||
API
|
||||
===================
|
||||
Please refer to `Model API <../reference/api.html#module-qlib.contrib.model.base>`_.
|
||||
Please refer to `Model API <../reference/api.html#module-qlib.model.base>`_.
|
||||
|
||||
48
docs/component/online.rst
Normal file
@@ -0,0 +1,48 @@
|
||||
.. _online:
|
||||
|
||||
=================================
|
||||
Online Serving
|
||||
=================================
|
||||
.. currentmodule:: qlib
|
||||
|
||||
|
||||
Introduction
|
||||
=============
|
||||
|
||||
.. image:: ../_static/img/online_serving.png
|
||||
:align: center
|
||||
|
||||
|
||||
In addition to backtesting, one way to test a model is effective is to make predictions in real market conditions or even do real trading based on those predictions.
|
||||
``Online Serving`` is a set of modules for online models using the latest data,
|
||||
which including `Online Manager <#Online Manager>`_, `Online Strategy <#Online Strategy>`_, `Online Tool <#Online Tool>`_, `Updater <#Updater>`_.
|
||||
|
||||
`Here <https://github.com/microsoft/qlib/tree/main/examples/online_srv>`_ are several examples for reference, which demonstrate different features of ``Online Serving``.
|
||||
If you have many models or `task` needs to be managed, please consider `Task Management <../advanced/task_management.html>`_.
|
||||
The `examples <https://github.com/microsoft/qlib/tree/main/examples/online_srv>`_ are based on some components in `Task Management <../advanced/task_management.html>`_ such as ``TrainerRM`` or ``Collector``.
|
||||
|
||||
**NOTE**: User should keep his data source updated to support online serving. For example, Qlib provides `a batch of scripts <https://github.com/microsoft/qlib/blob/main/scripts/data_collector/yahoo/README.md#automatic-update-of-daily-frequency-datafrom-yahoo-finance>`_ to help users update Yahoo daily data.
|
||||
|
||||
Online Manager
|
||||
=============
|
||||
|
||||
.. automodule:: qlib.workflow.online.manager
|
||||
:members:
|
||||
|
||||
Online Strategy
|
||||
=============
|
||||
|
||||
.. automodule:: qlib.workflow.online.strategy
|
||||
:members:
|
||||
|
||||
Online Tool
|
||||
=============
|
||||
|
||||
.. automodule:: qlib.workflow.online.utils
|
||||
:members:
|
||||
|
||||
Updater
|
||||
=============
|
||||
|
||||
.. automodule:: qlib.workflow.online.update
|
||||
:members:
|
||||
145
docs/component/recorder.rst
Normal file
@@ -0,0 +1,145 @@
|
||||
.. _recorder:
|
||||
|
||||
====================================
|
||||
Qlib Recorder: Experiment Management
|
||||
====================================
|
||||
.. currentmodule:: qlib
|
||||
|
||||
Introduction
|
||||
===================
|
||||
``Qlib`` contains an experiment management system named ``QlibRecorder``, which is designed to help users handle experiment and analyse results in an efficient way.
|
||||
|
||||
There are three components of the system:
|
||||
|
||||
- `ExperimentManager`
|
||||
a class that manages experiments.
|
||||
|
||||
- `Experiment`
|
||||
a class of experiment, and each instance of it is responsible for a single experiment.
|
||||
|
||||
- `Recorder`
|
||||
a class of recorder, and each instance of it is responsible for a single run.
|
||||
|
||||
Here is a general view of the structure of the system:
|
||||
|
||||
.. code-block::
|
||||
|
||||
ExperimentManager
|
||||
- Experiment 1
|
||||
- Recorder 1
|
||||
- Recorder 2
|
||||
- ...
|
||||
- Experiment 2
|
||||
- Recorder 1
|
||||
- Recorder 2
|
||||
- ...
|
||||
- ...
|
||||
|
||||
This experiment management system defines a set of interface and provided a concrete implementation ``MLflowExpManager``, which is based on the machine learning platform: ``MLFlow`` (`link <https://mlflow.org/>`_).
|
||||
|
||||
If users set the implementation of ``ExpManager`` to be ``MLflowExpManager``, they can use the command `mlflow ui` to visualize and check the experiment results. For more information, pleaes refer to the related documents `here <https://www.mlflow.org/docs/latest/cli.html#mlflow-ui>`_.
|
||||
|
||||
Qlib Recorder
|
||||
===================
|
||||
``QlibRecorder`` provides a high level API for users to use the experiment management system. The interfaces are wrapped in the variable ``R`` in ``Qlib``, and users can directly use ``R`` to interact with the system. The following command shows how to import ``R`` in Python:
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
from qlib.workflow import R
|
||||
|
||||
``QlibRecorder`` includes several common API for managing `experiments` and `recorders` within a workflow. For more available APIs, please refer to the following section about `Experiment Manager`, `Experiment` and `Recorder`.
|
||||
|
||||
Here are the available interfaces of ``QlibRecorder``:
|
||||
|
||||
.. autoclass:: qlib.workflow.__init__.QlibRecorder
|
||||
:members:
|
||||
|
||||
Experiment Manager
|
||||
===================
|
||||
|
||||
The ``ExpManager`` module in ``Qlib`` is responsible for managing different experiments. Most of the APIs of ``ExpManager`` are similar to ``QlibRecorder``, and the most important API will be the ``get_exp`` method. User can directly refer to the documents above for some detailed information about how to use the ``get_exp`` method.
|
||||
|
||||
.. autoclass:: qlib.workflow.expm.ExpManager
|
||||
:members: get_exp, list_experiments
|
||||
|
||||
For other interfaces such as `create_exp`, `delete_exp`, please refer to `Experiment Manager API <../reference/api.html#experiment-manager>`_.
|
||||
|
||||
Experiment
|
||||
===================
|
||||
|
||||
The ``Experiment`` class is solely responsible for a single experiment, and it will handle any operations that are related to an experiment. Basic methods such as `start`, `end` an experiment are included. Besides, methods related to `recorders` are also available: such methods include `get_recorder` and `list_recorders`.
|
||||
|
||||
.. autoclass:: qlib.workflow.exp.Experiment
|
||||
:members: get_recorder, list_recorders
|
||||
|
||||
For other interfaces such as `search_records`, `delete_recorder`, please refer to `Experiment API <../reference/api.html#experiment>`_.
|
||||
|
||||
``Qlib`` also provides a default ``Experiment``, which will be created and used under certain situations when users use the APIs such as `log_metrics` or `get_exp`. If the default ``Experiment`` is used, there will be related logged information when running ``Qlib``. Users are able to change the name of the default ``Experiment`` in the config file of ``Qlib`` or during ``Qlib``'s `initialization <../start/initialization.html#parameters>`_, which is set to be '`Experiment`'.
|
||||
|
||||
Recorder
|
||||
===================
|
||||
|
||||
The ``Recorder`` class is responsible for a single recorder. It will handle some detailed operations such as ``log_metrics``, ``log_params`` of a single run. It is designed to help user to easily track results and things being generated during a run.
|
||||
|
||||
Here are some important APIs that are not included in the ``QlibRecorder``:
|
||||
|
||||
.. autoclass:: qlib.workflow.recorder.Recorder
|
||||
:members: list_artifacts, list_metrics, list_params, list_tags
|
||||
|
||||
For other interfaces such as `save_objects`, `load_object`, please refer to `Recorder API <../reference/api.html#recorder>`_.
|
||||
|
||||
Record Template
|
||||
===================
|
||||
|
||||
The ``RecordTemp`` class is a class that enables generate experiment results such as IC and backtest in a certain format. We have provided three different `Record Template` class:
|
||||
|
||||
- ``SignalRecord``: This class generates the `prediction` results of the model.
|
||||
- ``SigAnaRecord``: This class generates the `IC`, `ICIR`, `Rank IC` and `Rank ICIR` of the model.
|
||||
|
||||
Here is a simple example of what is done in ``SigAnaRecord``, which users can refer to if they want to calculate IC, Rank IC, Long-Short Return with their own prediction and label.
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
from qlib.contrib.eva.alpha import calc_ic, calc_long_short_return
|
||||
|
||||
ic, ric = calc_ic(pred.iloc[:, 0], label.iloc[:, 0])
|
||||
long_short_r, long_avg_r = calc_long_short_return(pred.iloc[:, 0], label.iloc[:, 0])
|
||||
|
||||
- ``PortAnaRecord``: This class generates the results of `backtest`. The detailed information about `backtest` as well as the available `strategy`, users can refer to `Strategy <../component/strategy.html>`_ and `Backtest <../component/backtest.html>`_.
|
||||
|
||||
Here is a simple exampke of what is done in ``PortAnaRecord``, which users can refer to if they want to do backtest based on their own prediction and label.
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
from qlib.contrib.strategy.strategy import TopkDropoutStrategy
|
||||
from qlib.contrib.evaluate import (
|
||||
backtest as normal_backtest,
|
||||
risk_analysis,
|
||||
)
|
||||
|
||||
# backtest
|
||||
STRATEGY_CONFIG = {
|
||||
"topk": 50,
|
||||
"n_drop": 5,
|
||||
}
|
||||
BACKTEST_CONFIG = {
|
||||
"limit_threshold": 0.095,
|
||||
"account": 100000000,
|
||||
"benchmark": BENCHMARK,
|
||||
"deal_price": "close",
|
||||
"open_cost": 0.0005,
|
||||
"close_cost": 0.0015,
|
||||
"min_cost": 5,
|
||||
}
|
||||
|
||||
strategy = TopkDropoutStrategy(**STRATEGY_CONFIG)
|
||||
report_normal, positions_normal = normal_backtest(pred_score, strategy=strategy, **BACKTEST_CONFIG)
|
||||
|
||||
# analysis
|
||||
analysis = dict()
|
||||
analysis["excess_return_without_cost"] = risk_analysis(report_normal["return"] - report_normal["bench"])
|
||||
analysis["excess_return_with_cost"] = risk_analysis(report_normal["return"] - report_normal["bench"] - report_normal["cost"])
|
||||
analysis_df = pd.concat(analysis) # type: pd.DataFrame
|
||||
print(analysis_df)
|
||||
|
||||
For more information about the APIs, please refer to `Record Template API <../reference/api.html#module-qlib.workflow.record_temp>`_.
|
||||
@@ -1,12 +1,13 @@
|
||||
.. _report:
|
||||
|
||||
==========================================
|
||||
Aanalysis: Evaluation & Results Analysis
|
||||
Analysis: Evaluation & Results Analysis
|
||||
==========================================
|
||||
|
||||
Introduction
|
||||
===================
|
||||
|
||||
``Aanalysis`` is designed to show the graphical reports of ``Intraday Trading`` , which helps users to evaluate and analyse investment portfolios visually. The following are some graphics to view:
|
||||
``Analysis`` is designed to show the graphical reports of ``Intraday Trading`` , which helps users to evaluate and analyse investment portfolios visually. The following are some graphics to view:
|
||||
|
||||
- analysis_position
|
||||
- report_graph
|
||||
@@ -51,7 +52,7 @@ API
|
||||
Graphical Result
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
- Axis X: Trading day
|
||||
- Axis Y:
|
||||
@@ -100,7 +101,7 @@ Graphical Result
|
||||
- Axis Y:
|
||||
- `ic`
|
||||
The `Pearson correlation coefficient` series between `label` and `prediction score`.
|
||||
In the above example, the `label` is formulated as `Ref($close, -1)/$close - 1`. Please refer to `Data API Featrue <data.html>`_ for more details.
|
||||
In the above example, the `label` is formulated as `Ref($close, -1)/$close - 1`. Please refer to `Data Feature <data.html#feature>`_ for more details.
|
||||
|
||||
- `rank_ic`
|
||||
The `Spearman's rank correlation coefficient` series between `label` and `prediction score`.
|
||||
@@ -108,35 +109,35 @@ Graphical Result
|
||||
.. image:: ../_static/img/analysis/score_ic.png
|
||||
|
||||
|
||||
Usage of `analysis_position.cumulative_return`
|
||||
----------------------------------------------
|
||||
|
||||
API
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. automodule:: qlib.contrib.report.analysis_position.cumulative_return
|
||||
:members:
|
||||
|
||||
Graphical Result
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. note::
|
||||
|
||||
- Axis X: Trading day
|
||||
- Axis Y:
|
||||
- Above axis Y: `(((Ref($close, -1)/$close - 1) * weight).sum() / weight.sum()).cumsum()`
|
||||
- Below axis Y: Daily weight sum
|
||||
- In the **sell** graph, `y < 0` stands for profit; in other cases, `y > 0` stands for profit.
|
||||
- In the **buy_minus_sell** graph, the **y** value of the **weight** graph at the bottom is `buy_weight + sell_weight`.
|
||||
- In each graph, the **red line** in the histogram on the right represents the average.
|
||||
|
||||
.. image:: ../_static/img/analysis/cumulative_return_buy.png
|
||||
|
||||
.. image:: ../_static/img/analysis/cumulative_return_sell.png
|
||||
|
||||
.. image:: ../_static/img/analysis/cumulative_return_buy_minus_sell.png
|
||||
|
||||
.. image:: ../_static/img/analysis/cumulative_return_hold.png
|
||||
.. Usage of `analysis_position.cumulative_return`
|
||||
.. ----------------------------------------------
|
||||
..
|
||||
.. API
|
||||
.. ~~~~~~~~~~~~~~~~
|
||||
..
|
||||
.. .. automodule:: qlib.contrib.report.analysis_position.cumulative_return
|
||||
.. :members:
|
||||
..
|
||||
.. Graphical Result
|
||||
.. ~~~~~~~~~~~~~~~~~
|
||||
..
|
||||
.. .. note::
|
||||
..
|
||||
.. - Axis X: Trading day
|
||||
.. - Axis Y:
|
||||
.. - Above axis Y: `(((Ref($close, -1)/$close - 1) * weight).sum() / weight.sum()).cumsum()`
|
||||
.. - Below axis Y: Daily weight sum
|
||||
.. - In the **sell** graph, `y < 0` stands for profit; in other cases, `y > 0` stands for profit.
|
||||
.. - In the **buy_minus_sell** graph, the **y** value of the **weight** graph at the bottom is `buy_weight + sell_weight`.
|
||||
.. - In each graph, the **red line** in the histogram on the right represents the average.
|
||||
..
|
||||
.. .. image:: ../_static/img/analysis/cumulative_return_buy.png
|
||||
..
|
||||
.. .. image:: ../_static/img/analysis/cumulative_return_sell.png
|
||||
..
|
||||
.. .. image:: ../_static/img/analysis/cumulative_return_buy_minus_sell.png
|
||||
..
|
||||
.. .. image:: ../_static/img/analysis/cumulative_return_hold.png
|
||||
|
||||
|
||||
Usage of `analysis_position.risk_analysis`
|
||||
@@ -152,7 +153,7 @@ API
|
||||
Graphical Result
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
- general graphics
|
||||
- `std`
|
||||
@@ -178,10 +179,10 @@ Graphical Result
|
||||
The `Maximum Drawdown` of `CAR` (cumulative abnormal return) with cost.
|
||||
|
||||
|
||||
.. image:: ../_static/img/analysis/risk_analysis_bar.png
|
||||
.. image:: ../_static/img/analysis/risk_analysis_bar.png
|
||||
:align: center
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
- annualized_return/max_drawdown/information_ratio/std graphics
|
||||
- Axis X: Trading days grouped by month
|
||||
@@ -220,42 +221,42 @@ Graphical Result
|
||||
.. image:: ../_static/img/analysis/risk_analysis_std.png
|
||||
:align: center
|
||||
|
||||
|
||||
Usage of `analysis_position.rank_label`
|
||||
----------------------------------------------
|
||||
|
||||
API
|
||||
~~~~~
|
||||
|
||||
.. automodule:: qlib.contrib.report.analysis_position.rank_label
|
||||
:members:
|
||||
|
||||
|
||||
Graphical Result
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. note::
|
||||
|
||||
- hold/sell/buy graphics:
|
||||
- Axis X: Trading day
|
||||
- Axis Y:
|
||||
Average `ranking ratio`of `label` for stocks that is held/sold/bought on the trading day.
|
||||
|
||||
In the above example, the `label` is formulated as `Ref($close, -1)/$close - 1`. The `ranking ratio` can be formulated as follows.
|
||||
.. math::
|
||||
|
||||
ranking\ ratio = \frac{Ascending\ Ranking\ of\ label}{Number\ of\ Stocks\ in\ the\ Portfolio}
|
||||
|
||||
.. image:: ../_static/img/analysis/rank_label_hold.png
|
||||
:align: center
|
||||
|
||||
.. image:: ../_static/img/analysis/rank_label_buy.png
|
||||
:align: center
|
||||
|
||||
.. image:: ../_static/img/analysis/rank_label_sell.png
|
||||
:align: center
|
||||
|
||||
|
||||
..
|
||||
.. Usage of `analysis_position.rank_label`
|
||||
.. ----------------------------------------------
|
||||
..
|
||||
.. API
|
||||
.. ~~~~~
|
||||
..
|
||||
.. .. automodule:: qlib.contrib.report.analysis_position.rank_label
|
||||
.. :members:
|
||||
..
|
||||
..
|
||||
.. Graphical Result
|
||||
.. ~~~~~~~~~~~~~~~~~
|
||||
..
|
||||
.. .. note::
|
||||
..
|
||||
.. - hold/sell/buy graphics:
|
||||
.. - Axis X: Trading day
|
||||
.. - Axis Y:
|
||||
.. Average `ranking ratio`of `label` for stocks that is held/sold/bought on the trading day.
|
||||
..
|
||||
.. In the above example, the `label` is formulated as `Ref($close, -1)/$close - 1`. The `ranking ratio` can be formulated as follows.
|
||||
.. .. math::
|
||||
..
|
||||
.. ranking\ ratio = \frac{Ascending\ Ranking\ of\ label}{Number\ of\ Stocks\ in\ the\ Portfolio}
|
||||
..
|
||||
.. .. image:: ../_static/img/analysis/rank_label_hold.png
|
||||
.. :align: center
|
||||
..
|
||||
.. .. image:: ../_static/img/analysis/rank_label_buy.png
|
||||
.. :align: center
|
||||
..
|
||||
.. .. image:: ../_static/img/analysis/rank_label_sell.png
|
||||
.. :align: center
|
||||
..
|
||||
..
|
||||
|
||||
Usage of `analysis_model.analysis_model_performance`
|
||||
-----------------------------------------------------
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
.. _strategy:
|
||||
|
||||
========================================
|
||||
Interday Strategy: Portfolio Management
|
||||
Portfolio Strategy: Portfolio Management
|
||||
========================================
|
||||
.. currentmodule:: qlib
|
||||
|
||||
Introduction
|
||||
===================
|
||||
|
||||
``Interday Strategy`` is designed to adopt different trading strategies, which means that users can adopt different algorithms to generate investment portfolios based on the prediction scores of the ``Interday Model``. Users can use the ``Interday Strategy`` in an automatic workflow by ``Estimator``, please refer to `Estimator <estimator.html>`_.
|
||||
``Portfolio Strategy`` is designed to adopt different portfolio strategies, which means that users can adopt different algorithms to generate investment portfolios based on the prediction scores of the ``Forecast Model``. Users can use the ``Portfolio Strategy`` in an automatic workflow by ``Workflow`` module, please refer to `Workflow: Workflow Management <workflow.html>`_.
|
||||
|
||||
Because the components in ``Qlib`` are designed in a loosely-coupled way, ``Interday Strategy`` can be used as an independent module also.
|
||||
Because the components in ``Qlib`` are designed in a loosely-coupled way, ``Portfolio Strategy`` can be used as an independent module also.
|
||||
|
||||
``Qlib`` provides several implemented trading strategies. Also, ``Qlib`` supports custom strategy, users can customize strategies according to their own needs.
|
||||
``Qlib`` provides several implemented portfolio strategies. Also, ``Qlib`` supports custom strategy, users can customize strategies according to their own needs.
|
||||
|
||||
Base Class & Interface
|
||||
======================
|
||||
@@ -25,19 +26,20 @@ Qlib provides a base class ``qlib.contrib.strategy.BaseStrategy``. All strategy
|
||||
Return the proportion of your total value you will use in investment. Dynamically risk_degree will result in Market timing.
|
||||
|
||||
- `generate_order_list`
|
||||
Rerturn the order list.
|
||||
Return the order list.
|
||||
|
||||
Users can inherit `BaseStrategy` to customize their strategy class.
|
||||
|
||||
WeightStrategyBase
|
||||
--------------------
|
||||
|
||||
Qlib alse provides a class ``qlib.contrib.strategy.WeightStrategyBase`` that is a subclass of `BaseStrategy`.
|
||||
Qlib also provides a class ``qlib.contrib.strategy.WeightStrategyBase`` that is a subclass of `BaseStrategy`.
|
||||
|
||||
`WeightStrategyBase` only focuses on the target positions, and automatically generates an order list based on positions. It provides the `generate_target_weight_position` interface.
|
||||
|
||||
- `generate_target_weight_position`
|
||||
- According to the current position and trading date to generate the target position. The cash is not considered.
|
||||
- According to the current position and trading date to generate the target position. The cash is not considered in
|
||||
the output weight distribution.
|
||||
- Return the target position.
|
||||
|
||||
.. note::
|
||||
@@ -80,7 +82,7 @@ TopkDropoutStrategy
|
||||
|
||||
Usage & Example
|
||||
====================
|
||||
``Interday Strategy`` can be specified in the ``Intraday Trading(Backtest)``, the example is as follows.
|
||||
``Portfolio Strategy`` can be specified in the ``Intraday Trading(Backtest)``, the example is as follows.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -91,15 +93,16 @@ Usage & Example
|
||||
"n_drop": 5,
|
||||
}
|
||||
BACKTEST_CONFIG = {
|
||||
"verbose": False,
|
||||
"limit_threshold": 0.095,
|
||||
"account": 100000000,
|
||||
"benchmark": BENCHMARK,
|
||||
"deal_price": "vwap",
|
||||
"deal_price": "close",
|
||||
"open_cost": 0.0005,
|
||||
"close_cost": 0.0015,
|
||||
"min_cost": 5,
|
||||
|
||||
}
|
||||
|
||||
# use default strategy
|
||||
# custom Strategy, refer to: TODO: Strategy API url
|
||||
strategy = TopkDropoutStrategy(**STRATEGY_CONFIG)
|
||||
|
||||
# pred_score is the `prediction score` output by Model
|
||||
@@ -107,12 +110,10 @@ Usage & Example
|
||||
pred_score, strategy=strategy, **BACKTEST_CONFIG
|
||||
)
|
||||
|
||||
Also, the above example has been given in ``examples\train_backtest_analyze.ipynb``.
|
||||
|
||||
To know more about the `prediction score` `pred_score` output by ``Interday Model``, please refer to `Interday Model: Model Training & Prediction <model.html>`_.
|
||||
To know more about the `prediction score` `pred_score` output by ``Forecast Model``, please refer to `Forecast Model: Model Training & Prediction <model.html>`_.
|
||||
|
||||
To know more about ``Intraday Trading``, please refer to `Intraday Trading: Model&Strategy Testing <backtest.html>`_.
|
||||
|
||||
Reference
|
||||
===================
|
||||
To know more about ``Interday Strategy``, please refer to `Strategy API <../reference/api.html>`_.
|
||||
To know more about ``Portfolio Strategy``, please refer to `Strategy API <../reference/api.html#module-qlib.contrib.strategy.strategy>`_.
|
||||
|
||||
273
docs/component/workflow.rst
Normal file
@@ -0,0 +1,273 @@
|
||||
.. _workflow:
|
||||
|
||||
=================================
|
||||
Workflow: Workflow Management
|
||||
=================================
|
||||
.. currentmodule:: qlib
|
||||
|
||||
Introduction
|
||||
===================
|
||||
|
||||
The components in `Qlib Framework <../introduction/introduction.html#framework>`_ are designed in a loosely-coupled way. Users could build their own Quant research workflow with these components like `Example <https://github.com/microsoft/qlib/blob/main/examples/workflow_by_code.py>`_.
|
||||
|
||||
|
||||
Besides, ``Qlib`` provides more user-friendly interfaces named ``qrun`` to automatically run the whole workflow defined by configuration. Running the whole workflow is called an `execution`.
|
||||
With ``qrun``, user can easily start an `execution`, which includes the following steps:
|
||||
|
||||
- Data
|
||||
- Loading
|
||||
- Processing
|
||||
- Slicing
|
||||
- Model
|
||||
- Training and inference
|
||||
- Saving & loading
|
||||
- Evaluation
|
||||
- Forecast signal analysis
|
||||
- Backtest
|
||||
|
||||
For each `execution`, ``Qlib`` has a complete system to tracking all the information as well as artifacts generated during training, inference and evaluation phase. For more information about how ``Qlib`` handles this, please refer to the related document: `Recorder: Experiment Management <../component/recorder.html>`_.
|
||||
|
||||
Complete Example
|
||||
===================
|
||||
|
||||
Before getting into details, here is a complete example of ``qrun``, which defines the workflow in typical Quant research.
|
||||
Below is a typical config file of ``qrun``.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy.strategy
|
||||
kwargs:
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
backtest:
|
||||
limit_threshold: 0.095
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: LGBModel
|
||||
module_path: qlib.contrib.model.gbdt
|
||||
kwargs:
|
||||
loss: mse
|
||||
colsample_bytree: 0.8879
|
||||
learning_rate: 0.0421
|
||||
subsample: 0.8789
|
||||
lambda_l1: 205.6999
|
||||
lambda_l2: 580.9768
|
||||
max_depth: 8
|
||||
num_leaves: 210
|
||||
num_threads: 20
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs: {}
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
|
||||
After saving the config into `configuration.yaml`, users could start the workflow and test their ideas with a single command below.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
qrun configuration.yaml
|
||||
|
||||
If users want to use ``qrun`` under debug mode, please use the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m pdb qlib/workflow/cli.py examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml
|
||||
|
||||
.. note::
|
||||
|
||||
`qrun` will be placed in your $PATH directory when installing ``Qlib``.
|
||||
|
||||
.. note::
|
||||
|
||||
The symbol `&` in `yaml` file stands for an anchor of a field, which is useful when another fields include this parameter as part of the value. Taking the configuration file above as an example, users can directly change the value of `market` and `benchmark` without traversing the entire configuration file.
|
||||
|
||||
|
||||
Configuration File
|
||||
===================
|
||||
|
||||
Let's get into details of ``qrun`` in this section.
|
||||
|
||||
Before using ``qrun``, users need to prepare a configuration file. The following content shows how to prepare each part of the configuration file.
|
||||
|
||||
Qlib Init Section
|
||||
--------------------
|
||||
|
||||
At first, the configuration file needs to contain several basic parameters which will be used for qlib initialization.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
|
||||
The meaning of each field is as follows:
|
||||
|
||||
- `provider_uri`
|
||||
Type: str. The URI of the Qlib data. For example, it could be the location where the data loaded by ``get_data.py`` are stored.
|
||||
|
||||
- `region`
|
||||
- If `region` == "us", ``Qlib`` will be initialized in US-stock mode.
|
||||
- If `region` == "cn", ``Qlib`` will be initialized in China-stock mode.
|
||||
|
||||
.. note::
|
||||
|
||||
The value of `region` should be aligned with the data stored in `provider_uri`.
|
||||
|
||||
|
||||
Task Section
|
||||
--------------------
|
||||
|
||||
The `task` field in the configuration corresponds to a `task`, which contains the parameters of three different subsections: `Model`, `Dataset` and `Record`.
|
||||
|
||||
Model Section
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the `task` field, the `model` section describes the parameters of the model to be used for training and inference. For more information about the base ``Model`` class, please refer to `Qlib Model <../component/model.html>`_.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
model:
|
||||
class: LGBModel
|
||||
module_path: qlib.contrib.model.gbdt
|
||||
kwargs:
|
||||
loss: mse
|
||||
colsample_bytree: 0.8879
|
||||
learning_rate: 0.0421
|
||||
subsample: 0.8789
|
||||
lambda_l1: 205.6999
|
||||
lambda_l2: 580.9768
|
||||
max_depth: 8
|
||||
num_leaves: 210
|
||||
num_threads: 20
|
||||
|
||||
The meaning of each field is as follows:
|
||||
|
||||
- `class`
|
||||
Type: str. The name for the model class.
|
||||
|
||||
- `module_path`
|
||||
Type: str. The path for the model in qlib.
|
||||
|
||||
- `kwargs`
|
||||
The keywords arguments for the model. Please refer to the specific model implementation for more information: `models <https://github.com/microsoft/qlib/blob/main/qlib/contrib/model>`_.
|
||||
|
||||
.. note::
|
||||
|
||||
``Qlib`` provides a util named: ``init_instance_by_config`` to initialize any class inside ``Qlib`` with the configuration includes the fields: `class`, `module_path` and `kwargs`.
|
||||
|
||||
Dataset Section
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The `dataset` field describes the parameters for the ``Dataset`` module in ``Qlib`` as well those for the module ``DataHandler``. For more information about the ``Dataset`` module, please refer to `Qlib Model <../component/data.html#dataset>`_.
|
||||
|
||||
The keywords arguments configuration of the ``DataHandler`` is as follows:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
|
||||
Users can refer to the document of `DataHandler <../component/data.html#datahandler>`_ for more information about the meaning of each field in the configuration.
|
||||
|
||||
Here is the configuration for the ``Dataset`` module which will take care of data preprossing and slicing during the training and testing phase.
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
|
||||
Record Section
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The `record` field is about the parameters the ``Record`` module in ``Qlib``. ``Record`` is responsible for tracking training process and results such as `information Coefficient (IC)` and `backtest` in a standard format.
|
||||
|
||||
The following script is the configuration of `backtest` and the `strategy` used in `backtest`:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy.strategy
|
||||
kwargs:
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
backtest:
|
||||
limit_threshold: 0.095
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
|
||||
For more information about the meaning of each field in configuration of `strategy` and `backtest`, users can look up the documents: `Strategy <../component/strategy.html>`_ and `Backtest <../component/backtest.html>`_.
|
||||
|
||||
Here is the configuration details of different `Record Template` such as ``SignalRecord`` and ``PortAnaRecord``:
|
||||
|
||||
.. code-block:: YAML
|
||||
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs: {}
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
|
||||
For more information about the ``Record`` module in ``Qlib``, user can refer to the related document: `Record <../component/recorder.html#record-template>`_.
|
||||
18
docs/conf.py
@@ -53,7 +53,6 @@ source_suffix = ".rst"
|
||||
master_doc = "index"
|
||||
|
||||
|
||||
|
||||
# General information about the project.
|
||||
project = u"QLib"
|
||||
copyright = u"Microsoft"
|
||||
@@ -64,9 +63,9 @@ author = u"Microsoft"
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = pkg_resources.get_distribution("qlib").version
|
||||
version = pkg_resources.get_distribution("pyqlib").version
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = pkg_resources.get_distribution("qlib").version
|
||||
release = pkg_resources.get_distribution("pyqlib").version
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@@ -104,8 +103,7 @@ todo_include_todos = True
|
||||
#
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
|
||||
html_logo = '_static/img/logo/1.png'
|
||||
|
||||
html_logo = "_static/img/logo/1.png"
|
||||
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
@@ -126,7 +124,7 @@ html_theme_options = {
|
||||
"logo_only": True,
|
||||
"collapse_navigation": False,
|
||||
"display_version": False,
|
||||
"navigation_depth": 3,
|
||||
"navigation_depth": 4,
|
||||
}
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
@@ -161,15 +159,12 @@ latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
@@ -231,3 +226,8 @@ epub_exclude_files = ["search.html"]
|
||||
|
||||
autodoc_member_order = "bysource"
|
||||
autodoc_default_flags = ["members"]
|
||||
autodoc_default_options = {
|
||||
"members": True,
|
||||
"member-order": "bysource",
|
||||
"special-members": "__init__",
|
||||
}
|
||||
|
||||
22
docs/developer/code_standard.rst
Normal file
@@ -0,0 +1,22 @@
|
||||
.. _code_standard:
|
||||
|
||||
=================================
|
||||
Code Standard
|
||||
=================================
|
||||
|
||||
Docstring
|
||||
=================================
|
||||
Please use the `Numpydoc Style <https://stackoverflow.com/a/24385103>`_.
|
||||
|
||||
Continuous Integration
|
||||
=================================
|
||||
Continuous Integration (CI) tools help you stick to the quality standards by running tests every time you push a new commit and reporting the results to a pull request.
|
||||
|
||||
When you submit a PR request, you can check whether your code passes the CI tests in the "check" section at the bottom of the web page.
|
||||
|
||||
A common error is the mixed use of space and tab. You can fix the bug by inputing the following code in the command line.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
pip install black
|
||||
python -m black . -l 120
|
||||
@@ -93,7 +93,6 @@ We write a simple configuration example as following,
|
||||
fend_time: 2018-12-11
|
||||
backtest:
|
||||
normal_backtest_args:
|
||||
verbose: False
|
||||
limit_threshold: 0.095
|
||||
account: 500000
|
||||
benchmark: SH000905
|
||||
@@ -306,7 +305,6 @@ About the data and backtest
|
||||
fend_time: 2018-12-11
|
||||
backtest:
|
||||
normal_backtest_args:
|
||||
verbose: False
|
||||
limit_threshold: 0.095
|
||||
account: 500000
|
||||
benchmark: SH000905
|
||||
|
||||
@@ -35,12 +35,14 @@ Document Structure
|
||||
:maxdepth: 3
|
||||
:caption: COMPONENTS:
|
||||
|
||||
Estimator: Workflow Management <component/estimator.rst>
|
||||
Workflow: Workflow Management <component/workflow.rst>
|
||||
Data Layer: Data Framework&Usage <component/data.rst>
|
||||
Interday Model: Model Training & Prediction <component/model.rst>
|
||||
Interday Strategy: Portfolio Management <component/strategy.rst>
|
||||
Forecast Model: Model Training & Prediction <component/model.rst>
|
||||
Strategy: Portfolio Management <component/strategy.rst>
|
||||
Intraday Trading: Model&Strategy Testing <component/backtest.rst>
|
||||
Aanalysis: Evaluation & Results Analysis <component/report.rst>
|
||||
Qlib Recorder: Experiment Management <component/recorder.rst>
|
||||
Analysis: Evaluation & Results Analysis <component/report.rst>
|
||||
Online Serving: Online Management & Strategy & Tool <component/online.rst>
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
@@ -48,12 +50,20 @@ Document Structure
|
||||
|
||||
Building Formulaic Alphas <advanced/alpha.rst>
|
||||
Online & Offline mode <advanced/server.rst>
|
||||
Serialization <advanced/serial.rst>
|
||||
Task Management <advanced/task_management.rst>
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:caption: REFERENCE:
|
||||
|
||||
API <reference/api.rst>
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
FAQ <FAQ/FAQ.rst>
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:caption: Change Log:
|
||||
|
||||
@@ -15,33 +15,33 @@ With ``Qlib``, users can easily try their ideas to create better Quant investmen
|
||||
Framework
|
||||
===================
|
||||
|
||||
.. image:: ../_static/img/framework.png
|
||||
.. image:: ../_static/img/framework.svg
|
||||
:align: center
|
||||
|
||||
|
||||
At the module level, Qlib is a platform that consists of above components. The components are designed as loose-coupled modules and each component could be used stand-alone.
|
||||
|
||||
====================== ==============================================================================
|
||||
Name Description
|
||||
====================== ==============================================================================
|
||||
`Data layer` `DataServer` focuses on providing high-performance infrastructure for users to
|
||||
manage and retrieve raw data. `DataEnhancement` will preprocess the data and
|
||||
provide the best dataset to be fed into the models.
|
||||
|
||||
`Interday Model` `Interday model` focuses on producing prediction scores (aka. `alpha`). Models
|
||||
are trained by `Model Creator` and managed by `Model Manager`. Users could
|
||||
choose one or multiple models for prediction. Multiple models could be combined
|
||||
with `Ensemble` module.
|
||||
|
||||
`Interday Strategy` `Portfolio Generator` will take prediction scores as input and output the
|
||||
orders based on the current position to achieve the target portfolio.
|
||||
======================== ==============================================================================
|
||||
Name Description
|
||||
======================== ==============================================================================
|
||||
`Infrastructure` layer `Infrastructure` layer provides underlying support for Quant research.
|
||||
`DataServer` provides high-performance infrastructure for users to manage
|
||||
and retrieve raw data. `Trainer` provides flexible interface to control
|
||||
the training process of models which enable algorithms controlling the
|
||||
training process.
|
||||
|
||||
`Intraday Trading` `Order Executor` is responsible for executing orders output by
|
||||
`Interday Strategy` and returning the executed results.
|
||||
`Workflow` layer `Workflow` layer covers the whole workflow of quantitative investment.
|
||||
`Information Extractor` extracts data for models. `Forecast Model` focuses
|
||||
on producing all kinds of forecast signals (e.g. _alpha_, risk) for other
|
||||
modules. With these signals `Portfolio Generator` will generate the target
|
||||
portfolio and produce orders to be executed by `Order Executor`.
|
||||
|
||||
`Analysis` Users could get a detailed analysis report of forecasting signals and portfolios
|
||||
in this part.
|
||||
====================== ==============================================================================
|
||||
`Interface` layer `Interface` layer tries to present a user-friendly interface for the underlying
|
||||
system. `Analyser` module will provide users detailed analysis reports of
|
||||
forecasting signals, portfolios and execution results
|
||||
======================== ==============================================================================
|
||||
|
||||
- The modules with hand-drawn style are under development and will be released in the future.
|
||||
- The modules with dashed borders are highly user-customizable and extendible.
|
||||
|
||||
@@ -40,27 +40,28 @@ Load and prepare data by running the following code:
|
||||
|
||||
.. code-block::
|
||||
|
||||
python scripts/get_data.py qlib_data_cn --target_dir ~/.qlib/qlib_data/cn_data
|
||||
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn
|
||||
|
||||
This dataset is created by public data collected by crawler scripts in ``scripts/data_collector/``, which have been released in the same repository. Users could create the same dataset with it.
|
||||
|
||||
To kown more about `prepare data`, please refer to `Data Preparation <../component/data.html>`_.
|
||||
To kown more about `prepare data`, please refer to `Data Preparation <../component/data.html#data-preparation>`_.
|
||||
|
||||
Auto Quant Research Workflow
|
||||
====================================
|
||||
|
||||
``Qlib`` provides a tool named ``Estimator`` to run the whole workflow automatically (including building dataset, training models, backtest and evaluation). Users can start an auto quant research workflow and have a graphical reports analysis according to the following steps:
|
||||
``Qlib`` provides a tool named ``qrun`` to run the whole workflow automatically (including building dataset, training models, backtest and evaluation). Users can start an auto quant research workflow and have a graphical reports analysis according to the following steps:
|
||||
|
||||
- Quant Research Workflow:
|
||||
- Run ``Estimator`` with `estimator_config.yaml` as following.
|
||||
- Run ``qrun`` with a config file of the LightGBM model `workflow_config_lightgbm.yaml` as following.
|
||||
|
||||
.. code-block::
|
||||
|
||||
cd examples # Avoid running program under the directory contains `qlib`
|
||||
estimator -c estimator/estimator_config.yaml
|
||||
qrun benchmarks/LightGBM/workflow_config_lightgbm.yaml
|
||||
|
||||
|
||||
- Estimator result
|
||||
The result of ``Estimator`` is as follows, which is also the result of ``Interday Trading``. Please refer to please refer to `Interdat Trading <../component/backtest.html>`_. for more details about the result.
|
||||
- Workflow result
|
||||
The result of ``qrun`` is as follows, which is also the typical result of ``Forecast model(alpha)``. Please refer to `Intraday Trading <../component/backtest.html>`_. for more details about the result.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -77,17 +78,17 @@ Auto Quant Research Workflow
|
||||
max_drawdown -0.075024
|
||||
|
||||
|
||||
To know more about `Estimator`, please refer to `Estimator <../component/estimator.html>`_.
|
||||
To know more about `workflow` and `qrun`, please refer to `Workflow: Workflow Management <../component/workflow.html>`_.
|
||||
|
||||
- Graphical Reports Analysis:
|
||||
- Run ``examples/estimator/analyze_from_estimator.ipynb`` with jupyter notebook
|
||||
Users can have portfolio analysis or prediction score (model prediction) analysis by run ``examples/estimator/analyze_from_estimator.ipynb``.
|
||||
- Run ``examples/workflow_by_code.ipynb`` with jupyter notebook
|
||||
Users can have portfolio analysis or prediction score (model prediction) analysis by run ``examples/workflow_by_code.ipynb``.
|
||||
- Graphical Reports
|
||||
Users can get graphical reports about the analysis, please refer to `Aanalysis: Evaluation & Results Analysis <../component/report.html>`_ for more details.
|
||||
Users can get graphical reports about the analysis, please refer to `Analysis: Evaluation & Results Analysis <../component/report.html>`_ for more details.
|
||||
|
||||
|
||||
|
||||
Custom Model Integration
|
||||
===============================================
|
||||
|
||||
``Qlib`` provides ``lightGBM`` and ``Dnn`` model as the baseline of ``Interday Model``. In addition to the default model, users can integrate their own custom models into ``Qlib``. If users are interested in the custom model, please refer to `Custom Model Integration <../start/integration.html>`_.
|
||||
``Qlib`` provides a batch of models (such as ``lightGBM`` and ``MLP`` models) as examples of ``Forecast Model``. In addition to the default model, users can integrate their own custom models into ``Qlib``. If users are interested in the custom model, please refer to `Custom Model Integration <../start/integration.html>`_.
|
||||
|
||||
@@ -23,16 +23,13 @@ Filter
|
||||
.. automodule:: qlib.data.filter
|
||||
:members:
|
||||
|
||||
Feature
|
||||
--------------------
|
||||
|
||||
Class
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
--------------------
|
||||
.. automodule:: qlib.data.base
|
||||
:members:
|
||||
|
||||
Operator
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
--------------------
|
||||
.. automodule:: qlib.data.ops
|
||||
:members:
|
||||
|
||||
@@ -57,18 +54,63 @@ Cache
|
||||
:members:
|
||||
|
||||
|
||||
Storage
|
||||
-------------
|
||||
.. autoclass:: qlib.data.storage.storage.BaseStorage
|
||||
:members:
|
||||
|
||||
.. autoclass:: qlib.data.storage.storage.CalendarStorage
|
||||
:members:
|
||||
|
||||
.. autoclass:: qlib.data.storage.storage.InstrumentStorage
|
||||
:members:
|
||||
|
||||
.. autoclass:: qlib.data.storage.storage.FeatureStorage
|
||||
:members:
|
||||
|
||||
.. autoclass:: qlib.data.storage.file_storage.FileStorageMixin
|
||||
:members:
|
||||
|
||||
.. autoclass:: qlib.data.storage.file_storage.FileCalendarStorage
|
||||
:members:
|
||||
|
||||
.. autoclass:: qlib.data.storage.file_storage.FileInstrumentStorage
|
||||
:members:
|
||||
|
||||
.. autoclass:: qlib.data.storage.file_storage.FileFeatureStorage
|
||||
:members:
|
||||
|
||||
|
||||
Dataset
|
||||
---------------
|
||||
|
||||
Dataset Class
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
.. automodule:: qlib.data.dataset.__init__
|
||||
:members:
|
||||
|
||||
Data Loader
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
.. automodule:: qlib.data.dataset.loader
|
||||
:members:
|
||||
|
||||
Data Handler
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
.. automodule:: qlib.data.dataset.handler
|
||||
:members:
|
||||
|
||||
Processor
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
.. automodule:: qlib.data.dataset.processor
|
||||
:members:
|
||||
|
||||
|
||||
Contrib
|
||||
====================
|
||||
|
||||
|
||||
Data Handler
|
||||
---------------
|
||||
.. automodule:: qlib.contrib.estimator.handler
|
||||
:members:
|
||||
|
||||
Model
|
||||
--------------------
|
||||
.. automodule:: qlib.contrib.model.base
|
||||
.. automodule:: qlib.model.base
|
||||
:members:
|
||||
|
||||
Strategy
|
||||
@@ -116,3 +158,104 @@ Report
|
||||
:members:
|
||||
|
||||
|
||||
Workflow
|
||||
====================
|
||||
|
||||
|
||||
Experiment Manager
|
||||
--------------------
|
||||
.. autoclass:: qlib.workflow.expm.ExpManager
|
||||
:members:
|
||||
|
||||
Experiment
|
||||
--------------------
|
||||
.. autoclass:: qlib.workflow.exp.Experiment
|
||||
:members:
|
||||
|
||||
Recorder
|
||||
--------------------
|
||||
.. autoclass:: qlib.workflow.recorder.Recorder
|
||||
:members:
|
||||
|
||||
Record Template
|
||||
--------------------
|
||||
.. automodule:: qlib.workflow.record_temp
|
||||
:members:
|
||||
|
||||
Task Management
|
||||
====================
|
||||
|
||||
|
||||
TaskGen
|
||||
--------------------
|
||||
.. automodule:: qlib.workflow.task.gen
|
||||
:members:
|
||||
|
||||
TaskManager
|
||||
--------------------
|
||||
.. automodule:: qlib.workflow.task.manage
|
||||
:members:
|
||||
|
||||
Trainer
|
||||
--------------------
|
||||
.. automodule:: qlib.model.trainer
|
||||
:members:
|
||||
|
||||
Collector
|
||||
--------------------
|
||||
.. automodule:: qlib.workflow.task.collect
|
||||
:members:
|
||||
|
||||
Group
|
||||
--------------------
|
||||
.. automodule:: qlib.model.ens.group
|
||||
:members:
|
||||
|
||||
Ensemble
|
||||
--------------------
|
||||
.. automodule:: qlib.model.ens.ensemble
|
||||
:members:
|
||||
|
||||
Utils
|
||||
--------------------
|
||||
.. automodule:: qlib.workflow.task.utils
|
||||
:members:
|
||||
|
||||
|
||||
Online Serving
|
||||
====================
|
||||
|
||||
|
||||
Online Manager
|
||||
--------------------
|
||||
.. automodule:: qlib.workflow.online.manager
|
||||
:members:
|
||||
|
||||
Online Strategy
|
||||
--------------------
|
||||
.. automodule:: qlib.workflow.online.strategy
|
||||
:members:
|
||||
|
||||
Online Tool
|
||||
--------------------
|
||||
.. automodule:: qlib.workflow.online.utils
|
||||
:members:
|
||||
|
||||
|
||||
RecordUpdater
|
||||
--------------------
|
||||
.. automodule:: qlib.workflow.online.update
|
||||
:members:
|
||||
|
||||
|
||||
Utils
|
||||
====================
|
||||
|
||||
Serializable
|
||||
--------------------
|
||||
|
||||
.. automodule:: qlib.utils.serial.Serializable
|
||||
:members:
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
Cython==0.29.21
|
||||
Cython
|
||||
cmake
|
||||
numpy
|
||||
scipy
|
||||
scikit-learn
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.. _getdata:
|
||||
|
||||
=============================
|
||||
Data Retrieval
|
||||
=============================
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.. _initialization:
|
||||
|
||||
====================
|
||||
Qlib Initialization
|
||||
====================
|
||||
@@ -11,14 +12,16 @@ Initialization
|
||||
|
||||
Please follow the steps below to initialize ``Qlib``.
|
||||
|
||||
- Download and prepare the Data: execute the following command to download stock data.
|
||||
Download and prepare the Data: execute the following command to download stock data. Please pay `attention` that the data is collected from `Yahoo Finance <https://finance.yahoo.com/lookup>`_ and the data might not be perfect. We recommend users to prepare their own data if they have high-quality datasets. Please refer to `Data <../component/data.html#converting-csv-format-into-qlib-format>`_ for more information about customized dataset.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python scripts/get_data.py qlib_data_cn --target_dir ~/.qlib/qlib_data/cn_data
|
||||
Please refer to `Raw Data <../component/data.html>`_ for more information about ``get_data.py``,
|
||||
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn
|
||||
|
||||
Please refer to `Data Preparation <../component/data.html#data-preparation>`_ for more information about `get_data.py`,
|
||||
|
||||
|
||||
- Initialize Qlib before calling other APIs: run following code in python.
|
||||
Initialize Qlib before calling other APIs: run following code in python.
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
@@ -28,7 +31,8 @@ Please follow the steps below to initialize ``Qlib``.
|
||||
provider_uri = "~/.qlib/qlib_data/cn_data" # target_dir
|
||||
qlib.init(provider_uri=provider_uri, region=REG_CN)
|
||||
|
||||
|
||||
.. note::
|
||||
Do not import qlib package in the repository directory of ``Qlib``, otherwise, errors may occur.
|
||||
|
||||
Parameters
|
||||
-------------------
|
||||
@@ -43,7 +47,7 @@ Besides `provider_uri` and `region`, `qlib.init` has other parameters. The follo
|
||||
- ``qlib.config.REG_US``: US stock market.
|
||||
- ``qlib.config.REG_CN``: China stock market.
|
||||
|
||||
Different modse will result in different trading limitations and costs.
|
||||
Different modes will result in different trading limitations and costs.
|
||||
- `redis_host`
|
||||
Type: str, optional parameter(default: "127.0.0.1"), host of `redis`
|
||||
The lock and cache mechanism relies on redis.
|
||||
@@ -57,3 +61,29 @@ Besides `provider_uri` and `region`, `qlib.init` has other parameters. The follo
|
||||
.. note::
|
||||
|
||||
If Qlib fails to connect redis via `redis_host` and `redis_port`, cache mechanism will not be used! Please refer to `Cache <../component/data.html#cache>`_ for details.
|
||||
- `exp_manager`
|
||||
Type: dict, optional parameter, the setting of `experiment manager` to be used in qlib. Users can specify an experiment manager class, as well as the tracking URI for all the experiments. However, please be aware that we only support input of a dictionary in the following style for `exp_manager`. For more information about `exp_manager`, users can refer to `Recorder: Experiment Management <../component/recorder.html>`_.
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
# For example, if you want to set your tracking_uri to a <specific folder>, you can initialize qlib below
|
||||
qlib.init(provider_uri=provider_uri, region=REG_CN, exp_manager= {
|
||||
"class": "MLflowExpManager",
|
||||
"module_path": "qlib.workflow.expm",
|
||||
"kwargs": {
|
||||
"uri": "python_execution_path/mlruns",
|
||||
"default_exp_name": "Experiment",
|
||||
}
|
||||
})
|
||||
- `mongo`
|
||||
Type: dict, optional parameter, the setting of `MongoDB <https://www.mongodb.com/>`_ which will be used in some features such as `Task Management <../advanced/task_management.html>`_, with high performance and clustered processing.
|
||||
Users need to follow the steps in `installation <https://www.mongodb.com/try/download/community>`_ to install MongoDB firstly and then access it via a URI.
|
||||
Users can access mongodb with credential by setting "task_url" to a string like `"mongodb://%s:%s@%s" % (user, pwd, host + ":" + port)`.
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
# For example, you can initialize qlib below
|
||||
qlib.init(provider_uri=provider_uri, region=REG_CN, mongo={
|
||||
"task_url": "mongodb://localhost:27017/", # your mongo url
|
||||
"task_db_name": "rolling_db", # the database name of Task Management
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.. _installation:
|
||||
|
||||
====================
|
||||
Installation
|
||||
====================
|
||||
@@ -12,7 +13,14 @@ Installation
|
||||
|
||||
`Qlib` supports both `Windows` and `Linux`. It's recommended to use `Qlib` in `Linux`. ``Qlib`` supports Python3, which is up to Python3.8.
|
||||
|
||||
Please follow the steps below to install ``Qlib``:
|
||||
Users can easily install ``Qlib`` by pip according to the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install pyqlib
|
||||
|
||||
|
||||
Also, Users can install ``Qlib`` by the source code according to the following steps:
|
||||
|
||||
- Enter the root directory of ``Qlib``, in which the file ``setup.py`` exists.
|
||||
- Then, please execute the following command to install the environment dependencies and install ``Qlib``:
|
||||
@@ -24,12 +32,8 @@ Please follow the steps below to install ``Qlib``:
|
||||
$ git clone https://github.com/microsoft/qlib.git && cd qlib
|
||||
$ python setup.py install
|
||||
|
||||
|
||||
.. note::
|
||||
It's recommended to use anaconda/miniconda to setup the environment. ``Qlib`` needs lightgbm and pytorch packages, use pip to install them.
|
||||
|
||||
.. note::
|
||||
Do not import qlib in the root directory of ``Qlib``, otherwise, errors may occur.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,22 +5,22 @@ Custom Model Integration
|
||||
Introduction
|
||||
===================
|
||||
|
||||
``Qlib`` provides ``lightGBM`` and ``Dnn`` model as the baseline of ``Interday Model``. In addition to the default model, users can integrate their own custom models into ``Qlib``.
|
||||
``Qlib``'s `Model Zoo` includes models such as ``LightGBM``, ``MLP``, ``LSTM``, etc.. These models are examples of ``Forecast Model``. In addition to the default models ``Qlib`` provide, users can integrate their own custom models into ``Qlib``.
|
||||
|
||||
Users can integrate their own custom models according to the following steps.
|
||||
|
||||
- Define a custom model class, which should be a subclass of the `qlib.contrib.model.base.Model <../reference/api.html#module-qlib.contrib.model.base>`_.
|
||||
- Define a custom model class, which should be a subclass of the `qlib.model.base.Model <../reference/api.html#module-qlib.model.base>`_.
|
||||
- Write a configuration file that describes the path and parameters of the custom model.
|
||||
- Test the custom model.
|
||||
|
||||
Custom Model Class
|
||||
===========================
|
||||
The Custom models need to inherit `qlib.contrib.model.base.Model <../reference/api.html#module-qlib.contrib.model.base>`_ and override the methods in it.
|
||||
The Custom models need to inherit `qlib.model.base.Model <../reference/api.html#module-qlib.model.base>`_ and override the methods in it.
|
||||
|
||||
- Override the `__init__` method
|
||||
- ``Qlib`` passes the initialized parameters to the \_\_init\_\_ method.
|
||||
- The parameter must be consistent with the hyperparameters in the configuration file.
|
||||
- Code Example: In the following example, the hyperparameter filed of the configuration file should contain parameters such as `loss:mse`.
|
||||
- The hyperparameters of model in the configuration must be consistent with those defined in the `__init__` method.
|
||||
- Code Example: In the following example, the hyperparameters of model in the configuration file should contain parameters such as `loss:mse`.
|
||||
.. code-block:: Python
|
||||
|
||||
def __init__(self, loss='mse', **kwargs):
|
||||
@@ -31,80 +31,79 @@ The Custom models need to inherit `qlib.contrib.model.base.Model <../reference/a
|
||||
self._model = None
|
||||
|
||||
- Override the `fit` method
|
||||
- ``Qlib`` calls the fit method to train the model
|
||||
- The parameters must include training feature `x_train`, training label `y_train`, test feature `x_valid`, test label `y_valid` at least.
|
||||
- The parameters could include some optional parameters with default values, such as train weight `w_train`, test weight `w_valid` and `num_boost_round = 1000`.
|
||||
- ``Qlib`` calls the fit method to train the model.
|
||||
- The parameters must include training feature `dataset`, which is designed in the interface.
|
||||
- The parameters could include some `optional` parameters with default values, such as `num_boost_round = 1000` for `GBDT`.
|
||||
- Code Example: In the following example, `num_boost_round = 1000` is an optional parameter.
|
||||
.. code-block:: Python
|
||||
|
||||
def fit(self, x_train:pd.DataFrame, y_train:pd.DataFrame, x_valid:pd.DataFrame, y_valid:pd.DataFrame,
|
||||
w_train:pd.DataFrame = None, w_valid:pd.DataFrame = None, num_boost_round = 1000, **kwargs):
|
||||
def fit(self, dataset: DatasetH, num_boost_round = 1000, **kwargs):
|
||||
|
||||
# prepare dataset for lgb training and evaluation
|
||||
df_train, df_valid = dataset.prepare(
|
||||
["train", "valid"], col_set=["feature", "label"], data_key=DataHandlerLP.DK_L
|
||||
)
|
||||
x_train, y_train = df_train["feature"], df_train["label"]
|
||||
x_valid, y_valid = df_valid["feature"], df_valid["label"]
|
||||
|
||||
# Lightgbm need 1D array as its label
|
||||
if y_train.values.ndim == 2 and y_train.values.shape[1] == 1:
|
||||
y_train_1d, y_valid_1d = np.squeeze(y_train.values), np.squeeze(y_valid.values)
|
||||
y_train, y_valid = np.squeeze(y_train.values), np.squeeze(y_valid.values)
|
||||
else:
|
||||
raise ValueError('LightGBM doesn\'t support multi-label training')
|
||||
raise ValueError("LightGBM doesn't support multi-label training")
|
||||
|
||||
w_train_weight = None if w_train is None else w_train.values
|
||||
w_valid_weight = None if w_valid is None else w_valid.values
|
||||
dtrain = lgb.Dataset(x_train.values, label=y_train)
|
||||
dvalid = lgb.Dataset(x_valid.values, label=y_valid)
|
||||
|
||||
dtrain = lgb.Dataset(x_train.values, label=y_train_1d, weight=w_train_weight)
|
||||
dvalid = lgb.Dataset(x_valid.values, label=y_valid_1d, weight=w_valid_weight)
|
||||
self._model = lgb.train(
|
||||
self._params,
|
||||
dtrain,
|
||||
# fit the model
|
||||
self.model = lgb.train(
|
||||
self.params,
|
||||
dtrain,
|
||||
num_boost_round=num_boost_round,
|
||||
valid_sets=[dtrain, dvalid],
|
||||
valid_names=['train', 'valid'],
|
||||
valid_names=["train", "valid"],
|
||||
early_stopping_rounds=early_stopping_rounds,
|
||||
verbose_eval=verbose_eval,
|
||||
evals_result=evals_result,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
- Override the `predict` method
|
||||
- The parameters include the test features.
|
||||
- The parameters must include the parameter `dataset`, which will be userd to get the test dataset.
|
||||
- Return the `prediction score`.
|
||||
- Please refer to `qlib.contrib.model.base.Model <../reference/api.html#module-qlib.contrib.model.base>`_ for the parameter types of the fit method.
|
||||
- Code Example: In the following example, users need to use dnn to predict the label(such as `preds`) of test data `x_test` and return it.
|
||||
- Please refer to `Model API <../reference/api.html#module-qlib.model.base>`_ for the parameter types of the fit method.
|
||||
- Code Example: In the following example, users need to use `LightGBM` to predict the label(such as `preds`) of test data `x_test` and return it.
|
||||
.. code-block:: Python
|
||||
|
||||
def predict(self, x_test:pd.DataFrame, **kwargs)-> numpy.ndarray:
|
||||
if self._model is None:
|
||||
raise ValueError('model is not fitted yet!')
|
||||
return self._model.predict(x_test.values)
|
||||
def predict(self, dataset: DatasetH, **kwargs)-> pandas.Series:
|
||||
if self.model is None:
|
||||
raise ValueError("model is not fitted yet!")
|
||||
x_test = dataset.prepare("test", col_set="feature", data_key=DataHandlerLP.DK_I)
|
||||
return pd.Series(self.model.predict(x_test.values), index=x_test.index)
|
||||
|
||||
- Override the `score` method
|
||||
- The parameters include the test features and test labels.
|
||||
- Return the evaluation score of the model. It's recommended to adopt the loss between labels and `prediction score`.
|
||||
- Code Example: In the following example, users need to calculate the weighted loss with test data `x_test`, test label `y_test` and the weight `w_test`.
|
||||
- Override the `finetune` method (Optional)
|
||||
- This method is optional to the users. When users want to use this method on their own models, they should inherit the ``ModelFT`` base class, which includes the interface of `finetune`.
|
||||
- The parameters must include the parameter `dataset`.
|
||||
- Code Example: In the following example, users will use `LightGBM` as the model and finetune it.
|
||||
.. code-block:: Python
|
||||
|
||||
def score(self, x_test:pd.Dataframe, y_test:pd.Dataframe, w_test:pd.DataFrame = None) -> float:
|
||||
# Remove rows from x, y and w, which contain Nan in any columns in y_test.
|
||||
x_test, y_test, w_test = drop_nan_by_y_index(x_test, y_test, w_test)
|
||||
preds = self.predict(x_test)
|
||||
w_test_weight = None if w_test is None else w_test.values
|
||||
scorer = mean_squared_error if self.loss_type == 'mse' else roc_auc_score
|
||||
return scorer(y_test.values, preds, sample_weight=w_test_weight)
|
||||
|
||||
- Override the `save` method & `load` method
|
||||
- The `save` method parameter includes the a `filename` that represents an absolute path, user need to save model into the path.
|
||||
- The `load` method parameter includes the a `buffer` read from the `filename` passed in the `save` method, users need to load model from the `buffer`.
|
||||
- Code Example:
|
||||
.. code-block:: Python
|
||||
|
||||
def save(self, filename):
|
||||
if self._model is None:
|
||||
raise ValueError('model is not fitted yet!')
|
||||
self._model.save_model(filename)
|
||||
|
||||
def load(self, buffer):
|
||||
self._model = lgb.Booster(params={'model_str': buffer.decode('utf-8')})
|
||||
|
||||
def finetune(self, dataset: DatasetH, num_boost_round=10, verbose_eval=20):
|
||||
# Based on existing model and finetune by train more rounds
|
||||
dtrain, _ = self._prepare_data(dataset)
|
||||
self.model = lgb.train(
|
||||
self.params,
|
||||
dtrain,
|
||||
num_boost_round=num_boost_round,
|
||||
init_model=self.model,
|
||||
valid_sets=[dtrain],
|
||||
valid_names=["train"],
|
||||
verbose_eval=verbose_eval,
|
||||
)
|
||||
|
||||
Configuration File
|
||||
=======================
|
||||
|
||||
The configuration file is described in detail in the `estimator <../component/estimator.html#complete-example>`_ document. In order to integrate the custom model into ``Qlib``, users need to modify the "model" field in the configuration file.
|
||||
The configuration file is described in detail in the `Workflow <../component/workflow.html#complete-example>`_ document. In order to integrate the custom model into ``Qlib``, users need to modify the "model" field in the configuration file. The configuration describes which models to use and how we can initialize it.
|
||||
|
||||
- Example: The following example describes the `model` field of configuration file about the custom lightgbm model mentioned above, where `module_path` is the module path, `class` is the class name, and `args` is the hyperparameter passed into the __init__ method. All parameters in the field is passed to `self._params` by `\*\*kwargs` in `__init__` except `loss = mse`.
|
||||
|
||||
@@ -124,23 +123,23 @@ The configuration file is described in detail in the `estimator <../component/es
|
||||
num_leaves: 210
|
||||
num_threads: 20
|
||||
|
||||
Users could find configuration file of the baseline of the ``Model`` in ``qlib/examples/estimator/estimator_config.yaml`` and ``qlib/examples/estimator/estimator_config_dnn.yaml``
|
||||
Users could find configuration file of the baselines of the ``Model`` in ``examples/benchmarks``. All the configurations of different models are listed under the corresponding model folder.
|
||||
|
||||
Model Testing
|
||||
=====================
|
||||
Assuming that the configuration file is ``examples/estimator/estimator_config.yaml``, users can run the following command to test the custom model:
|
||||
Assuming that the configuration file is ``examples/benchmarks/LightGBM/workflow_config_lightgbm.yaml``, users can run the following command to test the custom model:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd examples # Avoid running program under the directory contains `qlib`
|
||||
estimator -c estimator/estimator_config.yaml
|
||||
qrun benchmarks/LightGBM/workflow_config_lightgbm.yaml
|
||||
|
||||
.. note:: ``estimator`` is a built-in command of ``Qlib``.
|
||||
.. note:: ``qrun`` is a built-in command of ``Qlib``.
|
||||
|
||||
Also, ``Model`` can also be tested as a single module. An example has been given in ``examples/train_backtest_analyze.ipynb``.
|
||||
Also, ``Model`` can also be tested as a single module. An example has been given in ``examples/workflow_by_code.ipynb``.
|
||||
|
||||
|
||||
Reference
|
||||
=====================
|
||||
|
||||
To know more about ``Model``, please refer to `Interday Model: Model Training & Prediction <../component/model.html>`_ and `Model API <../reference/api.html#module-qlib.contrib.model.base>`_.
|
||||
To know more about ``Forecast Model``, please refer to `Forecast Model: Model Training & Prediction <../component/model.html>`_ and `Model API <../reference/api.html#module-qlib.model.base>`_.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Requirements
|
||||
|
||||
Here is the minimal hardware requirements to run the example.
|
||||
Here is the minimal hardware requirements to run the `workflow_by_code` example.
|
||||
- Memory: 16G
|
||||
- Free Dick: 5G
|
||||
- Free Disk: 5G
|
||||
|
||||
|
||||
# NOTE
|
||||
|
||||
8
examples/benchmarks/ALSTM/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# ALSTM
|
||||
|
||||
- ALSTM contains a temporal attentive aggregation layer based on normal LSTM.
|
||||
|
||||
- Paper: A dual-stage attention-based recurrent neural network for time series prediction.
|
||||
|
||||
[https://www.ijcai.org/Proceedings/2017/0366.pdf](https://www.ijcai.org/Proceedings/2017/0366.pdf)
|
||||
|
||||
4
examples/benchmarks/ALSTM/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
numpy==1.17.4
|
||||
pandas==1.1.2
|
||||
scikit_learn==0.23.2
|
||||
torch==1.7.0
|
||||
100
examples/benchmarks/ALSTM/workflow_config_alstm_Alpha158.yaml
Executable file
@@ -0,0 +1,100 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors:
|
||||
- class: FilterCol
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
col_list: ["RESI5", "WVMA5", "RSQR5", "KLEN", "RSQR10", "CORR5", "CORD5", "CORR10",
|
||||
"ROC60", "RESI10", "VSTD5", "RSQR60", "CORR60", "WVMA60", "STD5",
|
||||
"RSQR20", "CORD60", "CORD10", "CORR20", "KLOW"
|
||||
]
|
||||
- class: RobustZScoreNorm
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
clip_outlier: true
|
||||
- class: Fillna
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: ALSTM
|
||||
module_path: qlib.contrib.model.pytorch_alstm_ts
|
||||
kwargs:
|
||||
d_feat: 20
|
||||
hidden_size: 64
|
||||
num_layers: 2
|
||||
dropout: 0.0
|
||||
n_epochs: 200
|
||||
lr: 1e-3
|
||||
early_stop: 10
|
||||
batch_size: 800
|
||||
metric: loss
|
||||
loss: mse
|
||||
n_jobs: 20
|
||||
GPU: 0
|
||||
rnn_type: GRU
|
||||
dataset:
|
||||
class: TSDatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
step_len: 20
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
@@ -0,0 +1,90 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors:
|
||||
- class: RobustZScoreNorm
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
clip_outlier: true
|
||||
- class: Fillna
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: ALSTM
|
||||
module_path: qlib.contrib.model.pytorch_alstm
|
||||
kwargs:
|
||||
d_feat: 6
|
||||
hidden_size: 64
|
||||
num_layers: 2
|
||||
dropout: 0.0
|
||||
n_epochs: 200
|
||||
lr: 1e-3
|
||||
early_stop: 20
|
||||
batch_size: 800
|
||||
metric: loss
|
||||
loss: mse
|
||||
GPU: 0
|
||||
rnn_type: GRU
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha360
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
3
examples/benchmarks/CatBoost/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# CatBoost
|
||||
* Code: [https://github.com/catboost/catboost](https://github.com/catboost/catboost)
|
||||
* Paper: CatBoost: unbiased boosting with categorical features. [https://proceedings.neurips.cc/paper/2018/file/14491b756b3a51daac41c24863285549-Paper.pdf](https://proceedings.neurips.cc/paper/2018/file/14491b756b3a51daac41c24863285549-Paper.pdf).
|
||||
3
examples/benchmarks/CatBoost/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
pandas==1.1.2
|
||||
numpy==1.17.4
|
||||
catboost==0.24.3
|
||||
@@ -0,0 +1,72 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: CatBoostModel
|
||||
module_path: qlib.contrib.model.catboost_model
|
||||
kwargs:
|
||||
loss: RMSE
|
||||
learning_rate: 0.0421
|
||||
subsample: 0.8789
|
||||
max_depth: 6
|
||||
num_leaves: 100
|
||||
thread_count: 20
|
||||
grow_policy: Lossguide
|
||||
bootstrap_type: Poisson
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
@@ -0,0 +1,79 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors: []
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: CatBoostModel
|
||||
module_path: qlib.contrib.model.catboost_model
|
||||
kwargs:
|
||||
loss: RMSE
|
||||
learning_rate: 0.0421
|
||||
subsample: 0.8789
|
||||
max_depth: 6
|
||||
num_leaves: 100
|
||||
thread_count: 20
|
||||
grow_policy: Lossguide
|
||||
bootstrap_type: Poisson
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha360
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
4
examples/benchmarks/DoubleEnsemble/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# DoubleEnsemble
|
||||
* DoubleEnsemble is an ensemble framework leveraging learning trajectory based sample reweighting and shuffling based feature selection, to solve both the low signal-to-noise ratio and increasing number of features problems. They identify the key samples based on the training dynamics on each sample and elicit key features based on the ablation impact of each feature via shuffling. The model is applicable to a wide range of base models, capable of extracting complex patterns, while mitigating the overfitting and instability issues for financial market prediction.
|
||||
* This code used in Qlib is implemented by ourselves.
|
||||
* Paper: DoubleEnsemble: A New Ensemble Method Based on Sample Reweighting and Feature Selection for Financial Data Analysis [https://arxiv.org/pdf/2010.01265.pdf](https://arxiv.org/pdf/2010.01265.pdf).
|
||||
3
examples/benchmarks/DoubleEnsemble/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
pandas==1.1.2
|
||||
numpy==1.17.4
|
||||
lightgbm==3.1.0
|
||||
@@ -0,0 +1,97 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: DEnsembleModel
|
||||
module_path: qlib.contrib.model.double_ensemble
|
||||
kwargs:
|
||||
base_model: "gbm"
|
||||
loss: mse
|
||||
num_models: 6
|
||||
enable_sr: True
|
||||
enable_fs: True
|
||||
alpha1: 1
|
||||
alpha2: 1
|
||||
bins_sr: 10
|
||||
bins_fs: 5
|
||||
decay: 0.5
|
||||
sample_ratios:
|
||||
- 0.8
|
||||
- 0.7
|
||||
- 0.6
|
||||
- 0.5
|
||||
- 0.4
|
||||
sub_weights:
|
||||
- 1
|
||||
- 0.2
|
||||
- 0.2
|
||||
- 0.2
|
||||
- 0.2
|
||||
- 0.2
|
||||
epochs: 28
|
||||
colsample_bytree: 0.8879
|
||||
learning_rate: 0.2
|
||||
subsample: 0.8789
|
||||
lambda_l1: 205.6999
|
||||
lambda_l2: 580.9768
|
||||
max_depth: 8
|
||||
num_leaves: 210
|
||||
num_threads: 20
|
||||
verbosity: -1
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
@@ -0,0 +1,104 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors: []
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: DEnsembleModel
|
||||
module_path: qlib.contrib.model.double_ensemble
|
||||
kwargs:
|
||||
base_model: "gbm"
|
||||
loss: mse
|
||||
num_models: 6
|
||||
enable_sr: True
|
||||
enable_fs: True
|
||||
alpha1: 1
|
||||
alpha2: 1
|
||||
bins_sr: 10
|
||||
bins_fs: 5
|
||||
decay: 0.5
|
||||
sample_ratios:
|
||||
- 0.8
|
||||
- 0.7
|
||||
- 0.6
|
||||
- 0.5
|
||||
- 0.4
|
||||
sub_weights:
|
||||
- 1
|
||||
- 0.2
|
||||
- 0.2
|
||||
- 0.2
|
||||
- 0.2
|
||||
- 0.2
|
||||
epochs: 136
|
||||
colsample_bytree: 0.8879
|
||||
learning_rate: 0.0421
|
||||
subsample: 0.8789
|
||||
lambda_l1: 205.6999
|
||||
lambda_l2: 580.9768
|
||||
max_depth: 8
|
||||
num_leaves: 210
|
||||
num_threads: 20
|
||||
verbosity: -1
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha360
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
5
examples/benchmarks/GATs/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# GATs
|
||||
* Graph Attention Networks(GATs) leverage masked self-attentional layers on graph-structured data. The nodes in stacked layers have different weights and they are able to attend over their
|
||||
neighborhoods’ features, without requiring any kind of costly matrix operation (such as inversion) or depending on knowing the graph structure upfront.
|
||||
* This code used in Qlib is implemented with PyTorch by ourselves.
|
||||
* Paper: Graph Attention Networks https://arxiv.org/pdf/1710.10903.pdf
|
||||
4
examples/benchmarks/GATs/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
pandas==1.1.2
|
||||
numpy==1.17.4
|
||||
scikit_learn==0.23.2
|
||||
torch==1.7.0
|
||||
98
examples/benchmarks/GATs/workflow_config_gats_Alpha158.yaml
Normal file
@@ -0,0 +1,98 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors:
|
||||
- class: FilterCol
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
col_list: ["RESI5", "WVMA5", "RSQR5", "KLEN", "RSQR10", "CORR5", "CORD5", "CORR10",
|
||||
"ROC60", "RESI10", "VSTD5", "RSQR60", "CORR60", "WVMA60", "STD5",
|
||||
"RSQR20", "CORD60", "CORD10", "CORR20", "KLOW"
|
||||
]
|
||||
- class: RobustZScoreNorm
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
clip_outlier: true
|
||||
- class: Fillna
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: GATs
|
||||
module_path: qlib.contrib.model.pytorch_gats_ts
|
||||
kwargs:
|
||||
d_feat: 20
|
||||
hidden_size: 64
|
||||
num_layers: 2
|
||||
dropout: 0.7
|
||||
n_epochs: 200
|
||||
lr: 1e-4
|
||||
early_stop: 10
|
||||
metric: loss
|
||||
loss: mse
|
||||
base_model: LSTM
|
||||
model_path: "benchmarks/LSTM/csi300_lstm_ts.pkl"
|
||||
GPU: 0
|
||||
dataset:
|
||||
class: TSDatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
step_len: 20
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
90
examples/benchmarks/GATs/workflow_config_gats_Alpha360.yaml
Normal file
@@ -0,0 +1,90 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors:
|
||||
- class: RobustZScoreNorm
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
clip_outlier: true
|
||||
- class: Fillna
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: GATs
|
||||
module_path: qlib.contrib.model.pytorch_gats
|
||||
kwargs:
|
||||
d_feat: 6
|
||||
hidden_size: 64
|
||||
num_layers: 2
|
||||
dropout: 0.7
|
||||
n_epochs: 200
|
||||
lr: 1e-4
|
||||
early_stop: 20
|
||||
metric: loss
|
||||
loss: mse
|
||||
base_model: LSTM
|
||||
model_path: "benchmarks/LSTM/model_lstm_csi300.pkl"
|
||||
GPU: 0
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha360
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
BIN
examples/benchmarks/GRU/csi300_gru_ts.pkl
Normal file
BIN
examples/benchmarks/GRU/model_gru_csi300.pkl
Normal file
4
examples/benchmarks/GRU/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
numpy==1.17.4
|
||||
pandas==1.1.2
|
||||
scikit_learn==0.23.2
|
||||
torch==1.7.0
|
||||
99
examples/benchmarks/GRU/workflow_config_gru_Alpha158.yaml
Executable file
@@ -0,0 +1,99 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors:
|
||||
- class: FilterCol
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
col_list: ["RESI5", "WVMA5", "RSQR5", "KLEN", "RSQR10", "CORR5", "CORD5", "CORR10",
|
||||
"ROC60", "RESI10", "VSTD5", "RSQR60", "CORR60", "WVMA60", "STD5",
|
||||
"RSQR20", "CORD60", "CORD10", "CORR20", "KLOW"
|
||||
]
|
||||
- class: RobustZScoreNorm
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
clip_outlier: true
|
||||
- class: Fillna
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: GRU
|
||||
module_path: qlib.contrib.model.pytorch_gru_ts
|
||||
kwargs:
|
||||
d_feat: 20
|
||||
hidden_size: 64
|
||||
num_layers: 2
|
||||
dropout: 0.0
|
||||
n_epochs: 200
|
||||
lr: 2e-4
|
||||
early_stop: 10
|
||||
batch_size: 800
|
||||
metric: loss
|
||||
loss: mse
|
||||
n_jobs: 20
|
||||
GPU: 0
|
||||
dataset:
|
||||
class: TSDatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
step_len: 20
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
89
examples/benchmarks/GRU/workflow_config_gru_Alpha360.yaml
Normal file
@@ -0,0 +1,89 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors:
|
||||
- class: RobustZScoreNorm
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
clip_outlier: true
|
||||
- class: Fillna
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: GRU
|
||||
module_path: qlib.contrib.model.pytorch_gru
|
||||
kwargs:
|
||||
d_feat: 6
|
||||
hidden_size: 64
|
||||
num_layers: 2
|
||||
dropout: 0.0
|
||||
n_epochs: 200
|
||||
lr: 1e-3
|
||||
early_stop: 20
|
||||
batch_size: 800
|
||||
metric: loss
|
||||
loss: mse
|
||||
GPU: 0
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha360
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
BIN
examples/benchmarks/LSTM/csi300_lstm_ts.pkl
Normal file
BIN
examples/benchmarks/LSTM/model_lstm_csi300.pkl
Normal file
4
examples/benchmarks/LSTM/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
numpy==1.17.4
|
||||
pandas==1.1.2
|
||||
scikit_learn==0.23.2
|
||||
torch==1.7.0
|
||||
99
examples/benchmarks/LSTM/workflow_config_lstm_Alpha158.yaml
Executable file
@@ -0,0 +1,99 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors:
|
||||
- class: FilterCol
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
col_list: ["RESI5", "WVMA5", "RSQR5", "KLEN", "RSQR10", "CORR5", "CORD5", "CORR10",
|
||||
"ROC60", "RESI10", "VSTD5", "RSQR60", "CORR60", "WVMA60", "STD5",
|
||||
"RSQR20", "CORD60", "CORD10", "CORR20", "KLOW"
|
||||
]
|
||||
- class: RobustZScoreNorm
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
clip_outlier: true
|
||||
- class: Fillna
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: LSTM
|
||||
module_path: qlib.contrib.model.pytorch_lstm_ts
|
||||
kwargs:
|
||||
d_feat: 20
|
||||
hidden_size: 64
|
||||
num_layers: 2
|
||||
dropout: 0.0
|
||||
n_epochs: 200
|
||||
lr: 1e-3
|
||||
early_stop: 10
|
||||
batch_size: 800
|
||||
metric: loss
|
||||
loss: mse
|
||||
n_jobs: 20
|
||||
GPU: 0
|
||||
dataset:
|
||||
class: TSDatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
step_len: 20
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
89
examples/benchmarks/LSTM/workflow_config_lstm_Alpha360.yaml
Normal file
@@ -0,0 +1,89 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors:
|
||||
- class: RobustZScoreNorm
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
clip_outlier: true
|
||||
- class: Fillna
|
||||
kwargs:
|
||||
fields_group: feature
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: LSTM
|
||||
module_path: qlib.contrib.model.pytorch_lstm
|
||||
kwargs:
|
||||
d_feat: 6
|
||||
hidden_size: 64
|
||||
num_layers: 2
|
||||
dropout: 0.0
|
||||
n_epochs: 200
|
||||
lr: 1e-3
|
||||
early_stop: 20
|
||||
batch_size: 800
|
||||
metric: loss
|
||||
loss: mse
|
||||
GPU: 0
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha360
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
4
examples/benchmarks/LightGBM/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# LightGBM
|
||||
* Code: [https://github.com/microsoft/LightGBM](https://github.com/microsoft/LightGBM)
|
||||
* Paper: LightGBM: A Highly Efficient Gradient Boosting
|
||||
Decision Tree. [https://proceedings.neurips.cc/paper/2017/file/6449f44a102fde848669bdd9eb6b76fa-Paper.pdf](https://proceedings.neurips.cc/paper/2017/file/6449f44a102fde848669bdd9eb6b76fa-Paper.pdf).
|
||||
18
examples/benchmarks/LightGBM/features_resample_N.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from qlib.data.inst_processor import InstProcessor
|
||||
from qlib.utils.resam import resam_calendar
|
||||
|
||||
|
||||
class ResampleNProcessor(InstProcessor):
|
||||
def __init__(self, target_frq: str, **kwargs):
|
||||
self.target_frq = target_frq
|
||||
|
||||
def __call__(self, df: pd.DataFrame, *args, **kwargs):
|
||||
df.index = pd.to_datetime(df.index)
|
||||
res_index = resam_calendar(df.index, "1min", self.target_frq)
|
||||
df = df.resample(self.target_frq).last().reindex(res_index)
|
||||
return df
|
||||
16
examples/benchmarks/LightGBM/features_sample.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import datetime
|
||||
import pandas as pd
|
||||
|
||||
from qlib.data.inst_processor import InstProcessor
|
||||
|
||||
|
||||
class Resample1minProcessor(InstProcessor):
|
||||
def __init__(self, hour: int, minute: int, **kwargs):
|
||||
self.hour = hour
|
||||
self.minute = minute
|
||||
|
||||
def __call__(self, df: pd.DataFrame, *args, **kwargs):
|
||||
df.index = pd.to_datetime(df.index)
|
||||
df = df.loc[df.index.time == datetime.time(self.hour, self.minute)]
|
||||
df.index = df.index.normalize()
|
||||
return df
|
||||
135
examples/benchmarks/LightGBM/multi_freq_handler.py
Normal file
@@ -0,0 +1,135 @@
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from qlib.data.dataset.loader import QlibDataLoader
|
||||
from qlib.contrib.data.handler import DataHandlerLP, _DEFAULT_LEARN_PROCESSORS, check_transform_proc
|
||||
|
||||
|
||||
class Avg15minLoader(QlibDataLoader):
|
||||
def load(self, instruments=None, start_time=None, end_time=None) -> pd.DataFrame:
|
||||
df = super(Avg15minLoader, self).load(instruments, start_time, end_time)
|
||||
if self.is_group:
|
||||
# feature_day(day freq) and feature_15min(1min freq, Average every 15 minutes) renamed feature
|
||||
df.columns = df.columns.map(lambda x: ("feature", x[1]) if x[0].startswith("feature") else x)
|
||||
return df
|
||||
|
||||
|
||||
class Avg15minHandler(DataHandlerLP):
|
||||
def __init__(
|
||||
self,
|
||||
instruments="csi500",
|
||||
start_time=None,
|
||||
end_time=None,
|
||||
freq="day",
|
||||
infer_processors=[],
|
||||
learn_processors=_DEFAULT_LEARN_PROCESSORS,
|
||||
fit_start_time=None,
|
||||
fit_end_time=None,
|
||||
process_type=DataHandlerLP.PTYPE_A,
|
||||
filter_pipe=None,
|
||||
inst_processor=None,
|
||||
**kwargs,
|
||||
):
|
||||
infer_processors = check_transform_proc(infer_processors, fit_start_time, fit_end_time)
|
||||
learn_processors = check_transform_proc(learn_processors, fit_start_time, fit_end_time)
|
||||
data_loader = Avg15minLoader(
|
||||
config=self.loader_config(), filter_pipe=filter_pipe, freq=freq, inst_processor=inst_processor
|
||||
)
|
||||
super().__init__(
|
||||
instruments=instruments,
|
||||
start_time=start_time,
|
||||
end_time=end_time,
|
||||
data_loader=data_loader,
|
||||
infer_processors=infer_processors,
|
||||
learn_processors=learn_processors,
|
||||
process_type=process_type,
|
||||
)
|
||||
|
||||
def loader_config(self):
|
||||
|
||||
# Results for dataset: df: pd.DataFrame
|
||||
# len(df.columns) == 6 + 6 * 16, len(df.index.get_level_values(level="datetime").unique()) == T
|
||||
# df.columns: close0, close1, ..., close16, open0, ..., open16, ..., vwap16
|
||||
# freq == day:
|
||||
# close0, open0, low0, high0, volume0, vwap0
|
||||
# freq == 1min:
|
||||
# close1, ..., close16, ..., vwap1, ..., vwap16
|
||||
# df.index.name == ["datetime", "instrument"]: pd.MultiIndex
|
||||
# Example:
|
||||
# feature ... label
|
||||
# close0 open0 low0 ... vwap1 vwap16 LABEL0
|
||||
# datetime instrument ...
|
||||
# 2020-10-09 SH600000 11.794546 11.819587 11.769505 ... NaN NaN -0.005214
|
||||
# 2020-10-15 SH600000 12.044961 11.944795 11.932274 ... NaN NaN -0.007202
|
||||
# ... ... ... ... ... ... ... ...
|
||||
# 2021-05-28 SZ300676 6.369684 6.495406 6.306568 ... NaN NaN -0.001321
|
||||
# 2021-05-31 SZ300676 6.601626 6.465643 6.465130 ... NaN NaN -0.023428
|
||||
|
||||
# features day: len(columns) == 6, freq = day
|
||||
# $close is the closing price of the current trading day:
|
||||
# if the user needs to get the `close` before the last T days, use Ref($close, T-1), for example:
|
||||
# $close Ref($close, 1) Ref($close, 2) Ref($close, 3) Ref($close, 4)
|
||||
# instrument datetime
|
||||
# SH600519 2021-06-01 244.271530
|
||||
# 2021-06-02 242.205917 244.271530
|
||||
# 2021-06-03 242.229889 242.205917 244.271530
|
||||
# 2021-06-04 245.421524 242.229889 242.205917 244.271530
|
||||
# 2021-06-07 247.547089 245.421524 242.229889 242.205917 244.271530
|
||||
|
||||
# WARNING: Ref($close, N), if N == 0, Ref($close, N) ==> $close
|
||||
|
||||
fields = ["$close", "$open", "$low", "$high", "$volume", "$vwap"]
|
||||
# names: close0, open0, ..., vwap0
|
||||
names = list(map(lambda x: x.strip("$") + "0", fields))
|
||||
|
||||
config = {"feature_day": (fields, names)}
|
||||
|
||||
# features 15min: len(columns) == 6 * 16, freq = 1min
|
||||
# $close is the closing price of the current trading day:
|
||||
# if the user gets 'close' for the i-th 15min of the last T days, use `Ref(Mean($close, 15), (T-1) * 240 + i * 15)`, for example:
|
||||
# Ref(Mean($close, 15), 225) Ref(Mean($close, 15), 465) Ref(Mean($close, 15), 705)
|
||||
# instrument datetime
|
||||
# SH600519 2021-05-31 241.769897 243.077942 244.712997
|
||||
# 2021-06-01 244.271530 241.769897 243.077942
|
||||
# 2021-06-02 242.205917 244.271530 241.769897
|
||||
|
||||
# WARNING: Ref(Mean($close, 15), N), if N == 0, Ref(Mean($close, 15), N) ==> Mean($close, 15)
|
||||
|
||||
# Results of the current script:
|
||||
# time: 09:00 --> 09:14, ..., 14:45 --> 14:59
|
||||
# fields: Ref(Mean($close, 15), 225), ..., Mean($close, 15)
|
||||
# name: close1, ..., close16
|
||||
#
|
||||
|
||||
# Expression description: take close as an example
|
||||
# Mean($close, 15) ==> df["$close"].rolling(15, min_periods=1).mean()
|
||||
# Ref(Mean($close, 15), 15) ==> df["$close"].rolling(15, min_periods=1).mean().shift(15)
|
||||
|
||||
# NOTE: The last data of each trading day, which is the average of the i-th 15 minutes
|
||||
|
||||
# Average:
|
||||
# Average of the i-th 15-minute period of each trading day: 1 <= i <= 250 // 16
|
||||
# Avg(15minutes): Ref(Mean($close, 15), 240 - i * 15)
|
||||
#
|
||||
# Average of the first 15 minutes of each trading day; i = 1
|
||||
# Avg(09:00 --> 09:14), df.index.loc["09:14"]: Ref(Mean($close, 15), 240- 1 * 15) ==> Ref(Mean($close, 15), 225)
|
||||
# Average of the last 15 minutes of each trading day; i = 16
|
||||
# Avg(14:45 --> 14:59), df.index.loc["14:59"]: Ref(Mean($close, 15), 240 - 16 * 15) ==> Ref(Mean($close, 15), 0) ==> Mean($close, 15)
|
||||
|
||||
# 15min resample to day
|
||||
# df.resample("1d").last()
|
||||
tmp_fields = []
|
||||
tmp_names = []
|
||||
for i, _f in enumerate(fields):
|
||||
_fields = [f"Ref(Mean({_f}, 15), {j * 15})" for j in range(1, 240 // 15)]
|
||||
_names = [f"{names[i][:-1]}{int(names[i][-1])+j}" for j in range(240 // 15 - 1, 0, -1)]
|
||||
_fields.append(f"Mean({_f}, 15)")
|
||||
_names.append(f"{names[i][:-1]}{int(names[i][-1])+240 // 15}")
|
||||
tmp_fields += _fields
|
||||
tmp_names += _names
|
||||
config["feature_15min"] = (tmp_fields, tmp_names)
|
||||
# label
|
||||
config["label"] = (["Ref($close, -2)/Ref($close, -1) - 1"], ["LABEL0"])
|
||||
return config
|
||||
3
examples/benchmarks/LightGBM/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
pandas==1.1.2
|
||||
numpy==1.17.4
|
||||
lightgbm==3.1.0
|
||||
@@ -0,0 +1,72 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: LGBModel
|
||||
module_path: qlib.contrib.model.gbdt
|
||||
kwargs:
|
||||
loss: mse
|
||||
colsample_bytree: 0.8879
|
||||
learning_rate: 0.2
|
||||
subsample: 0.8789
|
||||
lambda_l1: 205.6999
|
||||
lambda_l2: 580.9768
|
||||
max_depth: 8
|
||||
num_leaves: 210
|
||||
num_threads: 20
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
@@ -0,0 +1,86 @@
|
||||
qlib_init:
|
||||
provider_uri:
|
||||
day: "~/.qlib/qlib_data/cn_data"
|
||||
1min: "~/.qlib/qlib_data/cn_data_1min"
|
||||
region: cn
|
||||
dataset_cache: null
|
||||
maxtasksperchild: 1
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
# 1min closing time is 15:00:00
|
||||
end_time: "2020-08-01 15:00:00"
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
freq:
|
||||
label: day
|
||||
feature: 1min
|
||||
# with label as reference
|
||||
inst_processor:
|
||||
feature:
|
||||
- class: Resample1minProcessor
|
||||
module_path: features_sample.py
|
||||
kwargs:
|
||||
hour: 14
|
||||
minute: 56
|
||||
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy.strategy
|
||||
kwargs:
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
backtest:
|
||||
verbose: False
|
||||
limit_threshold: 0.095
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: LGBModel
|
||||
module_path: qlib.contrib.model.gbdt
|
||||
kwargs:
|
||||
loss: mse
|
||||
colsample_bytree: 0.8879
|
||||
learning_rate: 0.2
|
||||
subsample: 0.8789
|
||||
lambda_l1: 205.6999
|
||||
lambda_l2: 580.9768
|
||||
max_depth: 8
|
||||
num_leaves: 210
|
||||
num_threads: 20
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha158
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs: {}
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||
@@ -0,0 +1,80 @@
|
||||
qlib_init:
|
||||
provider_uri: "~/.qlib/qlib_data/cn_data"
|
||||
region: cn
|
||||
market: &market csi300
|
||||
benchmark: &benchmark SH000300
|
||||
data_handler_config: &data_handler_config
|
||||
start_time: 2008-01-01
|
||||
end_time: 2020-08-01
|
||||
fit_start_time: 2008-01-01
|
||||
fit_end_time: 2014-12-31
|
||||
instruments: *market
|
||||
infer_processors: []
|
||||
learn_processors:
|
||||
- class: DropnaLabel
|
||||
- class: CSRankNorm
|
||||
kwargs:
|
||||
fields_group: label
|
||||
label: ["Ref($close, -2) / Ref($close, -1) - 1"]
|
||||
port_analysis_config: &port_analysis_config
|
||||
strategy:
|
||||
class: TopkDropoutStrategy
|
||||
module_path: qlib.contrib.strategy
|
||||
kwargs:
|
||||
signal:
|
||||
- <MODEL>
|
||||
- <DATASET>
|
||||
topk: 50
|
||||
n_drop: 5
|
||||
backtest:
|
||||
start_time: 2017-01-01
|
||||
end_time: 2020-08-01
|
||||
account: 100000000
|
||||
benchmark: *benchmark
|
||||
exchange_kwargs:
|
||||
limit_threshold: 0.095
|
||||
deal_price: close
|
||||
open_cost: 0.0005
|
||||
close_cost: 0.0015
|
||||
min_cost: 5
|
||||
task:
|
||||
model:
|
||||
class: LGBModel
|
||||
module_path: qlib.contrib.model.gbdt
|
||||
kwargs:
|
||||
loss: mse
|
||||
colsample_bytree: 0.8879
|
||||
learning_rate: 0.0421
|
||||
subsample: 0.8789
|
||||
lambda_l1: 205.6999
|
||||
lambda_l2: 580.9768
|
||||
max_depth: 8
|
||||
num_leaves: 210
|
||||
num_threads: 20
|
||||
dataset:
|
||||
class: DatasetH
|
||||
module_path: qlib.data.dataset
|
||||
kwargs:
|
||||
handler:
|
||||
class: Alpha360
|
||||
module_path: qlib.contrib.data.handler
|
||||
kwargs: *data_handler_config
|
||||
segments:
|
||||
train: [2008-01-01, 2014-12-31]
|
||||
valid: [2015-01-01, 2016-12-31]
|
||||
test: [2017-01-01, 2020-08-01]
|
||||
record:
|
||||
- class: SignalRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
model: <MODEL>
|
||||
dataset: <DATASET>
|
||||
- class: SigAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
ana_long_short: False
|
||||
ann_scaler: 252
|
||||
- class: PortAnaRecord
|
||||
module_path: qlib.workflow.record_temp
|
||||
kwargs:
|
||||
config: *port_analysis_config
|
||||