├── README.md
├── betas-dow.csv
├── LICENSE
├── betas-nasdaq.csv
├── .gitignore
├── betas-sp500.csv
├── betas.csv
├── daytrade.py
├── model.py
├── betas-russell2000.csv
└── timeseriestransformer_stocks.ipynb
/README.md:
--------------------------------------------------------------------------------
1 | # tft-stocks
2 | Inference model for stock prediction using Temporal Fusion Transformers for Interpretable Multi-horizon Time Series Forecasting
3 |
--------------------------------------------------------------------------------
/betas-dow.csv:
--------------------------------------------------------------------------------
1 | ,Ticker,Beta
2 | 3,BA,1.44
3 | 10,GS,1.42
4 | 9,DOW,1.33
5 | 0,AAPL,1.3
6 | 8,DIS,1.3
7 | 5,CRM,1.21
8 | 2,AXP,1.2
9 | 7,CVX,1.15
10 | 22,NKE,1.11
11 | 12,HON,1.11
12 | 16,JPM,1.1
13 | 4,CAT,1.1
14 | 6,CSCO,0.98
15 | 26,V,0.97
16 | 19,MMM,0.96
17 | 11,HD,0.93
18 | 21,MSFT,0.92
19 | 13,IBM,0.85
20 | 14,INTC,0.81
21 | 28,WBA,0.72
22 | 25,UNH,0.69
23 | 1,AMGN,0.65
24 | 24,TRV,0.63
25 | 18,MCD,0.62
26 | 17,KO,0.54
27 | 15,JNJ,0.53
28 | 29,WMT,0.49
29 | 23,PG,0.39
30 | 20,MRK,0.35
31 | 27,VZ,0.34
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Murali Balcha
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/betas-nasdaq.csv:
--------------------------------------------------------------------------------
1 | ,Ticker,Beta
2 | 61,TSLA,2.07
3 | 68,AMD,1.95
4 | 48,NVDA,1.76
5 | 96,MRNA,1.7
6 | 14,AMAT,1.61
7 | 69,ALGN,1.6
8 | 38,MAR,1.59
9 | 95,MELI,1.59
10 | 41,MCHP,1.57
11 | 49,NXPI,1.53
12 | 94,MTCH,1.51
13 | 15,ADSK,1.51
14 | 37,LRCX,1.49
15 | 93,MRVL,1.47
16 | 42,MU,1.39
17 | 80,KLAC,1.38
18 | 26,EBAY,1.36
19 | 92,LULU,1.35
20 | 74,CTAS,1.33
21 | 53,PYPL,1.31
22 | 65,BKNG,1.31
23 | 54,QCOM,1.3
24 | 2,AAPL,1.3
25 | 58,SWKS,1.29
26 | 100,SPLK,1.29
27 | 33,ISRG,1.29
28 | 8,ADBE,1.27
29 | 47,NFLX,1.26
30 | 101,WDAY,1.26
31 | 11,AMZN,1.25
32 | 71,ANSS,1.24
33 | 83,ASMLF,1.24
34 | 84,ASML,1.24
35 | 24,CSX,1.22
36 | 77,CPRT,1.21
37 | 109,LCID,1.19
38 | 108,META,1.18
39 | 81,SNPS,1.18
40 | 79,IDXX,1.18
41 | 28,FAST,1.17
42 | 106,PANW,1.16
43 | 104,ABNB,1.16
44 | 32,INTU,1.16
45 | 31,ILMN,1.15
46 | 13,ADI,1.14
47 | 78,FTNT,1.14
48 | 20,CHTR,1.12
49 | 72,AVGO,1.12
50 | 97,OKTA,1.12
51 | 21,CTSH,1.11
52 | 67,HON,1.11
53 | 9,GOOGL,1.09
54 | 10,GOOG,1.09
55 | 85,DXCM,1.09
56 | 86,ODFL,1.08
57 | 39,0P0000KQL0,1.08
58 | 40,0P0001I1JH,1.08
59 | 73,CDNS,1.07
60 | 103,CRWD,1.02
61 | 62,TXN,1.02
62 | 90,DOCU,1.0
63 | 22,CMCSA,1.0
64 | 56,ROST,0.99
65 | 82,VRSN,0.99
66 | 105,DDOG,0.99
67 | 3,CSCO,0.98
68 | 52,PAYX,0.98
69 | 57,SIRI,0.97
70 | 59,SBUX,0.94
71 | 51,PCAR,0.94
72 | 5,MSFT,0.92
73 | 107,ZS,0.88
74 | 50,ORLY,0.88
75 | 44,MNST,0.87
76 | 29,FISV,0.86
77 | 27,EA,0.85
78 | 63,VRSK,0.84
79 | 89,TEAM,0.83
80 | 16,ADP,0.82
81 | 4,INTC,0.81
82 | 23,COST,0.79
83 | 98,PDD,0.76
84 | 6,WBA,0.72
85 | 36,KHC,0.7
86 | 17,BIDU,0.68
87 | 18,BAIDF,0.68
88 | 25,DLTR,0.68
89 | 43,MDLZ,0.66
90 | 12,AMGN,0.65
91 | 66,EXC,0.59
92 | 91,KDP,0.58
93 | 60,TMUS,0.56
94 | 87,PEP,0.54
95 | 99,SGEN,0.53
96 | 46,NETTF,0.49
97 | 45,NTES,0.49
98 | 64,VRTX,0.48
99 | 35,JDCMF,0.48
100 | 34,JD,0.48
101 | 70,AEP,0.44
102 | 7,ATVI,0.42
103 | 88,XEL,0.42
104 | 30,GILD,0.4
105 | 55,REGN,0.21
106 | 19,BIIB,0.19
107 | 1,AZNCF,0.17
108 | 0,AZN,0.17
109 | 102,ZM,-0.22
110 | 75,STZ,
111 | 76,CEG,
112 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
--------------------------------------------------------------------------------
/betas-sp500.csv:
--------------------------------------------------------------------------------
1 | ,Ticker,Beta
2 | 0,APA,3.51
3 | 1,CZR,2.88
4 | 2,NCLH,2.51
5 | 3,RCL,2.49
6 | 4,MRO,2.41
7 | 5,DVN,2.39
8 | 6,TRGP,2.28
9 | 7,HAL,2.14
10 | 8,TSLA,2.11
11 | 9,MGM,2.07
12 | 10,APTV,2.04
13 | 11,FANG,2.02
14 | 12,WYNN,2.01
15 | 13,FCX,2.0
16 | 14,AMD,1.95
17 | 15,DXCM,1.12
18 | 16,URI,1.87
19 | 17,ETSY,1.86
20 | 18,PANW,1.16
21 | 19,OXY,1.8
22 | 20,SLB,1.8
23 | 21,NVDA,1.79
24 | 22,KVUE,0.00
25 | 23,BBWI,1.76
26 | 24,ON,1.76
27 | 25,PARA,1.65
28 | 26,WDC,1.65
29 | 27,MRNA,1.64
30 | 28,HCA,1.63
31 | 29,SYF,1.63
32 | 30,VLO,1.63
33 | 31,OKE,1.62
34 | 32,EXPE,1.61
35 | 33,AMAT,1.61
36 | 34,ZBRA,1.61
37 | 35,NUE,1.6
38 | 36,STT,1.6
39 | 37,MPC,1.6
40 | 38,ALGN,1.6
41 | 39,C,1.59
42 | 40,TRMB,1.59
43 | 41,MCHP,1.59
44 | 42,MAR,1.59
45 | 43,ALB,1.58
46 | 44,MOS,1.56
47 | 45,HES,1.56
48 | 46,EPAM,1.56
49 | 47,AAL,1.55
50 | 48,PH,1.55
51 | 49,ALK,1.54
52 | 50,TER,1.54
53 | 51,SPG,1.54
54 | 52,DHI,1.53
55 | 53,BBY,1.53
56 | 54,STLD,1.53
57 | 55,EOG,1.52
58 | 56,F,1.52
59 | 57,ADSK,1.51
60 | 58,NXPI,1.51
61 | 59,WBD,1.51
62 | 60,WHR,1.5
63 | 61,COF,1.49
64 | 62,AMP,1.49
65 | 63,EMN,1.48
66 | 64,WY,1.48
67 | 65,LRCX,1.47
68 | 66,WAB,1.47
69 | 67,TXT,1.47
70 | 68,ROK,1.46
71 | 69,KMX,1.46
72 | 70,BKR,1.45
73 | 71,DFS,1.45
74 | 72,KIM,1.45
75 | 73,IR,1.45
76 | 74,EFX,1.45
77 | 75,CDAY,1.45
78 | 76,MTCH,1.45
79 | 77,UAL,1.44
80 | 78,BA,1.44
81 | 79,PXD,1.42
82 | 80,TPR,1.42
83 | 81,QRVO,1.42
84 | 82,LEN,1.42
85 | 83,BAC,1.41
86 | 84,BWA,1.41
87 | 85,PRU,1.41
88 | 86,GS,1.41
89 | 87,RL,1.4
90 | 88,IQV,1.39
91 | 89,PSX,1.39
92 | 90,TDG,1.39
93 | 91,GM,1.38
94 | 92,CBRE,1.38
95 | 93,LKQ,1.37
96 | 94,EMR,1.37
97 | 95,FSLR,1.36
98 | 96,CRL,1.36
99 | 97,KLAC,1.36
100 | 98,IVZ,1.36
101 | 99,DOV,1.35
102 | 100,HWM,1.35
103 | 101,MU,1.34
104 | 102,PAYC,1.34
105 | 103,MS,1.34
106 | 104,ENPH,1.34
107 | 105,CFG,1.34
108 | 106,FDX,1.34
109 | 107,PHM,1.34
110 | 108,EBAY,1.33
111 | 109,DOW,1.33
112 | 110,ULTA,1.32
113 | 111,IT,1.32
114 | 112,HST,1.32
115 | 113,CTAS,1.32
116 | 114,SEDG,1.32
117 | 115,BKNG,1.31
118 | 116,TEL,1.31
119 | 117,PFG,1.31
120 | 118,RHI,1.31
121 | 119,SWK,1.31
122 | 120,BEN,1.31
123 | 121,COP,1.31
124 | 122,CMG,1.3
125 | 123,AAPL,1.3
126 | 124,CE,1.3
127 | 125,PYPL,1.3
128 | 126,NWS,1.3
129 | 127,TROW,1.3
130 | 128,NSC,1.3
131 | 129,DIS,1.3
132 | 130,BLK,1.3
133 | 131,NWSA,1.3
134 | 132,KEY,1.29
135 | 133,LYV,1.29
136 | 134,QCOM,1.29
137 | 135,ISRG,1.28
138 | 136,MHK,1.28
139 | 137,ADBE,1.27
140 | 138,FICO,1.27
141 | 139,MCO,1.26
142 | 140,CTLT,1.26
143 | 141,NFLX,1.26
144 | 142,DAL,1.26
145 | 143,AOS,1.26
146 | 144,AMZN,1.25
147 | 145,APH,1.25
148 | 146,DD,1.25
149 | 147,SWKS,1.25
150 | 148,HLT,1.25
151 | 149,SEE,1.25
152 | 150,JCI,1.24
153 | 151,ACN,1.24
154 | 152,ANSS,1.24
155 | 153,UHS,1.24
156 | 154,ANET,1.24
157 | 155,VTR,1.23
158 | 156,FITB,1.23
159 | 157,LYB,1.23
160 | 158,RF,1.23
161 | 159,CMA,1.23
162 | 160,GE,1.23
163 | 161,CSX,1.22
164 | 162,WMB,1.22
165 | 163,AME,1.22
166 | 164,DRI,1.22
167 | 165,FRT,1.22
168 | 166,CPRT,1.21
169 | 167,MAS,1.21
170 | 168,FLT,1.21
171 | 169,TECH,1.21
172 | 170,SNPS,1.2
173 | 171,HPE,1.2
174 | 172,WFC,1.2
175 | 173,AXP,1.2
176 | 174,GWW,1.2
177 | 175,GNRC,1.19
178 | 176,CRM,1.19
179 | 177,EQT,1.19
180 | 178,TT,1.19
181 | 179,MTD,1.18
182 | 180,VTRS,1.18
183 | 181,META,1.18
184 | 182,PPG,1.18
185 | 183,CARR,1.17
186 | 184,FAST,1.17
187 | 185,IDXX,1.17
188 | 186,LVS,1.17
189 | 187,NTAP,1.17
190 | 188,REG,1.16
191 | 189,WRK,1.16
192 | 190,AIG,1.16
193 | 191,CVX,1.16
194 | 192,FTV,1.16
195 | 193,PTC,1.15
196 | 194,WST,1.15
197 | 195,INTU,1.15
198 | 196,ZION,1.15
199 | 197,ETN,1.15
200 | 198,MPWR,1.14
201 | 199,LUV,1.14
202 | 200,ADI,1.14
203 | 201,HUBB,0.90
204 | 202,HBAN,1.14
205 | 203,ILMN,1.13
206 | 204,FTNT,1.13
207 | 205,ITW,1.13
208 | 206,CDW,1.13
209 | 207,JBHT,1.13
210 | 208,AVGO,1.12
211 | 209,PWR,1.12
212 | 210,LOW,1.12
213 | 211,PNC,1.12
214 | 212,MSCI,1.12
215 | 213,CHTR,1.12
216 | 214,SNA,1.12
217 | 215,UPS,1.12
218 | 217,IPG,1.11
219 | 218,UNP,1.11
220 | 219,ABNB,1.23
221 | 220,BXP,1.11
222 | 221,PCG,1.11
223 | 222,JPM,1.1
224 | 223,ALLE,1.1
225 | 224,XOM,1.1
226 | 225,PNR,1.1
227 | 226,HON,1.1
228 | 227,CAT,1.1
229 | 228,SYY,1.09
230 | 229,ODFL,1.09
231 | 230,NKE,1.09
232 | 231,TFC,1.09
233 | 232,GOOGL,1.09
234 | 233,GOOG,1.09
235 | 234,BK,1.09
236 | 235,STX,1.09
237 | 236,NTRS,1.09
238 | 237,GLW,1.08
239 | 239,SPGI,1.08
240 | 240,TDY,1.08
241 | 241,MET,1.08
242 | 242,MA,1.08
243 | 243,WELL,1.07
244 | 244,FFIV,1.07
245 | 245,IFF,1.07
246 | 246,SHW,1.07
247 | 247,CTSH,1.07
248 | 248,CDNS,1.07
249 | 249,RJF,1.06
250 | 250,DE,1.06
251 | 251,CF,1.05
252 | 252,A,1.05
253 | 253,LH,1.05
254 | 254,XYL,1.05
255 | 255,KEYS,1.04
256 | 256,GEN,1.04
257 | 257,TGT,1.04
258 | 258,IP,1.03
259 | 259,ROP,1.03
260 | 260,HOLX,1.03
261 | 261,HPQ,1.03
262 | 262,ZBH,1.02
263 | 263,STZ,1.01
264 | 264,ORCL,1.01
265 | 265,TXN,1.01
266 | 266,CMI,1.01
267 | 267,VICI,1.0
268 | 268,NVR,1.0
269 | 269,PLD,1.0
270 | 270,GPN,1.0
271 | 271,ECL,1.0
272 | 272,CMCSA,1.0
273 | 273,EW,1.0
274 | 274,USB,1.0
275 | 275,AVY,0.99
276 | 276,NOW,0.99
277 | 277,TFX,0.99
278 | 278,EXPD,0.98
279 | 279,BR,0.98
280 | 280,IEX,0.98
281 | 281,ROST,0.98
282 | 282,YUM,0.98
283 | 283,PAYX,0.98
284 | 284,VFC,0.97
285 | 285,DVA,0.97
286 | 286,VRSN,0.97
287 | 287,GRMN,0.96
288 | 288,EL,0.96
289 | 289,NRG,0.96
290 | 290,ARE,0.96
291 | 291,V,0.96
292 | 292,MMM,0.96
293 | 293,GPC,0.95
294 | 294,CSCO,0.95
295 | 295,PCAR,0.95
296 | 296,NDAQ,0.95
297 | 297,XRAY,0.95
298 | 298,SYK,0.94
299 | 299,IRM,0.94
300 | 300,AFL,0.94
301 | 301,KMI,0.94
302 | 302,HD,0.94
303 | 303,JNPR,0.93
304 | 304,MSI,0.93
305 | 305,DGX,0.93
306 | 306,SCHW,0.93
307 | 307,AES,0.93
308 | 308,BIO,0.93
309 | 309,AVB,0.92
310 | 310,MSFT,0.92
311 | 311,SBUX,0.92
312 | 312,ICE,0.92
313 | 313,COR,0.54
314 | 314,ORLY,0.91
315 | 315,POOL,0.91
316 | 316,NDSN,0.91
317 | 317,MMC,0.9
318 | 318,PKG,0.9
319 | 319,MLM,0.89
320 | 320,COO,0.89
321 | 321,INVH,0.89
322 | 322,AON,0.89
323 | 323,HIG,0.89
324 | 324,FOX,0.88
325 | 325,J,0.88
326 | 326,MNST,0.88
327 | 327,BRK-B,0.88
328 | 328,TAP,0.88
329 | 329,LIN,0.88
330 | 330,PEAK,0.88
331 | 331,FOXA,0.88
332 | 332,TJX,0.88
333 | 333,TSCO,0.87
334 | 334,CNP,0.87
335 | 335,FMC,0.87
336 | 336,WAT,0.86
337 | 337,CSGP,0.86
338 | 338,ELV,0.86
339 | 339,OMC,0.86
340 | 340,FI,0.86
341 | 341,APD,0.86
342 | 342,IBM,0.85
343 | 343,AMCR,0.85
344 | 344,STE,0.85
345 | 345,FIS,0.83
346 | 346,L,0.83
347 | 347,EA,0.83
348 | 348,OTIS,0.82
349 | 349,ADP,0.82
350 | 350,EQR,0.82
351 | 351,FDS,0.82
352 | 352,GD,0.82
353 | 353,VRSK,0.82
354 | 354,GL,0.82
355 | 355,CPT,0.81
356 | 356,MTB,0.81
357 | 357,TYL,0.81
358 | 358,DHR,0.8
359 | 359,CHRW,0.8
360 | 360,PPL,0.8
361 | 361,O,0.8
362 | 362,TMO,0.79
363 | 363,HSIC,0.79
364 | 364,COST,0.79
365 | 365,ADM,0.79
366 | 366,BSX,0.79
367 | 367,CTVA,0.79
368 | 368,EIX,0.79
369 | 369,VMC,0.79
370 | 370,INTC,0.78
371 | 371,AKAM,0.78
372 | 372,LDOS,0.78
373 | 373,BALL,0.78
374 | 374,MAA,0.77
375 | 375,ESS,0.77
376 | 376,CAH,0.77
377 | 377,T,0.76
378 | 378,WTW,0.75
379 | 379,UDR,0.75
380 | 380,BRO,0.75
381 | 381,ZTS,0.74
382 | 382,ACGL,0.74
383 | 383,PODD,0.74
384 | 384,RTX,0.74
385 | 385,MKTX,0.74
386 | 386,MDT,0.73
387 | 387,WBA,0.73
388 | 388,KHC,0.73
389 | 389,TSN,0.73
390 | 390,INCY,0.73
391 | 391,HUM,0.72
392 | 392,TTWO,0.72
393 | 393,WM,0.72
394 | 394,DPZ,0.72
395 | 395,HAS,0.72
396 | 396,LHX,0.71
397 | 397,PM,0.71
398 | 398,SRE,0.71
399 | 399,DLTR,0.7
400 | 400,BF-B,0.7
401 | 401,AJG,0.7
402 | 402,AZO,0.69
403 | 403,UNH,0.69
404 | 404,MOH,0.69
405 | 405,LMT,0.68
406 | 406,CI,0.68
407 | 407,CB,0.67
408 | 408,RSG,0.67
409 | 409,ABT,0.67
410 | 410,BG,0.66
411 | 411,CCI,0.66
412 | 412,MO,0.66
413 | 413,MDLZ,0.66
414 | 414,CINF,0.65
415 | 415,CVS,0.65
416 | 416,AMGN,0.65
417 | 417,MCD,0.64
418 | 418,JKHY,0.64
419 | 419,TRV,0.64
420 | 420,EQIX,0.63
421 | 421,ETR,0.63
422 | 422,ROL,0.63
423 | 423,WRB,0.62
424 | 424,ATO,0.61
425 | 425,EG,0.61
426 | 426,MCK,0.61
427 | 427,HII,0.6
428 | 428,ABBV,0.59
429 | 429,EXC,0.59
430 | 430,DTE,0.59
431 | 431,ALL,0.59
432 | 432,PFE,0.58
433 | 433,PEG,0.58
434 | 434,KDP,0.58
435 | 435,PEP,0.57
436 | 436,BAX,0.56
437 | 437,BDX,0.56
438 | 438,CNC,0.56
439 | 439,AMT,0.56
440 | 440,KO,0.56
441 | 441,EXR,0.56
442 | 442,AWK,0.56
443 | 443,TMUS,0.56
444 | 444,DLR,0.55
445 | 445,MKC,0.55
446 | 446,JNJ,0.54
447 | 447,CAG,0.54
448 | 448,LULU,1.35
449 | 449,LW,0.53
450 | 450,WMT,0.53
451 | 451,AIZ,0.53
452 | 452,LNT,0.51
453 | 453,NOC,0.5
454 | 454,KR,0.49
455 | 455,SBAC,0.49
456 | 456,CBOE,0.48
457 | 457,SO,0.48
458 | 458,PGR,0.48
459 | 459,ES,0.47
460 | 460,EVRG,0.47
461 | 461,CL,0.47
462 | 462,NI,0.47
463 | 463,RMD,0.47
464 | 464,VRTX,0.46
465 | 465,CHD,0.45
466 | 466,BMY,0.45
467 | 467,D,0.45
468 | 468,AEP,0.44
469 | 469,NEE,0.44
470 | 470,CME,0.43
471 | 471,PNW,0.43
472 | 472,PSA,0.43
473 | 473,AEE,0.43
474 | 474,K,0.42
475 | 475,XEL,0.42
476 | 476,BX,1.43
477 | 477,KMB,0.42
478 | 478,FE,0.42
479 | 479,DUK,0.41
480 | 480,GILD,0.41
481 | 481,PG,0.4
482 | 482,WEC,0.39
483 | 483,MRK,0.37
484 | 484,ED,0.35
485 | 485,HSY,0.35
486 | 486,LLY,0.35
487 | 487,VZ,0.34
488 | 488,DG,0.34
489 | 489,CMS,0.33
490 | 490,CPB,0.32
491 | 491,GIS,0.3
492 | 492,NEM,0.3
493 | 493,CLX,0.27
494 | 494,CTRA,0.26
495 | 495,REGN,0.24
496 | 496,SJM,0.21
497 | 497,BIIB,0.19
498 | 498,HRL,0.18
499 | 499,VLTO,0.0
500 | 500,GEHC,0.0
501 | 501,CCL,0.0
502 | 502,CEG,0.0
503 | 503,AXON,0.0
504 | 504,RVTY,0.0
505 |
--------------------------------------------------------------------------------
/betas.csv:
--------------------------------------------------------------------------------
1 | ,Unnamed: 0,index,Ticker,Attribute,Recent
2 | 0,39,667,APA,Beta (5Y Monthly),3.51
3 | 1,126,2146,CZR,Beta (5Y Monthly),2.88
4 | 2,326,5546,NCLH,Beta (5Y Monthly),2.51
5 | 3,391,6651,RCL,Beta (5Y Monthly),2.49
6 | 4,317,5393,MRO,Beta (5Y Monthly),2.41
7 | 5,147,2503,DVN,Beta (5Y Monthly),2.39
8 | 6,444,7552,TRGP,Beta (5Y Monthly),2.28
9 | 7,215,3659,HAL,Beta (5Y Monthly),2.14
10 | 8,449,7637,TSLA,Beta (5Y Monthly),2.11
11 | 9,302,5138,MGM,Beta (5Y Monthly),2.07
12 | 10,42,718,APTV,Beta (5Y Monthly),2.04
13 | 11,178,3030,FANG,Beta (5Y Monthly),2.02
14 | 502,493,8385,WYNN,Beta (5Y Monthly),2.01
15 | 12,180,3064,FCX,Beta (5Y Monthly),2.0
16 | 13,29,497,AMD,Beta (5Y Monthly),1.95
17 | 14,148,2520,DXC,Beta (5Y Monthly),1.94
18 | 15,463,7875,URI,Beta (5Y Monthly),1.87
19 | 16,170,2894,ETSY,Beta (5Y Monthly),1.86
20 | 17,137,2333,DISH,Beta (5Y Monthly),1.81
21 | 18,356,6056,OXY,Beta (5Y Monthly),1.8
22 | 19,413,7025,SLB,Beta (5Y Monthly),1.8
23 | 20,341,5801,NVDA,Beta (5Y Monthly),1.79
24 | 491,281,4781,LNC,Beta (5Y Monthly),1.79
25 | 22,56,956,BBWI,Beta (5Y Monthly),1.76
26 | 21,352,5988,ON,Beta (5Y Monthly),1.76
27 | 24,357,6073,PARA,Beta (5Y Monthly),1.65
28 | 23,480,8164,WDC,Beta (5Y Monthly),1.65
29 | 25,316,5376,MRNA,Beta (5Y Monthly),1.64
30 | 26,218,3710,HCA,Beta (5Y Monthly),1.63
31 | 27,427,7263,SYF,Beta (5Y Monthly),1.63
32 | 28,468,7960,VLO,Beta (5Y Monthly),1.63
33 | 29,350,5954,OKE,Beta (5Y Monthly),1.62
34 | 487,175,2979,EXPE,Beta (5Y Monthly),1.61
35 | 30,27,463,AMAT,Beta (5Y Monthly),1.61
36 | 31,500,8504,ZBRA,Beta (5Y Monthly),1.61
37 | 33,340,5784,NUE,Beta (5Y Monthly),1.6
38 | 34,422,7178,STT,Beta (5Y Monthly),1.6
39 | 35,313,5325,MPC,Beta (5Y Monthly),1.6
40 | 32,23,395,ALGN,Beta (5Y Monthly),1.6
41 | 36,75,1279,C,Beta (5Y Monthly),1.59
42 | 37,445,7569,TRMB,Beta (5Y Monthly),1.59
43 | 38,295,5019,MCHP,Beta (5Y Monthly),1.59
44 | 39,292,4968,MAR,Beta (5Y Monthly),1.59
45 | 40,22,378,ALB,Beta (5Y Monthly),1.58
46 | 41,312,5308,MOS,Beta (5Y Monthly),1.56
47 | 42,220,3744,HES,Beta (5Y Monthly),1.56
48 | 43,162,2758,EPAM,Beta (5Y Monthly),1.56
49 | 44,1,21,AAL,Beta (5Y Monthly),1.55
50 | 45,369,6277,PH,Beta (5Y Monthly),1.55
51 | 46,24,412,ALK,Beta (5Y Monthly),1.54
52 | 47,436,7416,TER,Beta (5Y Monthly),1.54
53 | 48,417,7093,SPG,Beta (5Y Monthly),1.54
54 | 50,134,2282,DHI,Beta (5Y Monthly),1.53
55 | 51,57,973,BBY,Beta (5Y Monthly),1.53
56 | 49,421,7161,STLD,Beta (5Y Monthly),1.53
57 | 52,161,2741,EOG,Beta (5Y Monthly),1.52
58 | 53,177,3013,F,Beta (5Y Monthly),1.52
59 | 56,13,225,ADSK,Beta (5Y Monthly),1.51
60 | 54,346,5886,NXPI,Beta (5Y Monthly),1.51
61 | 55,479,8147,WBD,Beta (5Y Monthly),1.51
62 | 57,484,8232,WHR,Beta (5Y Monthly),1.5
63 | 58,107,1823,COF,Beta (5Y Monthly),1.49
64 | 59,32,548,AMP,Beta (5Y Monthly),1.49
65 | 60,158,2690,EMN,Beta (5Y Monthly),1.48
66 | 61,492,8368,WY,Beta (5Y Monthly),1.48
67 | 64,284,4832,LRCX,Beta (5Y Monthly),1.47
68 | 63,476,8096,WAB,Beta (5Y Monthly),1.47
69 | 62,454,7722,TXT,Beta (5Y Monthly),1.47
70 | 66,400,6804,ROK,Beta (5Y Monthly),1.46
71 | 65,269,4577,KMX,Beta (5Y Monthly),1.46
72 | 67,66,1126,BKR,Beta (5Y Monthly),1.45
73 | 69,131,2231,DFS,Beta (5Y Monthly),1.45
74 | 70,265,4509,KIM,Beta (5Y Monthly),1.45
75 | 71,247,4203,IR,Beta (5Y Monthly),1.45
76 | 72,154,2622,EFX,Beta (5Y Monthly),1.45
77 | 73,85,1449,CDAY,Beta (5Y Monthly),1.45
78 | 68,323,5495,MTCH,Beta (5Y Monthly),1.45
79 | 74,456,7756,UAL,Beta (5Y Monthly),1.44
80 | 75,52,888,BA,Beta (5Y Monthly),1.44
81 | 76,387,6583,PXD,Beta (5Y Monthly),1.42
82 | 79,443,7535,TPR,Beta (5Y Monthly),1.42
83 | 77,390,6634,QRVO,Beta (5Y Monthly),1.42
84 | 78,274,4662,LEN,Beta (5Y Monthly),1.42
85 | 81,53,905,BAC,Beta (5Y Monthly),1.41
86 | 80,73,1245,BWA,Beta (5Y Monthly),1.41
87 | 82,382,6498,PRU,Beta (5Y Monthly),1.41
88 | 83,213,3625,GS,Beta (5Y Monthly),1.41
89 | 84,398,6770,RL,Beta (5Y Monthly),1.4
90 | 85,246,4186,IQV,Beta (5Y Monthly),1.39
91 | 86,384,6532,PSX,Beta (5Y Monthly),1.39
92 | 87,432,7348,TDG,Beta (5Y Monthly),1.39
93 | 88,206,3506,GM,Beta (5Y Monthly),1.38
94 | 89,82,1398,CBRE,Beta (5Y Monthly),1.38
95 | 90,278,4730,LKQ,Beta (5Y Monthly),1.37
96 | 91,159,2707,EMR,Beta (5Y Monthly),1.37
97 | 95,195,3319,FSLR,Beta (5Y Monthly),1.36
98 | 94,114,1942,CRL,Beta (5Y Monthly),1.36
99 | 93,266,4526,KLAC,Beta (5Y Monthly),1.36
100 | 92,252,4288,IVZ,Beta (5Y Monthly),1.36
101 | 96,140,2384,DOV,Beta (5Y Monthly),1.35
102 | 97,233,3965,HWM,Beta (5Y Monthly),1.35
103 | 99,325,5529,MU,Beta (5Y Monthly),1.34
104 | 100,358,6090,PAYC,Beta (5Y Monthly),1.34
105 | 101,318,5410,MS,Beta (5Y Monthly),1.34
106 | 102,160,2724,ENPH,Beta (5Y Monthly),1.34
107 | 103,91,1551,CFG,Beta (5Y Monthly),1.34
108 | 104,182,3098,FDX,Beta (5Y Monthly),1.34
109 | 98,370,6294,PHM,Beta (5Y Monthly),1.34
110 | 105,151,2571,EBAY,Beta (5Y Monthly),1.33
111 | 106,141,2401,DOW,Beta (5Y Monthly),1.33
112 | 111,459,7807,ULTA,Beta (5Y Monthly),1.32
113 | 109,250,4254,IT,Beta (5Y Monthly),1.32
114 | 107,230,3914,HST,Beta (5Y Monthly),1.32
115 | 108,119,2027,CTAS,Beta (5Y Monthly),1.32
116 | 110,409,6957,SEDG,Beta (5Y Monthly),1.32
117 | 112,65,1109,BKNG,Beta (5Y Monthly),1.31
118 | 113,435,7399,TEL,Beta (5Y Monthly),1.31
119 | 114,366,6226,PFG,Beta (5Y Monthly),1.31
120 | 115,396,6736,RHI,Beta (5Y Monthly),1.31
121 | 116,425,7229,SWK,Beta (5Y Monthly),1.31
122 | 117,59,1007,BEN,Beta (5Y Monthly),1.31
123 | 118,109,1857,COP,Beta (5Y Monthly),1.31
124 | 128,102,1738,CMG,Beta (5Y Monthly),1.3
125 | 127,3,55,AAPL,Beta (5Y Monthly),1.3
126 | 126,88,1500,CE,Beta (5Y Monthly),1.3
127 | 125,388,6600,PYPL,Beta (5Y Monthly),1.3
128 | 124,344,5852,NWS,Beta (5Y Monthly),1.3
129 | 123,446,7586,TROW,Beta (5Y Monthly),1.3
130 | 122,337,5733,NSC,Beta (5Y Monthly),1.3
131 | 121,136,2316,DIS,Beta (5Y Monthly),1.3
132 | 120,67,1143,BLK,Beta (5Y Monthly),1.3
133 | 119,345,5869,NWSA,Beta (5Y Monthly),1.3
134 | 129,262,4458,KEY,Beta (5Y Monthly),1.29
135 | 130,289,4917,LYV,Beta (5Y Monthly),1.29
136 | 131,389,6617,QCOM,Beta (5Y Monthly),1.29
137 | 132,249,4237,ISRG,Beta (5Y Monthly),1.28
138 | 493,303,5155,MHK,Beta (5Y Monthly),1.28
139 | 133,9,157,ADBE,Beta (5Y Monthly),1.27
140 | 134,185,3149,FICO,Beta (5Y Monthly),1.27
141 | 135,297,5053,MCO,Beta (5Y Monthly),1.26
142 | 136,120,2044,CTLT,Beta (5Y Monthly),1.26
143 | 137,331,5631,NFLX,Beta (5Y Monthly),1.26
144 | 138,128,2180,DAL,Beta (5Y Monthly),1.26
145 | 139,38,650,AOS,Beta (5Y Monthly),1.26
146 | 140,34,582,AMZN,Beta (5Y Monthly),1.25
147 | 141,41,701,APH,Beta (5Y Monthly),1.25
148 | 484,129,2197,DD,Beta (5Y Monthly),1.25
149 | 142,426,7246,SWKS,Beta (5Y Monthly),1.25
150 | 143,223,3795,HLT,Beta (5Y Monthly),1.25
151 | 144,410,6974,SEE,Beta (5Y Monthly),1.25
152 | 146,255,4339,JCI,Beta (5Y Monthly),1.24
153 | 148,8,140,ACN,Beta (5Y Monthly),1.24
154 | 145,36,616,ANSS,Beta (5Y Monthly),1.24
155 | 147,458,7790,UHS,Beta (5Y Monthly),1.24
156 | 149,35,599,ANET,Beta (5Y Monthly),1.24
157 | 154,473,8045,VTR,Beta (5Y Monthly),1.23
158 | 150,188,3200,FITB,Beta (5Y Monthly),1.23
159 | 492,288,4900,LYB,Beta (5Y Monthly),1.23
160 | 153,395,6719,RF,Beta (5Y Monthly),1.23
161 | 151,99,1687,CMA,Beta (5Y Monthly),1.23
162 | 152,199,3387,GE,Beta (5Y Monthly),1.23
163 | 155,118,2010,CSX,Beta (5Y Monthly),1.22
164 | 156,486,8266,WMB,Beta (5Y Monthly),1.22
165 | 157,30,514,AME,Beta (5Y Monthly),1.22
166 | 158,143,2435,DRI,Beta (5Y Monthly),1.22
167 | 159,194,3302,FRT,Beta (5Y Monthly),1.22
168 | 163,112,1908,CPRT,Beta (5Y Monthly),1.21
169 | 162,293,4985,MAS,Beta (5Y Monthly),1.21
170 | 161,189,3217,FLT,Beta (5Y Monthly),1.21
171 | 160,434,7382,TECH,Beta (5Y Monthly),1.21
172 | 167,415,7059,SNPS,Beta (5Y Monthly),1.2
173 | 168,226,3846,HPE,Beta (5Y Monthly),1.2
174 | 165,483,8215,WFC,Beta (5Y Monthly),1.2
175 | 164,50,854,AXP,Beta (5Y Monthly),1.2
176 | 166,214,3642,GWW,Beta (5Y Monthly),1.2
177 | 169,207,3523,GNRC,Beta (5Y Monthly),1.19
178 | 170,115,1959,CRM,Beta (5Y Monthly),1.19
179 | 171,165,2809,EQT,Beta (5Y Monthly),1.19
180 | 501,451,7671,TT,Beta (5Y Monthly),1.19
181 | 496,324,5512,MTD,Beta (5Y Monthly),1.18
182 | 172,474,8062,VTRS,Beta (5Y Monthly),1.18
183 | 173,301,5121,META,Beta (5Y Monthly),1.18
184 | 174,380,6464,PPG,Beta (5Y Monthly),1.18
185 | 177,78,1330,CARR,Beta (5Y Monthly),1.17
186 | 175,179,3047,FAST,Beta (5Y Monthly),1.17
187 | 176,236,4016,IDXX,Beta (5Y Monthly),1.17
188 | 178,286,4866,LVS,Beta (5Y Monthly),1.17
189 | 179,338,5750,NTAP,Beta (5Y Monthly),1.17
190 | 181,393,6685,REG,Beta (5Y Monthly),1.16
191 | 180,489,8317,WRK,Beta (5Y Monthly),1.16
192 | 182,18,310,AIG,Beta (5Y Monthly),1.16
193 | 183,125,2129,CVX,Beta (5Y Monthly),1.16
194 | 184,197,3353,FTV,Beta (5Y Monthly),1.16
195 | 188,385,6549,PTC,Beta (5Y Monthly),1.15
196 | 187,490,8334,WST,Beta (5Y Monthly),1.15
197 | 189,242,4118,INTU,Beta (5Y Monthly),1.15
198 | 185,501,8521,ZION,Beta (5Y Monthly),1.15
199 | 186,168,2860,ETN,Beta (5Y Monthly),1.15
200 | 494,314,5342,MPWR,Beta (5Y Monthly),1.14
201 | 190,285,4849,LUV,Beta (5Y Monthly),1.14
202 | 191,10,174,ADI,Beta (5Y Monthly),1.14
203 | 193,2,38,AAP,Beta (5Y Monthly),1.14
204 | 192,217,3693,HBAN,Beta (5Y Monthly),1.14
205 | 198,239,4067,ILMN,Beta (5Y Monthly),1.13
206 | 197,196,3336,FTNT,Beta (5Y Monthly),1.13
207 | 196,251,4271,ITW,Beta (5Y Monthly),1.13
208 | 195,87,1483,CDW,Beta (5Y Monthly),1.13
209 | 194,254,4322,JBHT,Beta (5Y Monthly),1.13
210 | 202,47,803,AVGO,Beta (5Y Monthly),1.12
211 | 199,386,6566,PWR,Beta (5Y Monthly),1.12
212 | 200,283,4815,LOW,Beta (5Y Monthly),1.12
213 | 201,375,6379,PNC,Beta (5Y Monthly),1.12
214 | 203,319,5427,MSCI,Beta (5Y Monthly),1.12
215 | 204,94,1602,CHTR,Beta (5Y Monthly),1.12
216 | 205,414,7042,SNA,Beta (5Y Monthly),1.12
217 | 206,462,7858,UPS,Beta (5Y Monthly),1.12
218 | 210,193,3285,FRC,Beta (5Y Monthly),1.11
219 | 489,245,4169,IPG,Beta (5Y Monthly),1.11
220 | 207,461,7841,UNP,Beta (5Y Monthly),1.11
221 | 208,149,2537,DXCM,Beta (5Y Monthly),1.11
222 | 209,74,1262,BXP,Beta (5Y Monthly),1.11
223 | 211,361,6141,PCG,Beta (5Y Monthly),1.11
224 | 217,259,4407,JPM,Beta (5Y Monthly),1.1
225 | 216,26,446,ALLE,Beta (5Y Monthly),1.1
226 | 215,495,8419,XOM,Beta (5Y Monthly),1.1
227 | 214,376,6396,PNR,Beta (5Y Monthly),1.1
228 | 213,225,3829,HON,Beta (5Y Monthly),1.1
229 | 212,79,1347,CAT,Beta (5Y Monthly),1.1
230 | 221,429,7297,SYY,Beta (5Y Monthly),1.09
231 | 219,348,5920,ODFL,Beta (5Y Monthly),1.09
232 | 222,333,5665,NKE,Beta (5Y Monthly),1.09
233 | 220,437,7433,TFC,Beta (5Y Monthly),1.09
234 | 218,209,3557,GOOGL,Beta (5Y Monthly),1.09
235 | 226,208,3540,GOOG,Beta (5Y Monthly),1.09
236 | 225,64,1092,BK,Beta (5Y Monthly),1.09
237 | 224,423,7195,STX,Beta (5Y Monthly),1.09
238 | 223,339,5767,NTRS,Beta (5Y Monthly),1.09
239 | 231,205,3489,GLW,Beta (5Y Monthly),1.08
240 | 230,372,6328,PKI,Beta (5Y Monthly),1.08
241 | 229,418,7110,SPGI,Beta (5Y Monthly),1.08
242 | 228,433,7365,TDY,Beta (5Y Monthly),1.08
243 | 227,300,5104,MET,Beta (5Y Monthly),1.08
244 | 232,290,4934,MA,Beta (5Y Monthly),1.08
245 | 233,482,8198,WELL,Beta (5Y Monthly),1.07
246 | 238,184,3132,FFIV,Beta (5Y Monthly),1.07
247 | 237,238,4050,IFF,Beta (5Y Monthly),1.07
248 | 236,411,6991,SHW,Beta (5Y Monthly),1.07
249 | 235,122,2078,CTSH,Beta (5Y Monthly),1.07
250 | 234,86,1466,CDNS,Beta (5Y Monthly),1.07
251 | 240,397,6753,RJF,Beta (5Y Monthly),1.06
252 | 239,130,2214,DE,Beta (5Y Monthly),1.06
253 | 244,90,1534,CF,Beta (5Y Monthly),1.05
254 | 243,0,4,A,Beta (5Y Monthly),1.05
255 | 242,275,4679,LH,Beta (5Y Monthly),1.05
256 | 241,497,8453,XYL,Beta (5Y Monthly),1.05
257 | 245,263,4475,KEYS,Beta (5Y Monthly),1.04
258 | 246,201,3421,GEN,Beta (5Y Monthly),1.04
259 | 247,439,7467,TGT,Beta (5Y Monthly),1.04
260 | 251,244,4152,IP,Beta (5Y Monthly),1.03
261 | 248,402,6838,ROP,Beta (5Y Monthly),1.03
262 | 249,224,3812,HOLX,Beta (5Y Monthly),1.03
263 | 250,227,3863,HPQ,Beta (5Y Monthly),1.03
264 | 252,499,8487,ZBH,Beta (5Y Monthly),1.02
265 | 253,424,7212,STZ,Beta (5Y Monthly),1.01
266 | 254,353,6005,ORCL,Beta (5Y Monthly),1.01
267 | 255,453,7705,TXN,Beta (5Y Monthly),1.01
268 | 256,103,1755,CMI,Beta (5Y Monthly),1.01
269 | 259,467,7943,VICI,Beta (5Y Monthly),1.0
270 | 260,342,5818,NVR,Beta (5Y Monthly),1.0
271 | 499,373,6345,PLD,Beta (5Y Monthly),1.0
272 | 257,211,3591,GPN,Beta (5Y Monthly),1.0
273 | 258,152,2588,ECL,Beta (5Y Monthly),1.0
274 | 261,100,1704,CMCSA,Beta (5Y Monthly),1.0
275 | 262,172,2928,EW,Beta (5Y Monthly),1.0
276 | 263,464,7892,USB,Beta (5Y Monthly),1.0
277 | 264,48,820,AVY,Beta (5Y Monthly),0.99
278 | 265,335,5699,NOW,Beta (5Y Monthly),0.99
279 | 266,438,7450,TFX,Beta (5Y Monthly),0.99
280 | 272,174,2962,EXPD,Beta (5Y Monthly),0.98
281 | 267,69,1177,BR,Beta (5Y Monthly),0.98
282 | 268,237,4033,IEX,Beta (5Y Monthly),0.98
283 | 269,403,6855,ROST,Beta (5Y Monthly),0.98
284 | 270,498,8470,YUM,Beta (5Y Monthly),0.98
285 | 271,359,6107,PAYX,Beta (5Y Monthly),0.98
286 | 273,466,7926,VFC,Beta (5Y Monthly),0.97
287 | 275,146,2486,DVA,Beta (5Y Monthly),0.97
288 | 274,471,8011,VRSN,Beta (5Y Monthly),0.97
289 | 281,212,3608,GRMN,Beta (5Y Monthly),0.96
290 | 280,156,2656,EL,Beta (5Y Monthly),0.96
291 | 279,336,5716,NRG,Beta (5Y Monthly),0.96
292 | 278,43,735,ARE,Beta (5Y Monthly),0.96
293 | 277,465,7909,V,Beta (5Y Monthly),0.96
294 | 276,308,5240,MMM,Beta (5Y Monthly),0.96
295 | 282,210,3574,GPC,Beta (5Y Monthly),0.95
296 | 285,116,1976,CSCO,Beta (5Y Monthly),0.95
297 | 283,360,6124,PCAR,Beta (5Y Monthly),0.95
298 | 284,327,5563,NDAQ,Beta (5Y Monthly),0.95
299 | 286,496,8436,XRAY,Beta (5Y Monthly),0.95
300 | 287,428,7280,SYK,Beta (5Y Monthly),0.94
301 | 288,248,4220,IRM,Beta (5Y Monthly),0.94
302 | 289,17,293,AFL,Beta (5Y Monthly),0.94
303 | 290,268,4560,KMI,Beta (5Y Monthly),0.94
304 | 291,219,3727,HD,Beta (5Y Monthly),0.94
305 | 294,258,4390,JNPR,Beta (5Y Monthly),0.93
306 | 495,321,5461,MSI,Beta (5Y Monthly),0.93
307 | 296,133,2265,DGX,Beta (5Y Monthly),0.93
308 | 292,408,6940,SCHW,Beta (5Y Monthly),0.93
309 | 295,16,276,AES,Beta (5Y Monthly),0.93
310 | 293,63,1075,BIO,Beta (5Y Monthly),0.93
311 | 297,46,786,AVB,Beta (5Y Monthly),0.92
312 | 298,320,5444,MSFT,Beta (5Y Monthly),0.92
313 | 300,407,6923,SBUX,Beta (5Y Monthly),0.92
314 | 299,235,3999,ICE,Beta (5Y Monthly),0.92
315 | 301,343,5835,NWL,Beta (5Y Monthly),0.92
316 | 304,354,6022,ORLY,Beta (5Y Monthly),0.91
317 | 303,379,6447,POOL,Beta (5Y Monthly),0.91
318 | 302,328,5580,NDSN,Beta (5Y Monthly),0.91
319 | 306,307,5223,MMC,Beta (5Y Monthly),0.9
320 | 305,371,6311,PKG,Beta (5Y Monthly),0.9
321 | 310,306,5206,MLM,Beta (5Y Monthly),0.89
322 | 307,108,1840,COO,Beta (5Y Monthly),0.89
323 | 308,243,4135,INVH,Beta (5Y Monthly),0.89
324 | 309,37,633,AON,Beta (5Y Monthly),0.89
325 | 311,221,3761,HIG,Beta (5Y Monthly),0.89
326 | 320,191,3251,FOX,Beta (5Y Monthly),0.88
327 | 318,253,4305,J,Beta (5Y Monthly),0.88
328 | 312,309,5257,MNST,Beta (5Y Monthly),0.88
329 | 313,70,1194,BRK-B,Beta (5Y Monthly),0.88
330 | 314,431,7331,TAP,Beta (5Y Monthly),0.88
331 | 315,277,4713,LIN,Beta (5Y Monthly),0.88
332 | 317,362,6158,PEAK,Beta (5Y Monthly),0.88
333 | 319,192,3268,FOXA,Beta (5Y Monthly),0.88
334 | 316,440,7484,TJX,Beta (5Y Monthly),0.88
335 | 321,448,7620,TSCO,Beta (5Y Monthly),0.87
336 | 322,106,1806,CNP,Beta (5Y Monthly),0.87
337 | 323,190,3234,FMC,Beta (5Y Monthly),0.87
338 | 326,477,8113,WAT,Beta (5Y Monthly),0.86
339 | 324,117,1993,CSGP,Beta (5Y Monthly),0.86
340 | 325,157,2673,ELV,Beta (5Y Monthly),0.86
341 | 327,351,5971,OMC,Beta (5Y Monthly),0.86
342 | 328,187,3183,FISV,Beta (5Y Monthly),0.86
343 | 329,40,684,APD,Beta (5Y Monthly),0.86
344 | 330,234,3982,IBM,Beta (5Y Monthly),0.85
345 | 331,28,480,AMCR,Beta (5Y Monthly),0.85
346 | 500,420,7144,STE,Beta (5Y Monthly),0.85
347 | 333,186,3166,FIS,Beta (5Y Monthly),0.83
348 | 490,272,4628,L,Beta (5Y Monthly),0.83
349 | 332,150,2554,EA,Beta (5Y Monthly),0.83
350 | 498,355,6039,OTIS,Beta (5Y Monthly),0.82
351 | 334,12,208,ADP,Beta (5Y Monthly),0.82
352 | 486,164,2792,EQR,Beta (5Y Monthly),0.82
353 | 335,181,3081,FDS,Beta (5Y Monthly),0.82
354 | 336,198,3370,GD,Beta (5Y Monthly),0.82
355 | 337,470,7994,VRSK,Beta (5Y Monthly),0.82
356 | 338,204,3472,GL,Beta (5Y Monthly),0.82
357 | 340,113,1925,CPT,Beta (5Y Monthly),0.81
358 | 341,322,5478,MTB,Beta (5Y Monthly),0.81
359 | 339,455,7739,TYL,Beta (5Y Monthly),0.81
360 | 342,135,2299,DHR,Beta (5Y Monthly),0.8
361 | 343,93,1585,CHRW,Beta (5Y Monthly),0.8
362 | 344,381,6481,PPL,Beta (5Y Monthly),0.8
363 | 345,347,5903,O,Beta (5Y Monthly),0.8
364 | 351,441,7501,TMO,Beta (5Y Monthly),0.79
365 | 346,229,3897,HSIC,Beta (5Y Monthly),0.79
366 | 347,110,1874,COST,Beta (5Y Monthly),0.79
367 | 348,11,191,ADM,Beta (5Y Monthly),0.79
368 | 349,72,1228,BSX,Beta (5Y Monthly),0.79
369 | 350,123,2095,CTVA,Beta (5Y Monthly),0.79
370 | 352,155,2639,EIX,Beta (5Y Monthly),0.79
371 | 353,469,7977,VMC,Beta (5Y Monthly),0.79
372 | 354,241,4101,INTC,Beta (5Y Monthly),0.78
373 | 355,21,361,AKAM,Beta (5Y Monthly),0.78
374 | 356,273,4645,LDOS,Beta (5Y Monthly),0.78
375 | 357,54,922,BALL,Beta (5Y Monthly),0.78
376 | 358,291,4951,MAA,Beta (5Y Monthly),0.77
377 | 359,167,2843,ESS,Beta (5Y Monthly),0.77
378 | 360,77,1313,CAH,Beta (5Y Monthly),0.77
379 | 361,430,7314,T,Beta (5Y Monthly),0.76
380 | 364,491,8351,WTW,Beta (5Y Monthly),0.75
381 | 362,457,7773,UDR,Beta (5Y Monthly),0.75
382 | 363,71,1211,BRO,Beta (5Y Monthly),0.75
383 | 369,502,8538,ZTS,Beta (5Y Monthly),0.74
384 | 368,7,123,ACGL,Beta (5Y Monthly),0.74
385 | 365,378,6430,PODD,Beta (5Y Monthly),0.74
386 | 366,405,6889,RTX,Beta (5Y Monthly),0.74
387 | 367,305,5189,MKTX,Beta (5Y Monthly),0.74
388 | 374,299,5087,MDT,Beta (5Y Monthly),0.73
389 | 372,478,8130,WBA,Beta (5Y Monthly),0.73
390 | 371,264,4492,KHC,Beta (5Y Monthly),0.73
391 | 370,450,7654,TSN,Beta (5Y Monthly),0.73
392 | 373,240,4084,INCY,Beta (5Y Monthly),0.73
393 | 379,232,3948,HUM,Beta (5Y Monthly),0.72
394 | 378,452,7688,TTWO,Beta (5Y Monthly),0.72
395 | 377,485,8249,WM,Beta (5Y Monthly),0.72
396 | 376,142,2418,DPZ,Beta (5Y Monthly),0.72
397 | 375,216,3676,HAS,Beta (5Y Monthly),0.72
398 | 381,276,4696,LHX,Beta (5Y Monthly),0.71
399 | 380,374,6362,PM,Beta (5Y Monthly),0.71
400 | 382,419,7127,SRE,Beta (5Y Monthly),0.71
401 | 383,139,2367,DLTR,Beta (5Y Monthly),0.7
402 | 384,60,1024,BF-B,Beta (5Y Monthly),0.7
403 | 385,20,344,AJG,Beta (5Y Monthly),0.7
404 | 387,51,871,AZO,Beta (5Y Monthly),0.69
405 | 386,460,7824,UNH,Beta (5Y Monthly),0.69
406 | 388,311,5291,MOH,Beta (5Y Monthly),0.69
407 | 389,280,4764,LMT,Beta (5Y Monthly),0.68
408 | 390,95,1619,CI,Beta (5Y Monthly),0.68
409 | 391,80,1364,CB,Beta (5Y Monthly),0.67
410 | 392,404,6872,RSG,Beta (5Y Monthly),0.67
411 | 393,6,106,ABT,Beta (5Y Monthly),0.67
412 | 396,61,1041,BG,Beta (5Y Monthly),0.66
413 | 394,83,1415,CCI,Beta (5Y Monthly),0.66
414 | 395,310,5274,MO,Beta (5Y Monthly),0.66
415 | 397,298,5070,MDLZ,Beta (5Y Monthly),0.66
416 | 399,96,1636,CINF,Beta (5Y Monthly),0.65
417 | 398,124,2112,CVS,Beta (5Y Monthly),0.65
418 | 400,31,531,AMGN,Beta (5Y Monthly),0.65
419 | 401,294,5002,MCD,Beta (5Y Monthly),0.64
420 | 402,256,4356,JKHY,Beta (5Y Monthly),0.64
421 | 403,447,7603,TRV,Beta (5Y Monthly),0.64
422 | 405,163,2775,EQIX,Beta (5Y Monthly),0.63
423 | 404,169,2877,ETR,Beta (5Y Monthly),0.63
424 | 406,401,6821,ROL,Beta (5Y Monthly),0.63
425 | 407,488,8300,WRB,Beta (5Y Monthly),0.62
426 | 408,44,752,ATO,Beta (5Y Monthly),0.61
427 | 409,392,6668,RE,Beta (5Y Monthly),0.61
428 | 410,296,5036,MCK,Beta (5Y Monthly),0.61
429 | 411,222,3778,HII,Beta (5Y Monthly),0.6
430 | 413,4,72,ABBV,Beta (5Y Monthly),0.59
431 | 415,173,2945,EXC,Beta (5Y Monthly),0.59
432 | 414,144,2452,DTE,Beta (5Y Monthly),0.59
433 | 412,25,429,ALL,Beta (5Y Monthly),0.59
434 | 416,365,6209,PFE,Beta (5Y Monthly),0.58
435 | 417,363,6175,PEG,Beta (5Y Monthly),0.58
436 | 418,261,4441,KDP,Beta (5Y Monthly),0.58
437 | 419,364,6192,PEP,Beta (5Y Monthly),0.57
438 | 420,55,939,BAX,Beta (5Y Monthly),0.56
439 | 425,58,990,BDX,Beta (5Y Monthly),0.56
440 | 427,105,1789,CNC,Beta (5Y Monthly),0.56
441 | 424,33,565,AMT,Beta (5Y Monthly),0.56
442 | 423,270,4594,KO,Beta (5Y Monthly),0.56
443 | 422,176,2996,EXR,Beta (5Y Monthly),0.56
444 | 421,49,837,AWK,Beta (5Y Monthly),0.56
445 | 426,442,7518,TMUS,Beta (5Y Monthly),0.56
446 | 429,138,2350,DLR,Beta (5Y Monthly),0.55
447 | 428,304,5172,MKC,Beta (5Y Monthly),0.55
448 | 431,257,4373,JNJ,Beta (5Y Monthly),0.54
449 | 430,76,1296,CAG,Beta (5Y Monthly),0.54
450 | 432,5,89,ABC,Beta (5Y Monthly),0.54
451 | 435,287,4883,LW,Beta (5Y Monthly),0.53
452 | 433,487,8283,WMT,Beta (5Y Monthly),0.53
453 | 434,19,327,AIZ,Beta (5Y Monthly),0.53
454 | 436,282,4798,LNT,Beta (5Y Monthly),0.51
455 | 437,334,5682,NOC,Beta (5Y Monthly),0.5
456 | 439,271,4611,KR,Beta (5Y Monthly),0.49
457 | 438,406,6906,SBAC,Beta (5Y Monthly),0.49
458 | 442,81,1381,CBOE,Beta (5Y Monthly),0.48
459 | 441,416,7076,SO,Beta (5Y Monthly),0.48
460 | 440,368,6260,PGR,Beta (5Y Monthly),0.48
461 | 447,166,2826,ES,Beta (5Y Monthly),0.47
462 | 446,171,2911,EVRG,Beta (5Y Monthly),0.47
463 | 445,97,1653,CL,Beta (5Y Monthly),0.47
464 | 444,332,5648,NI,Beta (5Y Monthly),0.47
465 | 443,399,6787,RMD,Beta (5Y Monthly),0.47
466 | 448,472,8028,VRTX,Beta (5Y Monthly),0.46
467 | 450,92,1568,CHD,Beta (5Y Monthly),0.45
468 | 449,68,1160,BMY,Beta (5Y Monthly),0.45
469 | 451,127,2163,D,Beta (5Y Monthly),0.45
470 | 452,15,259,AEP,Beta (5Y Monthly),0.44
471 | 453,329,5597,NEE,Beta (5Y Monthly),0.44
472 | 454,101,1721,CME,Beta (5Y Monthly),0.43
473 | 455,377,6413,PNW,Beta (5Y Monthly),0.43
474 | 456,383,6515,PSA,Beta (5Y Monthly),0.43
475 | 457,14,242,AEE,Beta (5Y Monthly),0.43
476 | 458,260,4424,K,Beta (5Y Monthly),0.42
477 | 459,494,8402,XEL,Beta (5Y Monthly),0.42
478 | 460,45,769,ATVI,Beta (5Y Monthly),0.42
479 | 461,267,4543,KMB,Beta (5Y Monthly),0.42
480 | 462,183,3115,FE,Beta (5Y Monthly),0.42
481 | 485,145,2469,DUK,Beta (5Y Monthly),0.41
482 | 463,202,3438,GILD,Beta (5Y Monthly),0.41
483 | 464,367,6243,PG,Beta (5Y Monthly),0.4
484 | 465,481,8181,WEC,Beta (5Y Monthly),0.39
485 | 466,315,5359,MRK,Beta (5Y Monthly),0.37
486 | 467,153,2605,ED,Beta (5Y Monthly),0.35
487 | 468,231,3931,HSY,Beta (5Y Monthly),0.35
488 | 469,279,4747,LLY,Beta (5Y Monthly),0.35
489 | 470,475,8079,VZ,Beta (5Y Monthly),0.34
490 | 471,132,2248,DG,Beta (5Y Monthly),0.34
491 | 472,104,1772,CMS,Beta (5Y Monthly),0.33
492 | 473,111,1891,CPB,Beta (5Y Monthly),0.32
493 | 474,203,3455,GIS,Beta (5Y Monthly),0.3
494 | 475,330,5614,NEM,Beta (5Y Monthly),0.3
495 | 476,98,1670,CLX,Beta (5Y Monthly),0.27
496 | 477,121,2061,CTRA,Beta (5Y Monthly),0.26
497 | 478,394,6702,REGN,Beta (5Y Monthly),0.24
498 | 479,412,7008,SJM,Beta (5Y Monthly),0.21
499 | 480,62,1058,BIIB,Beta (5Y Monthly),0.19
500 | 481,228,3880,HRL,Beta (5Y Monthly),0.18
501 | 497,349,5937,OGN,Beta (5Y Monthly),0.0
502 | 488,200,3404,GEHC,Beta (5Y Monthly),0.0
503 | 482,84,1432,CCL,Beta (5Y Monthly),0.0
504 | 483,89,1517,CEG,Beta (5Y Monthly),0.0
505 |
--------------------------------------------------------------------------------
/daytrade.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """daytrade.ipynb
3 |
4 | Automatically generated by Colaboratory.
5 |
6 | Original file is located at
7 | https://colab.research.google.com/drive/1aravbFmBdESeZuvC9kwktRwUDOPvGgtt
8 |
9 | Small python script that plots the difference between close and open prices of s&p stocks
10 | """
11 |
12 | import os
13 | import random
14 | from time import sleep
15 | import pprint
16 | from dotenv import load_dotenv
17 | from datetime import datetime, timezone
18 | import json
19 |
20 | import pandas as pd
21 | import matplotlib.pyplot as plt
22 | import plotly.graph_objects as go
23 | import plotly.express as px
24 | import seaborn as sns
25 | import numpy as np
26 |
27 | import yfinance as yahooFinance
28 | import yahoo_fin.stock_info as si
29 | from pytickersymbols import PyTickerSymbols
30 | import robin_stocks.robinhood as r
31 |
32 | tzname = 'America/New_York'
33 |
34 | ## Hyper parameters
35 | history = "2y"
36 | buy_trigger = 3 # times standard deviation
37 | sell_trigger = 1 # times the avg cost of the security to grow before we sell
38 | security_age = 15 # number of days to hold the security before we cut the losses
39 | lockin_gains_factor = 1000 # times the orignal amount to grow before we lockin the gains.
40 | mean_type = "+ve" # only consider stocks with +ve mean of ND. These stocks have been growing over the period of time
41 | max_stocks_to_buy = 5 # number of stocks to buy at buy trigger. We can change this value to be
42 | # more adaptive based on market cap of the security and other parameters.
43 | backtest_iterations = 1 # number of backtests to run
44 | backtest_days = random.sample(range(100, 700), backtest_iterations) # starting days for back testing
45 | backtest_days.sort()
46 | prefer_beta = True
47 | above_beta_mean = False
48 | stop_falling_knife = False
49 | index_stocks = "SP500" # Other legal names are NASDAQ, DOW, SP500
50 |
51 | starting_balance = 10000 # seed money to start investing
52 | current_account = original_balance = starting_balance
53 | portfolio = {}
54 | stks = {}
55 |
56 | # Display test results. Debugging Tools
57 | print_final_portfolio = False # Prints the portfolio list at the end of each backtest iteration
58 | plot_every_test_graph = True # Prints the model performance during the back end against s&P500
59 | plot_summary_graph = True # prints the summary graph
60 | dump_all_trades = True # dumps all sells at the end of the trade. Use it sparingly, with iteration set to 1
61 |
62 | # Deploy the initial amount gradually
63 | tranche_pct = 100 # of amount to deploy
64 | tranche_period = 1 # calender days between deployment
65 |
66 | tests = [
67 | {
68 | "Name": "Test 1",
69 | "buy_trigger": 2,
70 | "sell_trigger": 1,
71 | "security_age": 15,
72 | "lockin_gains_factor": 1000,
73 | "prefer_beta": True,
74 | "mean_type": "+ve",
75 | "above_beta_mean": False,
76 | "stop_falling_knife": False,
77 | },
78 | {
79 | "Name": "Test 2",
80 | "buy_trigger": 2,
81 | "sell_trigger": 1,
82 | "security_age": 15,
83 | "lockin_gains_factor": 1.1,
84 | "prefer_beta": True,
85 | "mean_type": "+ve",
86 | "above_beta_mean": False,
87 | "stop_falling_knife": False,
88 | },
89 | {
90 | "Name": "Test 3",
91 | "buy_trigger": 2,
92 | "sell_trigger": 1,
93 | "security_age": 1000,
94 | "lockin_gains_factor": 1.1,
95 | "prefer_beta": True,
96 | "mean_type": "+ve",
97 | "above_beta_mean": False,
98 | "stop_falling_knife": False,
99 | },
100 | {
101 | "Name": "Test 4",
102 | "buy_trigger": 2,
103 | "sell_trigger": 1,
104 | "security_age": 1000,
105 | "lockin_gains_factor": 1.1,
106 | "prefer_beta": False,
107 | "mean_type": "+ve",
108 | "above_beta_mean": False,
109 | "stop_falling_knife": False,
110 | },
111 | {
112 | "Name": "Test 5",
113 | "buy_trigger": 2,
114 | "sell_trigger": 1,
115 | "security_age": 90,
116 | "lockin_gains_factor": 1.1,
117 | "prefer_beta": True,
118 | "mean_type": "+ve",
119 | "above_beta_mean": False,
120 | "stop_falling_knife": False,
121 | },
122 | {
123 | "Name": "Test 6",
124 | "buy_trigger": 2,
125 | "sell_trigger": 1,
126 | "security_age": 90,
127 | "lockin_gains_factor": 1.1,
128 | "prefer_beta": False,
129 | "mean_type": "+ve",
130 | "above_beta_mean": False,
131 | "stop_falling_knife": False,
132 | },
133 | {
134 | "Name": "Test 7",
135 | "buy_trigger": 2,
136 | "sell_trigger": 1,
137 | "security_age": 90,
138 | "lockin_gains_factor": 1.1,
139 | "prefer_beta": True,
140 | "mean_type": "",
141 | "above_beta_mean": False,
142 | "stop_falling_knife": False,
143 | },
144 | {
145 | "Name": "Test 8",
146 | "buy_trigger": 2,
147 | "sell_trigger": 1,
148 | "security_age": 90,
149 | "lockin_gains_factor": 1000,
150 | "prefer_beta": True,
151 | "mean_type": "+ve",
152 | "above_beta_mean": True,
153 | "stop_falling_knife": False,
154 | },
155 | {
156 | "Name": "Test 9",
157 | "buy_trigger": 2,
158 | "sell_trigger": 1,
159 | "security_age": 20,
160 | "lockin_gains_factor": 1000,
161 | "prefer_beta": True,
162 | "mean_type": "+ve",
163 | "above_beta_mean": True,
164 | "stop_falling_knife": False,
165 | },
166 | {
167 | "Name": "Test 10",
168 | "buy_trigger": 2,
169 | "sell_trigger": 1,
170 | "security_age": 20,
171 | "lockin_gains_factor": 1000,
172 | "prefer_beta": True,
173 | "mean_type": "+ve",
174 | "above_beta_mean": False,
175 | "stop_falling_knife": False,
176 | },
177 | {
178 | "Name": "Test 11",
179 | "buy_trigger": 2,
180 | "sell_trigger": 1,
181 | "security_age": 90,
182 | "lockin_gains_factor": 1000,
183 | "prefer_beta": True,
184 | "mean_type": "+ve",
185 | "above_beta_mean": True,
186 | "stop_falling_knife": True,
187 | },
188 | {
189 | "Name": "Test 12",
190 | "buy_trigger": 2,
191 | "sell_trigger": 1,
192 | "security_age": 20,
193 | "lockin_gains_factor": 1000,
194 | "prefer_beta": True,
195 | "mean_type": "+ve",
196 | "above_beta_mean": True,
197 | "stop_falling_knife": False,
198 | },
199 | {
200 | "Name": "Test 13 (DayTrade)",
201 | "buy_trigger": 6,
202 | "sell_trigger": 1,
203 | "security_age": 1,
204 | "lockin_gains_factor": 1000,
205 | "prefer_beta": True,
206 | "mean_type": "",
207 | "above_beta_mean": True,
208 | "stop_falling_knife": False,
209 | },
210 | ]
211 |
212 | tests_to_run = [13]
213 |
214 | pp = pprint.PrettyPrinter(indent=4)
215 |
216 | stock_indexes = {"SP500": '^GSPC', 'NASDAQ': '^IXIC', 'DOW': '^DJI'}
217 |
218 | assert index_stocks in stock_indexes
219 | indices = list(stock_indexes.values())
220 |
221 | if index_stocks == "SP500":
222 | stocks = si.tickers_sp500()
223 | if 'FRC' in stocks:
224 | stocks.remove('FRC')
225 | elif index_stocks == "NASDAQ":
226 | stock_data = PyTickerSymbols()
227 | stocks = stock_data.get_nasdaq_100_nyc_yahoo_tickers()
228 | elif index_stocks == "DOW":
229 | stocks = si.tickers_dow()
230 |
231 | stocks_ts = pd.DataFrame()
232 | delta1 = pd.DataFrame()
233 | delta2 = pd.DataFrame()
234 | indices_ts = pd.DataFrame()
235 |
236 | for idx in indices:
237 | data = yahooFinance.Ticker(idx).history(period=history)
238 | d = data.copy()[['High', 'Low', 'Open', "Close"]]
239 | indices_ts[idx+"_High"] = d['High']
240 | indices_ts[idx+"_Low"] = d['Low']
241 | indices_ts[idx+"_Open"] = d["Open"]
242 | indices_ts[idx+"_Close"] = d["Close"]
243 |
244 | for stock in stocks:
245 | data = yahooFinance.Ticker(stock).history(period=history)
246 | d = data.copy()[['High', 'Low', "Open", "Close"]]
247 | stocks_ts[stock+"_High"] = d['High']
248 | stocks_ts[stock+"_Low"] = d['Low']
249 | stocks_ts[stock+"_Open"] = d["Open"]
250 | stocks_ts[stock+"_Close"] = d["Close"]
251 | m = (d['Open'] + d['Close']) / 2
252 | delta1[stock] = (m - d['Low']) * 100/m
253 | delta2[stock] = (d['High'] - m) * 100/m
254 |
255 | stocks_ts = stocks_ts.copy()
256 | delta1 = delta1.copy()
257 | delta2 = delta2.copy()
258 |
259 | indices_ts.index = indices_ts.index.tz_convert(tzname)
260 | stocks_ts.index = stocks_ts.index.tz_convert(tzname)
261 |
262 | for stock in stocks[:1]:
263 | fig = go.Figure(data=[go.Candlestick(x=d.index,
264 | open=d['High'],
265 | high=d['Low'],
266 | low=d['High'],
267 | close=d['Low'])])
268 | fig.update_layout(
269 | title=stock,
270 | yaxis_title=stock +' Stock',
271 | shapes = [dict(
272 | x0='2022-12-09', x1='2022-12-09', y0=0, y1=1, xref='x', yref='paper',
273 | line_width=2)],
274 | annotations=[dict(
275 | x='2022-12-09', y=0.05, xref='x', yref='paper',
276 | showarrow=False, xanchor='left', text='Increase Period Begins')]
277 | )
278 |
279 | #fig.show()
280 |
281 | delta1['Date'] = delta1.index
282 | fig = px.line(delta1, x="Date", y=stock, title="Lows Price change", markers=True)
283 | #fig.show()
284 |
285 | x = pd.Series(delta1[stock])
286 | ax = x.plot.kde(figsize=(30,8))
287 |
288 | delta2['Date'] = delta2.index
289 | fig = px.line(delta2, x="Date", y=stock, title="High Price change", markers=True)
290 | #fig.show()
291 |
292 | x = pd.Series(delta2[stock])
293 | ax = x.plot.kde(figsize=(30,8))
294 |
295 | #sns.set(rc={'figure.figsize':(25.7,8.27)})
296 | #sns.lineplot(x="Date",y=stock, data=stocks_spread, markers=True, err_style="bars")
297 | #sns.despine();
298 |
299 | #print(delta1.describe())
300 | std_delta1 = delta1.describe().loc['std']
301 | mean_delta1 = delta1.describe().loc['mean']
302 | std_delta1 = pd.DataFrame.from_dict(std_delta1)
303 | std_delta1.columns = ['std_delta1',]
304 |
305 | mean = pd.DataFrame.from_dict(mean_delta1)
306 | mean.columns = ['mean',]
307 |
308 | fig = px.line(std_delta1, title="Daily Low Price", markers=True)
309 | #fig.show()
310 |
311 | #print(delta1.describe())
312 | std_delta2 = delta2.describe().loc['std']
313 | mean_delta2 = delta2.describe().loc['mean']
314 | std_delta2 = pd.DataFrame.from_dict(std_delta2)
315 | std_delta2.columns = ['std_delta2',]
316 |
317 | mean = pd.DataFrame.from_dict(mean_delta2)
318 | mean.columns = ['mean',]
319 |
320 | fig = px.line(std_delta2, title="Daily High Price", markers=True)
321 | #fig.show()
322 |
323 | # Determine what stocks are in buy zone and what stocks are in sell zone
324 | # Start date of the investing
325 |
326 | def getsellbuy(portfolio, security_profit, security_loss):
327 | latest = {}
328 | index = stks['A'].index[0]
329 | for s in stocks:
330 | latest[s] = (stks[s].loc[index]["Close"] - stocks_ts.loc[index][s+"_Open"])* 100 /stocks_ts.loc[index][s+"_Open"]
331 |
332 | latest = pd.Series(latest)
333 | pd.DataFrame.from_dict(latest)
334 | latest_diff = pd.DataFrame.from_dict(latest)
335 | latest_diff.columns = ['diff',]
336 |
337 | latest_diff['std_delta1'] = std_delta1['std_delta1']
338 | latest_diff['std_delta2'] = std_delta2['std_delta2']
339 |
340 | # Find stocks that are in buy range
341 | # also lets avoid outliers too. If the fall is too steep, we don't want to consider it
342 | latest_diff['buy'] = np.where(((latest_diff['diff'] < 0) &
343 | (latest_diff['diff'] < -1 * buy_trigger * std_delta1['std_delta1']) &
344 | (latest_diff['diff'] > -(buy_trigger + 2) * std_delta1['std_delta1'])), True, False)
345 |
346 | # Find stocks that are in sell range
347 | latest_diff['sell'] = False #np.where((latest_diff['diff'] >= std['std']), True, False)
348 | profit = loss = 0
349 | for s in stocks:
350 | if s in portfolio:
351 | latest_diff.at[s, 'buy'] = False
352 | t = index - pd.Timestamp(portfolio[s]['date']).tz_convert(tzname)
353 | avg = sum(portfolio[s]['costs'])/len(portfolio[s]['costs'])
354 | if avg + sell_trigger * std_delta1['std_delta1'][s] * avg / 100 <= stks[s].loc[index, "Close"]:
355 | # If the avg cost of the security has grown more than std
356 | profit = len(portfolio[s]['costs']) * stks[s].loc[index, "Close"] - sum(portfolio[s]['costs'])
357 | if dump_all_trades:
358 | print("Selling %s at profit. closing price %f. profit %f days %d" %
359 | (s, stks[s].loc[index, "Close"], profit, t.days), portfolio[s])
360 | security_profit.loc[len(security_profit.index)] = {'days':t.days, 'profit':profit}
361 | latest_diff.at[s, 'sell'] = True
362 | elif t.days > security_age or \
363 | latest_diff['diff'][s] < -(buy_trigger + 2) * std_delta1['std_delta1'][s]:
364 |
365 | # if the security has aged for certain days, cut the losses
366 | loss = len(portfolio[s]['costs']) * stks[s].loc[index, "Close"] - sum(portfolio[s]['costs'])
367 | if dump_all_trades:
368 | print("Dumping %s because of age. closing price %f. loss %f" %
369 | (s, stks[s].loc[index, "Close"], loss), portfolio[s])
370 | if loss > 0:
371 | security_profit.loc[len(security_profit.index)] = {'days':t.days, 'profit':loss}
372 | else:
373 | security_loss.loc[len(security_loss.index)] = {'loss':loss}
374 | latest_diff.at[s, 'sell'] = True
375 |
376 |
377 | # Print which stocks are buy and which are sell
378 | #print("Stock to Buy on " + str(index))
379 | #print(latest_diff[latest_diff['buy']])
380 | #print()
381 | #print("Stocks to Sell on " + str(index))
382 | #print(latest_diff[latest_diff['sell']])
383 |
384 | sell_stocks = latest_diff[latest_diff['sell']]
385 | buy_stocks = latest_diff[latest_diff['buy']]
386 | buy_stocks = buy_stocks.sort_values('std_delta2', ascending=False)
387 | return sell_stocks, buy_stocks
388 |
389 | # We assume that we invest $100 in each stock that is in the buy zone
390 | # and sell all stocks in the sell zone
391 |
392 | # We will start back testing from year back. We can always change the starting point and tune the model.
393 |
394 | def calculate_networth():
395 | networth = current_account
396 | for stock, value in portfolio.items():
397 | networth += value['shares'] * stks[stock].loc[stks[stock].index[0]]["Close"]
398 | return networth
399 |
400 | def do_one_backtesting():
401 | global portfolio
402 | global original_balance
403 | global current_account
404 |
405 | stocks_bought = pd.DataFrame(columns=stocks)
406 | stocks_sold = pd.DataFrame(columns=stocks)
407 | stocks_profit = pd.DataFrame(columns=['days', 'profit'])
408 | stocks_loss = pd.DataFrame(columns=['loss'])
409 |
410 | original_balance = starting_balance
411 | portfolio = {}
412 | capital_to_be_deployed = original_balance
413 |
414 | idx = 0
415 | price_movement = []
416 | cash_inhand = []
417 |
418 | if os.path.exists("holdings.json"):
419 | with open("holdings.json", "r") as f:
420 | portfolio = json.load(f)
421 |
422 | if os.path.exists("cash_balance.json"):
423 | with open("cash_balance.json", "r") as f:
424 | c = {}
425 | c = json.load(f)
426 | current_account = c['cash']
427 |
428 | hrs = r.get_market_today_hours('XNYS')
429 | #while pd.to_datetime(datetime.now(timezone.utc)) < pd.to_datetime(hrs['closes_at']) and \
430 | #pd.to_datetime(datetime.now(timezone.utc)) > pd.to_datetime(hrs['opens_at']):
431 | while True:
432 | # Load test data
433 | try:
434 | for i in stocks:
435 | try:
436 | data = yahooFinance.Ticker(i).history("1d")
437 | stks[i] = pd.DataFrame()
438 | d = data.copy()[['High', 'Low', "Open", "Close"]]
439 | stks[i]['High'] = d['High']
440 | stks[i]['Low'] = d['Low']
441 | stks[i]['Open'] = d['Open']
442 | stks[i]['Close'] = d['Close']
443 | stks[i].index = stks[i].index.tz_convert(tzname)
444 | except:
445 | pass
446 |
447 | backtest_start_date = stks[i].index[0]
448 | sell, buy = getsellbuy(portfolio, stocks_profit, stocks_loss)
449 | except:
450 | # yahoo api changes the index from utc or localized value between market open and close
451 | # in that case we may get an exception. Wait for 60 seconds and try again
452 | sleep(60)
453 | continue
454 |
455 | # process the stocks that are marked sell
456 | for st in sell.iterrows():
457 | stock = st[0].split('_')[0]
458 | if stock in portfolio:
459 | current_account += portfolio[stock]['shares'] * stks[stock].loc[backtest_start_date]["Close"]
460 | stocks_sold.loc[backtest_start_date, stock] = portfolio[stock]['shares'] * stks[stock].loc[backtest_start_date]["Close"]
461 | portfolio.pop(stock)
462 |
463 | # buy stocks that are marked by. We are buying max_stocks_to_buy number of stocks
464 | # TODO: The number of stocks to be must be adaptive. Will come up with some
465 | # algorithm based on:
466 | # 1. Market capitalization
467 | # 2. Beta
468 | # and other criteria
469 | # The goal is to put the money to work
470 | for st in buy.iterrows():
471 | stock = st[0].split('_')[0]
472 | try:
473 | earning_calls_date=pd.to_datetime(r.get_earnings(st)[-2]['call']['datetime']).tz_convert('America/New_York')
474 | delta = pd.Timestamp.utcnow() - earning_calls_date
475 | if delta.days > 0 and delta.days < 4:
476 | # skip the stock for few days after earnings call
477 | continue
478 | except:
479 | pass
480 | if current_account > max_stocks_to_buy * stks[stock].loc[backtest_start_date]["Close"]:
481 | current_account -= max_stocks_to_buy * stks[stock].loc[backtest_start_date]["Close"]
482 | if not stock in portfolio:
483 | assert portfolio.get(stock, None) == None
484 | portfolio[stock] = {'shares': 0, 'costs':[], 'date': str(backtest_start_date)}
485 | portfolio[stock]['shares'] += max_stocks_to_buy
486 | stocks_bought.loc[backtest_start_date, stock] = max_stocks_to_buy * stks[stock].loc[backtest_start_date]["Close"]
487 | for i in range(max_stocks_to_buy):
488 | portfolio[stock]['costs'].append(stks[stock].loc[backtest_start_date]["Close"])
489 |
490 | # lock in the gains after 10% increase of networth
491 | nw = calculate_networth()
492 | price_movement.append(nw)
493 | cash_inhand.append(current_account)
494 | if nw > original_balance * lockin_gains_factor:
495 | #print(backtest_start_date, calculate_networth(), current_account, portfolio)
496 | for stock, value in portfolio.items():
497 | current_account += value['shares'] * stks[stock].loc[backtest_start_date]["Close"]
498 | stocks_sold.loc[backtest_start_date, stock] = stks[stock].loc[backtest_start_date]["Close"]
499 | portfolio = {}
500 | original_balance = current_account
501 | #print(current_account, portfolio)
502 |
503 | with open("holdings.json", "w") as f:
504 | json.dump(portfolio, f, indent=4, sort_keys=True, default=str)
505 |
506 | with open("cash_balance.json", "w") as f:
507 | json.dump({"cash": current_account}, f)
508 | print("=======================================================")
509 | print(datetime.now())
510 | print("Cash: %d" % current_account)
511 | print("Holdings:")
512 | networth = current_account
513 | total_gain = 0;
514 | for s, v in portfolio.items():
515 | networth += v['shares'] * stks[s]["Close"][0]
516 | total_gain += v['shares'] * (stks[s]["Close"][0] - v['costs'][0])
517 | gain = v['shares'] * (stks[s]["Close"][0] - v['costs'][0])
518 | print("%s(%d)\t%s\t%f\t%f\t%f" % (s, v['shares'], str(v['date']), v['costs'][0], stks[s]["Close"][0], gain))
519 | print("Completed one iteration with unrealized total gain: %f and networth: %f" % (total_gain, networth))
520 | print("=======================================================")
521 | sleep(15 * 60)
522 |
523 | #if dump_all_trades:
524 | #print(stocks_profit)
525 | #print(stocks_loss)
526 | print("Profit Distribution")
527 | print("===================")
528 | print(stocks_profit.describe())
529 | print()
530 | print("Loss Distribution")
531 | print("=================")
532 | print(stocks_loss.describe())
533 | print("Total Profit %f and Total Loss %f" % (stocks_profit['profit'].sum(), stocks_loss['loss'].sum()))
534 | return calculate_networth(), current_account, price_movement, cash_inhand
535 |
536 | def run_backtest():
537 | nws = {}
538 | sp_ret = {}
539 | hrs = r.get_market_today_hours('XNYS')
540 | while True:
541 | if hrs['is_open'] == False:
542 | sleep(15 * 60)
543 | hrs = r.get_market_today_hours('XNYS')
544 | continue
545 | tradingdays_togoback = 1
546 | networth, current, pm, cih = do_one_backtesting()
547 | # normalize s&p500 for starting balance
548 | idx = pd.Timestamp("%d-%d-%d" %(stks['A'].index[0].year, stks['A'].index[0].month, stks['A'].index[0].day))
549 | #idx_list = list(indices_ts.loc[indices_ts.index[-tradingdays_togoback:], "^GSPC_Close"] * starting_balance/indices_ts.loc[indices_ts.index[-tradingdays_togoback], "^GSPC_Close"])
550 | idx_list = list(indices_ts.loc[idx:]["^GSPC_Close"] * starting_balance/indices_ts.loc[idx, "^GSPC_Close"])
551 | pm_pct = (pm[-1]-starting_balance)*100/starting_balance
552 | d = pd.DataFrame({'Portfolio_Performance':pm, "Cash_In_Hand": cih})
553 | idx_pct = (idx_list[-1] - idx_list[0])*100/idx_list[0]
554 | print("Total networth: %d (Cash %d) after going back %d days (%s)" % (networth, current_account, 15, idx))
555 | print("Model (%f)%% vs S&P Performance (%f)%%" % (pm_pct, idx_pct))
556 | if print_final_portfolio:
557 | pp.pprint(portfolio)
558 | nws[i] = networth
559 | sp_ret[i] = idx_list[-1]
560 | if plot_every_test_graph:
561 | fig = px.line(d, title="Model (%f)%% vs %s Performance (%f)%% starting at %s" % (pm_pct, index_stocks, idx_pct, idx), markers=True)
562 | fig.show()
563 |
564 | if plot_summary_graph:
565 | plt.bar(nws.keys(), nws.values(), color="green", label='Model')
566 | plt.bar(sp_ret.keys(), sp_ret.values(), color="blue", label=index_stocks)
567 | plt.title("Networth at the end of each iteration")
568 | plt.xlabel('Days')
569 | plt.ylabel('Networth')
570 | plt.legend()
571 | plt.show()
572 | print(sum(nws.values())/len(nws))
573 | idx_list = []
574 | for i in backtest_days:
575 | idx_list.append(indices_ts.index[-i])
576 | summary = pd.DataFrame(data={"Model":nws.values(), index_stocks:sp_ret.values()},
577 | index=list(idx_list))
578 | fig = px.bar(summary, title="Model vs %s Backtesting Results. Seed money $%f" % (index_stocks, starting_balance), barmode="group")
579 | fig.show()
580 |
581 | login = r.login(os.environ['robin_username'], os.environ['robin_password'], store_session=True, by_sms=True)
582 |
583 | for i in tests_to_run:
584 | t = tests[i-1]
585 | buy_trigger = t['buy_trigger'] # times standard deviation
586 | sell_trigger = t['sell_trigger'] # times the avg cost of the security to grow before we sell
587 | security_age = t['security_age'] # number of days to hold the security before we cut the losses
588 | lockin_gains_factor = t['lockin_gains_factor'] # times the orignal amount to grow before we lockin the gains.
589 | prefer_beta = t['prefer_beta']
590 | mean_type = t["mean_type"]
591 | stop_falling_knife = t["stop_falling_knife"]
592 | above_beta_mean = t["above_beta_mean"]
593 | print("Test Parameters for " + t['Name'])
594 | print("=================================")
595 | pp.pprint(t)
596 | run_backtest()
597 | print()
598 | print("==================================\n")
599 |
--------------------------------------------------------------------------------
/model.py:
--------------------------------------------------------------------------------
1 | """
2 | TODO:
3 | ====
4 | 1. start_cash_balance with respect to security_age
5 | 2. Take care of timezones or run the script in EST zone only
6 |
7 | 3. Robinhood does not have the transaction date. we need to find a way to save and use date on which he security is bought
8 | 4. stocks removed from s&p500() that we still hold
9 |
10 | 5. portfolio.stock.date reflects the first time the security is bought even after multiple purchases?
11 | """
12 | # yahooFinance provides last traded price as closing price, so we are good for trading. The resolution is pretty good. Nothing much to do here
13 |
14 | import datetime
15 | import json
16 | from json import JSONEncoder
17 | import os
18 | import pprint
19 |
20 | import pandas as pd
21 | import numpy as np
22 | import plotly.graph_objects as go
23 | import plotly.express as px
24 | import matplotlib.pyplot as plt
25 |
26 | import yfinance as yf
27 | import yahoo_fin.stock_info as si
28 | import robin_stocks.robinhood as r
29 | from dotenv import load_dotenv
30 |
31 | pp = pprint.PrettyPrinter(indent=4)
32 |
33 | tzname = 'America/New_York'
34 |
35 | model_parameters = {
36 | "history": "7y", # history to consider std and mean of stock daily price change
37 | "buy_trigger": 2, # times standard deviation
38 | "sell_trigger": 1, # times the avg cost of the security to grow before we sell
39 | "security_age": 20, # number of days to hold the security before we cut the losses
40 | "lockin_gains_factor": 1000, # times the orignal amount to grow before we lockin the gains.
41 | "mean_type": "+ve", # only consider stocks with +ve mean of ND. These stocks have been growing over the period of time
42 | "max_stocks_to_buy": 1, # number of stocks to buy at buy trigger. We can change this value to be more adaptive based on market cap of the security and other parameters.
43 | "prefer_beta": True, # favors stocks that has larger beta
44 | "above_beta_mean": True, # only biy stocks above mean beta value of s&p
45 |
46 | # Display test results. Debugging Tools
47 | "print_final_portfolio": False, # Prints the portfolio list at the end of each backtest iteration
48 | "plot_every_test_graph": True, # Prints the model performance during the back end against s&P500
49 | "plot_summary_graph": True, # prints the summary graph
50 | "dump_all_trades": False, # dumps all sells at the end of the trade. Use it sparingly, with iteration set to 1
51 | "start_cash_balance": 10000, # Model started with this cash balance
52 | }
53 |
54 | # subclass JSONEncoder
55 | class DateTimeEncoder(JSONEncoder):
56 | #Override the default method
57 | def default(self, obj):
58 | if isinstance(obj, (datetime.date, datetime.datetime)):
59 | return obj.isoformat()
60 |
61 |
62 | class brokerage:
63 | def __init__(self):
64 | pass
65 |
66 | def cashbalance(self):
67 | pass
68 |
69 | def get_stocks(self):
70 | pass
71 |
72 | def buy_a_stock(self, ticker, quantity):
73 | pass
74 |
75 | def sell_a_stock(self, ticker):
76 | pass
77 |
78 | def get_current_stock_price(self, ticker):
79 | pass
80 |
81 | def get_open_price_of_stock(self, ticker):
82 | pass
83 |
84 |
85 | class NextDay:
86 | """Class to implement an iterator
87 | of 1 increment"""
88 |
89 | def __init__(self, backtest_day):
90 | assert backtest_day < 0
91 | self.backtest_day = backtest_day
92 |
93 | def __iter__(self):
94 | return self
95 |
96 | def __next__(self):
97 | if self.backtest_day < 0:
98 | ret = self.backtest_day
99 | self.backtest_day += 1
100 | return ret
101 | else:
102 | raise StopIteration
103 |
104 | def current_day(self):
105 | return self.backtest_day
106 |
107 |
108 | class LocalBrokerage(brokerage):
109 | def __init__(self, cash=10000, backtest_days=-1):
110 | self.backtest_days = backtest_days
111 | self.backtest = backtest_days != -1
112 | if os.path.exists("localbrokerage.json"):
113 | with open("localbrokerage.json", "r") as f:
114 | self.account = json.load(f)
115 | else:
116 | self.account = {'cash_balance': cash, 'portfolio': {}}
117 |
118 | self.stocks = si.tickers_sp500()
119 | self.stocks_ts = pd.DataFrame()
120 | for ticker in self.stocks:
121 | if False and os.path.exists(os.path.join("history", ticker)):
122 | data = pd.read_csv(os.path.join("history", ticker))
123 | data['Date'] = pd.to_datetime(data['Date']).tz_localize(None)
124 | data = data.set_index('Date')
125 | else:
126 | data = yf.Ticker(ticker).history(period=model_parameters["history"])
127 | data.to_csv(os.path.join("history", ticker))
128 | d = data.copy()[['Open', 'Close']]
129 | self.stocks_ts[ticker+"_Open"] = d['Open']
130 | self.stocks_ts[ticker+"_Close"] = d['Close']
131 |
132 | self.stocks_ts = self.stocks_ts.copy()
133 | self.stocks_ts.index = self.stocks_ts.index.tz_convert(tzname)
134 |
135 | def __enter__(self):
136 | return self
137 |
138 | def __exit__(self, exc_type, exc_val, exc_tb):
139 | with open("localbrokerage.json", "w") as f:
140 | json.dump(self.account, f, indent=4, cls=DateTimeEncoder)
141 |
142 | def day_iter(self):
143 | if not self.backtest:
144 | raise Exception("LocalBrokerage is not in backtest mode")
145 |
146 | self.iter = NextDay(-self.backtest_days)
147 | return self.iter
148 |
149 | def backtest_day(self):
150 | if not self.backtest:
151 | raise Exception("LocalBrokerage is not in backtest mode")
152 |
153 | return self.backtest_days
154 |
155 | def cashbalance(self):
156 | return self.account['cash_balance']
157 |
158 | def get_stocks(self):
159 | return self.account['portfolio'].keys()
160 |
161 | def get_stock_holdings(self, ticker):
162 | if not self.has_stock(ticker):
163 | raise Exception("Stock %s not found" % ticker)
164 |
165 | return self.account.portfolio[ticker]
166 |
167 | def has_stock(self, ticker):
168 | return ticker in self.account['portfolio']
169 |
170 | def buy_a_stock(self, ticker, quantity, backtest_day=-1, limit=0):
171 | close = self.get_current_stock_price(ticker, backtest_day=backtest_day)
172 |
173 | portfolio = self.account['portfolio']
174 | if close * quantity > self.account['cash_balance']:
175 | raise Exception("Not enough cash available")
176 |
177 | if ticker not in portfolio:
178 | portfolio[ticker] = []
179 | t = pd.Timestamp.now(tz=tzname)
180 | t = t.tz_convert(tzname)
181 | portfolio[ticker].append({"count": quantity,
182 | "cost": close,
183 | "date": str(t)
184 | })
185 | self.account['cash_balance'] -= quantity * close
186 |
187 | return
188 |
189 | def sell_a_stock(self, ticker, backtest_day=-1):
190 | close = self.get_current_stock_price(ticker, backtest_day=backtest_day)
191 |
192 | if ticker not in self.account['portfolio']:
193 | raise Exception("We don't own any of these stocks")
194 |
195 | portfolio = self.account['portfolio']
196 | # Find number of shares
197 | quantity = 0
198 | for s in portfolio[ticker]:
199 | quantity += s['count']
200 |
201 | self.account['cash_balance'] += quantity * close
202 | portfolio.pop(ticker)
203 |
204 | return
205 |
206 | def get_current_stock_price(self, ticker, backtest_day=-1):
207 | if self.backtest:
208 | close = self.stocks_ts[ticker+"_Close"][len(self.stocks_ts[ticker+"_Close"])+backtest_day]
209 | else:
210 | close = yf.Ticker(ticker).history("1d")['Close'][0]
211 | return close
212 |
213 | def get_open_price_of_stock(self, ticker, backtest_day=-1):
214 | if self.backtest:
215 | open = self.stocks_ts[ticker+"_Open"][len(self.stocks_ts[ticker+"_Open"])+backtest_day]
216 | else:
217 | open = yf.Ticker(ticker).history("1d")['Open'][0]
218 |
219 | return open
220 |
221 | def avg_cost_of_stock(self, ticker):
222 | if ticker not in self.account["portfolio"]:
223 | raise Exception("Stock %s not found in portfolio" % ticker)
224 |
225 | avg = 0
226 | for s in self.account["portfolio"][ticker]:
227 | avg += s['cost']
228 | return avg/len(self.account["portfolio"][ticker])
229 |
230 | def oldest_stock(self, ticker):
231 | if ticker not in self.account["portfolio"]:
232 | raise Exception("Stock %s not found in portfolio" % ticker)
233 |
234 | oldest = pd.Timestamp(self.account["portfolio"][ticker][0]['date']).tz_convert(tzname)
235 | for e in self.account["portfolio"][ticker]:
236 | if oldest > pd.Timestamp(e['date']).tz_convert(tzname):
237 | oldest = pd.Timestamp(e['date']).tz_convert(tzname)
238 |
239 | return oldest
240 |
241 | def netgain(self, ticker, backtest_day=-1):
242 | if ticker not in self.account["portfolio"]:
243 | raise Exception("Stock %s not found in portfolio" % ticker)
244 | netgain = 0
245 | for e in self.account["portfolio"][ticker]:
246 | netgain += e['count'] * (self.get_current_stock_price(ticker, backtest_day=backtest_day) -
247 | e['cost'])
248 |
249 | return netgain
250 |
251 | def calculate_networth(self, backtest_day=-1):
252 | networth = self.cashbalance()
253 | for ticker in self.get_stocks():
254 | for e in self.account["portfolio"][ticker]:
255 | networth += e['count'] * self.get_current_stock_price(ticker, backtest_day=backtest_day)
256 | return networth
257 |
258 |
259 | class RobinhoodBrokerage(brokerage):
260 | def __init__(self):
261 | r.login(username=os.environ['robin_username'],
262 | password=os.environ['robin_password'],
263 | expiresIn=86400,
264 | by_sms=True)
265 | positions = r.get_open_stock_positions()
266 | my_stocks = r.build_holdings()
267 | self.portfolio = {}
268 | for p in positions:
269 | ticker = r.get_symbol_by_url(p["instrument"])
270 | if float(my_stocks[ticker]['quantity']) > 0:
271 | self.portfolio[ticker] = {'count': float(my_stocks[ticker]['quantity']),
272 | 'cost': float(my_stocks[ticker]['average_buy_price']),
273 | 'date': pd.Timestamp(p['updated_at']).tz_convert(tzname)}
274 |
275 | def __enter__(self):
276 | return self
277 |
278 | def __exit__(self, exc_type, exc_val, exc_tb):
279 | r.logout()
280 |
281 | def cashbalance(self):
282 | return float(r.load_phoenix_account()['account_buying_power']['amount'])
283 |
284 | def get_stocks(self):
285 | return list(portfolio.keys())
286 |
287 | def has_stock(self, ticker):
288 | return ticker in self.portfolio
289 |
290 | def get_stock_holdings(self, ticker):
291 | if not self.has_stock(ticker):
292 | raise Exception("Stock %s not found" % ticker)
293 |
294 | return porfolio[ticker]
295 |
296 | def buy_a_stock(self, ticker, quantity, backtest_day=-1, limit=0):
297 | import pdb;pdb.set_trace()
298 | cost = self.get_current_stock_price(ticker)
299 | if self.cashbalance() > quantity * cost:
300 | order = r.order_buy_market(ticker, quantity, jsonify=False)
301 | if order.status_code in [200, 201]:
302 | my_stocks = r.build_holdings()
303 | t = pd.Timestamp.now(tz=tzname)
304 | t = t.tz_convert(tzname)
305 | if float(my_stocks[ticker]['quantity']) > 0:
306 | self.portfolio[ticker] = {'count': float(my_stocks[ticker]['quantity']),
307 | 'cost': float(my_stocks[ticker]['average_buy_price']),
308 | 'date': pd.Timestamp(t).tz_convert(tzname)}
309 | try:
310 | if limit:
311 | order = r.order_sell_limit(ticker, quantity, limit, jsonify=True)
312 | if not order.status_code in [200, 201]:
313 | print("Cannot set limit order on '%s'" % ticker)
314 | except:
315 | pass
316 |
317 | else:
318 | print("Failed to execute the order for %s" % ticker)
319 | print(self.portfolio)
320 |
321 | def sell_a_stock(self, ticker, quantity=1, backtest_day=-1):
322 | import pdb;pdb.set_trace()
323 | assert self.has_stock(ticker)
324 |
325 | for item in r.get_all_open_stock_orders():
326 | if r.get_symbol_by_url(item["instrument"]) == ticker:
327 | r.cancel_stock_order(item["id"])
328 | order = r.order_sell_market(ticker, quantity, jsonify=False)
329 | if order.status_code in [200, 201]:
330 | self.portfolio.pop(ticker)
331 | print("Sold %s successfully" % ticker)
332 | print(self.portfolio)
333 |
334 | def get_current_stock_price(self, ticker, backtest_day=-1):
335 | close = yf.Ticker(ticker).history("1d")['Close'][0]
336 |
337 | return close
338 |
339 | def get_open_price_of_stock(self, ticker, backtest_day=-1):
340 | assert backtest_day == -1
341 |
342 | open = yf.Ticker(ticker).history("1d")['Open'][0]
343 |
344 | return open
345 |
346 | def avg_cost_of_stock(self, ticker):
347 | if not self.has_stock(ticker):
348 | raise Exception("Stock %s not found" % ticker)
349 |
350 | return self.portfolio[ticker]['cost']
351 |
352 | def oldest_stock(self, ticker):
353 | if not self.has_stock(ticker):
354 | raise Exception("Stock %s not found" % ticker)
355 |
356 | return self.portfolio[ticker]['date']
357 |
358 | def netgain(self, ticker, backtest_day=-1):
359 | if not self.has_stock(ticker):
360 | raise Exception("Stock %s not found" % ticker)
361 |
362 | holdings = r.build_holdings()[ticker]
363 | return float(holdings['equity_change'])
364 |
365 | def calculate_networth(self, backtest_day=-1):
366 | networth = self.cashbalance()
367 |
368 | for ticker, value in r.build_holdings().items():
369 | networth += float(value['equity'])
370 |
371 | return networth
372 |
373 |
374 | class Model:
375 | # Read the last few years of stocks and indices to calculate betas and standard deviations
376 | def __init__(self, brokerage):
377 | self.brokerage = brokerage
378 | self.stocks = si.tickers_sp500()
379 | self.indices = ['^IXIC', '^GSPC', '^DJI']
380 | self.stocks_ts = pd.DataFrame()
381 | self.stocks_spread = pd.DataFrame()
382 | self.indices_ts = pd.DataFrame()
383 |
384 | self.security_profit = pd.DataFrame(columns=['beta', 'days', 'profit'])
385 | self.security_loss = pd.DataFrame(columns=['beta', 'loss'])
386 |
387 | self.price_movement = []
388 | self.cash_inhand = []
389 |
390 | for idx in self.indices:
391 | data = yf.Ticker(idx).history(period=model_parameters["history"])
392 | d = data.copy()[['Open', 'Close']]
393 | self.indices_ts[idx+"_Open"] = d['Open']
394 | self.indices_ts[idx+"_Close"] = d['Close']
395 |
396 | self.betas = pd.read_csv("betas-sp500.csv")
397 | self.betas = self.betas.drop(['Unnamed: 0'], axis=1)
398 | self.betas = self.betas.rename(columns={"Recent": "Beta"})
399 | self.betas = self.betas.set_index('Ticker')
400 |
401 | for ticker in self.stocks:
402 | if False and os.path.exists(os.path.join("history", ticker)):
403 | data = pd.read_csv(os.path.join("history", ticker))
404 | data['Date'] = pd.to_datetime(data['Date']).tz_convert(tzname)
405 | data = data.set_index('Date')
406 | else:
407 | data = yf.Ticker(ticker).history(period=model_parameters["history"])
408 | data.to_csv(os.path.join("history", ticker))
409 | d = data.copy()[['Open', 'Close']]
410 | self.stocks_ts[ticker+"_Open"] = d['Open']
411 | self.stocks_ts[ticker+"_Close"] = d['Close']
412 | self.stocks_spread[ticker] = (d['Close'] - d['Open']) * 100/d['Open']
413 |
414 | self.stocks_ts = self.stocks_ts.copy()
415 | self.stocks_spread = self.stocks_spread.copy()
416 |
417 | self.indices_ts.index = self.indices_ts.index.tz_convert(tzname)
418 | self.stocks_ts.index = self.stocks_ts.index.tz_convert(tzname)
419 | self.std = self.stocks_spread.describe().loc['std']
420 | self.mean = self.stocks_spread.describe().loc['mean']
421 | self.std = pd.DataFrame.from_dict(self.std)
422 | self.std.columns = ['std',]
423 | self.betas_mean = self.betas.describe()['Beta']['mean']
424 |
425 | self.mean = pd.DataFrame.from_dict(self.mean)
426 | self.mean.columns = ['mean',]
427 |
428 |
429 | def analyze_a_stock(self, ticker):
430 | data = yf.Ticker(ticker).history(period=model_parameters["history"])
431 | fig = go.Figure(data=[go.Candlestick(x=data.index,
432 | open=data['Open'],
433 | high=data['High'],
434 | low=data['Low'],
435 | close=data['Close'])])
436 | fig.update_layout(title=ticker,
437 | yaxis_title=ticker +' Stock',
438 | shapes = [dict(x0='2022-12-09', x1='2022-12-09', y0=0, y1=1, xref='x', yref='paper',
439 | line_width=2)],
440 | annotations=[dict( x='2022-12-09', y=0.05, xref='x', yref='paper',
441 | showarrow=False, xanchor='left', text='Increase Period Begins')])
442 |
443 | fig.show()
444 |
445 | self.stocks_spread['Date'] = self.stocks_spread.index
446 | fig = px.line(self.stocks_spread, x="Date", y=ticker, title="Stocks Daily Price change", markers=True)
447 | fig.show()
448 |
449 | x = pd.Series(self.stocks_spread[ticker])
450 | ax = x.plot.kde(figsize=(30,8))
451 |
452 | def analyze_std_mean(self):
453 | fig = px.line(self.std, title="Daily Stock Price change", markers=True)
454 | fig.show()
455 | fig = px.line(self.betas, title="Stocks Betas", markers=True)
456 | fig.show()
457 |
458 | def _getsellbuy(self, backtest_day=-1):
459 | todays_delta = {}
460 | for ticker in self.stocks:
461 | open = self.brokerage.get_open_price_of_stock(ticker, backtest_day=backtest_day)
462 | close = self.brokerage.get_current_stock_price(ticker, backtest_day=backtest_day)
463 | todays_delta[ticker] = (close - open) * 100/open
464 |
465 |
466 | todays_delta = pd.Series(todays_delta)
467 | latest_diff = pd.DataFrame.from_dict(todays_delta)
468 | latest_diff.columns = ['diff',]
469 | latest_diff['std'] = self.std['std']
470 |
471 | # Find stocks that are in buy range
472 | latest_diff['buy'] = np.where(((model_parameters["mean_type"] != "+ve" or self.mean['mean'] > 0) & (latest_diff['diff'] < 0) &
473 | (model_parameters["above_beta_mean"] == False or self.betas_mean >= self.betas['Beta']) &
474 | (latest_diff['diff'] < -model_parameters["buy_trigger"] * self.std['std'])), True, False)
475 |
476 | latest_diff['beta'] = self.betas['Beta']
477 |
478 | # Find stocks that are in sell range
479 | latest_diff['sell'] = False
480 | index = self.stocks_ts.index[backtest_day]
481 | for ticker in self.stocks:
482 | if not self.brokerage.has_stock(ticker):
483 | continue
484 |
485 | oldest = self.brokerage.oldest_stock(ticker)
486 | t = index - oldest
487 |
488 | avg = self.brokerage.avg_cost_of_stock(ticker)
489 |
490 | netgain = self.brokerage.netgain(ticker, backtest_day=backtest_day)
491 | if avg + model_parameters["sell_trigger"] * self.std['std'][ticker] * avg / 100 <= self.brokerage.get_current_stock_price(ticker, backtest_day=backtest_day):
492 | # If the avg cost of the security has grown more than std
493 | # print(s, avg, portfolio[s]['costs'], std['std'][s+"_Diff"], stocks_ts.loc[index, s+"_Close"])
494 |
495 | if model_parameters["dump_all_trades"]:
496 | print("Selling %s (beta %f) at profit. closing price %f. netgain %f days %d" %
497 | (s, betas['Beta'][s], stocks_ts.loc[index, s+"_Close"], netgain, t.days),
498 | self.get_stock_holdings(ticker))
499 | self.security_profit.loc[index] = {'beta':self.betas['Beta'][ticker],
500 | 'days': t.days, 'profit': netgain}
501 | latest_diff.at[ticker, 'sell'] = True
502 | elif t.days > model_parameters["security_age"]:
503 | # if the security has aged for certain days, cut the losses
504 | if model_parameters["dump_all_trades"]:
505 | print("Dumping %s(beta %f) because of age. closing price %f. netgain %f" %
506 | (ticker, self.betas['Beta'][ticker], netgain),
507 | self.get_stock_holdings(ticker))
508 | if netgain > 0:
509 | self.security_profit.loc[len(self.security_profit.index)] = {'beta':self.betas['Beta'][ticker],
510 | 'days':t.days, 'profit':netgain}
511 | else:
512 | self.security_loss.loc[len(self.security_loss.index)] = {'beta':self.betas['Beta'][ticker],
513 | 'loss':netgain}
514 | latest_diff.at[ticker, 'sell'] = True
515 |
516 | sell_stocks = latest_diff[latest_diff['sell']]
517 | buy_stocks = latest_diff[latest_diff['buy']]
518 | if model_parameters["prefer_beta"]:
519 | buy_stocks = buy_stocks.sort_values('beta',ascending=False)
520 | return sell_stocks, buy_stocks
521 |
522 | def do_todays_trade(self, backtest_day=-1):
523 |
524 | sell, buy = self._getsellbuy(backtest_day=backtest_day)
525 |
526 | # process the stocks that are marked sell
527 | for st in sell.iterrows():
528 | ticker = st[0].split('_')[0]
529 | self.brokerage.sell_a_stock(ticker, backtest_day=backtest_day)
530 |
531 | # buy stocks that are marked by. We are buying max_stocks_to_buy number of stocks
532 | # TODO: The number of stocks to be must be adaptive. Will come up with some
533 | # algorithm based on:
534 | # 1. Market capitalization
535 | # 2. Beta
536 | # and other criteria
537 | # The goal is to put the money to work
538 | for st in buy.iterrows():
539 | ticker = st[0].split('_')[0]
540 | if self.brokerage.cashbalance() > self.brokerage.get_current_stock_price(ticker, backtest_day=backtest_day) * model_parameters["max_stocks_to_buy"]:
541 | self.brokerage.buy_a_stock(ticker,
542 | model_parameters["max_stocks_to_buy"],
543 | backtest_day=backtest_day)
544 | #limit=self.brokerage.get_current_stock_price(ticker,
545 | #backtest_day=backtest_day)+self.std['std'][ticker])
546 |
547 | # lock in the gains after 10% increase of networth
548 | nw = self.brokerage.calculate_networth(backtest_day=backtest_day)
549 | self.price_movement.append(nw)
550 | self.cash_inhand.append(self.brokerage.cashbalance())
551 | if nw > model_parameters["start_cash_balance"] * model_parameters["lockin_gains_factor"]:
552 | #print(backtest_start_date, self.brokerage.calculate_networth(backtest_start_date), current_account, portfolio)
553 | for ticker in self.brokerage.get_stocks():
554 | self.brokerage.sell_a_stock(ticker, backtest_day=backtest_day)
555 | return
556 |
557 | def dump_profit_loss_distribution(self):
558 | if model_parameters["dump_all_trades"]:
559 | print("Profit Distribution")
560 | print("===================")
561 | print(self.stocks_profit.describe())
562 | print()
563 | print("Loss Distribution")
564 | print("=================")
565 | print(self.stocks_loss.describe())
566 | return
567 |
568 | def do_backtest(self):
569 | for i in self.brokerage.day_iter():
570 | self.do_todays_trade(backtest_day=i)
571 |
572 | networth = self.brokerage.calculate_networth()
573 |
574 | # normalize s&p500 for starting balance
575 | idx_list = list(self.indices_ts.loc[self.indices_ts.index[-self.brokerage.backtest_day():], "^GSPC_Close"] *
576 | model_parameters["start_cash_balance"]/self.indices_ts.loc[self.indices_ts.index[-self.brokerage.backtest_day()], "^GSPC_Close"])
577 | pm_pct = (self.price_movement[-1]-model_parameters["start_cash_balance"]) * 100/model_parameters["start_cash_balance"]
578 |
579 | d = pd.DataFrame({'Portfolio_Performance':self.price_movement,'SP_Performance':idx_list, "Cash_In_Hand": self.cash_inhand})
580 | d.index = self.indices_ts.index[-self.brokerage.backtest_day():]
581 | idx_pct = (idx_list[-1] - idx_list[0])*100/idx_list[0]
582 | print("Total networth: %d (Cash %d) after going back %d days (%s)" %
583 | (networth, self.brokerage.cashbalance(),
584 | self.brokerage.backtest_day(),
585 | self.stocks_ts.index[-self.brokerage.backtest_day()]))
586 | print("Model (%f)%% vs S&P Performance (%f)%%" % (pm_pct, idx_pct))
587 | if model_parameters["print_final_portfolio"]:
588 | pp.pprint(portfolio)
589 | if model_parameters["plot_every_test_graph"]:
590 | fig = px.line(d, title="Model (%f)%% vs S&P Performance (%f)%% starting at %s" %
591 | (pm_pct, idx_pct, self.stocks_ts.index[-self.brokerage.backtest_day()]),
592 | markers=True)
593 | fig.show()
594 |
595 |
596 | load_dotenv()
597 | if os.environ.get('robin_username', None) and os.environ.get('robin_password', None):
598 | with RobinhoodBrokerage() as lb:
599 | m = Model(lb)
600 | # m.analyze_a_stock('AAPL')
601 | # m.analyze_std_mean()
602 | m.do_todays_trade()
603 | else:
604 | with LocalBrokerage(cash=1000) as lb:
605 | m = Model(lb)
606 | # m.analyze_a_stock('AAPL')
607 | # m.analyze_std_mean()
608 | m.do_todays_trade()
609 |
--------------------------------------------------------------------------------
/betas-russell2000.csv:
--------------------------------------------------------------------------------
1 | ,Ticker,Beta
2 | 0,TGNA,0.341054883811523
3 | 1,PECO,0.8203832650120121
4 | 2,ADNT,1.797695500321972
5 | 3,FCFS,0.8202189882891231
6 | 4,ALIT,1.403274001192782
7 | 5,SHLS,1.480745757910651
8 | 6,CADE,0.932640620337636
9 | 7,AVNT,1.495107414847315
10 | 8,MTSI,1.298309148260022
11 | 9,EPRT,0.8059077806965681
12 | 10,DUOL,1.488819144101454
13 | 11,CNMD,1.331763990712662
14 | 12,STAA,1.586688754913249
15 | 13,LTHM,1.753647845972992
16 | 14,NARI,1.310820303094362
17 | 15,APLE,1.027666548083072
18 | 16,TWNK,0.4942789402782161
19 | 17,AEIS,1.324361630593085
20 | 18,STNE,1.904141800077161
21 | 19,SMPL,0.859242092815614
22 | 20,TNET,0.9665708208613012
23 | 21,MODG,1.17434008720584
24 | 22,ARRY,1.67928591077164
25 | 23,ARWR,1.719088490672836
26 | 24,FOLD,0.955328954648626
27 | 25,CYTK,
28 | 26,COOP,1.086140630174332
29 | 27,BLKB,0.950692974855442
30 | 28,BXMT,0.9986940138103412
31 | 29,BECN,0.970882760465501
32 | 30,NTLA,2.000550686766141
33 | 31,SANM,1.024071501322109
34 | 32,OTTR,0.656172574541192
35 | 33,FOCS,1.474335898941136
36 | 34,FWRD,1.002835570614274
37 | 35,AXNX,1.220267333337058
38 | 36,TGTX,2.727481705859927
39 | 37,WERN,0.8010853987263871
40 | 38,BPMC,1.259956481057218
41 | 39,SPXC,
42 | 40,CCOI,0.655187140864647
43 | 41,ACIW,1.036270302640348
44 | 42,WIRE,1.183689383691901
45 | 43,MGEE,0.535121936259865
46 | 44,LCII,1.216473757222464
47 | 45,IPAR,0.8954634150844081
48 | 46,MSTR,3.102528233792198
49 | 47,UCBI,0.886801443502342
50 | 48,CALX,1.383743814272488
51 | 49,OMCL,1.298655245493289
52 | 50,RETA,1.037703281877171
53 | 51,MOGA,0.8284794631616721
54 | 52,DNLI,1.580954548947396
55 | 53,PACB,2.858450067365814
56 | 54,TMDX,1.735055783676811
57 | 55,VRNS,1.586560155410645
58 | 56,CVCO,1.371290116393493
59 | 57,ITGR,0.990507853569715
60 | 58,ESGR,0.557923783454594
61 | 59,WDFC,0.6762841833608101
62 | 60,SHOO,1.204507375004314
63 | 61,LIVN,0.894836288263222
64 | 62,NGVT,1.05744805926078
65 | 63,INDB,0.6233159930819241
66 | 64,HLNE,1.238201072518574
67 | 65,STNG,0.3981814659129531
68 | 66,KLIC,1.418733738743675
69 | 67,HUBG,0.9322790897508112
70 | 68,PGNY,1.419638307282576
71 | 69,APPF,1.003124617099692
72 | 70,REZI,1.45132408564048
73 | 71,SONO,1.227258537404953
74 | 72,RVNC,1.348035290081425
75 | 73,CVLT,0.92819942639044
76 | 74,UMBF,0.8564503321871121
77 | 75,COKE,0.944917885254268
78 | 76,IOSP,0.7724176558341931
79 | 77,SBRA,0.651670309687572
80 | 78,CWEN,0.824951487334541
81 | 79,PTEN,1.341063816160962
82 | 80,SFBS,0.724501812745813
83 | 81,TCBI,1.017102361375514
84 | 82,AVAV,1.24997290331562
85 | 83,ARNC,1.260347563073057
86 | 84,FIBK,0.627520954776949
87 | 85,AMBA,2.019112293837509
88 | 86,PLXS,0.8506012353356861
89 | 87,HASI,1.394881110751197
90 | 88,INSM,1.192618180547397
91 | 89,SAGE,1.139909542097852
92 | 90,PIPR,1.092230673474207
93 | 91,PZZA,0.946820094739898
94 | 92,MATX,1.206365795523391
95 | 93,PRGS,
96 | 94,PRMW,0.924038391097854
97 | 95,ACAD,
98 | 96,DOCN,2.044989436988464
99 | 97,PDCO,0.753161981553874
100 | 98,VRNT,1.138555725869741
101 | 99,AMKR,1.437130247953185
102 | 100,LGIH,1.479194951846696
103 | 101,ITRI,1.384123402589821
104 | 102,CBRL,0.9485175559530292
105 | 103,SITC,1.113924894348684
106 | 104,CATY,0.931191882814649
107 | 105,AXSM,0.8530872232216421
108 | 106,ALRM,1.136810402028081
109 | 107,ARCB,1.466072105239433
110 | 108,WSFS,0.879523277346935
111 | 109,VRRM,0.8508946467034131
112 | 110,CHGG,1.173719344484519
113 | 111,JJSF,0.445762062678885
114 | 112,GKOS,1.163635748921926
115 | 113,IBOC,0.738004288515219
116 | 114,DORM,0.670173196121381
117 | 115,ABCB,0.9590668702222672
118 | 116,MTRN,1.156329071643278
119 | 117,PRFT,1.325894891611689
120 | 118,FTDR,0.9612695618905632
121 | 119,NUVA,0.998720782568806
122 | 120,GLNG,0.8740270992157351
123 | 121,FORM,1.350293011455259
124 | 122,BOOT,1.602924034741293
125 | 123,MGRC,
126 | 124,PCRX,0.7840262256394751
127 | 125,FCPT,0.610817421215589
128 | 126,PRTA,1.787045149638655
129 | 127,APAM,1.1294106479588
130 | 128,BLMN,1.144210074914463
131 | 129,RVMD,1.507597606240047
132 | 130,STRA,0.5831291375414951
133 | 131,SEAS,1.364609586257371
134 | 132,PPBI,1.048145705270598
135 | 133,IDCC,
136 | 134,SHAK,1.47725212130412
137 | 135,HELE,1.102268403782332
138 | 136,SGRY,1.999973607202672
139 | 137,CALM,0.323462843853415
140 | 138,FULT,0.815784014427509
141 | 139,CVBF,
142 | 140,DOOR,1.182890168604887
143 | 141,MYRG,0.7747847480547241
144 | 142,SFNC,0.8458923734057331
145 | 143,CSWI,0.8412651353342161
146 | 144,ICFI,0.62733067941937
147 | 145,VIAV,0.934238390424259
148 | 146,EVTC,0.8634942605605621
149 | 147,HLIO,1.059291242214267
150 | 148,YELP,1.076724307373715
151 | 149,BEAM,2.22868618310557
152 | 150,EXTR,1.263928851372129
153 | 151,ETRN,1.194857586090746
154 | 152,INSW,0.37664712566752
155 | 153,CEIX,0.9355991346503212
156 | 154,CORT,0.7001420878222151
157 | 155,NTCT,0.72182798290836
158 | 156,FFBC,0.7973932420792531
159 | 157,CTRE,
160 | 158,DBRG,1.68081060372413
161 | 159,SUPN,0.6989173344340911
162 | 160,IIPR,1.284359645446918
163 | 161,ATRC,1.259851817727312
164 | 162,SITM,2.305482792499327
165 | 163,SAVE,0.8758771676134861
166 | 164,PSMT,0.763883554831096
167 | 165,THRM,1.238820356854333
168 | 166,NMIH,0.990566648743584
169 | 167,JACK,0.84993645107832
170 | 168,WAFD,0.7901980887370731
171 | 169,FSLY,2.338618948990419
172 | 170,KRYS,1.251631647992914
173 | 171,ARCH,0.805502014023572
174 | 172,ATGE,0.599765956071525
175 | 173,RELY,1.504454692315982
176 | 174,LBRT,1.139363721259828
177 | 175,SNEX,0.6127568105870741
178 | 176,NOVA,1.900072622603876
179 | 177,MYGN,1.497684601301142
180 | 178,FGEN,1.260805855961382
181 | 179,CSTM,1.372301075284621
182 | 180,CRVL,0.764308305026407
183 | 181,BMBL,1.812840947466309
184 | 182,FRME,0.73016468162692
185 | 183,SILK,1.419993814673361
186 | 184,CARG,1.515031956845625
187 | 185,ADUS,0.6167670926509811
188 | 186,URBN,1.219910160067503
189 | 187,GOLF,0.819932121616712
190 | 188,EMBC,0.8259413722628081
191 | 189,PFSI,1.327211175722066
192 | 190,FLYW,1.970241730364953
193 | 191,NAVI,1.131969912093745
194 | 192,AGYS,0.556960017298332
195 | 193,BBIO,2.117476547127026
196 | 194,AMPH,0.614200591178863
197 | 195,CLDX,1.334231592567063
198 | 196,TOWN,0.681329431437767
199 | 197,RIOT,2.799004254045068
200 | 198,COHU,1.455101954690169
201 | 199,XPRO,1.224028894457009
202 | 200,XNCR,1.00567237058946
203 | 201,VCYT,2.195934639903841
204 | 202,SBCF,0.8799045431629671
205 | 203,CSGS,0.7195355968506051
206 | 204,WSBC,0.6270138488707611
207 | 205,HURN,0.435582169811055
208 | 206,BANF,0.5585536788078891
209 | 207,AKRO,-0.394281425357777
210 | 208,BANR,0.7873511123328111
211 | 209,CAKE,1.224259370683742
212 | 210,SSTK,1.268967256487673
213 | 211,APPN,1.923618481441944
214 | 212,LAUR,0.569120956528357
215 | 213,OSIS,0.6921291828292601
216 | 214,TROX,1.35214186460927
217 | 215,ROIC,0.964736417254311
218 | 216,CPRX,1.055481552574702
219 | 217,SDGR,1.505402173445524
220 | 218,HAIN,1.132481345780047
221 | 219,ELME,0.7565242209373061
222 | 220,UNFI,0.940498510655105
223 | 221,XPEL,1.185210248457538
224 | 222,ALGT,1.336516565814039
225 | 223,KTOS,1.332294544020426
226 | 224,SLVM,0.8336776891062431
227 | 225,AMLX,1.023527561764228
228 | 226,VRTV,1.250412784987154
229 | 227,CERE,1.382404179032898
230 | 228,EFSC,0.7320212284227511
231 | 229,RNST,0.752631512922678
232 | 230,ROCK,1.132498923696408
233 | 231,PRVB,0.974888717857874
234 | 232,RAMP,1.216431075401185
235 | 233,PGTI,1.091186009805295
236 | 234,PATK,1.163304958241573
237 | 235,MNRO,0.8214934323627561
238 | 236,AMEH,1.28674187311917
239 | 237,TBBK,1.325557674331495
240 | 238,HTLF,0.7186933046157881
241 | 239,ABCL,1.156372481134797
242 | 240,ENVA,1.331553935793724
243 | 241,BGCP,1.261259147028726
244 | 242,IBTX,0.8456523884181031
245 | 243,PLAY,1.371685411891257
246 | 244,IRWD,0.52347457510212
247 | 245,VSTO,1.040609062913461
248 | 246,VCEL,1.701022673435984
249 | 247,PRAA,0.458265103533369
250 | 248,SYBT,0.5325122704299711
251 | 249,TRMK,0.630869780317577
252 | 250,AVNS,0.988727141162506
253 | 251,AUPH,1.236664355397016
254 | 252,LAZR,2.355351448639719
255 | 253,ANDE,0.588301696989701
256 | 254,EPAC,0.8156969091778311
257 | 255,HIMS,1.418189013542548
258 | 256,SUMO,1.451957229926119
259 | 257,LKFN,
260 | 258,ALEX,0.986253608876814
261 | 259,BORR,1.194358981819265
262 | 260,NWBI,0.6125966466589401
263 | 261,NBTB,0.586441985699033
264 | 262,BCRX,1.232610438901815
265 | 263,ARVN,1.648016449573152
266 | 264,ACVA,1.887519345212049
267 | 265,RDNT,1.165921450175025
268 | 266,AMRC,1.754901400689252
269 | 267,MGPI,0.722370009788854
270 | 268,MSEX,0.679317838457929
271 | 269,QTWO,1.919439974555933
272 | 270,ENVX,2.020570334036605
273 | 271,MDRX,0.8511928671354391
274 | 272,PRVA,1.14828277597351
275 | 273,USPH,0.7117241065439911
276 | 274,UCTT,1.601430240729534
277 | 275,ASAN,2.619906258007355
278 | 276,EVRI,1.187537499935334
279 | 277,ETWO,1.481477565274973
280 | 278,CHCO,
281 | 279,CNNE,1.367341604386403
282 | 280,HEES,1.341474629975937
283 | 281,VRTS,1.415106599536436
284 | 282,MLKN,1.303506399054672
285 | 283,KYMR,1.630584919059124
286 | 284,DVAX,1.380267636890798
287 | 285,AROC,0.887317626619299
288 | 286,HLIT,0.945453586174767
289 | 287,SMTC,1.343066769228029
290 | 288,SNDX,0.8924133127322
291 | 289,TRUP,2.107774047560177
292 | 290,TVTX,0.870785099227927
293 | 291,UPWK,1.793404778998056
294 | 292,NVEE,0.9452654245314652
295 | 293,PLMR,1.027539685829922
296 | 294,PRIM,0.988436433597232
297 | 295,KFRC,0.9010671383495832
298 | 296,STEP,1.316985551655398
299 | 297,PLUS,1.03081495132623
300 | 298,CARS,1.284332401472429
301 | 299,FBNC,0.7520242824808251
302 | 300,MODN,0.772685234765481
303 | 301,MGNI,2.605936931956764
304 | 302,TTMI,1.257205759767318
305 | 303,LGFB,0.8090199593175621
306 | 304,PAYO,1.279958134247849
307 | 305,ERII,1.112667676383814
308 | 306,AGIO,1.477150267258165
309 | 307,AVTA,0.8242821129277491
310 | 308,GPRE,1.3317565232544
311 | 309,SABR,1.886098939837891
312 | 310,MNTV,1.484879322492726
313 | 311,TCBK,0.6334405363877771
314 | 312,TFIN,1.289669361174454
315 | 313,FIZZ,0.8005420548563851
316 | 314,SKYW,1.183194645732729
317 | 315,ECPG,0.448981755566395
318 | 316,INFN,1.320090588297821
319 | 317,PDFS,1.208725568811939
320 | 318,CDMO,1.670884656217354
321 | 319,MRTN,0.810425104420577
322 | 320,COUR,1.387351135288904
323 | 321,ATSG,0.899916912270721
324 | 322,DNOW,1.170637200618066
325 | 323,ATEC,1.407992091220246
326 | 324,PARR,1.067743250917937
327 | 325,CODI,0.9311271825665132
328 | 326,IRBT,0.656564252487922
329 | 327,ACLX,0.927647291033979
330 | 328,NVRO,1.474500252299523
331 | 329,LGND,
332 | 330,DICE,0.8152002077242161
333 | 331,APPS,3.180231517375507
334 | 332,ZETA,1.780089830550289
335 | 333,UPBD,
336 | 334,MORF,1.656454947457591
337 | 335,CTKB,1.514270543290719
338 | 336,SPWR,1.677534536655242
339 | 337,MBUU,1.046004347299345
340 | 338,CASH,1.082975194419989
341 | 339,GERN,1.225092031286834
342 | 340,CHEF,0.9780814285678472
343 | 341,MATW,0.73418285657671
344 | 342,DFIN,1.295932766028958
345 | 343,VRDN,0.7823989788672211
346 | 344,EVBG,1.826321641714484
347 | 345,HOPE,0.8186304142888731
348 | 346,DGII,1.045028684570644
349 | 347,SKIN,2.023620786280719
350 | 348,HSKA,1.140449008947851
351 | 349,GOGL,0.8368821402823811
352 | 350,RADI,1.209421655931071
353 | 351,AVDX,1.557862646697426
354 | 352,PTGX,1.223813142048829
355 | 353,KDNY,1.011267543210456
356 | 354,HLMN,1.116866412737895
357 | 355,MATV,0.7781745631597201
358 | 356,NSSC,0.94197636846739
359 | 357,DNUT,0.8274228342392991
360 | 358,AVID,1.392392764811473
361 | 359,RLAY,1.787657249531794
362 | 360,STRL,0.9230448789472172
363 | 361,WABC,0.560880968258849
364 | 362,SCHL,0.506019574271781
365 | 363,CMTG,0.831789153374158
366 | 364,SASR,0.7490333723243201
367 | 365,SAFT,0.4462515933161521
368 | 366,ACCD,2.535284648171822
369 | 367,HCSG,0.8729823076348371
370 | 368,LMAT,0.780507194835926
371 | 369,CRNC,1.666812636283639
372 | 370,MARA,3.250923986866891
373 | 371,GSHD,1.824422448701883
374 | 372,LADR,0.9652063358764612
375 | 373,AMSF,0.5002933494581481
376 | 374,MNKD,1.418833107761789
377 | 375,JELD,1.584869549777749
378 | 376,ASIX,1.303908758129612
379 | 377,STEL,0.5698657445617551
380 | 378,RCKT,1.993513575697757
381 | 379,FBRT,0.946061548775914
382 | 380,STBA,0.664930315964804
383 | 381,RCUS,1.556328834321593
384 | 382,ROAD,1.09343810798976
385 | 383,YEXT,1.251425647485407
386 | 384,GRBK,1.45314635814693
387 | 385,KALU,
388 | 386,NXGN,0.676549263919619
389 | 387,SBSI,0.5419767223944301
390 | 388,NXRT,0.946727822141001
391 | 389,JOBY,1.56159645019648
392 | 390,CYRX,2.132506607972233
393 | 391,ZNTL,1.691291310064309
394 | 392,FLNG,1.020759066148658
395 | 393,BUSE,
396 | 394,NTST,0.605251517144288
397 | 395,TALO,1.268800170409292
398 | 396,MCRI,0.920957946440054
399 | 397,TMCI,1.304492369468422
400 | 398,SQSP,1.062180591635181
401 | 399,CMCO,1.246457786643454
402 | 400,APOG,1.085804759378217
403 | 401,PWSC,1.024678943295115
404 | 402,OCFC,0.7413172793521291
405 | 403,WINA,0.7074983389980231
406 | 404,ADPT,2.394323894765965
407 | 405,IMAX,1.09866677255491
408 | 406,UFPT,0.68872655917136
409 | 407,ECVT,0.8752628107950161
410 | 408,NYMT,1.236791344644068
411 | 409,PRCT,1.255495482247023
412 | 410,VECO,1.219877323618521
413 | 411,BHLB,0.8604627122057551
414 | 412,NBHC,0.810790075681299
415 | 413,CRNX,1.037451815810029
416 | 414,VTYX,1.360990314928006
417 | 415,LBAI,0.7066050893339461
418 | 416,ARGO,0.577218084919346
419 | 417,ASTE,1.110925770309516
420 | 418,VICR,1.77865716730288
421 | 419,TTGT,1.101996612302316
422 | 420,SHEN,1.0533439360097
423 | 421,RDFN,2.720206577341824
424 | 422,COMM,1.729646511756126
425 | 423,MODV,0.890247392780483
426 | 424,VBTX,1.040921051165272
427 | 425,INDI,1.831024756082971
428 | 426,ATEN,1.145451437763518
429 | 427,JBSS,0.456445289939538
430 | 428,IMGN,1.356513868950154
431 | 429,GABC,0.535881122089868
432 | 430,GPOR,0.865319700454038
433 | 431,SLCA,1.269544459189919
434 | 432,PLAB,1.545509846079794
435 | 433,BHVN,
436 | 434,NABL,1.13951801815718
437 | 435,WRBY,2.027138853632484
438 | 436,RVLV,1.728411376567365
439 | 437,SAVA,0.905671925822458
440 | 438,PRDO,0.57609427165826
441 | 439,FORG,0.807976758142773
442 | 440,ATRI,0.608682670026238
443 | 441,MLAB,0.9394921658775092
444 | 442,AHCO,1.05461266012208
445 | 443,GDEN,1.235169988769336
446 | 444,BRKL,0.7053239888067291
447 | 445,KROS,1.400028217119759
448 | 446,SPTN,0.599657254765078
449 | 447,NMRK,1.297225577498927
450 | 448,IOVA,1.116555103415253
451 | 449,SWTX,1.205629715878082
452 | 450,BYND,2.438163470948136
453 | 451,SPNT,0.8013527297543941
454 | 452,RKLB,1.872180699964084
455 | 453,CHCT,0.6201866870209181
456 | 454,COMP,2.694146061796151
457 | 455,SPCE,2.09833641353285
458 | 456,CFFN,0.619074258567473
459 | 457,FIGS,1.767707045886919
460 | 458,AMWD,1.226987546734397
461 | 459,HRMY,0.7318489395697191
462 | 460,ADEA,0.5029789403189341
463 | 461,EGBN,0.646442809923895
464 | 462,CRDO,1.438273140670328
465 | 463,CCRN,0.876534545643159
466 | 464,FCEL,2.300396434947008
467 | 465,EXPI,2.013163661354903
468 | 466,GDOT,1.272537599745466
469 | 467,PGRE,1.119868256168723
470 | 468,HWKN,0.746405387827459
471 | 469,ESRT,1.116799876795428
472 | 470,MSGE,
473 | 471,CSII,0.741740171337629
474 | 472,REPL,1.15085243291747
475 | 473,SHYF,1.360496101256243
476 | 474,ICHR,1.855221088511534
477 | 475,CMPR,1.763876373088406
478 | 476,IMXI,0.6850101139301681
479 | 477,SBGI,1.16561751769572
480 | 478,VERV,2.127881578503407
481 | 479,STKL,0.902856185019406
482 | 480,UUUU,2.056822836723763
483 | 481,ROCC,1.333798580254495
484 | 482,TMST,1.512786548216881
485 | 483,VTLE,1.57752906125466
486 | 484,SCHN,
487 | 485,TWST,2.392995101309885
488 | 486,PRLB,1.100035423801566
489 | 487,PLYM,0.9225200310070332
490 | 488,RXRX,1.990409636103048
491 | 489,UNIT,1.441383364730917
492 | 490,COLL,0.7021693485676911
493 | 491,RGNX,1.393932561830356
494 | 492,BSIG,1.050120567746561
495 | 493,DCPH,1.210753720588678
496 | 494,OSTK,1.820485569140587
497 | 495,INVA,
498 | 496,TBPH,0.6816322511242501
499 | 497,SIBN,1.323407020174572
500 | 498,IONQ,2.442875093888047
501 | 499,ADMA,1.32109591347606
502 | 500,OBNK,0.6523827649460121
503 | 501,KIDS,1.218872086340952
504 | 502,CCSI,1.036924394231524
505 | 503,USNA,0.640165724030839
506 | 504,FLNC,2.09795324076012
507 | 505,ADTN,
508 | 506,SCSC,0.7970815651063401
509 | 507,CRAI,0.6360142101214701
510 | 508,HIBB,1.303867812295438
511 | 509,ENTA,1.003143822231815
512 | 510,LPRO,1.953300350226432
513 | 511,HCAT,1.711717517685154
514 | 512,SRCE,0.6269814243723371
515 | 513,JRVR,0.72902628585645
516 | 514,PEBO,0.550938657264034
517 | 515,COGT,0.651617718120813
518 | 516,CLNE,1.83258090033832
519 | 517,KURA,0.9958379214896372
520 | 518,CRSR,1.684383787995079
521 | 519,BJRI,1.302709335067707
522 | 520,HTLD,0.760394012022729
523 | 521,LGFA,0.807271672905977
524 | 522,DCGO,0.903820366279982
525 | 523,OSCR,1.804023413557458
526 | 524,ARKO,0.6058717660043831
527 | 525,GIII,1.398017922149002
528 | 526,GSAT,1.26091700728532
529 | 527,AMBC,0.6853790197151961
530 | 528,TELL,1.793517487627383
531 | 529,NUVL,1.870227108231141
532 | 530,VREX,0.736657836286963
533 | 531,GOGO,1.059047860845177
534 | 532,IMVT,1.144041991895044
535 | 533,AMPL,1.788277378791743
536 | 534,HFWA,0.619787984131012
537 | 535,INBX,2.036155656457838
538 | 536,OFIX,0.9049033128052292
539 | 537,TTEC,1.203836542398262
540 | 538,RILY,1.604232352823104
541 | 539,OSPN,1.043292632497458
542 | 540,DCOM,0.972932502512528
543 | 541,BALY,1.540033624722727
544 | 542,HSTM,
545 | 543,SPHR,0.972436781742374
546 | 544,QCRH,0.710231147473908
547 | 545,AMRK,
548 | 546,XPOF,1.350588999015487
549 | 547,INTA,1.160570023247837
550 | 548,SPNS,
551 | 549,BLFS,2.257624663649936
552 | 550,IDYA,0.933070431628238
553 | 551,CLBK,0.424091382878295
554 | 552,PLOW,0.8248833898408191
555 | 553,UDMY,1.148216138274966
556 | 554,UVSP,0.5744445877266441
557 | 555,FDMT,1.270705551973574
558 | 556,ARCT,2.227943062879673
559 | 557,HOUS,1.725486294201071
560 | 558,PTLO,1.227795122639531
561 | 559,ESMT,1.111230405346996
562 | 560,RICK,1.136716246311579
563 | 561,SOVO,0.751858329069728
564 | 562,KREF,0.909614496221632
565 | 563,CHUY,1.046864561163178
566 | 564,SNCY,1.09152791587992
567 | 565,DSEY,1.527073003472715
568 | 566,LICY,1.355762873581803
569 | 567,BANC,0.8827439060169471
570 | 568,FLGT,1.201693938533018
571 | 569,STEM,2.254406770631627
572 | 570,NAPA,0.803453003355554
573 | 571,DENN,0.971826578418606
574 | 572,GDYN,1.4886141023589
575 | 573,CEVA,1.420031882272087
576 | 574,BRMK,1.089186414847004
577 | 575,YORW,0.4754160882873431
578 | 576,EGLE,0.580707433088495
579 | 577,CNOB,0.8549940303052871
580 | 578,TITN,1.199390048005034
581 | 579,CHRS,1.630789652513363
582 | 580,PUBM,1.614128049458802
583 | 581,KAMN,1.30720364000589
584 | 582,PUMP,1.079496926533941
585 | 583,CSTL,1.844333322058144
586 | 584,VZIO,1.415033298467512
587 | 585,QNST,0.838085246201774
588 | 586,THRY,0.960466073049384
589 | 587,ESTE,1.302613309103973
590 | 588,MTTR,2.110427494800031
591 | 589,CUBI,1.574520431586703
592 | 590,UFCS,0.473789664466469
593 | 591,HAYN,1.271595368747944
594 | 592,BBSI,0.67064092062975
595 | 593,CNDT,0.965561403092777
596 | 594,SATS,0.8442901212583591
597 | 595,GPRO,1.291704153544057
598 | 596,LMND,2.187149453599956
599 | 597,ACRS,0.964586878971845
600 | 598,RAPT,1.906355135885391
601 | 599,ATEX,0.66732342645302
602 | 600,CTBI,0.5292687095063341
603 | 601,TRNS,0.935892087270472
604 | 602,ARLO,1.497652141691197
605 | 603,FBMS,0.6961954628403271
606 | 604,GMRE,0.93818611045145
607 | 605,WASH,0.591704340404671
608 | 606,RPAY,1.918235681558241
609 | 607,ARQT,0.836826835678049
610 | 608,LFST,1.760669036786944
611 | 609,IIIV,1.295831885472485
612 | 610,COCO,1.358172648639844
613 | 611,AVPT,1.282080304166303
614 | 612,TRST,0.5450406131366881
615 | 613,EDIT,2.229904371683868
616 | 614,BIGC,2.083361150363821
617 | 615,AMCX,1.381439617624978
618 | 616,OSBC,0.7860643152134441
619 | 617,AVXL,1.973269331114257
620 | 618,AORT,1.209991573629823
621 | 619,CLFD,1.402344697649032
622 | 620,NWLI,0.7867651626006611
623 | 621,SWBI,1.064012012879915
624 | 622,AOSL,1.895275977366709
625 | 623,AGEN,1.824393417799573
626 | 624,HCCI,0.8374972647298401
627 | 625,CVGW,0.513387376853087
628 | 626,BRSP,1.151728824064241
629 | 627,HSII,0.8989552220699071
630 | 628,CTIC,1.075544654955206
631 | 629,HAFC,0.8914580382134001
632 | 630,LAND,
633 | 631,SNBR,1.735883750211777
634 | 632,KNTK,
635 | 633,WTTR,1.042261162825261
636 | 634,FATE,1.755566910377592
637 | 635,ALHC,1.078084736106055
638 | 636,DOMO,2.311243370354861
639 | 637,VTOL,1.235348185516622
640 | 638,CASS,0.680509786346849
641 | 639,IIIN,1.081739492461775
642 | 640,MCFT,1.026940795479269
643 | 641,AMTB,0.746493109810443
644 | 642,OSUR,1.20455557811142
645 | 643,HONE,
646 | 644,RUTH,1.000192482968352
647 | 645,SHCR,1.440057785100347
648 | 646,GSBC,0.481046104075552
649 | 647,AGTI,0.964072247121108
650 | 648,MIRM,0.649921074940295
651 | 649,DHIL,0.734211126592692
652 | 650,TRTX,1.143522374050798
653 | 651,IHRT,1.954710855768665
654 | 652,VMEO,1.718044660493358
655 | 653,PFBC,
656 | 654,NTGR,1.087287867329332
657 | 655,CMRE,0.8542942662465861
658 | 656,CLDT,1.193614292236608
659 | 657,ACMR,1.931784284099933
660 | 658,NRIX,1.504133395340759
661 | 659,OCUL,1.676855688823895
662 | 660,STGW,1.243584729575006
663 | 661,LWLG,2.149928835887888
664 | 662,ANIP,0.9982104405005532
665 | 663,ACEL,0.922050218734516
666 | 664,VCTR,1.113675217116396
667 | 665,BBUC,1.220993807099722
668 | 666,ZEUS,1.327940308598751
669 | 667,REPX,
670 | 668,HTBK,0.7195577192255921
671 | 669,AMWL,1.470354226691495
672 | 670,NFBK,0.5146651246390841
673 | 671,KRNY,0.632654582134851
674 | 672,BASE,1.681505043804189
675 | 673,XMTR,1.209059515893736
676 | 674,FMBH,0.6878410602664371
677 | 675,GOOD,
678 | 676,VSEC,1.276928086632285
679 | 677,TPIC,1.723085806143038
680 | 678,AMOT,1.089706870090379
681 | 679,CNXN,0.637413895466993
682 | 680,MBWM,0.6689836027611981
683 | 681,NSTG,2.279164361876965
684 | 682,ICPT,1.086071131574003
685 | 683,EWCZ,1.072798305501607
686 | 684,SLGC,1.831249057967298
687 | 685,ALKT,1.294707355786871
688 | 686,SANA,2.334243037877497
689 | 687,INST,0.67450008021728
690 | 688,EBIX,2.359633340064863
691 | 689,CRMT,1.303308121462508
692 | 690,CRGY,1.089254519327973
693 | 691,CENX,2.424136193304316
694 | 692,ANAB,0.8876604003143481
695 | 693,ACRE,1.172995046229338
696 | 694,TILE,1.193123171283799
697 | 695,MCRB,1.490713844524506
698 | 696,PSFE,2.062901543172611
699 | 697,FARO,1.137003067318455
700 | 698,MNTK,1.090322701150235
701 | 699,MXCT,
702 | 700,ACCO,0.906455927022586
703 | 701,HBNC,
704 | 702,BOWL,1.107369944636621
705 | 703,CATC,0.657524382337037
706 | 704,CDNA,1.453961786083583
707 | 705,MSBI,0.6528262627138931
708 | 706,HCKT,0.728034985179142
709 | 707,KBAL,1.020135672480801
710 | 708,QTRX,2.027516908627919
711 | 709,GEFB,0.815879396192671
712 | 710,AMPS,1.37292490204715
713 | 711,ALLO,1.595691071691533
714 | 712,ASLE,0.9722719135056492
715 | 713,BTAI,1.847330746111679
716 | 714,EZPW,0.7241356251570401
717 | 715,CERS,1.670143765476116
718 | 716,LUNG,1.703590695787633
719 | 717,MDXG,1.59358624848772
720 | 718,ATNI,0.5011684675879821
721 | 719,EVGO,1.999936107261632
722 | 720,XPER,
723 | 721,ORGN,1.330189315218047
724 | 722,LXFR,0.905317601289522
725 | 723,SCVL,1.213988903008346
726 | 724,RXST,1.06032345037795
727 | 725,MGNX,1.538277711734955
728 | 726,ALEC,1.657797905943356
729 | 727,CDRE,0.840922709036183
730 | 728,VTNR,1.852205250907831
731 | 729,LOVE,1.807432458342707
732 | 730,ROVR,1.119631898642801
733 | 731,FCBC,0.5854592205658511
734 | 732,CCBG,0.5201305720848031
735 | 733,ATRO,1.176654989419173
736 | 734,MBIN,0.8265391152729241
737 | 735,CPSI,0.7479009838854
738 | 736,LASR,1.579019564919733
739 | 737,LYEL,1.667785861816538
740 | 738,THFF,0.366793911212373
741 | 739,PLCE,1.415356236398411
742 | 740,VITL,0.7650602079211921
743 | 741,BFST,0.741531352626819
744 | 742,ANIK,0.815668871972085
745 | 743,NRDS,1.063855806519756
746 | 744,FMNB,0.606071790310685
747 | 745,LIND,1.959399537281036
748 | 746,FFIC,0.571112360045809
749 | 747,MRSN,1.380466095134059
750 | 748,FRPH,0.518096162276673
751 | 749,TWOU,2.358890520792122
752 | 750,MPLN,1.175327841716973
753 | 751,AXGN,1.111251848012203
754 | 752,MITK,1.255315121911555
755 | 753,BOOM,1.609659201704989
756 | 754,CUTR,1.639880140397737
757 | 755,DXPE,0.8757774747075701
758 | 756,DAWN,0.146429413631663
759 | 757,ONTF,1.115231748107484
760 | 758,FORR,0.90802771012653
761 | 759,EQRX,1.180450204825315
762 | 760,CCNE,0.657850465948523
763 | 761,EQBK,0.710788511148685
764 | 762,KNSA,0.8223809620055
765 | 763,CTOS,1.135668699128468
766 | 764,OFLX,
767 | 765,IESC,0.988997080879504
768 | 766,RMAX,1.103575521713567
769 | 767,REVG,1.068259642203335
770 | 768,IBCP,0.7231881164011441
771 | 769,TCMD,1.2602120373306
772 | 770,POWL,0.86660476892918
773 | 771,FFWM,0.938531823875746
774 | 772,HTBI,0.540194051325669
775 | 773,LPSN,2.164245500318007
776 | 774,ULCC,1.348798443528347
777 | 775,EGHT,2.060360559571593
778 | 776,VNDA,0.7560335552769141
779 | 777,CENT,0.644376702804188
780 | 778,TIPT,0.622473093729077
781 | 779,PTVE,0.8150301715486351
782 | 780,BLUE,
783 | 781,WRLD,1.736140282450519
784 | 782,SMBK,0.62567013097889
785 | 783,GLDD,0.9171675729514732
786 | 784,INDT,0.4520734298046301
787 | 785,HDSN,1.085885799532137
788 | 786,MLNK,0.9378676180445992
789 | 787,BMRC,0.573314497230885
790 | 788,SFIX,2.536057441069035
791 | 789,LILA,1.318948517315034
792 | 790,CARE,0.7234273719895661
793 | 791,ABUS,0.990830822600763
794 | 792,LQDT,1.039702871380649
795 | 793,LQDA,1.190624128262903
796 | 794,MVIS,2.052119507428403
797 | 795,CVLG,0.9713513702651552
798 | 796,CTLP,1.092192053888383
799 | 797,RYAM,1.370119898638595
800 | 798,GCMG,0.7256085984627041
801 | 799,NVTA,4.087875270527494
802 | 800,ANGO,0.90130936487197
803 | 801,PNTG,1.131669804506248
804 | 802,CZNC,0.385172393414727
805 | 803,SRDX,1.10132073660698
806 | 804,AROW,0.596161312126534
807 | 805,PAHC,0.775182890830705
808 | 806,AMNB,0.5854047543753641
809 | 807,USLM,0.595548721094593
810 | 808,DNMR,2.186940841024352
811 | 809,DSKE,1.372680045033933
812 | 810,DJCO,
813 | 811,ITOS,1.209498456073897
814 | 812,MYPS,1.182433477529946
815 | 813,EOLS,1.06747686218236
816 | 814,HMST,0.956004858805739
817 | 815,PLPC,0.752932324780286
818 | 816,HIPO,1.49362459740363
819 | 817,BFLY,2.156087762710606
820 | 818,PETQ,1.620266516794751
821 | 819,AMAL,0.5488665780542521
822 | 820,TSVT,1.60050006650005
823 | 821,JOUT,0.9725574276186
824 | 822,PETS,0.8605896822063571
825 | 823,KPTI,1.791039037533252
826 | 824,MOFG,0.734494515507881
827 | 825,NKLA,1.791733518464118
828 | 826,MCBS,0.862836041224568
829 | 827,EVCM,1.409993361882535
830 | 828,BAND,1.952033768695281
831 | 829,KRUS,1.367473509996122
832 | 830,INGN,1.199865386174506
833 | 831,SLDP,1.353033220250441
834 | 832,BLBD,1.021477666186369
835 | 833,ONEW,0.982944433789958
836 | 834,SENS,1.930405175478256
837 | 835,XERS,1.471680871441854
838 | 836,UTMD,0.620596859790382
839 | 837,BLNK,1.92515097758837
840 | 838,OABI,
841 | 839,CLOV,1.937196781164564
842 | 840,PFIS,0.693221791102213
843 | 841,SMBC,0.638768605289447
844 | 842,CMTL,1.182461353989321
845 | 843,SMRT,1.544782611776662
846 | 844,FISI,0.682829049716088
847 | 845,CSTR,0.5492286775057901
848 | 846,FNKO,1.124505410658999
849 | 847,ZUMZ,1.392766998000412
850 | 848,CLAR,1.569570146585595
851 | 849,HRTX,1.901532791025489
852 | 850,FLIC,0.608554248786177
853 | 851,EGRX,0.8330813944535911
854 | 852,CLSK,2.779586686934978
855 | 853,WSBF,
856 | 854,OOMA,0.866356560663421
857 | 855,QUOT,1.271221915299166
858 | 856,ATRA,2.379023583006129
859 | 857,ALTG,1.131143948176919
860 | 858,ACHR,1.67428709942265
861 | 859,CGEM,1.166227032888268
862 | 860,EWTX,1.311502813070388
863 | 861,FLWS,1.33877911634368
864 | 862,WTBA,0.741108514940889
865 | 863,NNOX,1.592269058783179
866 | 864,HIFS,0.740922408717403
867 | 865,INSE,1.062410956105161
868 | 866,IRMD,0.849532534624429
869 | 867,ASPN,2.175364326036178
870 | 868,MCBC,0.403687409716612
871 | 869,CNSL,1.504175701721503
872 | 870,FMAO,0.74239366493158
873 | 871,DXLG,1.28434447438536
874 | 872,AVNW,1.050868492344842
875 | 873,EBTC,0.775022740938138
876 | 874,NWPX,0.612318164457718
877 | 875,SBOW,1.304560914942936
878 | 876,STER,1.517577326595658
879 | 877,FNLC,
880 | 878,SIGA,1.020294073643159
881 | 879,GLRE,0.57391083671039
882 | 880,PFHC,
883 | 881,CDXS,1.828907243354272
884 | 882,EVLV,1.724873880521588
885 | 883,JANX,1.437278026134496
886 | 884,OPRX,1.263658301856142
887 | 885,TARS,0.876048660812052
888 | 886,PTRA,1.668149290503013
889 | 887,ACNB,0.552551189555591
890 | 888,PHAT,1.726887255961412
891 | 889,ZYXI,1.259005733237978
892 | 890,SLQT,2.512810845086624
893 | 891,HBCP,0.609128887510481
894 | 892,PRTS,1.809752471546916
895 | 893,TREE,2.150924678057125
896 | 894,STRO,1.039222954515002
897 | 895,BLFY,0.5165045561590921
898 | 896,AVIR,1.229449157001122
899 | 897,FRST,0.617869253502896
900 | 898,AMPY,1.336808859781715
901 | 899,CRBU,1.921659300168871
902 | 900,CIVB,0.573688652739885
903 | 901,PSTL,0.649426403310778
904 | 902,RLGT,0.9158495004386812
905 | 903,GEVO,2.290358707039879
906 | 904,SHBI,0.500583156024743
907 | 905,ALRS,0.7926209079865361
908 | 906,SSTI,0.901719684663996
909 | 907,FBIZ,0.5063313657026061
910 | 908,FSBC,0.6365219560937021
911 | 909,BSRR,0.5684330227482101
912 | 910,NEXT,1.449034278589293
913 | 911,VUZI,2.001416485910236
914 | 912,NRDY,1.655761728920651
915 | 913,GPMT,1.103379354996184
916 | 914,HLVX,
917 | 915,ENFN,1.14859747541068
918 | 916,SPFI,0.593913417453903
919 | 917,DOUG,1.302105390218628
920 | 918,TRUE,1.215063025178879
921 | 919,SPWH,1.002017161082437
922 | 920,NETI,0.671295089162079
923 | 921,DMRC,1.712303445110037
924 | 922,SFST,0.715744527193347
925 | 923,IBRX,2.51071555375479
926 | 924,JYNT,1.479379599564182
927 | 925,FWRG,1.097255946107784
928 | 926,YMAB,1.805476963820673
929 | 927,SGMO,1.678767262992386
930 | 928,AKTS,2.117351726313515
931 | 929,SMMF,0.5796536629562771
932 | 930,CDLX,2.945996872735622
933 | 931,APLD,2.441686884034373
934 | 932,FUBO,2.517309649495944
935 | 933,NUVB,1.155534164419852
936 | 934,SGHT,1.876152440500584
937 | 935,EHTH,1.451658151443007
938 | 936,GBIO,1.734847362375472
939 | 937,EYPT,1.177988855280159
940 | 938,GOEV,1.690415934656868
941 | 939,JMSB,
942 | 940,DSGR,0.8128250672566321
943 | 941,GNTY,0.4880048526523371
944 | 942,TNYA,1.523336606887094
945 | 943,RRBI,0.6725338822051511
946 | 944,ORRF,0.461652288186688
947 | 945,BCML,0.54594939950152
948 | 946,DSGN,1.447337425083952
949 | 947,RIGL,1.200106991989166
950 | 948,BNGO,2.399573139296189
951 | 949,KALV,0.5631619108750571
952 | 950,AFCG,0.742899642902045
953 | 951,SKLZ,2.805769902169608
954 | 952,KODK,1.567296163340624
955 | 953,ERAS,1.409155315856711
956 | 954,LXRX,1.73012836810007
957 | 955,STOK,1.453051690271325
958 | 956,HYLN,1.792521892416012
959 | 957,PACK,1.387564434873971
960 | 958,AURA,0.9403345857054192
961 | 959,NDLS,1.510341582271856
962 | 960,SEER,2.335898286470086
963 | 961,IBEX,0.5419921143706601
964 | 962,SKWD,
965 | 963,METC,1.001700506817109
966 | 964,PKBK,
967 | 965,ACET,1.328177176248013
968 | 966,SEAT,1.35425262208837
969 | 967,MVBF,0.652704742440781
970 | 968,CANO,0.336908089532273
971 | 969,ITIC,
972 | 970,RBBN,1.407323235053071
973 | 971,RMNI,1.149851549358818
974 | 972,PCYO,0.792435526009266
975 | 973,MVST,1.709645758570195
976 | 974,CARA,1.266857605594413
977 | 975,AVTE,1.642369064250987
978 | 976,HUMA,1.279493248475395
979 | 977,CNTY,1.503905953256302
980 | 978,VRAY,1.12721835710557
981 | 979,LOCO,0.8884854087771181
982 | 980,SAMG,0.8205792744161641
983 | 981,TCBX,0.549513362015434
984 | 982,PMVP,1.538509049949223
985 | 983,MGTX,1.07951200575332
986 | 984,BHIL,1.377722593133113
987 | 985,NGMS,1.482466644245675
988 | 986,GRWG,2.009322065812529
989 | 987,UNTY,0.390045119971116
990 | 988,POWW,1.268926704076045
991 | 989,PEPG,
992 | 990,TYRA,1.428529255264964
993 | 991,BRBS,
994 | 992,MASS,2.086193273380773
995 | 993,ZIMV,1.40932208158131
996 | 994,BGFV,1.11851396706335
997 | 995,MLYS,
998 | 996,SNPO,1.362178732627019
999 | 997,HEAR,1.730844172543069
1000 | 998,LEGH,0.8579362652283961
1001 | 999,PTSI,1.457574742616136
1002 | 1000,CMBM,1.341175179927785
1003 | 1001,STKS,1.379213820272165
1004 | 1002,OCGN,2.380651678150385
1005 | 1003,CBAN,0.445318334127934
1006 | 1004,BCBP,0.575003852439196
1007 | 1005,FOSL,1.827899880541178
1008 | 1006,NUTX,1.733438945656614
1009 | 1007,TDUP,1.855125139079852
1010 | 1008,FEAM,1.59008325635777
1011 | 1009,TNGX,1.609112065959192
1012 | 1010,AMRX,1.196676714277481
1013 | 1011,VERI,2.359670685484822
1014 | 1012,WISH,
1015 | 1013,RCKY,1.302000986351387
1016 | 1014,PRPL,1.994117566878018
1017 | 1015,BBCP,0.6411728559770811
1018 | 1016,CATO,0.8745895837780591
1019 | 1017,NKTX,1.409815268386487
1020 | 1018,GLUE,1.831878410787046
1021 | 1019,CBNK,0.63056253135259
1022 | 1020,WLDN,1.193087039391306
1023 | 1021,ARIS,1.148463873976328
1024 | 1022,TLYS,0.981549563515538
1025 | 1023,NKTR,1.532078887474237
1026 | 1024,EVER,1.292403772435455
1027 | 1025,AMRS,3.11923739612559
1028 | 1026,THRX,1.424658910145521
1029 | 1027,NESR,0.983308749003158
1030 | 1028,BWFG,0.5004657113286141
1031 | 1029,OTLK,1.01976107025418
1032 | 1030,ALCO,0.6102084378868541
1033 | 1031,BLDE,1.29400540581265
1034 | 1032,CTRN,1.558764510591878
1035 | 1033,BCOV,0.959350750925046
1036 | 1034,ALPN,0.96448478210931
1037 | 1035,PGEN,1.839157574525989
1038 | 1036,WKHS,2.052835678000381
1039 | 1037,WEYS,0.519868600229754
1040 | 1038,FRBA,0.6583741769118361
1041 | 1039,RDVT,0.921647259361503
1042 | 1040,BLND,1.879071330360324
1043 | 1041,FVCB,0.310864524923163
1044 | 1042,RENT,2.35712805347461
1045 | 1043,TTSH,0.9823268477813012
1046 | 1044,ORGO,1.142640575657384
1047 | 1045,CRDA,0.428613883916256
1048 | 1046,INBK,1.056382779104771
1049 | 1047,EGAN,0.939177060498188
1050 | 1048,VERA,0.9698117551404072
1051 | 1049,WEAV,1.567983889282596
1052 | 1050,CCCC,1.828802866100381
1053 | 1051,FHTX,1.48012993174207
1054 | 1052,ATLC,1.589105436089128
1055 | 1053,GCBC,
1056 | 1054,PRME,
1057 | 1055,FULC,1.460957859122198
1058 | 1056,MYFW,0.6928144645234381
1059 | 1057,GWRS,
1060 | 1058,ICVX,1.569779989813451
1061 | 1059,BRCC,1.057517352171263
1062 | 1060,CRGE,1.397114342964152
1063 | 1061,NRGV,1.47955680897146
1064 | 1062,NATR,0.73403358646283
1065 | 1063,DZSI,1.075072790494269
1066 | 1064,ALXO,1.361613091153165
1067 | 1065,UEIC,1.073551804875521
1068 | 1066,BIRD,2.01467556546739
1069 | 1067,AXTI,1.362928328863877
1070 | 1068,AFMD,1.443609211406802
1071 | 1069,HFFG,1.147599426372198
1072 | 1070,CMAX,1.503754821043519
1073 | 1071,HNST,1.592635773344981
1074 | 1072,BARK,1.54273065031762
1075 | 1073,RBOT,1.835571716653383
1076 | 1074,IGMS,1.963329380409508
1077 | 1075,ILPT,
1078 | 1076,XXII,1.583602066770661
1079 | 1077,NOTV,2.020045693676911
1080 | 1078,STRS,0.7204697318430341
1081 | 1079,ALVR,1.733226332147202
1082 | 1080,SKYT,2.152542973681815
1083 | 1081,INNV,1.149295613334473
1084 | 1082,INVE,1.358262120437971
1085 | 1083,APEI,0.689207551817081
1086 | 1084,AADI,0.959429654208166
1087 | 1085,NODK,0.489393376128946
1088 | 1086,FTCI,1.924356791145415
1089 | 1087,AKYA,1.370160074063013
1090 | 1088,SKIL,1.478402372011281
1091 | 1089,HLLY,0.978854503869996
1092 | 1090,QUAD,1.020413209217836
1093 | 1091,RSVR,0.959364430885206
1094 | 1092,UPLD,1.471108187123241
1095 | 1093,HLTH,1.466619421935053
1096 | 1094,REAL,3.192023988272416
1097 | 1095,FFIE,
1098 | 1096,ALTO,1.472748669435535
1099 | 1097,OUST,1.990804190583039
1100 | 1098,COOK,1.680177757157055
1101 | 1099,LFCR,
1102 | 1100,OPRT,1.593494694625428
1103 | 1101,MKFG,1.794569318543228
1104 | 1102,MULN,1.292250291936413
1105 | 1103,AEVA,2.128433252687613
1106 | 1104,ATOM,2.063067313790603
1107 | 1105,SWIM,1.857199669663237
1108 | 1106,NAUT,1.515742430677405
1109 | 1107,PVBC,0.611262970115493
1110 | 1108,SOND,2.359327211499705
1111 | 1109,CMRX,1.577570477335277
1112 | 1110,PBFS,0.35177139169866
1113 | 1111,USCB,0.268152008256662
1114 | 1112,ATHA,1.496098916926753
1115 | 1113,AOMR,0.974028880519104
1116 | 1114,VERU,
1117 | 1115,WULF,1.969693993813391
1118 | 1116,ESPR,0.584976912432844
1119 | 1117,SCWX,1.093548811604778
1120 | 1118,CPSS,1.738724172229358
1121 | 1119,VXRT,2.241131624582461
1122 | 1120,NGVC,0.852097586227041
1123 | 1121,CIFR,1.950893081787211
1124 | 1122,PRCH,2.271055418155148
1125 | 1123,SPIR,1.897358567944762
1126 | 1124,BKKT,2.004820082244153
1127 | 1125,ABSI,1.88837167217855
1128 | 1126,GRPN,1.90948244874222
1129 | 1127,DIBS,1.233924603840116
1130 | 1128,MPAA,0.992612741973636
1131 | 1129,CSTE,0.7753403698482311
1132 | 1130,EGIO,0.65001879990969
1133 | 1131,VCSA,1.676368536580139
1134 | 1132,FREE,1.024754454197285
1135 | 1133,NREF,0.8106302885935791
1136 | 1134,ACRV,
1137 | 1135,RIDE,1.732871473764044
1138 | 1136,KNTE,1.361470018461524
1139 | 1137,RLYB,1.180526983209045
1140 | 1138,ANTX,1.048380109276746
1141 | 1139,LLAP,1.044108800050573
1142 | 1140,GAMB,0.609691439098296
1143 | 1141,TTCF,1.491235441707682
1144 | 1142,UONE,1.072198398941169
1145 | 1143,HYZN,1.866322183955618
1146 | 1144,PLBY,1.387558441092032
1147 | 1145,JNCE,0.7373521408415481
1148 | 1146,CELL,1.830186254439474
1149 | 1147,GOSS,1.316461436568859
1150 | 1148,AMTX,2.574902402372713
1151 | 1149,LTCH,1.673351684133764
1152 | 1150,CENN,1.780117556930264
1153 | 1151,RLMD,0.453055041344701
1154 | 1152,PFSW,0.5268213299875291
1155 | 1153,DLTH,1.111492288666393
1156 | 1154,RMBL,1.733511752414052
1157 | 1155,FGBI,0.52353214926948
1158 | 1156,BGRY,2.100127292068696
1159 | 1157,LSEA,0.963673394668516
1160 | 1158,AIRS,1.838922573314692
1161 | 1159,HYFM,2.242088209818165
1162 | 1160,FRBK,0.884137152680266
1163 | 1161,CMLS,1.034933459523685
1164 | 1162,CURV,1.806971194355142
1165 | 1163,CLPR,0.803543519344567
1166 | 1164,LCUT,0.945678524943206
1167 | 1165,CONN,1.909731679263716
1168 | 1166,ASTR,2.004695986128431
1169 | 1167,BBIG,
1170 | 1168,TGAN,0.9983828549593292
1171 | 1169,REFI,0.393362738830792
1172 | 1170,IVVD,1.443724457133955
1173 | 1171,EXPR,1.852873045584025
1174 | 1172,IPSC,1.307376627327331
1175 | 1173,TALS,1.343959217490318
1176 | 1174,LVOX,0.6739535162699131
1177 | 1175,HYMC,1.175851115625207
1178 | 1176,OMIC,1.924886514652975
1179 | 1177,MAPS,1.753629464006697
1180 | 1178,PRDS,0.837938268502952
1181 | 1179,INSG,1.973554563846654
1182 | 1180,CMPO,0.6722215626005931
1183 | 1181,THRN,0.6366073525908881
1184 | 1182,PRAX,0.8833130658059011
1185 | 1183,VALU,
1186 | 1184,ADTH,0.773633967926557
1187 | 1185,ATER,1.555791832783214
1188 | 1186,KRON,1.924222537666887
1189 | 1187,THRD,
1190 | 1188,APPH,1.439984599554925
1191 | 1189,DOMA,1.687161761093895
1192 | 1190,AREN,1.146040743799356
1193 | 1191,PRTH,0.9645678371077652
1194 | 1192,EIGR,0.9238871204173812
1195 | 1193,HLGN,1.875810152041439
1196 | 1194,FCUV,
1197 | 1195,CASA,1.822339711948444
1198 | 1196,AVAH,1.086648370008911
1199 | 1197,CELU,1.644771010855644
1200 | 1198,STRC,1.215435882296649
1201 | 1199,KORE,1.534073433244263
1202 | 1200,VIEW,1.562922466238129
1203 | 1201,BODY,1.471306837786795
1204 | 1202,LOCL,
1205 | 1203,ONDS,1.44540864789522
1206 | 1204,CURO,1.999918847690107
1207 | 1205,RGTI,1.527644193132516
1208 | 1206,PIII,0.986034073438366
1209 | 1207,SNCE,1.007123561047838
1210 | 1208,FXLV,1.43004048978611
1211 | 1209,LVLU,1.483010660494422
1212 | 1210,SWKH,0.270525014188148
1213 | 1211,MNTS,1.778153187812032
1214 | 1212,OPAD,2.034568524017831
1215 | 1213,VTGN,1.755963868342045
1216 | 1214,ENOB,1.253657698284479
1217 | 1215,ROOT,2.043431947339874
1218 | 1216,BBBY,1.646386358502566
1219 | 1217,GRNA,0.821648744454858
1220 | 1218,WEJO,1.408907933101231
1221 | 1219,BBLN,1.539416968402876
1222 | 1220,ATIP,0.8901740459758071
1223 | 1221,HMPT,0.7736885260354691
1224 | 1222,CPTN,1.475427252239825
1225 | 1223,IRNT,1.267250020211493
1226 | 1224,ISPO,1.244262371030995
1227 | 1225,JOAN,1.418826729940807
1228 | 1226,OPFI,1.015125604124733
1229 | 1227,MKTW,1.434854166173613
1230 | 1228,VBIV,
1231 | 1229,SUNL,1.629827322623221
1232 | 1230,LIDR,1.498266593357102
1233 | 1231,TKNO,1.59044201761448
1234 | 1232,CYXT,1.517295730417408
1235 | 1233,BRDS,1.967992790573394
1236 | 1234,GREE,2.348187699475537
1237 | 1235,OCTO,
1238 | 1236,BATL,1.082092721883185
1239 | 1237,PDLI,
1240 | 1238,CISO,1.157843907028596
1241 | 1239,EME,0.7753177773007761
1242 | 1240,RBC,0.9985892952383372
1243 | 1241,ADC,0.445186577472227
1244 | 1242,LNW,1.521730051312352
1245 | 1243,RLI,0.468659772151894
1246 | 1244,CMC,1.144569991995089
1247 | 1245,MUR,1.221459869365415
1248 | 1246,CHX,1.089760418362346
1249 | 1247,AIT,0.9142546290548432
1250 | 1248,SSB,0.913071937719895
1251 | 1249,NJR,0.6152796903533511
1252 | 1250,ASO,1.392399254852418
1253 | 1251,MMS,0.770913435657657
1254 | 1252,RHP,1.178789780922449
1255 | 1253,FIX,1.003866173261708
1256 | 1254,SSD,1.129457079989169
1257 | 1255,HLI,0.8628510421013981
1258 | 1256,ATI,1.177728099102672
1259 | 1257,ELF,0.950716380200656
1260 | 1258,HQY,0.382421180879649
1261 | 1259,MTH,1.266526254046788
1262 | 1260,NSP,0.9155378263733552
1263 | 1261,DEN,0.9954428434393512
1264 | 1262,KRG,1.088762649987121
1265 | 1263,ORA,0.82104904855697
1266 | 1264,POR,0.5962036987553151
1267 | 1265,ABG,1.214519604865746
1268 | 1266,APG,1.25592215791709
1269 | 1267,WTS,1.078336905577908
1270 | 1268,OGS,0.58166480155405
1271 | 1269,HAE,0.8017609925171201
1272 | 1270,BKH,0.602373513714739
1273 | 1271,PBF,0.9367584306516832
1274 | 1272,FLR,0.9767930742400732
1275 | 1273,PNM,0.205931956346757
1276 | 1274,CBT,1.30611558319601
1277 | 1275,SKY,1.633909953732114
1278 | 1276,ONB,0.742485843069389
1279 | 1277,BMI,0.929073339976728
1280 | 1278,HGV,1.251860101399892
1281 | 1279,SWX,0.4740627267019261
1282 | 1280,AMN,0.736572235171838
1283 | 1281,MLI,1.035074959293453
1284 | 1282,PCH,0.958944500319563
1285 | 1283,BOX,0.9546179613991412
1286 | 1284,MGY,1.095855091801156
1287 | 1285,VLY,1.028497782654552
1288 | 1286,VAL,1.046521883220375
1289 | 1287,RDN,0.884185972909945
1290 | 1288,FHI,0.7543837915554621
1291 | 1289,IRT,0.960308323280123
1292 | 1290,ALE,0.6064973538024101
1293 | 1291,FUL,1.024058236179143
1294 | 1292,ENV,1.002888224875737
1295 | 1293,SFM,0.7865063449843671
1296 | 1294,NWE,0.483257200959598
1297 | 1295,JBT,1.322652251475448
1298 | 1296,AWR,0.621912683790518
1299 | 1297,ENS,1.298733901429712
1300 | 1298,BDC,1.127500398569514
1301 | 1299,SIG,1.459368963989387
1302 | 1300,DOC,0.5893114339741671
1303 | 1301,SUM,1.203383527639869
1304 | 1302,GPI,1.077912080897677
1305 | 1303,AVA,0.513238860548439
1306 | 1304,KBH,1.284406080972326
1307 | 1305,CWT,0.654709094530556
1308 | 1306,HWC,0.9884666769618152
1309 | 1307,SXT,0.8824060338336921
1310 | 1308,KOS,1.291394042761813
1311 | 1309,PBH,0.485032267919731
1312 | 1310,RPD,1.647805869572427
1313 | 1311,FSS,0.8501683630332341
1314 | 1312,TEX,1.380093093438698
1315 | 1313,SEM,1.119637809752226
1316 | 1314,ROG,0.604965585988114
1317 | 1315,EVH,1.040767459302695
1318 | 1316,GNW,0.8679156869341771
1319 | 1317,BCO,0.8606506815552171
1320 | 1318,CRC,0.941913157146065
1321 | 1319,ACA,0.859355277386849
1322 | 1320,IBP,1.320656697013763
1323 | 1321,AIN,0.899009947139611
1324 | 1322,BTU,1.096981074303429
1325 | 1323,ABM,0.942620287468426
1326 | 1324,IGT,1.613483515752783
1327 | 1325,BNL,0.8175954557909141
1328 | 1326,VSH,1.104166919943525
1329 | 1327,JXN,1.563174217155515
1330 | 1328,ASB,0.907392530228411
1331 | 1329,TPH,1.237811239212596
1332 | 1330,THS,0.417550513273523
1333 | 1331,AEL,0.953750141363175
1334 | 1332,WHD,1.241022645125142
1335 | 1333,LXP,0.904280839358822
1336 | 1334,CNX,0.8979930190267621
1337 | 1335,BCC,1.178736182311015
1338 | 1336,ZWS,1.122755504213974
1339 | 1337,HRI,1.504324172933701
1340 | 1338,KFY,0.970811111458128
1341 | 1339,KTB,1.117941604323371
1342 | 1340,UNF,0.7082816597018221
1343 | 1341,KWR,1.441147044123895
1344 | 1342,CBU,0.7101096019961071
1345 | 1343,OFC,0.7309398791471781
1346 | 1344,ESE,0.934400069410806
1347 | 1345,CNO,0.969858170511868
1348 | 1346,CBZ,0.773644014503431
1349 | 1347,SPT,2.369849115397063
1350 | 1348,AUB,0.8507984877472671
1351 | 1349,RRR,1.15385432610541
1352 | 1350,OUT,1.419813318154747
1353 | 1351,BRC,0.7189985398242841
1354 | 1352,AMR,0.950920809488768
1355 | 1353,RCM,
1356 | 1354,GMS,1.321330415074076
1357 | 1355,EPC,0.603901333939677
1358 | 1356,ENR,0.7722928841383021
1359 | 1357,MXL,1.835114765006415
1360 | 1358,MDC,1.193319082511833
1361 | 1359,CPK,0.530837098718386
1362 | 1360,CRS,1.439987055811588
1363 | 1361,KAI,1.022017498978538
1364 | 1362,EQC,0.341423973899634
1365 | 1363,NOG,1.218906358052607
1366 | 1364,GHC,0.7004418834181221
1367 | 1365,MAC,1.450954462056703
1368 | 1366,SJW,0.477398651369919
1369 | 1367,KMT,1.226559112765987
1370 | 1368,SCL,0.8085881689450061
1371 | 1369,MWA,0.904332617015962
1372 | 1370,NHI,0.5110299131739611
1373 | 1371,AEO,1.290995578836412
1374 | 1372,TDW,0.9412450816657312
1375 | 1373,SHO,1.208213451933829
1376 | 1374,NUS,0.910212352195169
1377 | 1375,FBP,1.066113842357229
1378 | 1376,NPO,0.975149161298126
1379 | 1377,NEO,1.901744208509638
1380 | 1378,TRN,1.114153885669565
1381 | 1379,FRO,0.765656671790919
1382 | 1380,SKT,1.113858291588831
1383 | 1381,WOR,1.292867865670499
1384 | 1382,MTX,1.005459123571998
1385 | 1383,VIR,1.287215835600074
1386 | 1384,HCC,0.6897183815338711
1387 | 1385,DAN,1.602327262496395
1388 | 1386,CCS,1.41399244447478
1389 | 1387,PEB,1.367679448073459
1390 | 1388,EBC,0.709197374949023
1391 | 1389,AIR,1.002716772799762
1392 | 1390,ALG,0.809460060455312
1393 | 1391,CNK,1.267736660539704
1394 | 1392,VGR,0.766985537411619
1395 | 1393,STR,
1396 | 1394,ODP,0.763489062052061
1397 | 1395,PJT,0.584769031688919
1398 | 1396,WGO,1.239237057985423
1399 | 1397,ABR,1.040338778444362
1400 | 1398,MHO,1.359523185784129
1401 | 1399,OII,1.227282677066233
1402 | 1400,EAT,1.431515509083561
1403 | 1401,DRH,1.303540807762343
1404 | 1402,PHR,1.610544798697284
1405 | 1403,YOU,1.733783457726448
1406 | 1404,WLY,0.922441206545993
1407 | 1405,CPE,1.383016820742246
1408 | 1406,GVA,0.756960114400623
1409 | 1407,NWN,0.503632260381857
1410 | 1408,RLJ,1.223261558017542
1411 | 1409,BKU,1.151863421669783
1412 | 1410,EYE,1.359492623549644
1413 | 1411,XRX,1.179565871400108
1414 | 1412,GEF,0.676072618126343
1415 | 1413,CNS,1.073443050177957
1416 | 1414,OXM,1.119263996771016
1417 | 1415,LRN,0.488584884740649
1418 | 1416,PRK,0.702047600336356
1419 | 1417,HTH,1.005226135087431
1420 | 1418,TGH,0.89714179547141
1421 | 1419,INT,0.938929764918859
1422 | 1420,PSN,0.69332410704236
1423 | 1421,CWK,1.338285135699493
1424 | 1422,BRP,1.487557209552357
1425 | 1423,IVT,1.002719127194115
1426 | 1424,SBH,1.146032670903182
1427 | 1425,SVC,
1428 | 1426,MEI,0.9794836287729972
1429 | 1427,KAR,1.18969288512864
1430 | 1428,OEC,1.149049360436041
1431 | 1429,USD,3.13980511313306
1432 | 1430,XHR,1.390556561741838
1433 | 1431,HLF,1.177295464595935
1434 | 1432,GTY,0.5721053930519641
1435 | 1433,SXI,0.869669667929418
1436 | 1434,JOE,1.167536167478644
1437 | 1435,NEX,1.201560068237765
1438 | 1436,WMK,0.503014942581477
1439 | 1437,CTS,0.86350292367541
1440 | 1438,LNN,0.838048539929217
1441 | 1439,NNI,0.6011016903824441
1442 | 1440,LTC,0.4216478467411081
1443 | 1441,TWO,1.001704665189938
1444 | 1442,ARI,1.336733382319943
1445 | 1443,CIM,1.29869727374985
1446 | 1444,PFS,0.6762575544596711
1447 | 1445,DHT,0.636982750890635
1448 | 1446,VRE,0.984010892062359
1449 | 1447,HMN,0.478129202246912
1450 | 1448,UVV,0.4914428264667051
1451 | 1449,NTB,0.8834026709772621
1452 | 1450,WWW,1.443145937123876
1453 | 1451,ZIP,1.568709109417257
1454 | 1452,DEA,0.5233131485813071
1455 | 1453,AKR,1.144655514568049
1456 | 1454,GFF,1.20089699245909
1457 | 1455,DDS,1.355966769959998
1458 | 1456,TNC,0.8606148331710911
1459 | 1457,PRG,1.651202554653452
1460 | 1458,AGM,0.909958806799872
1461 | 1459,PRO,1.611846330814696
1462 | 1460,LZB,1.085822626291963
1463 | 1461,OFG,0.7935171191057551
1464 | 1462,UTZ,0.704154971271163
1465 | 1463,GNL,0.8204663674730751
1466 | 1464,AIV,0.997514916011867
1467 | 1465,ANF,1.363788441895333
1468 | 1466,EIG,0.445081392950071
1469 | 1467,DDD,1.918467713931423
1470 | 1468,MIR,1.276581369191363
1471 | 1469,OMI,1.296898751578897
1472 | 1470,FCF,0.7545485751750921
1473 | 1471,TRS,0.8248441624979951
1474 | 1472,STC,0.9321698616582552
1475 | 1473,BGS,0.591964474584014
1476 | 1474,HNI,0.9713614933764392
1477 | 1475,CMP,1.499472146458564
1478 | 1476,HLX,1.012204649353196
1479 | 1477,ZUO,1.738501289332545
1480 | 1478,FBK,0.8541745869905161
1481 | 1479,MFA,1.263704110589715
1482 | 1480,WNC,1.102785779502067
1483 | 1481,NXT,
1484 | 1482,RNA,1.138469016975702
1485 | 1483,SFL,0.630589400610542
1486 | 1484,PMT,1.135569074462312
1487 | 1485,CXW,0.820312055525218
1488 | 1486,MOD,1.253548935912367
1489 | 1487,MED,0.9921929848480372
1490 | 1488,TDS,0.600775447096883
1491 | 1489,BKE,0.941071394379036
1492 | 1490,NBR,1.51138501293499
1493 | 1491,CDE,1.417789185698421
1494 | 1492,CRK,1.292207293241611
1495 | 1493,PRA,0.548614992630847
1496 | 1494,RGR,0.6596670969574671
1497 | 1495,MGI,0.137346692610347
1498 | 1496,AZZ,0.996360014447906
1499 | 1497,DIN,1.089736529334556
1500 | 1498,SAH,1.229698513549018
1501 | 1499,PLL,1.94253709448858
1502 | 1500,EAF,1.060519804159073
1503 | 1501,UEC,2.150245949293055
1504 | 1502,GBX,0.99974426296889
1505 | 1503,DRQ,1.057992077738311
1506 | 1504,UTL,0.5209867358824171
1507 | 1505,GEO,0.7779402857824611
1508 | 1506,FDP,0.4898261345717551
1509 | 1507,TNK,0.4868997330622921
1510 | 1508,AAT,0.8376493962325811
1511 | 1509,FNA,1.244439708906671
1512 | 1510,PRM,1.070690126700397
1513 | 1511,PAR,1.554973135751585
1514 | 1512,CWH,1.273295397366154
1515 | 1513,MCY,0.523367885500027
1516 | 1514,MEG,1.6827086806696
1517 | 1515,TMP,0.685438993867134
1518 | 1516,BFH,1.564128694433597
1519 | 1517,ARR,0.938816933057879
1520 | 1518,CVI,0.9682388044789152
1521 | 1519,CSR,0.7549953197593781
1522 | 1520,PDM,0.94560378141415
1523 | 1521,MMI,1.078692727877838
1524 | 1522,RPT,1.144124250729325
1525 | 1523,CAL,1.051670757080579
1526 | 1524,AXL,1.569234651977989
1527 | 1525,BKD,1.044929517195156
1528 | 1526,CCF,0.7932938893218651
1529 | 1527,OSW,0.7578400194832701
1530 | 1528,FSR,1.666207637830657
1531 | 1529,LOB,1.470022649045782
1532 | 1530,AHH,0.9332236386402052
1533 | 1531,UMH,0.913844880443654
1534 | 1532,MRC,1.194511936149628
1535 | 1533,ZGN,0.556570598599551
1536 | 1534,SGH,1.598713080974588
1537 | 1535,RWT,1.16309887970729
1538 | 1536,BHE,0.799201830281824
1539 | 1537,EFC,0.9521069020195032
1540 | 1538,LTH,1.471536166092067
1541 | 1539,RYI,1.561210609251081
1542 | 1540,JBI,1.27461263176334
1543 | 1541,CYH,1.520547865467741
1544 | 1542,SMP,0.693077482017431
1545 | 1543,SCS,1.079995802674686
1546 | 1544,NAT,0.7444615160008751
1547 | 1545,MYE,0.7682195583916701
1548 | 1546,ACT,0.7151388717588181
1549 | 1547,THR,0.834928986421107
1550 | 1548,FRG,1.177638800539367
1551 | 1549,NIC,0.7358339893950261
1552 | 1550,NHC,0.421250804649546
1553 | 1551,TGI,
1554 | 1552,SXC,0.9384489785918132
1555 | 1553,OLO,1.424812549455057
1556 | 1554,PNT,1.232143424705087
1557 | 1555,BDN,1.065008825663398
1558 | 1556,INN,1.282445699020182
1559 | 1557,PFC,0.7900271560413701
1560 | 1558,KOP,1.123045636316139
1561 | 1559,AMK,0.8785960401485221
1562 | 1560,LPG,0.619034262485881
1563 | 1561,SLP,
1564 | 1562,LXU,0.94837160074215
1565 | 1563,CBL,0.8708065158954551
1566 | 1564,DLX,1.099399410255013
1567 | 1565,TSE,1.575028357319023
1568 | 1566,GTN,0.992423146678658
1569 | 1567,CHS,1.300862340081534
1570 | 1568,BXC,1.689095920186498
1571 | 1569,ASC,0.6113991210242821
1572 | 1570,GES,1.285872644048399
1573 | 1571,NRC,0.5422204858463741
1574 | 1572,OPK,1.537325415894397
1575 | 1573,ETD,0.896697339864275
1576 | 1574,HZO,0.9859907386430092
1577 | 1575,UHT,0.6039782501548491
1578 | 1576,BRY,0.936567971569228
1579 | 1577,WOW,1.148707204161912
1580 | 1578,IAS,1.400538460555554
1581 | 1579,DCO,0.980603818877736
1582 | 1580,GNK,0.8302487534794221
1583 | 1581,TBI,0.8801693663547201
1584 | 1582,PCT,1.440015998413354
1585 | 1583,AVD,0.8533685549806891
1586 | 1584,RES,1.212536165975196
1587 | 1585,CLW,0.552752765751922
1588 | 1586,MTW,1.385681678272953
1589 | 1587,FPI,0.679093289557818
1590 | 1588,HSC,1.488858419188815
1591 | 1589,EBS,1.769287158432149
1592 | 1590,MBI,1.16343682449942
1593 | 1591,TWI,1.411964783354428
1594 | 1592,UVE,0.5667532383408821
1595 | 1593,SSP,1.460888450846063
1596 | 1594,GRC,0.8122828478422711
1597 | 1595,BLX,0.662169451396733
1598 | 1596,CIR,1.429254201369357
1599 | 1597,AGX,0.6650752519536931
1600 | 1598,VVX,0.7184129321741971
1601 | 1599,BFC,0.543819426123345
1602 | 1600,UBA,0.7616869737680281
1603 | 1601,IDT,0.852493639179927
1604 | 1602,BZH,1.626071856111637
1605 | 1603,PGC,0.783811255194188
1606 | 1604,EBF,0.550862654593552
1607 | 1605,CAC,
1608 | 1606,SRI,1.110297078927041
1609 | 1607,OIS,1.226040917524741
1610 | 1608,PBI,1.28581670600306
1611 | 1609,RGP,0.9081444727607292
1612 | 1610,REX,0.989362855205801
1613 | 1611,VPG,0.757953133395818
1614 | 1612,CFB,0.604953637088489
1615 | 1613,CCO,2.230055267553872
1616 | 1614,BOC,1.112977246985463
1617 | 1615,DBI,1.250572678962356
1618 | 1616,GCO,1.305513676128686
1619 | 1617,EGY,1.17436664626674
1620 | 1618,HVT,0.8534189899136031
1621 | 1619,AVO,0.5224491066778021
1622 | 1620,SWI,1.339349529208689
1623 | 1621,WTI,1.384652029252921
1624 | 1622,BFS,0.976021474093144
1625 | 1623,MCS,0.704039581429527
1626 | 1624,CPF,0.808380584159865
1627 | 1625,WSR,0.8655757814782281
1628 | 1626,ORC,0.935683228260459
1629 | 1627,MOV,1.082615237092084
1630 | 1628,ALX,0.5544634420233561
1631 | 1629,CVT,1.144282174406639
1632 | 1630,CSV,0.9064449544297852
1633 | 1631,BHB,0.817775395849311
1634 | 1632,IVR,1.355661524175478
1635 | 1633,VVI,1.044016809039219
1636 | 1634,CCB,0.8174733395382341
1637 | 1635,EVC,1.255435836175817
1638 | 1636,TTI,1.358822891885609
1639 | 1637,RMR,
1640 | 1638,NPK,0.6830731597680001
1641 | 1639,MCB,1.227418829701194
1642 | 1640,ONL,0.7925523590805501
1643 | 1641,DYN,1.319785398282816
1644 | 1642,MLR,0.614286399071706
1645 | 1643,MPB,0.54543297401002
1646 | 1644,PWP,1.138865268613167
1647 | 1645,TRC,0.75535596890175
1648 | 1646,OLP,0.8192306742028681
1649 | 1647,HCI,0.704613129618962
1650 | 1648,TPB,0.5807518800001751
1651 | 1649,HOV,2.003186923513617
1652 | 1650,CTO,0.637185036982861
1653 | 1651,GIC,1.331753454525161
1654 | 1652,OPI,
1655 | 1653,BBW,1.261410132443519
1656 | 1654,USM,0.4383165043250291
1657 | 1655,LEU,2.167035775624858
1658 | 1656,AAN,1.229925825198812
1659 | 1657,DFH,1.157375563852129
1660 | 1658,OPY,0.7222184924467651
1661 | 1659,FOR,1.008171101884124
1662 | 1660,BVH,1.022691295806454
1663 | 1661,IPI,1.507704911826812
1664 | 1662,SMR,0.6251115124558191
1665 | 1663,ESQ,0.616475961992621
1666 | 1664,GCI,1.337952308080638
1667 | 1665,PKE,0.609956072124572
1668 | 1666,BHR,1.464017297204025
1669 | 1667,CIO,0.9641069590800032
1670 | 1668,NBN,0.535603284886714
1671 | 1669,BIG,1.434792945864537
1672 | 1670,SOI,0.9913184267698152
1673 | 1671,HRT,1.070626629135728
1674 | 1672,MAX,1.162145992653982
1675 | 1673,DHC,
1676 | 1674,UIS,1.34261804904787
1677 | 1675,BWB,0.646080023332193
1678 | 1676,FLL,1.383596456924808
1679 | 1677,UTI,0.8677652689129981
1680 | 1678,TCX,1.149663140207439
1681 | 1679,INO,2.151224525802923
1682 | 1680,TPC,1.011209679818081
1683 | 1681,ULH,0.973787656533565
1684 | 1682,KRO,0.782236107381815
1685 | 1683,BRT,0.8366272394991131
1686 | 1684,RBB,0.688015632217288
1687 | 1685,SCU,1.289402724744374
1688 | 1686,HBT,0.542174882820418
1689 | 1687,RSI,1.781358575472408
1690 | 1688,GLT,1.504962949042471
1691 | 1689,TSP,2.610691463826656
1692 | 1690,URG,1.749224158922298
1693 | 1691,III,1.001720284022484
1694 | 1692,REI,1.267607487722473
1695 | 1693,DTC,1.420843394149907
1696 | 1694,KOD,1.61183508516766
1697 | 1695,HPK,1.172194786799798
1698 | 1696,NGM,0.8111629255793391
1699 | 1697,LBC,0.698080392723988
1700 | 1698,DHX,0.913139797258388
1701 | 1699,PCB,0.588840363646152
1702 | 1700,QSI,2.171689437179563
1703 | 1701,LAW,2.026309180019127
1704 | 1702,KZR,0.8468087997490461
1705 | 1703,TIG,
1706 | 1704,VLD,2.63443472344809
1707 | 1705,RAD,1.774272090484211
1708 | 1706,FSP,
1709 | 1707,AHT,2.122814124255453
1710 | 1708,TLS,1.57944651268713
1711 | 1709,PLM,1.066719629849442
1712 | 1710,RXT,2.301692790520226
1713 | 1711,MPX,1.087783919278303
1714 | 1712,UFI,0.9888984526733052
1715 | 1713,TCS,1.200401570459434
1716 | 1714,SBT,0.386594208528254
1717 | 1715,ADV,0.9237381040344412
1718 | 1716,SGC,0.8707227287821661
1719 | 1717,GWH,2.075015090493404
1720 | 1718,WGS,2.645820314497981
1721 | 1719,VEL,0.90733314703405
1722 | 1720,CTV,1.321124943404112
1723 | 1721,AIP,1.233702481361411
1724 | 1722,KRT,0.843431922060878
1725 | 1723,DBD,2.253478800994415
1726 | 1724,TUP,2.313381417997486
1727 | 1725,RDW,1.449262523132602
1728 | 1726,DSP,0.939257093686448
1729 | 1727,TIL,1.508455339618201
1730 | 1728,VHI,1.059371723089986
1731 | 1729,FOA,1.025719906762616
1732 | 1730,VWE,1.168498819497959
1733 | 1731,BHG,2.085266517786098
1734 | 1732,CIX,0.649896380607578
1735 | 1733,VIA,
1736 | 1734,BVS,1.444894881096789
1737 | 1735,XOS,1.201255878895994
1738 | 1736,TCI,0.540647380356386
1739 | 1737,KLR,1.689631209768528
1740 | 1738,ARL,0.59824094640085
1741 | 1739,AKA,1.35323883450524
1742 | 1740,ZEV,2.000139730445514
1743 | 1741,AUD,1.800530377407491
1744 | 1742,TOI,0.799458268452057
1745 | 1743,TFM,
1746 | 1744,WK,1.586316043868662
1747 | 1745,VC,1.301223666620609
1748 | 1746,HP,1.223904933246418
1749 | 1747,SR,0.573469336548155
1750 | 1748,FN,1.091436853940009
1751 | 1749,BL,1.575202897946227
1752 | 1750,ZD,1.087085711193768
1753 | 1751,HL,1.387894384013213
1754 | 1752,OI,1.103593986299367
1755 | 1753,FL,1.153602559663583
1756 | 1754,SM,1.323027752038873
1757 | 1755,BE,2.034683949184264
1758 | 1756,NE,
1759 | 1757,HI,1.074334355573492
1760 | 1758,PI,1.481936733391841
1761 | 1759,GT,1.719226089453663
1762 | 1760,PD,2.014066033313241
1763 | 1761,MC,1.312559803123109
1764 | 1762,DY,0.91593326117573
1765 | 1763,PR,1.377487603208001
1766 | 1764,AX,1.385445463435314
1767 | 1765,WD,1.361128712277137
1768 | 1766,KW,1.042517596464088
1769 | 1767,MQ,1.970604422441346
1770 | 1768,UE,1.030559167734935
1771 | 1769,DK,0.869170851187361
1772 | 1770,KN,0.915692713336623
1773 | 1771,NG,0.980223633863547
1774 | 1772,MD,0.972411126747196
1775 | 1773,AI,2.105706578119944
1776 | 1774,DO,1.218315800937172
1777 | 1775,TA,0.984859803961862
1778 | 1776,LZ,1.670726546589037
1779 | 1777,WT,
1780 | 1778,OM,1.699013180941376
1781 | 1779,PL,1.240870726195467
1782 | 1780,FA,1.041496167718029
1783 | 1781,LC,1.969284352317315
1784 | 1782,RC,1.009952355078988
1785 | 1783,TR,0.4182765057685111
1786 | 1784,SP,0.7497429303877511
1787 | 1785,NX,1.058895937231652
1788 | 1786,SG,1.813480392316819
1789 | 1787,EB,1.647385112124228
1790 | 1788,DX,0.8168875933959071
1791 | 1789,DM,2.126953350498238
1792 | 1790,HY,1.073207083241084
1793 | 1791,ME,1.934197218863134
1794 | 1792,IE,
1795 | 1793,BY,0.7319001144140831
1796 | 1794,KE,0.9617609103410032
1797 | 1795,WW,1.987875599260174
1798 | 1796,FC,0.7227426600666901
1799 | 1797,HA,1.454043210758099
1800 | 1798,TK,0.622888941747601
1801 | 1799,EE,0.935192573085736
1802 | 1800,BW,1.432976352875604
1803 | 1801,TH,0.538006558365657
1804 | 1802,SD,1.150052972306171
1805 | 1803,NR,1.01841368058692
1806 | 1804,SB,0.9269306978568672
1807 | 1805,TG,0.722353883595508
1808 | 1806,BV,1.058766984834224
1809 | 1807,FF,0.963601042049479
1810 | 1808,HT,1.445050502127859
1811 | 1809,RM,1.060708349334899
1812 | 1810,DC,0.771160587677248
1813 | 1811,OB,1.446660207707044
1814 | 1812,BH,0.5742719359050571
1815 | 1813,NC,1.005136918666114
1816 | 1814,NN,0.831736195155057
1817 | 1815,EP,0.70032631338048
1818 | 1816,LE,1.410089802106038
1819 | 1817,LL,1.246506422224382
1820 | 1818,UP,1.915676218237751
1821 | 1819,AC,
1822 | 1820,NL,0.8838520338196411
1823 | 1821,ML,1.742585251749639
1824 | 1822,B,0.939966332428771
1825 |
--------------------------------------------------------------------------------
/timeseriestransformer_stocks.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "view-in-github",
7 | "colab_type": "text"
8 | },
9 | "source": [
10 | "
"
11 | ]
12 | },
13 | {
14 | "cell_type": "markdown",
15 | "metadata": {
16 | "id": "C4H0ganQCvdw"
17 | },
18 | "source": [
19 | "This notebook uses time series transformer in https://huggingface.co/blog/time-series-transformers to implement stock price predictor"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": null,
25 | "metadata": {
26 | "id": "uN36MU-CEbtw"
27 | },
28 | "outputs": [],
29 | "source": [
30 | "# Installation\n",
31 | "!pip install --upgrade mxnet==1.6.0\n",
32 | "!pip install gluonts\n",
33 | "!pip install yfinance\n",
34 | "!pip install datasets\n",
35 | "!pip install transformers\n",
36 | "!pip install accelerate\n",
37 | "!pip install torch\n",
38 | "!pip install evaluate\n",
39 | "!pip install torchviz"
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "source": [
45 | "load_from_pretrained = True # loads parameters and configuration from saved directory\n",
46 | "model_save_path = \"sample_data/timeseriestransformer-stocks\" # model saved directory path\n",
47 | "skip_training = False # skip training if the model is loaded from pretained\n",
48 | "epoches = 2"
49 | ],
50 | "metadata": {
51 | "id": "hYDVSU5ec2ta"
52 | },
53 | "execution_count": null,
54 | "outputs": []
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": null,
59 | "metadata": {
60 | "id": "ZtB77RObE0jz"
61 | },
62 | "outputs": [],
63 | "source": [
64 | "import yfinance as yahooFinance\n",
65 | "import tensorflow as tf\n",
66 | "import pandas as pd\n",
67 | "import sklearn\n",
68 | "import matplotlib.pyplot as plt\n",
69 | "\n",
70 | "stocks = [\"AAPL\", '^IXIC', '^GSPC', '^DJI','MSFT', 'GOOG', 'GOOGL', 'AMZN', 'UNH', 'XOM', 'JNJ', 'V', 'JPM', 'NVDA']\n",
71 | "stocks1 = ['AAPL', 'MSFT', 'GOOG', 'GOOGL', 'AMZN', 'UNH', 'XOM', 'JNJ', 'V', 'JPM', 'NVDA',\n",
72 | " 'WMT', 'TSLA', 'PG', 'META', 'MA', 'CVX', 'LLY', 'HD', 'ABBV', 'MRK', 'BAC', 'KO', \n",
73 | " 'PFE', 'PEP', 'AVGO', 'ORCL', 'TMO', 'COST', 'CSCO', 'ABT', 'MCD', 'NKE', 'DHR', \n",
74 | " 'TMUS', 'ACN', 'DIS', 'VZ', 'NEE', 'CMCSA', 'WFC', 'TXN', 'LIN', 'PM', 'UPS', 'ADBE', \n",
75 | " 'BMY', 'SCHW', 'MS', 'CRM', 'COP', 'RTX', 'AMGN', 'NFLX', 'HON', 'T', 'UNP', 'QCOM', \n",
76 | " 'IBM', 'DE', 'CAT', 'LOW', 'BA', 'SBUX', 'INTC', 'SPGI', 'LMT', 'GS', 'CVS', 'BLK', \n",
77 | " 'AXP', 'ELV', 'AMD', 'GILD', 'INTU', 'PLD', 'MDT', 'AMT', 'ADP', 'SYK', 'ISRG', \n",
78 | " 'TJX', 'EL', 'C', 'CB', 'CI', 'MDLZ', 'AMAT', 'PYPL', 'ADI', 'BKNG', 'MMC', 'MO', 'GE', \n",
79 | " 'DUK', 'SLB', 'SO', 'PGR', 'NOW', 'NOC', 'VRTX', 'EOG', 'REGN', 'ZTS', 'TGT', 'MRNA', 'BDX', \n",
80 | " 'MMM', 'HCA', 'USB', 'ITW', 'APD', 'CSX', 'GD', 'PNC', 'BSX', 'CL', 'WM', 'EQIX', 'FISV', 'FCX', \n",
81 | " 'CME', 'ETN', 'CCI', 'AON', 'SHW', 'LRCX', 'MU', 'TFC', 'HUM', 'ATVI', 'ICE', 'KLAC', 'NSC', \n",
82 | " 'CHTR', 'OXY', 'EMR', 'MET', 'PXD', 'MPC', 'MCO', 'MCK', 'DG', 'GM', 'MNST', 'KHC', 'ORLY', \n",
83 | " 'D', 'VLO', 'SNPS', 'SRE', 'F', 'KDP', 'AEP', 'GIS', 'PSA', 'MAR', 'PSX', 'ROP', 'FDX', 'EW', \n",
84 | " 'ADM', 'APH', 'AIG', 'JCI', 'HSY', 'A', 'KMB', 'AZO', 'CTAS', 'CDNS', 'TRV', 'AFL', 'HES', 'CTVA', \n",
85 | " 'MSI', 'EXC', 'ECL', 'CNC', 'NXPI', 'DXCM', 'PAYX', 'NEM', 'KMI', 'ADSK', 'TT', 'MCHP', 'DVN', \n",
86 | " 'ROST', 'LVS', 'FIS', 'AJG', 'STZ', 'BIIB', 'SYY', 'CMG', 'O', 'RSG', 'IQV', 'PH', 'XEL', 'DOW', \n",
87 | " 'SPG', 'WMB', 'TEL', 'MSCI', 'IDXX', 'BK', 'NUE', 'LHX', 'FTNT', 'COF', 'ALL', 'HAL', 'PRU', 'CARR', \n",
88 | " 'DD', 'TDG', 'YUM', 'ANET', 'HLT', 'PCAR', 'CMI', 'ED', 'ABC', 'EA', 'AMP', 'OTIS', 'WELL', 'MTD', \n",
89 | " 'ODFL', 'SBAC', 'KR', 'AME', 'DLTR', 'VICI', 'DHI', 'ROK', 'WBA', 'KEYS', 'PEG', 'PCG', 'CSGP', \n",
90 | " 'CTSH', 'ENPH', 'RMD', 'OKE', 'WEC', 'BKR', 'NDAQ', 'WBD', 'ILMN', 'PPG', 'GLW', 'STT', 'LYB', \n",
91 | " 'ES', 'IFF', 'DLR', 'AWK', 'VRSK', 'DFS', 'HPQ', 'GWW', 'GPN', 'WTW', 'ON', 'FAST', 'LEN', 'CEG', \n",
92 | " 'APTV', 'TROW', 'URI', 'IT', 'ALB', 'CBRE', 'ZBH', 'EIX', 'MTB', 'CDW', 'ULTA', 'EFX', 'HRL', 'FANG', \n",
93 | " 'TSCO', 'EBAY', 'DAL', 'FE', 'VMC', 'HIG', 'ARE', 'K', 'RJF', 'GPC', 'TSN', 'FITB', 'WY', 'FTV', \n",
94 | " 'ACGL', 'DTE', 'BAX', 'AEE', 'IR', 'AVB', 'FRC', 'MKC', 'VRSN', 'PPL', 'EQR', 'ETR', 'HPE', 'LH', \n",
95 | " 'ANSS', 'LUV', 'PFG', 'MLM', 'HBAN', 'XYL', 'RF', 'CAH', 'WAT', 'CFG', 'STE', 'PWR', 'CHD', 'HOLX', \n",
96 | " 'CTRA', 'NTRS', 'VTR', 'EXR', 'DOV', 'CAG', 'CNP', 'WRB', 'TDY', 'GRMN', 'CMS', 'EPAM', 'STLD', 'BBY', \n",
97 | " 'WST', 'WAB', 'DRI', 'FSLR', 'INVH', 'MPWR', 'AES', 'JBHT', 'ALGN', 'AMCR', 'ROL', 'PAYC', 'MAA', 'IEX', \n",
98 | " 'INCY', 'TTWO', 'BALL', 'OMC', 'CLX', 'DGX', 'CINF', 'EXPD', 'MRO', 'MOH', 'KEY', 'COO', 'BRO', 'TRGP', \n",
99 | " 'SEDG', 'FOX', 'FOXA', 'PKI', 'SJM', 'HWM', 'CPB', 'LYV', 'BR', 'CF', 'FMC', 'J', 'ATO', 'ETSY', 'FDS', \n",
100 | " 'SWKS', 'UAL', 'ZBRA', 'NVR', 'AVY', 'MOS', 'SIVB', 'PTC', 'RCL', 'LKQ', 'MGM', 'SYF', 'TXT', 'TER', \n",
101 | " 'EVRG', 'CPRT', 'BEN', 'IRM', 'VTRS', 'EXPE', 'FLT', 'LW', 'GEN', 'PEAK', 'L', 'KIM', 'APA', 'IPG', \n",
102 | " 'ESS', 'NTAP', 'RE', 'NDSN', 'LNT', 'AKAM', 'LDOS', 'IP', 'TYL', 'TRMB', 'SNA', 'UDR', 'PARA', 'JKHY', \n",
103 | " 'CBOE', 'CE', 'BIO', 'POOL', 'MTCH', 'EQT', 'SWK', 'PKG', 'WDC', 'TFX', 'MKTX', 'CPT', 'DPZ', 'CRL', 'GL', \n",
104 | " 'STX', 'HST', 'VFC', 'MAS', 'NWS', 'NWSA', 'NI', 'PHM', 'CHRW', 'WYNN', 'HSIC', 'CCL', 'EMN', 'KMX', 'REG', \n",
105 | " 'BXP', 'UHS', 'BBWI', 'JNPR', 'TPR', 'BWA', 'AAL', 'ALLE', 'QRVO', 'CZR', 'CDAY', 'WRK', 'AOS', 'AAP', 'HII', \n",
106 | " 'HAS', 'IVZ', 'CMA', 'FFIV', 'CTLT', 'PNW', 'WHR', 'FRT', 'RHI', 'PNR', 'DISH', 'SEE', 'RL', 'ZION', 'OGN', \n",
107 | " 'NRG', 'XRAY', 'MHK', 'DVA', 'SBNY', 'GNRC', 'AIZ', 'DXC', 'NWL', 'ALK', 'NCLH', 'LUMN', 'LNC', 'VNO', 'TECH', \n",
108 | " 'TAP', '^IXIC', '^GSPC', '^DJI']\n",
109 | "\n",
110 | "stocks_ts = pd.DataFrame()\n",
111 | "for stock in stocks:\n",
112 | " data = yahooFinance.Ticker(stock).history(period=\"10y\")\n",
113 | " d = data.copy()[['Open', 'Volume']]\n",
114 | " stocks_ts.insert(0, stock+\"_Open\", d['Open'])\n",
115 | " stocks_ts.insert(0, stock+\"_Volume\", d['Volume'])\n",
116 | "\n",
117 | "print(stocks_ts)\n",
118 | "\n",
119 | "# add other indicators\n",
120 | "# inflation rate, interest rate, employment\n",
121 | "\n",
122 | "fig, axs = plt.subplots(5, 2, figsize=(20, 20), sharex=True)\n",
123 | "axx = axs.ravel()\n",
124 | "for i in range(0, 10):\n",
125 | " stocks_ts[stocks_ts.columns[i]].plot(ax=axx[i])\n",
126 | " axx[i].set_xlabel(\"date\") \n",
127 | " axx[i].set_ylabel(\"Open\") \n",
128 | " axx[i].grid(which='minor', axis='x')"
129 | ]
130 | },
131 | {
132 | "cell_type": "code",
133 | "execution_count": null,
134 | "metadata": {
135 | "id": "WzUsBWZPE-Bj"
136 | },
137 | "outputs": [],
138 | "source": [
139 | "import pandas as pd\n",
140 | "infvalues=pd.read_csv(\"sample_data/Book2.csv\")\n",
141 | "infvalues=infvalues.drop([\"Year\", \"Annual\"], axis=1).values\n",
142 | "inf=[]\n",
143 | "for i in infvalues:\n",
144 | " inf = inf + list(i)\n",
145 | "\n",
146 | "dti=pd.date_range(start=\"1948-01-01 00:00:00-05:00\", end=\"2023-12-31 00:00:00-05:00\", freq=\"M\")\n",
147 | "\n",
148 | "inf.reverse()\n",
149 | "csvdf=pd.DataFrame(inf)\n",
150 | "csvdf.index=dti\n",
151 | "\n",
152 | "dti=pd.date_range(start=\"1948-01-01 00:00:00-05:00\", end=\"2023-12-31 00:00:00-05:00\", freq=\"D\")\n",
153 | "dti.name = 'date'\n",
154 | "csvdf=csvdf.reindex(dti, method='ffill')\n",
155 | "csvdf.columns = [\"Rates\"]\n",
156 | "stocks_ts = stocks_ts.assign(Inflation=csvdf[\"Rates\"])"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {
163 | "id": "HMe1o5ktFEBa"
164 | },
165 | "outputs": [],
166 | "source": [
167 | "import pandas as pd\n",
168 | "fedrates=pd.read_csv(\"sample_data/fed-funds-rate-historical-chart.csv\")\n",
169 | "\n",
170 | "#fedrates = fedrates.drop(\"date\", axis=1)\n",
171 | "dti=pd.date_range(start=\"1955-12-12 00:00:00-05:00\", end=\"2023-01-31 00:00:00-05:00\", freq=\"D\")\n",
172 | "fedrates.index = dti\n",
173 | "stocks_ts = stocks_ts.assign(InterestRates=fedrates[\"value\"])"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "source": [
179 | "import pandas as pd\n",
180 | "\n",
181 | "crudeprices=pd.read_csv(\"sample_data/crudeoil.csv\")\n",
182 | "crudeprices['Datetime'] = pd.to_datetime(crudeprices['date'] + \" 00:00:00-05:00\")\n",
183 | "crudeprices = crudeprices.set_index('Datetime')\n",
184 | "\n",
185 | "crudeprices.resample('1D').mean().ffill()\n",
186 | "crudeprices = crudeprices.drop(\"date\", axis=1)\n",
187 | "\n",
188 | "dti=pd.date_range(start=\"2010-01-21 00:00:00-05:00\", end=\"2023-02-02 00:00:00-05:00\", freq=\"D\")\n",
189 | "crudeprices=crudeprices.reindex(dti, method='ffill')\n",
190 | "print(crudeprices.head())\n",
191 | "stocks_ts = stocks_ts.assign(CrudeRates=crudeprices[\"value\"])"
192 | ],
193 | "metadata": {
194 | "colab": {
195 | "base_uri": "https://localhost:8080/"
196 | },
197 | "id": "Eo48W2TCbFKE",
198 | "outputId": "c6266917-7fb3-4a53-f664-fdb89093e3a7"
199 | },
200 | "execution_count": null,
201 | "outputs": [
202 | {
203 | "output_type": "stream",
204 | "name": "stdout",
205 | "text": [
206 | " value\n",
207 | "2010-01-21 00:00:00-05:00 75.84\n",
208 | "2010-01-22 00:00:00-05:00 74.25\n",
209 | "2010-01-23 00:00:00-05:00 74.25\n",
210 | "2010-01-24 00:00:00-05:00 74.25\n",
211 | "2010-01-25 00:00:00-05:00 74.90\n"
212 | ]
213 | }
214 | ]
215 | },
216 | {
217 | "cell_type": "code",
218 | "source": [
219 | "import pandas as pd\n",
220 | "\n",
221 | "vix=pd.read_csv(\"sample_data/vix-volatility-index-historical-chart.csv\")\n",
222 | "vix['Datetime'] = pd.to_datetime(vix['date'] + \" 00:00:00-05:00\")\n",
223 | "vix = vix.set_index('Datetime')\n",
224 | "\n",
225 | "vix.resample('1D').mean().ffill()\n",
226 | "vix = vix.drop(\"date\", axis=1)\n",
227 | "\n",
228 | "dti=pd.date_range(start=\"1990-01-02 00:00:00-05:00\", end=\"2023-02-08 00:00:00-05:00\", freq=\"D\")\n",
229 | "vix=vix.reindex(dti, method='ffill')\n",
230 | "print(vix)\n",
231 | "stocks_ts = stocks_ts.assign(Vix=vix[\"value\"])"
232 | ],
233 | "metadata": {
234 | "colab": {
235 | "base_uri": "https://localhost:8080/"
236 | },
237 | "id": "ItBMm1RSnXgV",
238 | "outputId": "eb3a92e3-bfd4-4945-f51b-483e8133cac7"
239 | },
240 | "execution_count": null,
241 | "outputs": [
242 | {
243 | "output_type": "stream",
244 | "name": "stdout",
245 | "text": [
246 | " value\n",
247 | "1990-01-02 00:00:00-05:00 17.24\n",
248 | "1990-01-03 00:00:00-05:00 18.19\n",
249 | "1990-01-04 00:00:00-05:00 19.22\n",
250 | "1990-01-05 00:00:00-05:00 20.11\n",
251 | "1990-01-06 00:00:00-05:00 20.11\n",
252 | "... ...\n",
253 | "2023-02-04 00:00:00-05:00 20.34\n",
254 | "2023-02-05 00:00:00-05:00 20.34\n",
255 | "2023-02-06 00:00:00-05:00 20.34\n",
256 | "2023-02-07 00:00:00-05:00 20.34\n",
257 | "2023-02-08 00:00:00-05:00 20.34\n",
258 | "\n",
259 | "[12091 rows x 1 columns]\n"
260 | ]
261 | }
262 | ]
263 | },
264 | {
265 | "cell_type": "code",
266 | "source": [
267 | "import pandas as pd\n",
268 | "from datetime import datetime\n",
269 | "\n",
270 | "pcr=pd.read_csv(\"sample_data/pcr.csv\")\n",
271 | "pcr[\"date\"] = [datetime.fromtimestamp(x/1000) for x in pcr[\"date\"]]\n",
272 | "pcr[\"date\"] = [str(x.date()) + \" 00:00:00-05:00\" for x in pcr[\"date\"]]\n",
273 | "pcr = pcr.drop_duplicates(subset='date', keep=\"first\")\n",
274 | "pcr['Datetime'] = pd.to_datetime(pcr['date'])\n",
275 | "pcr = pcr.set_index(\"Datetime\")\n",
276 | "\n",
277 | "pcr.resample('1D').mean().ffill()\n",
278 | "pcr = pcr.drop(\"date\", axis=1)\n",
279 | "\n",
280 | "dti = pd.date_range(start=\"2006-10-31 00:00:00-05:00\", end=\"2023-01-20 00:00:00-05:00\", freq=\"D\")\n",
281 | "\n",
282 | "pcr = pcr.reindex(dti, method='ffill')\n",
283 | "print(pcr)\n",
284 | "stocks_ts = stocks_ts.assign(Pcr=pcr[\"value\"])\n",
285 | "print(stocks_ts)"
286 | ],
287 | "metadata": {
288 | "id": "nSHIzouiv166"
289 | },
290 | "execution_count": null,
291 | "outputs": []
292 | },
293 | {
294 | "cell_type": "code",
295 | "execution_count": null,
296 | "metadata": {
297 | "id": "gSQ55fKTFaLA"
298 | },
299 | "outputs": [],
300 | "source": [
301 | "import pandas as pd\n",
302 | "unemplrates=pd.read_csv(\"sample_data/us-national-unemployment-rate.csv\")\n",
303 | "\n",
304 | "#fedrates = fedrates.drop(\"date\", axis=1)\n",
305 | "dti=pd.date_range(start=\"1948-01-01 00:00:00-05:00\", end=\"2023-07-01 00:00:00-05:00\", freq=\"M\")\n",
306 | "unemplrates.index = dti\n",
307 | "\n",
308 | "dti=pd.date_range(start=\"1948-01-01 00:00:00-05:00\", end=\"2023-07-01 00:00:00-05:00\", freq=\"D\")\n",
309 | "dti.name = 'date'\n",
310 | "unemplrates=unemplrates.reindex(dti, method='ffill')\n",
311 | "\n",
312 | "stocks_ts = stocks_ts.assign(UnemploymentRates=unemplrates[\"value\"])\n",
313 | "print(stocks_ts)"
314 | ]
315 | },
316 | {
317 | "cell_type": "code",
318 | "source": [
319 | "import pandas as pd\n",
320 | "\n",
321 | "macd=pd.read_csv(\"sample_data/macd.csv\")\n",
322 | "macd['Datetime'] = pd.to_datetime(macd['Trade Date'] + \" 00:00:00-05:00\")\n",
323 | "macd = macd.set_index(\"Datetime\")\n",
324 | "\n",
325 | "macd.resample('1D').mean().ffill()\n",
326 | "macd = macd.drop(\"Trade Date\", axis=1)\n",
327 | "\n",
328 | "dti = pd.date_range(start=\"2000-02-21 00:00:00-05:00\", end=\"2023-01-20 00:00:00-05:00\", freq=\"D\")\n",
329 | "\n",
330 | "macd = macd.reindex(dti, method='ffill')\n",
331 | "print(macd)\n",
332 | "\n",
333 | "stocks_ts = stocks_ts.assign(MACD=macd[\"MACD(26,12)\"])\n",
334 | "stocks_ts = stocks_ts.assign(EXP=macd[\"Exp(9)\"])\n",
335 | "stocks_ts = stocks_ts.assign(MacdHist=macd[\"Macd Histogram\"])\n",
336 | "print(stocks_ts)\n"
337 | ],
338 | "metadata": {
339 | "id": "TdyfOBGyM3rx"
340 | },
341 | "execution_count": null,
342 | "outputs": []
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": null,
347 | "metadata": {
348 | "id": "eYbpC9WYNVtK",
349 | "colab": {
350 | "base_uri": "https://localhost:8080/"
351 | },
352 | "outputId": "d00ead4a-5e8b-4879-b889-50bde963f4a3"
353 | },
354 | "outputs": [
355 | {
356 | "output_type": "stream",
357 | "name": "stdout",
358 | "text": [
359 | "2518 (2518, 37)\n",
360 | "2283 2283 2259 235 2518\n"
361 | ]
362 | }
363 | ],
364 | "source": [
365 | "train_data = stocks_ts[:-259]\n",
366 | "l = stocks_ts.shape[0]\n",
367 | "print(l, stocks_ts.shape)\n",
368 | "validation_data = stocks_ts[:-259+24]\n",
369 | "l = l - 259 + 24\n",
370 | "test_data = stocks_ts[l:]\n",
371 | "print(l, len(validation_data), len(train_data), len(test_data), len(stocks_ts))"
372 | ]
373 | },
374 | {
375 | "cell_type": "code",
376 | "execution_count": null,
377 | "metadata": {
378 | "id": "HzUfKL6uNW8X"
379 | },
380 | "outputs": [],
381 | "source": [
382 | "from gluonts.dataset.common import ListDataset\n",
383 | "from gluonts.dataset.field_names import FieldName\n",
384 | "\n",
385 | "\n",
386 | "def to_deepar_format(dataframe):\n",
387 | " freq = pd.infer_freq(dataframe.index) \n",
388 | " if not freq:\n",
389 | " freq = 'D'\n",
390 | " start_index = dataframe.index.min()\n",
391 | " data = [{\n",
392 | " FieldName.START: start_index,\n",
393 | " FieldName.TARGET: dataframe[c].values,\n",
394 | " FieldName.ITEM_ID: c,\n",
395 | " FieldName.FEAT_STATIC_CAT: [idx],\n",
396 | " } \n",
397 | " for idx, c in enumerate(dataframe.columns)]\n",
398 | " return ListDataset(data, freq=freq)\n",
399 | "train_data_lds = to_deepar_format(train_data)\n",
400 | "test_data_lds = to_deepar_format(test_data)\n",
401 | "validation_data_lds = to_deepar_format(validation_data)\n"
402 | ]
403 | },
404 | {
405 | "cell_type": "code",
406 | "execution_count": null,
407 | "metadata": {
408 | "id": "R7qMMxfCFfrg"
409 | },
410 | "outputs": [],
411 | "source": [
412 | "from datasets import Dataset, DatasetDict\n",
413 | "l = stocks_ts.shape[0]\n",
414 | "train = Dataset.from_pandas(stocks_ts[:-259])\n",
415 | "l = l-259\n",
416 | "validation = Dataset.from_pandas(stocks_ts[:-259+24])\n",
417 | "l = l + 24\n",
418 | "test = Dataset.from_pandas(stocks_ts[l:])\n",
419 | "dataset = DatasetDict({\"train\":train_data_lds, \"validation\":validation_data_lds, \"test\":test_data_lds})"
420 | ]
421 | },
422 | {
423 | "cell_type": "code",
424 | "execution_count": null,
425 | "metadata": {
426 | "id": "-HWxCzP2Fubo"
427 | },
428 | "outputs": [],
429 | "source": [
430 | "train_example = dataset['train'][1]\n",
431 | "train_example.keys()\n",
432 | "validation_example = dataset['validation'][1]\n",
433 | "freq = \"1D\"\n",
434 | "prediction_length = 24\n",
435 | "\n",
436 | "assert len(train_example['target']) + prediction_length == len(validation_example['target'])"
437 | ]
438 | },
439 | {
440 | "cell_type": "code",
441 | "execution_count": null,
442 | "metadata": {
443 | "id": "6WjdeupFQsth",
444 | "colab": {
445 | "base_uri": "https://localhost:8080/",
446 | "height": 268
447 | },
448 | "outputId": "5b2e5a32-21a6-489a-e642-dcade46c4238"
449 | },
450 | "outputs": [
451 | {
452 | "output_type": "display_data",
453 | "data": {
454 | "text/plain": [
455 | ""
456 | ],
457 | "image/png": "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\n"
458 | },
459 | "metadata": {
460 | "needs_background": "light"
461 | }
462 | }
463 | ],
464 | "source": [
465 | "import matplotlib.pyplot as plt\n",
466 | "\n",
467 | "figure, axes = plt.subplots()\n",
468 | "axes.plot(train_example['target'], color=\"blue\") \n",
469 | "axes.plot(validation_example['target'], color=\"red\", alpha=0.5)\n",
470 | "\n",
471 | "plt.show()"
472 | ]
473 | },
474 | {
475 | "cell_type": "code",
476 | "execution_count": null,
477 | "metadata": {
478 | "id": "n39NHFX_Q_yq",
479 | "colab": {
480 | "base_uri": "https://localhost:8080/"
481 | },
482 | "outputId": "5a52a100-32ac-4a4e-b45f-76f831387673"
483 | },
484 | "outputs": [
485 | {
486 | "output_type": "stream",
487 | "name": "stdout",
488 | "text": [
489 | "37 2259 2283 235\n"
490 | ]
491 | }
492 | ],
493 | "source": [
494 | "train_dataset = dataset[\"train\"]\n",
495 | "test_dataset = dataset[\"test\"]\n",
496 | "validation_dataset = dataset['validation']\n",
497 | "\n",
498 | "print(len(train_dataset), len(train_dataset[0]['target']), len(validation_dataset[0]['target']), len(test_dataset[0]['target']))"
499 | ]
500 | },
501 | {
502 | "cell_type": "code",
503 | "execution_count": null,
504 | "metadata": {
505 | "id": "Ip_SfsrysRuX",
506 | "colab": {
507 | "base_uri": "https://localhost:8080/"
508 | },
509 | "outputId": "b1b8ef9d-c049-46a0-b08b-e310a0a34bbf"
510 | },
511 | "outputs": [
512 | {
513 | "output_type": "stream",
514 | "name": "stdout",
515 | "text": [
516 | "[1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 15, 20, 21, 22, 27, 28, 29, 30, 31, 56, 84, 363, 364, 365, 727, 728, 729, 1091, 1092, 1093]\n"
517 | ]
518 | }
519 | ],
520 | "source": [
521 | "from gluonts.time_feature import get_lags_for_frequency\n",
522 | "\n",
523 | "lags_sequence = get_lags_for_frequency(freq)\n",
524 | "print(lags_sequence)\n"
525 | ]
526 | },
527 | {
528 | "cell_type": "code",
529 | "execution_count": null,
530 | "metadata": {
531 | "id": "NVk0suubscss",
532 | "colab": {
533 | "base_uri": "https://localhost:8080/"
534 | },
535 | "outputId": "6514ea4a-618d-4b16-bd4f-194644f0533d"
536 | },
537 | "outputs": [
538 | {
539 | "output_type": "stream",
540 | "name": "stdout",
541 | "text": [
542 | "[, , ]\n"
543 | ]
544 | }
545 | ],
546 | "source": [
547 | "from gluonts.time_feature import time_features_from_frequency_str\n",
548 | "\n",
549 | "time_features = time_features_from_frequency_str(freq)\n",
550 | "print(time_features)"
551 | ]
552 | },
553 | {
554 | "cell_type": "code",
555 | "execution_count": null,
556 | "metadata": {
557 | "id": "_ChF_bIWsnTJ"
558 | },
559 | "outputs": [],
560 | "source": [
561 | "from transformers import TimeSeriesTransformerConfig, TimeSeriesTransformerForPrediction\n",
562 | "\n",
563 | "config = TimeSeriesTransformerConfig(\n",
564 | " prediction_length=prediction_length,\n",
565 | " context_length=prediction_length*3, # context length\n",
566 | " lags_sequence=lags_sequence,\n",
567 | " num_time_features=len(time_features) + 1, # we'll add 3 time features (day of week, day of month, day of year)\n",
568 | " num_static_categorical_features=1, # we have a single static categorical feature, namely time series ID\n",
569 | " cardinality=[len(train_dataset)], # it has 1011 possible values\n",
570 | " embedding_dimension=[10], # the model will learn an embedding of size 10 for each of the 1011 possible values\n",
571 | " encoder_layers=4, \n",
572 | " decoder_layers=4,\n",
573 | " output_attentions=True,\n",
574 | ")\n",
575 | "model = TimeSeriesTransformerForPrediction(config)\n"
576 | ]
577 | },
578 | {
579 | "cell_type": "code",
580 | "execution_count": null,
581 | "metadata": {
582 | "id": "ILWWd7rkt1xI"
583 | },
584 | "outputs": [],
585 | "source": [
586 | "from gluonts.time_feature import time_features_from_frequency_str, TimeFeature, get_lags_for_frequency\n",
587 | "from gluonts.dataset.field_names import FieldName\n",
588 | "from gluonts.transform import (\n",
589 | " AddAgeFeature,\n",
590 | " AddObservedValuesIndicator,\n",
591 | " AddTimeFeatures,\n",
592 | " AsNumpyArray,\n",
593 | " Chain,\n",
594 | " ExpectedNumInstanceSampler,\n",
595 | " InstanceSplitter,\n",
596 | " RemoveFields,\n",
597 | " SelectFields,\n",
598 | " SetField,\n",
599 | " TestSplitSampler,\n",
600 | " Transformation,\n",
601 | " ValidationSplitSampler,\n",
602 | " VstackFeatures,\n",
603 | " RenameFields,\n",
604 | ")\n"
605 | ]
606 | },
607 | {
608 | "cell_type": "code",
609 | "execution_count": null,
610 | "metadata": {
611 | "id": "qIHw3Zawt7O9"
612 | },
613 | "outputs": [],
614 | "source": [
615 | "from transformers import PretrainedConfig\n",
616 | "\n",
617 | "def create_transformation(freq: str, config: PretrainedConfig) -> Transformation:\n",
618 | " remove_field_names = []\n",
619 | " if config.num_static_real_features == 0:\n",
620 | " remove_field_names.append(FieldName.FEAT_STATIC_REAL)\n",
621 | " if config.num_dynamic_real_features == 0:\n",
622 | " remove_field_names.append(FieldName.FEAT_DYNAMIC_REAL)\n",
623 | "\n",
624 | " # a bit like torchvision.transforms.Compose\n",
625 | " return Chain(\n",
626 | " # step 1: remove static/dynamic fields if not specified\n",
627 | " [RemoveFields(field_names=remove_field_names)]\n",
628 | " # step 2: use static features if available, if not add dummy values\n",
629 | " + (\n",
630 | " [SetField(output_field=FieldName.FEAT_STATIC_CAT, value=[0])]\n",
631 | " if not config.num_static_categorical_features > 0\n",
632 | " else []\n",
633 | " )\n",
634 | " + (\n",
635 | " [SetField(output_field=FieldName.FEAT_STATIC_REAL, value=[0.0])]\n",
636 | " if not config.num_static_real_features > 0\n",
637 | " else []\n",
638 | " )\n",
639 | " # step 3: convert the data to NumPy (potentially not needed)\n",
640 | " + [\n",
641 | " AsNumpyArray(\n",
642 | " field=FieldName.FEAT_STATIC_CAT,\n",
643 | " expected_ndim=1,\n",
644 | " dtype=int,\n",
645 | " ),\n",
646 | " AsNumpyArray(\n",
647 | " field=FieldName.FEAT_STATIC_REAL,\n",
648 | " expected_ndim=1,\n",
649 | " ),\n",
650 | " AsNumpyArray(\n",
651 | " field=FieldName.TARGET,\n",
652 | " # in the following line, we add 1 for the time dimension\n",
653 | " expected_ndim=1 if config.input_size==1 else 2,\n",
654 | " ),\n",
655 | " # step 4: handle the NaN's by filling in the target with zero\n",
656 | " # and return the mask (which is in the observed values)\n",
657 | " # true for observed values, false for nan's\n",
658 | " # the decoder uses this mask (no loss is incurred for unobserved values)\n",
659 | " # see loss_weights inside the xxxForPrediction model\n",
660 | " AddObservedValuesIndicator(\n",
661 | " target_field=FieldName.TARGET,\n",
662 | " output_field=FieldName.OBSERVED_VALUES,\n",
663 | " ),\n",
664 | " # step 5: add temporal features based on freq of the dataset\n",
665 | " # month of year in this case\n",
666 | " # these serve as positional encodings\n",
667 | " AddTimeFeatures(\n",
668 | " start_field=FieldName.START,\n",
669 | " target_field=FieldName.TARGET,\n",
670 | " output_field=FieldName.FEAT_TIME,\n",
671 | " time_features=time_features_from_frequency_str(freq),\n",
672 | " pred_length=config.prediction_length,\n",
673 | " ),\n",
674 | " # step 6: add another temporal feature (just a single number)\n",
675 | " # tells the model where in the life the value of the time series is\n",
676 | " # sort of running counter\n",
677 | " AddAgeFeature(\n",
678 | " target_field=FieldName.TARGET,\n",
679 | " output_field=FieldName.FEAT_AGE,\n",
680 | " pred_length=config.prediction_length,\n",
681 | " log_scale=True,\n",
682 | " ),\n",
683 | " # step 7: vertically stack all the temporal features\n",
684 | " VstackFeatures(\n",
685 | " output_field=FieldName.FEAT_TIME,\n",
686 | " input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE]\n",
687 | " + ([FieldName.FEAT_DYNAMIC_REAL] if config.num_dynamic_real_features > 0 else []),\n",
688 | " ),\n",
689 | " # step 8: rename to match HuggingFace names\n",
690 | " RenameFields(\n",
691 | " mapping={\n",
692 | " FieldName.FEAT_STATIC_CAT: \"static_categorical_features\",\n",
693 | " FieldName.FEAT_STATIC_REAL: \"static_real_features\",\n",
694 | " FieldName.FEAT_TIME: \"time_features\",\n",
695 | " FieldName.TARGET: \"values\",\n",
696 | " FieldName.OBSERVED_VALUES: \"observed_mask\",\n",
697 | " }\n",
698 | " ),\n",
699 | " ]\n",
700 | " )\n"
701 | ]
702 | },
703 | {
704 | "cell_type": "code",
705 | "execution_count": null,
706 | "metadata": {
707 | "id": "-mFCGR6nuXkW"
708 | },
709 | "outputs": [],
710 | "source": [
711 | "from gluonts.transform.sampler import InstanceSampler\n",
712 | "from typing import Optional\n",
713 | "\n",
714 | "def create_instance_splitter(config: PretrainedConfig, mode: str, train_sampler: Optional[InstanceSampler] = None,\n",
715 | " validation_sampler: Optional[InstanceSampler] = None,) -> Transformation:\n",
716 | " assert mode in [\"train\", \"validation\", \"test\"]\n",
717 | "\n",
718 | " instance_sampler = {\n",
719 | " \"train\": train_sampler or ExpectedNumInstanceSampler(\n",
720 | " num_instances=1.0, min_future=config.prediction_length\n",
721 | " ),\n",
722 | " \"validation\": validation_sampler or ValidationSplitSampler(\n",
723 | " min_future=config.prediction_length\n",
724 | " ),\n",
725 | " \"test\": TestSplitSampler(),\n",
726 | " }[mode]\n",
727 | "\n",
728 | " return InstanceSplitter(\n",
729 | " target_field=\"values\",\n",
730 | " is_pad_field=FieldName.IS_PAD,\n",
731 | " start_field=FieldName.START,\n",
732 | " forecast_start_field=FieldName.FORECAST_START,\n",
733 | " instance_sampler=instance_sampler,\n",
734 | " past_length=config.context_length + max(config.lags_sequence),\n",
735 | " future_length=config.prediction_length,\n",
736 | " time_series_fields=[\n",
737 | " \"time_features\",\n",
738 | " \"observed_mask\",\n",
739 | " ],\n",
740 | " )\n"
741 | ]
742 | },
743 | {
744 | "cell_type": "code",
745 | "execution_count": null,
746 | "metadata": {
747 | "id": "CuN-7_-cuc0Y"
748 | },
749 | "outputs": [],
750 | "source": [
751 | "from gluonts.itertools import Cyclic, IterableSlice, PseudoShuffled\n",
752 | "from gluonts.torch.util import IterableDataset\n",
753 | "from torch.utils.data import DataLoader\n",
754 | "\n",
755 | "from typing import Iterable\n",
756 | "\n",
757 | "def create_train_dataloader(\n",
758 | " config: PretrainedConfig,\n",
759 | " freq,\n",
760 | " data,\n",
761 | " batch_size: int,\n",
762 | " num_batches_per_epoch: int,\n",
763 | " shuffle_buffer_length: Optional[int] = None,\n",
764 | " **kwargs,\n",
765 | ") -> Iterable:\n",
766 | " PREDICTION_INPUT_NAMES = [\n",
767 | " \"static_categorical_features\",\n",
768 | " \"static_real_features\",\n",
769 | " \"past_time_features\",\n",
770 | " \"past_values\",\n",
771 | " \"past_observed_mask\",\n",
772 | " \"future_time_features\",\n",
773 | " ]\n",
774 | "\n",
775 | " TRAINING_INPUT_NAMES = PREDICTION_INPUT_NAMES + [\n",
776 | " \"future_values\",\n",
777 | " \"future_observed_mask\",\n",
778 | " ]\n",
779 | " \n",
780 | " transformation = create_transformation(freq, config)\n",
781 | " transformed_data = transformation.apply(data, is_train=True)\n",
782 | "\n",
783 | " # we initialize a Training instance\n",
784 | " instance_splitter = create_instance_splitter(\n",
785 | " config, \"train\"\n",
786 | " ) + SelectFields(TRAINING_INPUT_NAMES)\n",
787 | "\n",
788 | "\n",
789 | " # the instance splitter will sample a window of \n",
790 | " # context length + lags + prediction length (from the 366 possible transformed time series)\n",
791 | " # randomly from within the target time series and return an iterator.\n",
792 | " training_instances = instance_splitter.apply(\n",
793 | " Cyclic(transformed_data)\n",
794 | " if shuffle_buffer_length is None\n",
795 | " else PseudoShuffled(\n",
796 | " Cyclic(transformed_data), \n",
797 | " shuffle_buffer_length=shuffle_buffer_length,\n",
798 | " )\n",
799 | " )\n",
800 | " # from the training instances iterator we now return a Dataloader which will \n",
801 | " # continue to sample random windows for as long as it is called\n",
802 | " # to return batch_size of the appropriate tensors ready for training!\n",
803 | " return IterableSlice(\n",
804 | " iter(\n",
805 | " DataLoader(\n",
806 | " IterableDataset(training_instances),\n",
807 | " batch_size=batch_size,\n",
808 | " **kwargs,\n",
809 | " )\n",
810 | " ),\n",
811 | " num_batches_per_epoch,\n",
812 | " )\n"
813 | ]
814 | },
815 | {
816 | "cell_type": "code",
817 | "execution_count": null,
818 | "metadata": {
819 | "id": "aEsj8tKBumMs"
820 | },
821 | "outputs": [],
822 | "source": [
823 | "def create_test_dataloader(\n",
824 | " config: PretrainedConfig,\n",
825 | " freq,\n",
826 | " data,\n",
827 | " batch_size: int,\n",
828 | " **kwargs,\n",
829 | "):\n",
830 | " PREDICTION_INPUT_NAMES = [\n",
831 | " \"static_categorical_features\",\n",
832 | " \"static_real_features\",\n",
833 | " \"past_time_features\",\n",
834 | " \"past_values\",\n",
835 | " \"past_observed_mask\",\n",
836 | " \"future_time_features\",\n",
837 | " ]\n",
838 | " \n",
839 | " transformation = create_transformation(freq, config)\n",
840 | " transformed_data = transformation.apply(data, is_train=False)\n",
841 | " \n",
842 | " # we create a Test Instance splitter which will sample the very last \n",
843 | " # context window seen during training only for the encoder.\n",
844 | " instance_splitter = create_instance_splitter(\n",
845 | " config, \"test\"\n",
846 | " ) + SelectFields(PREDICTION_INPUT_NAMES)\n",
847 | " \n",
848 | " # we apply the transformations in test mode\n",
849 | " testing_instances = instance_splitter.apply(transformed_data, is_train=False)\n",
850 | " \n",
851 | " # This returns a Dataloader which will go over the dataset once.\n",
852 | " return DataLoader(IterableDataset(testing_instances), batch_size=batch_size, **kwargs)\n"
853 | ]
854 | },
855 | {
856 | "cell_type": "code",
857 | "execution_count": null,
858 | "metadata": {
859 | "id": "dRx6aJtvutD_"
860 | },
861 | "outputs": [],
862 | "source": [
863 | "train_dataloader = create_train_dataloader(\n",
864 | " config=config, \n",
865 | " freq=freq, \n",
866 | " data=train_dataset, \n",
867 | " batch_size=256, \n",
868 | " num_batches_per_epoch=100,\n",
869 | ")\n",
870 | "\n",
871 | "test_dataloader = create_test_dataloader(\n",
872 | " config=config, \n",
873 | " freq=freq, \n",
874 | " data=test_dataset,\n",
875 | " batch_size=64,\n",
876 | ")\n"
877 | ]
878 | },
879 | {
880 | "cell_type": "code",
881 | "execution_count": null,
882 | "metadata": {
883 | "id": "vlAZGMrku3Qa"
884 | },
885 | "outputs": [],
886 | "source": [
887 | "batch = next(iter(train_dataloader))\n",
888 | "for k,v in batch.items():\n",
889 | " print(k,v, v.type())"
890 | ]
891 | },
892 | {
893 | "cell_type": "code",
894 | "execution_count": null,
895 | "metadata": {
896 | "id": "SYgy4j3rGeXZ"
897 | },
898 | "outputs": [],
899 | "source": [
900 | "# perform forward pass\n",
901 | "outputs = model(\n",
902 | " past_values=batch[\"past_values\"],\n",
903 | " past_time_features=batch[\"past_time_features\"],\n",
904 | " past_observed_mask=batch[\"past_observed_mask\"],\n",
905 | " static_categorical_features=batch[\"static_categorical_features\"],\n",
906 | " static_real_features=batch[\"static_real_features\"],\n",
907 | " future_values=batch[\"future_values\"],\n",
908 | " future_time_features=batch[\"future_time_features\"],\n",
909 | " future_observed_mask=batch[\"future_observed_mask\"],\n",
910 | " output_hidden_states=True\n",
911 | ")\n"
912 | ]
913 | },
914 | {
915 | "cell_type": "code",
916 | "execution_count": null,
917 | "metadata": {
918 | "id": "aot03-jUGncx"
919 | },
920 | "outputs": [],
921 | "source": [
922 | "print(\"Loss:\", outputs['encoder_attentions'])"
923 | ]
924 | },
925 | {
926 | "cell_type": "code",
927 | "execution_count": null,
928 | "metadata": {
929 | "id": "fHCdPnqKGsFX"
930 | },
931 | "outputs": [],
932 | "source": [
933 | "import os\n",
934 | "from accelerate import Accelerator\n",
935 | "from torch.optim import Adam\n",
936 | "\n",
937 | "accelerator = Accelerator()\n",
938 | "device = accelerator.device\n",
939 | "\n",
940 | "model.to(device)\n",
941 | "optimizer = Adam(model.parameters(), lr=1e-6)\n",
942 | " \n",
943 | "model, optimizer, train_dataloader = accelerator.prepare(\n",
944 | " model, optimizer, train_dataloader, \n",
945 | ")\n",
946 | "\n",
947 | "if os.path.exists(model_save_path) and \\\n",
948 | " load_from_pretrained:\n",
949 | " model.from_pretrained(model_save_path)\n",
950 | "else:\n",
951 | " skip_training = False\n",
952 | "\n",
953 | "if skip_training:\n",
954 | " outputs = model(\n",
955 | " past_values=batch[\"past_values\"],\n",
956 | " past_time_features=batch[\"past_time_features\"],\n",
957 | " past_observed_mask=batch[\"past_observed_mask\"],\n",
958 | " static_categorical_features=batch[\"static_categorical_features\"],\n",
959 | " static_real_features=batch[\"static_real_features\"],\n",
960 | " future_values=batch[\"future_values\"],\n",
961 | " future_time_features=batch[\"future_time_features\"],\n",
962 | " future_observed_mask=batch[\"future_observed_mask\"],\n",
963 | " output_hidden_states=True\n",
964 | " )\n",
965 | " print(\"Loss:\", outputs.loss.item())\n",
966 | "\n",
967 | "else:\n",
968 | " losses = []\n",
969 | " for epoch in range(epoches):\n",
970 | " model.train()\n",
971 | " print(\"Epoch \", epoch)\n",
972 | " for batch in train_dataloader:\n",
973 | " optimizer.zero_grad()\n",
974 | " outputs = model(\n",
975 | " static_categorical_features=batch[\"static_categorical_features\"].to(device),\n",
976 | " static_real_features=batch[\"static_real_features\"].to(device),\n",
977 | " past_time_features=batch[\"past_time_features\"].to(device),\n",
978 | " past_values=batch[\"past_values\"].to(device),\n",
979 | " future_time_features=batch[\"future_time_features\"].to(device),\n",
980 | " future_values=batch[\"future_values\"].to(device),\n",
981 | " past_observed_mask=batch[\"past_observed_mask\"].to(device),\n",
982 | " future_observed_mask=batch[\"future_observed_mask\"].to(device),\n",
983 | " )\n",
984 | " loss = outputs.loss\n",
985 | "\n",
986 | " # Backpropagation\n",
987 | " accelerator.backward(loss)\n",
988 | " optimizer.step()\n",
989 | " losses.append(loss.item())\n",
990 | " print(loss)\n",
991 | "\n",
992 | " plt.plot(losses)\n",
993 | " plt.show()\n",
994 | "\n",
995 | " model.save_pretrained(model_save_path)\n"
996 | ]
997 | },
998 | {
999 | "cell_type": "code",
1000 | "execution_count": null,
1001 | "metadata": {
1002 | "id": "wWdVGhu_JZEO"
1003 | },
1004 | "outputs": [],
1005 | "source": [
1006 | "model.eval()\n",
1007 | "\n",
1008 | "forecasts = []\n",
1009 | "i = 0\n",
1010 | "for batch in test_dataloader:\n",
1011 | " outputs = model.generate(\n",
1012 | " static_categorical_features=batch[\"static_categorical_features\"].to(device),\n",
1013 | " static_real_features=batch[\"static_real_features\"].to(device),\n",
1014 | " past_time_features=batch[\"past_time_features\"].to(device),\n",
1015 | " past_values=batch[\"past_values\"].to(device),\n",
1016 | " future_time_features=batch[\"future_time_features\"].to(device),\n",
1017 | " past_observed_mask=batch[\"past_observed_mask\"].to(device),\n",
1018 | " )\n",
1019 | " forecasts.append(outputs.sequences.cpu().numpy())"
1020 | ]
1021 | },
1022 | {
1023 | "cell_type": "code",
1024 | "execution_count": null,
1025 | "metadata": {
1026 | "id": "aVJdRTpfM2Nh"
1027 | },
1028 | "outputs": [],
1029 | "source": [
1030 | "import numpy as np\n",
1031 | "print(len(forecasts), forecasts[0].shape)\n",
1032 | "stacked_forecasts = np.vstack(forecasts)\n",
1033 | "print(stacked_forecasts.shape)"
1034 | ]
1035 | },
1036 | {
1037 | "cell_type": "code",
1038 | "execution_count": null,
1039 | "metadata": {
1040 | "id": "ePP2tEZMM3hY"
1041 | },
1042 | "outputs": [],
1043 | "source": [
1044 | "import numpy as np\n",
1045 | "from evaluate import load\n",
1046 | "from gluonts.time_feature import get_seasonality\n",
1047 | "\n",
1048 | "mase_metric = load(\"evaluate-metric/mase\")\n",
1049 | "smape_metric = load(\"evaluate-metric/smape\")\n",
1050 | "\n",
1051 | "forecast_median = np.median(stacked_forecasts, 1)\n",
1052 | "print(len(forecast_median[0]))\n",
1053 | "mase_metrics = []\n",
1054 | "smape_metrics = []\n",
1055 | "for item_id, ts in enumerate(test_dataset):\n",
1056 | " try:\n",
1057 | " training_data = ts[\"target\"][:-prediction_length]\n",
1058 | " ground_truth = ts[\"target\"][-prediction_length:]\n",
1059 | " mase = mase_metric.compute(\n",
1060 | " predictions=forecast_median[item_id], \n",
1061 | " references=np.array(ground_truth), \n",
1062 | " training=np.array(training_data), \n",
1063 | " periodicity=get_seasonality(freq))\n",
1064 | " mase_metrics.append(mase[\"mase\"])\n",
1065 | " \n",
1066 | " smape = smape_metric.compute(\n",
1067 | " predictions=forecast_median[item_id], \n",
1068 | " references=np.array(ground_truth), \n",
1069 | " )\n",
1070 | " smape_metrics.append(smape[\"smape\"])\n",
1071 | " except:\n",
1072 | " pass"
1073 | ]
1074 | },
1075 | {
1076 | "cell_type": "code",
1077 | "source": [
1078 | "from google.colab import drive\n",
1079 | "drive.mount('/content/drive')"
1080 | ],
1081 | "metadata": {
1082 | "id": "snYp7YHxO5i_"
1083 | },
1084 | "execution_count": null,
1085 | "outputs": []
1086 | },
1087 | {
1088 | "cell_type": "code",
1089 | "execution_count": null,
1090 | "metadata": {
1091 | "id": "DS_XVW22M85n"
1092 | },
1093 | "outputs": [],
1094 | "source": [
1095 | "\n",
1096 | "print(f\"MASE: {np.mean(mase_metrics)}\")\n",
1097 | "\n",
1098 | "print(f\"sMAPE: {np.mean(smape_metrics)}\")\n"
1099 | ]
1100 | },
1101 | {
1102 | "cell_type": "code",
1103 | "execution_count": null,
1104 | "metadata": {
1105 | "id": "hlPe8NFBND_F"
1106 | },
1107 | "outputs": [],
1108 | "source": [
1109 | "plt.scatter(mase_metrics, smape_metrics, alpha=0.3)\n",
1110 | "plt.xlabel(\"MASE\")\n",
1111 | "plt.ylabel(\"sMAPE\")\n",
1112 | "plt.show()"
1113 | ]
1114 | },
1115 | {
1116 | "cell_type": "code",
1117 | "execution_count": null,
1118 | "metadata": {
1119 | "id": "d8nH50mPNI2_"
1120 | },
1121 | "outputs": [],
1122 | "source": [
1123 | "import matplotlib.dates as mdates\n",
1124 | "\n",
1125 | "def plot(ts_index):\n",
1126 | " ticker = test_dataset[ts_index][\"item_id\"].split('_')[0]\n",
1127 | " fig, ax = plt.subplots()\n",
1128 | "\n",
1129 | " index = pd.period_range(\n",
1130 | " start=test_dataset[ts_index][FieldName.START],\n",
1131 | " periods=len(test_dataset[ts_index][FieldName.TARGET]),\n",
1132 | " freq=freq,\n",
1133 | " ).to_timestamp()\n",
1134 | " myFmt = mdates.DateFormatter('%b %d')\n",
1135 | " ax.xaxis.set_major_formatter(myFmt)\n",
1136 | " plt.suptitle(ticker,fontsize=24, y=1)\n",
1137 | " plt.xlabel(\"Date\")\n",
1138 | " plt.ylabel(\"Price\")\n",
1139 | " plt.grid()\n",
1140 | " ax.plot(\n",
1141 | " index[-2*prediction_length:], \n",
1142 | " test_dataset[ts_index][\"target\"][-2*prediction_length:],\n",
1143 | " label=\"actual\",\n",
1144 | " )\n",
1145 | "\n",
1146 | " plt.plot(\n",
1147 | " index[-prediction_length:], \n",
1148 | " np.median(stacked_forecasts[ts_index], axis=0),\n",
1149 | " label=\"median\",\n",
1150 | " )\n",
1151 | " \n",
1152 | " plt.fill_between(\n",
1153 | " index[-prediction_length:],\n",
1154 | " stacked_forecasts[ts_index].mean(0) - stacked_forecasts[ts_index].std(axis=0), \n",
1155 | " stacked_forecasts[ts_index].mean(0) + stacked_forecasts[ts_index].std(axis=0), \n",
1156 | " alpha=0.3, \n",
1157 | " interpolate=True,\n",
1158 | " label=\"+/- 1-std\",\n",
1159 | " )\n",
1160 | " plt.legend()\n",
1161 | " plt.show()\n"
1162 | ]
1163 | },
1164 | {
1165 | "cell_type": "code",
1166 | "execution_count": null,
1167 | "metadata": {
1168 | "id": "Mx1-z52sj7b0"
1169 | },
1170 | "outputs": [],
1171 | "source": [
1172 | "for i in range(10):\n",
1173 | " plot(i)"
1174 | ]
1175 | }
1176 | ],
1177 | "metadata": {
1178 | "colab": {
1179 | "provenance": [],
1180 | "mount_file_id": "1QqoiLYdFijnNSHQEruI6cdzJtOwQAbG3",
1181 | "authorship_tag": "ABX9TyOTzINNjx83ESmDtAMfA1Ak",
1182 | "include_colab_link": true
1183 | },
1184 | "kernelspec": {
1185 | "display_name": "Python 3",
1186 | "name": "python3"
1187 | },
1188 | "language_info": {
1189 | "name": "python"
1190 | }
1191 | },
1192 | "nbformat": 4,
1193 | "nbformat_minor": 0
1194 | }
--------------------------------------------------------------------------------