├── 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 | "\"Open" 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 | } --------------------------------------------------------------------------------