├── LICENSE.txt ├── MNQ 03-22.Last.txt ├── Request.py ├── Strategy.py ├── assets ├── avocado.csv ├── favicon.ico ├── style.css └── tickers.csv ├── config.cfg ├── dashboard.py ├── display.py ├── dist ├── __init__.py ├── __pycache__ │ └── __init__.cpython-310.pyc ├── data │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ └── random.cpython-310.pyc │ ├── crypto.py │ ├── forex.py │ ├── random.py │ ├── stock.py │ └── tickers.py ├── engine │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ ├── abstraction.cpython-310.pyc │ │ ├── backtest.cpython-310.pyc │ │ ├── btv2.cpython-310.pyc │ │ └── optimise.cpython-310.pyc │ ├── abstraction.py │ ├── aliases.py │ ├── backtest.py │ ├── btv2.py │ ├── conversion.py │ └── optimise.py ├── strategies │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ ├── examples.cpython-310.pyc │ │ └── t.cpython-310.pyc │ ├── examples.py │ └── t.py └── utils │ ├── __pycache__ │ ├── calculators.cpython-310.pyc │ ├── listclasses.cpython-310.pyc │ └── series.cpython-310.pyc │ ├── calculators.py │ ├── get_ticker_list.py │ ├── listclasses.py │ └── series.py ├── main.py ├── pages ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-310.pyc │ ├── backtest.cpython-310.pyc │ └── optimise.cpython-310.pyc ├── backtest.py └── optimise.py ├── readme.md ├── requirements.txt ├── t.py └── test.py /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2021] [pyine] 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 | -------------------------------------------------------------------------------- /Request.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | from binance.client import Client 3 | import configparser 4 | 5 | config = configparser.ConfigParser() 6 | config.read('config.cfg') 7 | api = config['BINANCE'] 8 | 9 | class request: 10 | client = Client(api['KEY'], api['SECRET']) 11 | constants = { 12 | '1m':client.KLINE_INTERVAL_1MINUTE , 13 | '3m':client.KLINE_INTERVAL_3MINUTE , 14 | '5m':client.KLINE_INTERVAL_5MINUTE , 15 | '15m':client.KLINE_INTERVAL_15MINUTE , 16 | '30m':client.KLINE_INTERVAL_30MINUTE , 17 | '1h':client.KLINE_INTERVAL_1HOUR , 18 | '2h':client.KLINE_INTERVAL_2HOUR , 19 | '4h':client.KLINE_INTERVAL_4HOUR , 20 | '6h':client.KLINE_INTERVAL_6HOUR , 21 | '8h':client.KLINE_INTERVAL_8HOUR , 22 | '12h':client.KLINE_INTERVAL_12HOUR , 23 | '1d':client.KLINE_INTERVAL_1DAY , 24 | '3d':client.KLINE_INTERVAL_3DAY , 25 | '1w':client.KLINE_INTERVAL_1WEEK , 26 | '1M':client.KLINE_INTERVAL_1MONTH , 27 | } 28 | 29 | def __init__(self) -> None: 30 | pass 31 | 32 | def security(symbol, timeframe): 33 | data = request.client.get_historical_klines(f"{symbol}", request.constants[timeframe]) 34 | d = pd.DataFrame({ 35 | 'time':[int(i[0])/1000 for i in data][:-1], 36 | 'open':[float(i[1]) for i in data][:-1], 37 | 'high':[float(i[2]) for i in data][:-1], 38 | 'low':[float(i[3]) for i in data][:-1], 39 | 'close':[float(i[4]) for i in data][:-1], 40 | 'volume':[float(i[5]) for i in data][:-1], 41 | 'hl2':[(float(i[2])+float(i[3]))/2 for i in data][:-1], 42 | 'hlc3':[(float(i[2])+float(i[3])+float(i[4]))/3 for i in data][:-1], 43 | 'ohlc4':[(float(i[1])+float(i[2])+float(i[3])+float(i[4]))/4 for i in data][:-1], 44 | }) 45 | return d -------------------------------------------------------------------------------- /Strategy.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import configparser 3 | from datetime import datetime 4 | import pandas as pd 5 | from binance.client import Client 6 | from Request import request 7 | 8 | class Strategy: 9 | 10 | CONVERSION = { 11 | 't':'time', 12 | 'o':'open', 13 | 'h':'high', 14 | 'l':'low', 15 | 'c':'close', 16 | 'v':'volume', 17 | 't':'time', 18 | 'T':'TIME', 19 | } 20 | 21 | def __init__(self, ticker="BTCUSDT", timeframe="1m", name=''): 22 | self.data = pd.DataFrame() 23 | 24 | self.cache = pd.DataFrame() 25 | 26 | self.debug = False 27 | 28 | self.ticker = ticker 29 | 30 | self.name = name if name else type(self).__name__ 31 | 32 | self.status = "alive" 33 | 34 | self.alerts = [] 35 | 36 | config = configparser.ConfigParser() 37 | config.read('config.cfg') 38 | self.config = config[self.name] 39 | api = config['BINANCE'] 40 | self.client = Client(api['KEY'], api['SECRET']) 41 | 42 | def calculator(func): 43 | def inner_function(*args, **kwargs): 44 | try: 45 | n = func(*args, **kwargs) 46 | return n 47 | except: 48 | pass 49 | n = inner_function 50 | if n: return n 51 | else: pass 52 | 53 | def reset_data(self): 54 | self.data = pd.DataFrame({ 55 | 'time':[], 56 | 'open':[], 57 | 'high':[], 58 | 'low':[], 59 | 'close':[], 60 | 'volume':[], 61 | }) 62 | 63 | def alertcondition(self, when, title="", message=""): 64 | cond = when.iloc[-1].bool() 65 | if cond: 66 | print(datetime.fromtimestamp(self.data.time.iloc[-1]), self.ticker, message) 67 | l = [] 68 | for i in range(len(when)): 69 | if when.iloc[i].bool() == True: 70 | l.append([self.data.time.iloc[i], message, self.ticker]) 71 | self.alerts.append(l) 72 | 73 | def tick(self): 74 | return "Tick Success" 75 | -------------------------------------------------------------------------------- /assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/assets/favicon.ico -------------------------------------------------------------------------------- /assets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Lato", sans-serif; 3 | margin: 0; 4 | background-color: #F7F7F7; 5 | } 6 | 7 | .header { 8 | background-color: #222222; 9 | height: 288px; 10 | padding: 16px 0 0 0; 11 | } 12 | 13 | .header-emoji { 14 | font-size: 48px; 15 | margin: 0 auto; 16 | text-align: center; 17 | } 18 | 19 | .header-title { 20 | color: #FFFFFF; 21 | font-size: 48px; 22 | font-weight: bold; 23 | text-align: center; 24 | margin: 0 auto; 25 | } 26 | 27 | .header-description { 28 | color: #CFCFCF; 29 | margin: 16px auto; 30 | text-align: center; 31 | } 32 | 33 | .wrapper { 34 | margin-right: auto; 35 | margin-left: auto; 36 | max-width: 1024px; 37 | padding-right: 10px; 38 | padding-left: 10px; 39 | margin-top: 32px; 40 | } 41 | 42 | .card { 43 | margin-bottom: 24px; 44 | box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.18); 45 | } 46 | 47 | .menu { 48 | height: 112px; 49 | width: 912px; 50 | display: flex; 51 | justify-content: space-evenly; 52 | padding-top: 24px; 53 | margin: -80px auto 0 auto; 54 | background-color: #FFFFFF; 55 | box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.18); 56 | } 57 | 58 | .menu2 { 59 | height: 112px; 60 | width: 912px; 61 | display: flex; 62 | justify-content: space-evenly; 63 | padding-top: 24px; 64 | margin: 0px auto 0 auto; 65 | background-color: #FFFFFF; 66 | box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.18); 67 | display: 'none'; 68 | } 69 | 70 | .menu3 { 71 | height: 100px; 72 | width: 912px; 73 | display: flex; 74 | justify-content: space-evenly; 75 | padding-top: 50px; 76 | padding-bottom: 0px; 77 | margin: 0px auto 0 auto; 78 | margin-bottom: 40px; 79 | background-color: #FFFFFF; 80 | box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.18); 81 | display: 'none'; 82 | } 83 | 84 | .Select-control { 85 | width: 256px; 86 | height: 48px; 87 | } 88 | 89 | .Select--single > .Select-control .Select-value, .Select-placeholder { 90 | line-height: 48px; 91 | } 92 | 93 | .Select--multi .Select-value-label { 94 | line-height: 32px; 95 | } 96 | 97 | .menu-title { 98 | margin-bottom: 6px; 99 | font-weight: bold; 100 | color: #079A82; 101 | } 102 | 103 | .input { 104 | width: 246px; 105 | height: 43px; 106 | border: 1px solid lightgray; 107 | margin-top: 1px; 108 | border-radius:4px; 109 | padding-left: 10px; 110 | } 111 | 112 | .output { 113 | width: 236px; 114 | height: 43px; 115 | border: 1px solid lightgray; 116 | margin-top: 1px; 117 | border-radius:4px; 118 | padding-left: 10px; 119 | padding-right: 10px; 120 | } 121 | 122 | .stats { 123 | justify-content: space-evenly; 124 | } -------------------------------------------------------------------------------- /assets/tickers.csv: -------------------------------------------------------------------------------- 1 | No,Ticker,MarketCap,PE,FwdPE,PEG,PS,PB,PC,PFCF,EPSthisY,EPSnextY,EPSpast5Y,EPSnext5Y,Salespast5Y,Price,Change,Volume 2 | 21,AJG,32.43B,34.68,22.30,2.99,3.95,3.77,11.86,27.90,19.40%,13.54%,15.30%,11.60%,5.40%,154.90,1.01%,"306,055" 3 | 22,AKAM,18.25B,30.40,18.66,2.53,5.37,3.93,9.52,17.49,16.10%,4.62%,13.60%,12.00%,7.80%,110.98,0.30%,"1,020,693" 4 | 23,ALB,27.23B,120.47,37.04,4.04,8.22,4.68,45.76,-,-29.90%,52.08%,5.40%,29.83%,2.10%,241.27,5.97%,"574,457" 5 | 24,ALGN,41.70B,52.14,32.18,1.21,10.55,11.35,-,46.58,305.50%,25.59%,66.20%,43.25%,23.90%,520.48,2.93%,"355,953" 6 | 25,ALK,7.37B,15.23,8.80,0.78,1.19,2.02,2.31,15.74,-273.30%,124.27%,-29.50%,19.43%,-8.60%,59.70,4.72%,"1,610,254" 7 | 26,ALL,35.75B,7.36,9.62,-,0.71,1.48,51.81,8.04,20.10%,33.28%,27.20%,-4.00%,3.00%,124.10,-0.56%,"978,810" 8 | 27,ALLE,10.78B,23.24,20.68,2.99,3.73,12.29,21.39,27.71,-20.50%,12.37%,16.30%,7.77%,5.60%,117.91,-0.35%,"728,937" 9 | 28,AMAT,123.60B,20.56,14.76,1.24,5.36,9.67,22.64,31.40,63.40%,9.07%,33.00%,16.54%,16.30%,138.61,5.12%,"4,252,804" 10 | 29,AMCR,17.56B,18.78,13.61,2.70,1.29,3.94,28.05,173.85,55.60%,6.78%,23.80%,6.95%,6.40%,11.82,2.16%,"3,048,927" 11 | 30,AMD,152.29B,44.39,23.94,1.29,9.27,18.43,42.21,47.29,24.70%,17.71%,44.60%,34.37%,30.90%,120.04,5.05%,"97,613,191" 12 | 31,AME,31.19B,30.61,22.44,-,5.62,4.59,86.94,31.06,0.50%,6.70%,9.10%,-1.20%,2.70%,132.21,1.58%,"322,250" 13 | 32,AMGN,126.67B,21.76,11.68,3.05,4.88,15.48,9.80,25.31,-4.40%,9.00%,6.30%,7.13%,3.30%,223.14,-0.50%,"1,187,366" 14 | 33,AMP,34.99B,13.05,10.16,0.49,2.60,6.14,4.48,167.42,-12.30%,15.31%,7.60%,26.39%,-0.40%,308.12,2.38%,"257,563" 15 | 34,AMT,109.23B,42.64,43.77,2.66,12.09,19.70,33.33,60.25,-10.60%,-7.77%,21.90%,16.01%,11.00%,234.29,0.00%,"905,955" 16 | 35,AMZN,1637.94B,47.95,42.78,1.38,3.49,11.43,17.05,-,54.90%,50.94%,67.60%,34.80%,28.10%,3117.33,0.45%,"1,707,044" 17 | 36,ANET,39.66B,49.89,35.43,2.62,14.31,9.77,11.71,43.37,-24.90%,24.85%,36.70%,19.02%,22.60%,131.15,6.78%,"4,836,716" 18 | 37,ANSS,28.88B,59.65,40.01,5.33,15.41,6.38,26.71,48.76,-5.00%,9.50%,12.50%,11.18%,12.30%,323.91,2.14%,"174,710" 19 | 38,ANTM,110.09B,17.96,13.77,1.40,0.79,3.02,20.05,23.17,-2.60%,13.22%,13.90%,12.86%,9.00%,447.78,0.86%,"337,027" 20 | 39,AON,62.51B,50.22,19.21,3.53,5.13,28.56,8.53,26.49,32.50%,10.57%,14.50%,14.21%,3.10%,283.25,1.20%,"414,519" 21 | 40,AOS,11.48B,23.57,18.68,2.95,3.24,5.98,16.76,32.69,-4.40%,7.44%,6.10%,8.00%,2.70%,72.81,2.22%,"465,014" 22 | 41,APA,11.44B,20.26,5.30,-,1.66,-,30.35,3.99,-36.40%,47.72%,14.80%,-,-7.40%,32.21,0.22%,"4,658,502" 23 | 42,APD,55.75B,25.59,20.81,2.28,5.10,3.91,15.14,-,6.60%,13.61%,12.60%,11.20%,6.60%,248.49,2.05%,"671,210" 24 | 43,APH,46.56B,30.02,24.92,2.86,4.28,7.15,37.50,55.89,28.20%,9.69%,14.00%,10.50%,11.60%,76.83,2.02%,"1,127,367" 25 | 44,APTV,37.48B,70.27,22.03,1.42,2.40,4.43,11.94,61.34,-70.30%,39.85%,-8.60%,49.34%,4.90%,143.37,4.95%,"1,341,081" 26 | 45,ARE,31.15B,48.78,43.01,487.83,14.73,1.74,86.20,-,-36.50%,11.75%,31.40%,0.10%,18.10%,186.49,1.56%,"270,018" 27 | 46,ATO,14.26B,20.20,17.95,2.79,4.07,1.71,54.00,-,4.80%,7.11%,9.00%,7.25%,6.80%,105.88,-0.09%,"426,075" 28 | 47,ATVI,63.44B,23.64,18.87,1.44,7.21,3.74,6.34,25.52,44.90%,21.12%,18.80%,16.45%,11.60%,81.61,0.13%,"4,258,450" 29 | 48,AVB,33.46B,31.05,51.38,12.23,15.07,3.08,103.82,129.60,4.70%,14.33%,1.30%,2.54%,4.40%,240.90,1.15%,"206,620" 30 | 49,AVGO,246.35B,38.54,16.04,2.62,8.97,9.57,20.25,34.65,137.10%,9.19%,40.00%,14.74%,15.70%,601.08,3.89%,"1,153,555" 31 | 50,AVY,15.32B,20.57,17.01,2.65,1.82,8.38,73.92,24.91,85.10%,10.74%,17.50%,7.77%,3.20%,186.10,2.38%,"186,000" 32 | 51,AWK,27.04B,35.42,33.19,4.32,6.93,3.92,386.34,-,13.50%,5.02%,8.10%,8.20%,3.60%,147.09,-0.64%,"926,017" 33 | 52,AXP,151.86B,19.25,16.94,0.56,3.54,6.19,5.56,18.17,-52.90%,17.14%,-5.70%,34.57%,2.20%,197.66,2.76%,"2,037,846" 34 | 53,AZO,39.51B,18.64,16.39,1.33,2.61,-,41.11,13.67,32.30%,10.56%,18.50%,14.00%,6.60%,1934.43,0.51%,"85,426" 35 | 54,BA,126.17B,-,29.39,-,2.03,-,7.77,-,65.80%,124.18%,-23.80%,20.17%,-7.80%,218.60,4.08%,"7,708,444" 36 | 55,BAC,397.24B,13.32,12.51,0.56,8.33,1.61,0.45,-,-32.00%,16.25%,7.40%,23.89%,0.80%,47.94,1.09%,"26,516,469" 37 | 56,BAX,43.70B,35.86,19.59,3.21,3.51,4.87,13.41,44.55,37.10%,20.83%,24.40%,11.17%,3.20%,85.81,0.42%,"845,513" 38 | 57,BBWI,15.02B,11.58,11.51,0.67,1.55,-,10.43,48.62,326.50%,6.29%,-6.60%,17.36%,-0.50%,55.73,1.27%,"1,440,297" 39 | 58,BBY,24.19B,9.76,10.83,1.04,0.46,5.80,-,35.05,18.90%,-7.26%,24.30%,9.40%,3.60%,102.51,1.86%,"853,603" 40 | 59,BDX,77.13B,46.48,19.24,5.11,3.87,3.17,40.36,46.77,152.40%,8.08%,8.80%,9.10%,10.20%,271.31,0.90%,"385,888" 41 | 60,BEN,15.64B,8.03,7.94,2.19,1.81,1.29,3.44,33.27,124.60%,1.11%,4.00%,3.67%,4.90%,31.15,2.47%,"717,077" 42 | 61,BF-B,31.01B,41.59,34.80,3.93,8.56,10.88,28.90,67.41,9.10%,14.26%,-2.10%,10.59%,2.30%,66.41,0.06%,"488,048" 43 | 62,BIIB,32.27B,20.60,13.18,-,2.94,2.88,8.49,8.91,-58.10%,5.38%,-9.30%,-9.20%,-0.80%,216.27,1.01%,"298,207" 44 | 63,BIO,18.46B,4.43,38.86,0.25,6.31,1.21,13.80,31.47,116.60%,7.97%,101.00%,17.80%,4.70%,621.77,0.13%,"142,518" 45 | 64,BK,51.69B,15.54,10.65,1.23,17.12,1.33,0.26,-,-15.10%,21.21%,7.20%,12.65%,4.30%,62.37,1.46%,"2,355,086" 46 | 65,BKNG,108.60B,283.92,25.62,-,11.78,18.85,8.93,63.99,-98.90%,132.14%,-52.20%,-,-5.90%,2627.19,3.20%,"260,603" 47 | 66,BKR,27.86B,-,16.64,-,1.36,1.44,6.44,57.56,2200.00%,35.36%,-27.10%,50.90%,5.60%,28.68,0.51%,"3,119,138" 48 | 67,BLK,116.36B,19.90,16.02,1.57,6.01,3.14,15.81,74.88,12.10%,11.60%,10.00%,12.66%,7.30%,782.51,2.92%,"263,468" 49 | 68,BLL,29.96B,34.82,19.51,2.36,2.17,8.12,20.72,141.34,1.10%,16.13%,11.10%,14.78%,8.10%,92.38,0.10%,"446,584" 50 | 69,BMY,144.82B,21.42,8.06,4.28,3.12,4.09,8.54,13.36,178.00%,6.38%,3.30%,5.00%,19.00%,67.55,1.11%,"9,588,881" 51 | 70,BR,17.13B,31.70,20.53,2.69,3.19,9.66,60.91,110.78,17.60%,9.65%,12.90%,11.80%,11.50%,147.26,1.67%,"438,115" 52 | 71,BRK-B,763.70B,-,24.63,-,2.84,0.00,-,-,28.40%,8.50%,-,23.30%,-,315.82,0.49%,"1,574,553" 53 | 72,BRO,19.24B,32.15,25.85,2.43,6.51,4.44,20.08,31.28,20.10%,9.11%,14.70%,13.22%,9.50%,66.83,1.29%,"429,798" 54 | 73,BSX,61.79B,62.29,21.34,3.86,5.20,3.70,31.74,33.33,-119.10%,13.36%,14.60%,16.15%,5.80%,43.99,2.95%,"3,833,305" 55 | 74,BWA,10.41B,13.28,9.19,0.44,0.69,1.53,6.91,10.70,-37.10%,21.10%,-1.80%,30.25%,4.80%,45.22,5.75%,"2,001,167" 56 | 75,BXP,17.94B,36.90,33.21,5.27,6.21,3.20,17.90,51.40,68.00%,14.65%,8.30%,7.00%,2.10%,120.48,3.02%,"395,069" 57 | 76,C,132.56B,6.59,8.17,0.97,2.63,0.73,0.13,9.46,-41.10%,7.41%,-2.70%,6.83%,-0.20%,67.29,1.24%,"7,885,918" 58 | 77,CAG,16.57B,15.50,13.25,9.34,1.48,1.95,241.17,105.13,54.90%,8.78%,59.30%,1.66%,5.20%,35.37,0.18%,"1,383,564" 59 | 78,CAH,14.56B,27.36,8.83,5.36,0.08,14.61,4.61,26.42,116.50%,11.82%,-13.60%,5.10%,6.00%,53.48,2.28%,"1,044,539" 60 | 79,CARR,39.71B,23.96,17.51,2.00,1.93,5.73,13.29,26.90,-17.00%,12.05%,-,12.01%,-,45.70,2.03%,"2,369,792" 61 | 80,CAT,109.11B,16.88,13.88,0.80,2.14,6.53,-,23.30,-49.00%,18.01%,4.90%,20.97%,-2.30%,203.79,1.95%,"1,305,576" 62 | 81,CB,88.98B,10.49,12.38,0.35,2.17,1.48,54.92,8.99,-19.70%,10.38%,-2.00%,29.79%,13.50%,203.79,0.85%,"810,444" 63 | 82,CBOE,12.95B,24.49,18.73,5.21,3.70,3.68,30.89,8.87,28.20%,5.49%,11.70%,4.70%,40.10%,120.81,0.19%,"237,710" 64 | 83,CBRE,33.74B,22.87,17.23,2.08,1.29,4.14,12.19,17.10,-41.00%,6.94%,6.40%,11.00%,17.00%,99.96,1.79%,"540,216" 65 | 84,CCI,74.22B,62.69,40.20,5.06,11.71,8.50,207.89,-,31.50%,7.61%,10.30%,12.40%,9.80%,166.79,-0.47%,"988,843" 66 | 85,CCL,25.24B,-,11.34,-,13.22,1.99,2.76,-,35.90%,750.00%,-33.70%,9.95%,-35.00%,22.69,6.23%,"23,958,474" 67 | 86,CDAY,11.32B,-,111.92,-,11.06,4.74,29.89,-,-105.20%,64.91%,47.30%,12.50%,4.00%,71.12,1.68%,"651,562" 68 | 87,CDNS,41.14B,57.27,39.88,3.15,13.83,14.75,40.58,43.78,-40.10%,13.40%,21.20%,18.20%,9.50%,145.61,2.48%,"489,014" 69 | 88,CDW,24.52B,25.03,17.02,1.91,1.18,28.87,100.03,29.78,9.20%,11.46%,18.30%,13.10%,7.30%,184.41,4.72%,"608,535" 70 | 89,CE,17.26B,9.05,9.58,-,2.02,4.00,31.62,17.51,1.20%,1.97%,22.50%,-2.22%,9.60%,158.63,2.89%,"211,370" 71 | 90,CERN,26.85B,53.51,24.78,3.96,4.70,7.07,34.33,-,53.10%,12.23%,10.40%,13.52%,4.50%,92.10,0.47%,"985,316" 72 | 91,CF,14.73B,51.82,6.44,0.83,2.89,5.23,19.46,15.71,-33.80%,142.93%,-13.10%,62.70%,-0.90%,72.70,1.74%,"2,382,343" 73 | 92,CFG,23.09B,10.40,10.57,-,4.76,1.07,1.46,-,-41.70%,19.55%,7.50%,-2.76%,6.80%,55.06,2.61%,"1,830,071" 74 | 93,CHD,23.81B,29.43,28.05,3.76,4.59,6.81,132.26,62.37,27.60%,8.52%,15.20%,7.83%,7.60%,97.25,-0.33%,"752,313" 75 | 94,CHRW,11.70B,14.16,15.35,1.15,0.51,6.03,57.77,-,-11.20%,-7.63%,1.20%,12.30%,3.80%,89.96,0.84%,"474,043" 76 | 95,CHTR,105.33B,24.49,15.98,0.76,2.04,7.60,175.25,12.24,58.90%,23.39%,8.90%,32.03%,12.20%,610.57,0.43%,"1,783,408" 77 | 96,CI,75.56B,9.46,8.97,0.85,0.44,1.59,21.69,16.26,70.90%,11.67%,23.40%,11.15%,33.40%,227.41,0.96%,"1,119,564" 78 | 97,CINF,19.48B,7.69,23.12,0.53,2.16,1.63,17.95,13.12,-38.10%,-10.68%,14.40%,14.39%,7.90%,120.91,1.20%,"335,736" 79 | 98,CL,66.96B,31.06,22.07,4.68,3.84,113.23,63.29,67.23,14.10%,8.23%,15.60%,6.63%,0.50%,78.91,-0.44%,"2,193,169" 80 | 99,CLX,17.27B,71.80,24.00,-,2.44,56.28,89.93,1015.70,-24.20%,37.23%,2.50%,-3.53%,5.00%,142.95,-0.00%,"519,079" 81 | 100,CMA,13.04B,11.76,12.66,-,6.86,1.76,0.55,-,-56.50%,25.68%,3.80%,-10.70%,3.20%,100.47,2.63%,"327,152" 82 | 101,CMCSA,220.74B,15.59,11.90,1.09,1.90,2.25,25.34,14.30,33.50%,12.17%,11.30%,14.31%,7.60%,48.12,1.51%,"9,119,243" 83 | 102,CME,87.03B,32.56,29.69,4.22,18.56,3.14,55.45,-,-0.60%,8.21%,9.70%,7.71%,8.00%,239.21,0.02%,"788,067" 84 | 103,CMG,44.46B,68.27,37.68,2.35,5.89,19.14,41.31,52.96,82.90%,31.16%,97.10%,29.02%,14.10%,1572.09,0.52%,"122,173" 85 | 104,CMI,31.40B,15.04,10.92,1.40,1.31,3.70,9.85,44.04,21.60%,14.65%,12.20%,10.72%,6.50%,222.94,1.59%,"385,721" 86 | 105,CMS,17.90B,24.21,19.96,3.72,2.44,2.82,39.59,-,4.00%,8.92%,4.00%,6.50%,2.80%,62.24,-0.24%,"589,788" 87 | 106,CNC,48.33B,36.14,12.98,3.38,0.38,1.81,3.60,16.88,-0.60%,16.82%,16.60%,10.69%,37.30%,83.72,2.09%,"934,874" 88 | 107,CNP,17.06B,19.44,19.15,10.80,2.11,2.02,16.34,-,-229.10%,-5.83%,2.10%,1.80%,0.10%,27.09,0.69%,"1,587,613" 89 | 108,COF,66.67B,5.78,8.06,0.13,2.59,1.18,2.50,5.55,-53.00%,-4.36%,-5.80%,45.90%,4.90%,159.45,2.78%,"913,166" 90 | 109,COO,19.72B,6.61,24.08,0.66,6.75,2.77,205.59,37.72,8.70%,13.10%,60.30%,10.00%,8.20%,397.28,1.52%,"64,868" 91 | 110,COP,118.67B,15.09,11.66,8.50,2.59,2.77,11.29,55.79,-139.20%,-9.72%,6.80%,1.78%,-8.60%,89.36,-2.39%,"4,934,152" 92 | 111,COST,228.51B,43.59,35.95,4.37,1.13,12.17,16.96,7371.26,25.00%,9.32%,16.20%,9.98%,10.50%,514.39,1.55%,"649,938" 93 | 112,CPB,13.00B,13.96,15.18,6.17,1.55,4.11,188.36,30.51,69.70%,3.98%,12.80%,2.27%,1.30%,44.27,0.55%,"799,177" 94 | 113,CPRT,30.82B,29.63,26.56,1.33,10.59,7.67,23.74,46.40,32.90%,7.24%,28.60%,22.30%,16.20%,126.28,2.89%,"458,015" 95 | 114,CRL,16.95B,42.40,28.24,2.72,4.95,6.80,79.41,37.51,41.90%,12.90%,17.90%,15.56%,16.50%,311.82,-4.77%,"690,139" 96 | 115,CRM,212.86B,112.36,43.65,11.22,8.52,3.55,22.67,38.75,-4.90%,1.05%,129.30%,10.02%,26.10%,211.84,2.64%,"2,809,510" 97 | 116,CSCO,228.33B,19.77,14.44,3.03,4.50,5.25,9.78,28.76,-5.20%,7.60%,3.40%,6.53%,0.20%,54.18,1.88%,"8,645,175" 98 | 117,CSX,76.63B,20.23,17.36,1.23,6.12,5.77,-,36.90,-13.70%,8.74%,12.50%,16.46%,-2.20%,34.68,2.24%,"8,570,579" 99 | 118,CTAS,39.06B,34.58,30.93,2.91,5.26,10.78,345.04,42.01,26.30%,9.43%,20.60%,11.90%,8.20%,376.37,1.58%,"174,731" 100 | 119,CTLT,18.11B,30.39,23.68,1.92,4.04,3.86,19.79,-,174.00%,11.47%,28.60%,15.80%,16.70%,99.74,0.77%,"507,115" 101 | 120,CTRA,18.02B,26.58,6.82,0.36,10.72,3.99,236.19,60.41,-69.30%,16.56%,30.70%,74.49%,1.60%,22.92,-1.31%,"3,152,939" 102 | 121,CTSH,46.81B,21.29,16.95,1.85,2.53,3.92,19.40,27.60,-21.80%,11.72%,-0.60%,11.49%,6.00%,88.79,2.96%,"1,414,508" 103 | 122,CTVA,37.03B,20.92,17.55,0.93,2.37,1.46,8.15,21.07,149.40%,16.46%,29.80%,22.39%,2.40%,50.97,0.15%,"1,291,182" 104 | 123,CTXS,12.74B,41.87,17.66,6.44,3.96,31.76,28.32,36.77,-20.50%,11.77%,24.40%,6.50%,4.10%,102.07,0.11%,"1,878,210" 105 | 124,CVS,136.59B,17.29,11.48,3.01,0.47,1.81,10.91,10.41,8.80%,8.15%,3.90%,5.74%,10.50%,103.08,0.08%,"2,602,094" 106 | 125,CVX,258.20B,16.80,14.82,-,1.66,1.93,42.80,-,-291.90%,-11.97%,-26.20%,-4.90%,-6.10%,134.48,-1.60%,"8,096,052" 107 | 126,CZR,17.93B,-,76.70,-,2.12,3.55,-,113.51,72.90%,135.80%,-49.90%,27.50%,37.00%,84.74,4.32%,"993,287" 108 | 127,D,63.12B,24.79,17.99,3.62,4.64,2.60,350.66,-,119.90%,6.19%,-11.90%,6.85%,3.90%,78.84,0.11%,"1,007,789" 109 | 128,DAL,27.86B,101.13,7.35,7.60,0.93,10.26,2.11,-,-366.80%,187.94%,-40.40%,13.31%,-15.90%,44.47,5.97%,"10,552,576" 110 | 129,DD,41.64B,24.75,14.39,1.80,2.50,1.55,-,19.83,-314.70%,15.34%,-17.30%,13.73%,-16.00%,81.56,2.82%,"776,926" 111 | 130,DE,119.50B,20.39,15.37,1.59,2.72,6.50,14.91,20.47,118.60%,13.46%,31.60%,12.84%,10.50%,394.89,1.97%,"804,807" 112 | 131,DFS,36.57B,7.43,8.83,0.13,3.43,3.03,2.88,6.98,-60.40%,0.26%,-6.90%,56.42%,6.90%,128.15,3.21%,"873,172" 113 | 132,DG,46.82B,19.64,17.90,2.97,1.38,7.54,95.81,38.17,60.00%,10.18%,21.90%,6.62%,10.60%,200.15,-0.23%,"808,752" 114 | 133,DGX,16.15B,8.38,15.37,-,1.50,2.51,16.36,8.66,70.70%,-6.26%,16.60%,-10.24%,4.70%,131.36,0.82%,"607,862" 115 | 134,DHI,29.67B,6.65,4.97,0.61,1.03,1.88,12.15,142.78,78.00%,5.98%,37.00%,10.95%,18.00%,84.63,2.03%,"1,345,459" 116 | 135,DHR,200.80B,32.07,24.72,1.90,6.82,4.83,78.68,32.47,49.80%,5.01%,14.60%,16.87%,9.10%,271.39,-0.04%,"1,192,280" 117 | 136,DIS,279.59B,87.65,26.85,2.03,3.83,3.05,19.36,188.53,170.70%,29.54%,-28.00%,43.17%,3.90%,154.62,2.50%,"7,595,733" 118 | 137,DISCA,15.11B,15.70,9.20,3.18,1.27,1.28,4.85,7.26,-37.10%,16.12%,11.60%,4.93%,10.80%,30.35,3.18%,"2,233,650" 119 | 138,DISCK,-,19.62,9.19,0.98,-,1.66,-,-,-15.30%,17.70%,-,20.00%,-,30.20,2.98%,"1,627,357" 120 | 139,DISH,16.72B,7.43,11.05,-,0.93,1.09,3.19,5.50,15.90%,-22.53%,11.90%,-,0.30%,32.08,3.60%,"785,556" 121 | 140,DLR,39.75B,57.54,89.33,2.48,9.08,2.33,342.64,-,-57.40%,-39.60%,-8.50%,23.19%,17.20%,137.45,0.96%,"770,981" 122 | 141,DLTR,30.92B,23.12,18.35,1.55,1.19,4.25,44.09,87.50,62.90%,34.31%,34.90%,14.90%,10.50%,138.26,0.95%,"960,549" 123 | 142,DOV,23.75B,20.83,17.03,1.44,3.00,5.96,32.13,31.69,1.90%,9.92%,4.70%,14.50%,-0.80%,163.20,1.27%,"267,681" 124 | 143,DOW,44.65B,7.26,9.23,0.13,0.81,2.47,-,7.07,411.70%,-1.38%,7.80%,56.83%,2.70%,61.91,1.78%,"2,413,903" 125 | 144,DPZ,15.93B,32.73,28.22,2.69,3.64,-,34.47,32.73,29.70%,12.01%,29.00%,12.16%,13.20%,431.36,0.15%,"161,988" 126 | 145,DRE,21.05B,24.28,56.76,4.05,19.04,3.48,2126.68,-,-31.60%,11.61%,8.50%,6.00%,4.60%,54.58,0.06%,"633,779" 127 | 146,DRI,18.63B,20.49,16.97,0.68,2.17,7.29,24.96,39.28,75.60%,12.00%,11.50%,30.10%,0.70%,146.62,2.23%,"394,468" 128 | 147,DTE,22.43B,29.34,18.52,4.89,1.65,2.57,800.99,10.50,-24.90%,5.86%,-3.30%,6.00%,7.10%,117.21,1.00%,"846,758" 129 | 148,DUK,76.93B,20.25,17.34,5.47,3.07,1.62,-,-,-66.40%,5.45%,-14.80%,3.70%,1.30%,99.79,-0.16%,"1,502,755" 130 | 149,DVA,11.56B,12.81,11.19,0.96,1.00,10.36,10.78,10.29,39.30%,23.47%,38.60%,13.37%,-3.50%,116.62,2.61%,"315,143" 131 | 150,DVN,34.14B,30.23,9.48,1.21,3.83,3.93,14.71,12.41,3855.60%,64.25%,26.40%,25.00%,-18.20%,51.29,-1.85%,"7,356,207" 132 | 151,DXC,9.20B,-,8.40,-,0.55,1.92,3.15,13.15,97.10%,19.05%,-27.90%,29.10%,20.10%,37.38,1.89%,"565,450" 133 | 152,DXCM,41.49B,76.52,85.94,4.14,17.89,18.47,15.38,412.79,362.20%,37.79%,55.20%,18.50%,36.80%,415.92,2.19%,"318,862" 134 | 153,EA,37.76B,60.04,17.68,2.59,5.80,4.96,12.52,25.76,-72.20%,9.09%,-3.90%,23.16%,5.10%,133.98,0.43%,"739,889" 135 | 154,EBAY,36.69B,20.73,12.89,1.66,3.44,3.44,2.52,17.11,99.90%,13.74%,17.30%,12.49%,3.60%,59.59,2.42%,"1,615,725" 136 | 155,ECL,53.25B,46.66,32.98,2.69,4.28,7.56,59.30,55.77,-36.60%,16.86%,0.30%,17.33%,-2.70%,182.68,-0.13%,"1,208,682" 137 | 156,ED,29.29B,24.78,18.53,12.39,2.22,1.46,443.75,19.08,-19.50%,5.96%,-4.10%,2.00%,-0.50%,82.00,-1.23%,"535,082" 138 | 157,EFX,27.72B,36.68,21.67,2.70,5.63,7.61,13.69,49.38,228.40%,16.52%,3.60%,13.60%,9.20%,222.43,0.66%,"609,224" 139 | 158,EIX,22.94B,29.96,13.18,5.16,1.56,1.68,43.78,-,-47.50%,2.17%,-8.00%,5.80%,3.30%,60.21,0.25%,"1,080,284" 140 | 159,EL,114.36B,34.33,35.07,2.27,6.45,17.62,24.84,61.52,318.10%,13.76%,21.40%,15.09%,7.60%,309.54,1.87%,"459,104" 141 | 160,EMN,16.32B,19.20,11.42,1.30,1.56,2.67,22.76,17.66,-36.10%,8.91%,-9.20%,14.81%,-2.60%,123.36,2.21%,"388,757" 142 | 161,EMR,57.07B,20.49,17.20,1.96,3.08,5.45,12.08,38.02,18.10%,8.93%,9.30%,10.46%,4.70%,95.00,1.10%,"1,413,000" 143 | 162,ENPH,20.61B,140.97,36.38,9.04,14.91,29.92,14.78,81.11,-22.90%,28.03%,31.30%,15.60%,16.70%,154.25,7.17%,"1,867,212" 144 | 163,EOG,64.03B,21.93,10.64,0.30,4.12,3.03,14.92,12.69,-122.20%,23.49%,33.90%,73.84%,4.80%,110.64,-2.45%,"2,401,277" 145 | 164,EPAM,26.79B,59.37,38.34,2.08,7.94,10.36,21.15,71.70,23.70%,27.07%,28.10%,28.50%,23.80%,459.20,7.30%,"467,518" 146 | 165,EQIX,61.72B,140.95,87.65,3.81,9.51,5.69,44.76,-,-30.20%,38.00%,5.40%,37.00%,17.10%,678.70,1.39%,"196,924" 147 | 166,EQR,32.49B,25.10,49.41,3.86,13.18,3.03,818.27,107.04,-5.70%,19.03%,0.80%,6.50%,-1.30%,86.87,1.11%,"640,486" 148 | 167,ES,28.46B,23.88,20.03,3.79,2.96,1.96,322.63,-,26.00%,6.51%,5.10%,6.30%,2.30%,82.39,0.23%,"1,375,912" 149 | 168,ESS,20.65B,42.20,53.27,5.34,14.34,3.46,413.85,90.70,30.20%,13.60%,20.00%,7.90%,4.60%,320.62,1.35%,"117,747" 150 | 169,ETN,62.32B,28.51,18.34,1.53,3.17,3.80,94.42,56.91,-33.60%,10.70%,-3.70%,18.61%,-3.10%,155.58,2.24%,"1,013,211" 151 | 170,ETR,21.13B,16.89,16.48,2.81,1.85,1.87,21.13,15.76,9.60%,6.25%,55.20%,6.00%,-2.60%,104.00,-0.48%,"469,578" 152 | 171,ETSY,18.25B,41.88,39.75,0.93,8.18,33.88,22.34,30.48,272.90%,17.48%,45.80%,44.90%,44.50%,145.70,2.14%,"1,120,182" 153 | 172,EVRG,14.32B,16.19,17.52,3.16,2.58,1.53,566.12,-,-2.70%,-0.81%,5.40%,5.12%,14.80%,61.69,-0.35%,"717,449" 154 | 173,EW,68.27B,45.23,37.01,2.90,13.05,12.12,38.04,64.97,-21.00%,13.67%,11.70%,15.57%,12.00%,110.00,2.10%,"1,123,798" 155 | 174,EXC,41.20B,24.71,18.81,1.54,1.18,1.22,13.93,-,-33.30%,-20.14%,-4.60%,16.00%,2.30%,41.92,-0.68%,"3,872,598" 156 | 175,EXPD,18.57B,15.82,16.74,2.03,1.30,5.31,10.20,31.90,20.20%,-16.14%,11.10%,7.80%,8.90%,108.04,0.97%,"371,115" 157 | 176,EXPE,30.72B,-,18.35,-,4.24,14.73,7.13,9.99,90.50%,39.68%,-24.40%,22.80%,-0.40%,209.26,6.13%,"3,567,676" 158 | 177,EXR,26.26B,36.10,34.82,6.02,17.47,8.69,400.29,73.19,14.70%,5.92%,18.90%,6.00%,11.60%,193.79,-0.22%,"251,763" 159 | 178,F,72.03B,3.94,7.57,0.05,0.53,1.44,1.45,7.87,363.40%,11.83%,31.10%,74.15%,-2.10%,18.05,3.35%,"35,888,460" 160 | 179,FANG,22.74B,67.71,7.36,1.11,4.10,2.06,49.76,7.91,269.40%,58.66%,-27.70%,61.03%,44.50%,127.11,-2.58%,"1,426,314" 161 | 180,FAST,30.41B,32.39,26.65,5.12,5.06,9.81,128.73,-,7.40%,8.89%,13.20%,6.33%,8.70%,52.35,0.83%,"1,104,686" 162 | 181,FB,615.56B,15.79,14.59,0.74,5.22,4.82,12.82,15.74,36.40%,18.20%,31.60%,21.35%,33.70%,217.90,0.09%,"25,622,955" 163 | 182,FBHS,12.22B,16.13,12.41,1.73,1.60,4.03,26.54,23.73,29.10%,11.78%,16.00%,9.30%,5.90%,90.76,1.70%,"551,144" 164 | 183,FCX,63.95B,22.20,13.78,0.77,3.38,4.67,8.34,10.82,344.60%,-17.91%,15.30%,28.90%,-0.60%,43.17,1.68%,"8,933,075" 165 | 184,FDS,15.16B,37.99,29.27,3.92,9.31,13.71,21.39,41.22,7.40%,9.97%,4.80%,9.70%,7.10%,407.96,1.98%,"81,476" 166 | 185,FDX,62.67B,13.24,9.98,0.75,0.70,2.43,9.17,30.71,276.30%,10.66%,23.10%,17.73%,10.80%,233.85,2.36%,"1,059,083" 167 | 186,FE,22.11B,21.72,15.80,-,2.01,2.96,38.31,-,11.20%,6.35%,6.30%,-6.60%,-6.40%,40.76,0.04%,"1,661,416" 168 | 187,FFIV,12.07B,35.54,15.25,2.78,4.53,4.90,14.05,21.48,6.60%,19.44%,-0.20%,12.80%,5.50%,200.37,3.39%,"265,590" 169 | 188,FIS,68.97B,304.64,15.29,21.27,5.10,1.45,13.90,17.67,-61.90%,11.53%,-35.20%,14.32%,13.70%,101.92,-8.59%,"6,138,512" 170 | 189,FISV,65.81B,49.24,13.20,3.14,4.06,2.05,70.54,19.73,-18.00%,15.03%,-1.30%,15.69%,23.10%,97.04,-0.87%,"2,824,120" 171 | 190,FITB,33.37B,12.93,12.46,-,6.40,1.65,0.88,-,-45.10%,13.72%,-1.80%,-2.98%,6.70%,49.33,2.29%,"1,881,021" 172 | 191,FLT,19.94B,24.50,13.97,1.57,7.04,6.31,15.69,21.23,-18.30%,14.48%,16.10%,15.65%,7.00%,245.70,0.41%,"262,236" 173 | 192,FMC,14.60B,26.10,13.28,3.26,3.12,4.90,42.82,42.93,8.40%,12.70%,38.80%,8.00%,7.20%,117.91,1.87%,"208,267" 174 | 193,FOX,22.74B,13.10,16.49,1.42,1.72,1.93,-,-,-,14.60%,-,9.20%,-,39.08,0.85%,"524,173" 175 | 194,FOXA,23.39B,17.41,11.68,2.90,1.72,2.15,5.50,21.68,122.80%,24.62%,15.90%,6.00%,7.70%,43.02,0.82%,"1,240,530" 176 | 195,FRC,31.49B,22.37,17.97,1.32,7.18,2.57,2.29,-,11.80%,15.80%,12.80%,16.93%,18.30%,173.56,1.04%,"566,933" 177 | 196,FRT,9.48B,39.06,43.28,5.83,10.34,3.78,58.46,131.44,100.70%,20.33%,1.30%,6.70%,3.50%,120.09,1.67%,"182,632" 178 | 197,FTI,2.89B,17.10,37.78,-,0.35,0.86,1.85,4.24,-35.90%,266.70%,-11.63%,-,2.60%,6.68,0.38%,"7,841,989" 179 | 198,FTNT,53.21B,85.43,51.73,4.88,15.92,45.37,17.05,48.01,54.70%,21.07%,129.90%,17.50%,20.80%,318.34,2.58%,"319,337" 180 | 199,FTV,23.50B,39.74,18.91,1.05,4.47,2.51,28.03,-,558.00%,10.90%,9.00%,37.89%,-5.60%,65.81,1.17%,"842,017" 181 | 200,GD,58.03B,18.28,15.13,1.67,1.51,3.33,36.20,28.32,5.00%,15.10%,6.00%,10.95%,4.70%,213.94,1.31%,"337,405" 182 | 201,GE,108.23B,-,18.28,-,1.46,2.83,3.58,1745.61,2450.00%,54.67%,38.20%,7.00%,-8.00%,101.29,4.86%,"3,919,524" 183 | 202,GILD,76.31B,12.38,9.31,165.11,2.79,3.58,13.30,15.44,-97.70%,0.57%,-61.80%,0.07%,-5.40%,61.28,0.27%,"4,994,580" 184 | 203,GIS,40.21B,18.63,17.20,4.03,2.16,4.32,39.38,31.57,6.30%,4.35%,6.40%,4.63%,1.80%,67.10,-0.78%,"1,365,191" 185 | 204,GL,10.59B,14.41,11.36,1.40,2.07,1.23,109.95,8.24,-0.10%,11.62%,10.90%,10.31%,4.70%,105.70,1.61%,"205,520" 186 | 205,GLW,35.76B,34.04,15.38,1.54,2.54,2.90,16.17,38.57,-49.80%,13.63%,-11.70%,22.14%,4.40%,42.18,2.16%,"1,512,438" 187 | 206,GM,72.50B,7.22,6.57,0.47,0.57,1.18,2.53,9.68,54.70%,5.10%,2.20%,15.20%,-3.20%,49.77,2.83%,"8,141,540" 188 | 207,GNRC,17.90B,32.59,23.36,4.07,5.22,9.51,42.24,39.60,37.20%,21.06%,37.40%,8.00%,13.50%,275.00,1.68%,"568,127" 189 | 208,GOOG,1857.57B,26.07,24.10,1.24,7.77,7.35,-,-,84.90%,3.60%,-,21.00%,-,2719.22,0.49%,"697,192" 190 | 209,GOOGL,1849.33B,24.15,20.04,1.15,7.18,7.14,13.24,27.60,91.40%,16.72%,32.10%,21.00%,23.30%,2724.37,0.51%,"751,081" 191 | 210,GPC,18.20B,22.55,17.29,4.90,0.99,5.70,19.80,19.41,-74.60%,9.44%,-24.60%,4.60%,1.60%,129.60,2.00%,"277,464" 192 | 211,GPN,42.30B,44.70,13.21,2.44,4.96,1.64,18.02,20.96,-10.10%,16.75%,-0.90%,18.31%,20.70%,143.81,-2.14%,"1,749,666" 193 | 212,GPS,6.22B,15.49,7.91,3.16,0.38,2.07,5.78,-,-308.80%,43.15%,-24.10%,4.90%,-2.70%,15.37,0.00%,"9,635,091" 194 | 213,GRMN,23.41B,20.61,19.36,2.63,4.74,3.97,11.80,41.53,3.60%,9.67%,16.70%,7.83%,8.20%,120.77,0.01%,"591,214" 195 | 214,GS,123.10B,6.07,8.67,0.51,1.89,1.30,0.58,2.07,17.70%,3.32%,15.30%,11.97%,7.40%,363.58,0.93%,"953,220" 196 | 215,GWW,24.33B,23.38,17.03,1.62,1.87,13.19,74.17,39.95,-16.60%,11.58%,2.30%,14.44%,3.40%,472.77,1.37%,"113,689" 197 | 216,HAL,28.12B,19.84,13.83,0.32,1.84,4.31,9.24,29.56,148.90%,32.88%,17.50%,62.70%,-0.80%,32.40,0.11%,"6,279,159" 198 | 217,HAS,13.12B,27.96,16.10,1.58,2.04,4.33,11.11,16.86,-60.10%,11.99%,-14.60%,17.70%,4.20%,96.69,2.25%,"550,508" 199 | 218,HBAN,22.89B,17.25,10.76,-,5.46,1.33,1.89,28.02,-45.20%,9.95%,-3.00%,-2.15%,11.50%,16.20,3.22%,"2,295,722" 200 | 219,HCA,73.97B,11.07,11.35,0.77,1.26,-,72.03,234.84,8.50%,9.46%,17.00%,14.42%,5.40%,241.77,2.70%,"606,038" 201 | 220,HD,372.14B,23.51,21.70,1.68,2.52,355.11,73.44,71.09,16.50%,4.74%,16.90%,14.00%,8.30%,353.83,0.65%,"1,458,859" 202 | 221,HES,28.18B,52.42,16.75,-,3.77,5.20,11.65,19.02,-641.90%,13.76%,0.90%,-,-6.40%,93.46,-1.34%,"2,096,538" 203 | 222,HIG,24.18B,10.49,8.80,0.90,1.08,1.37,104.22,6.83,-16.20%,16.71%,11.10%,11.71%,5.00%,71.41,2.51%,"680,613" 204 | 223,HII,7.09B,13.40,10.28,19.15,0.74,2.60,11.32,29.20,-21.30%,18.73%,2.10%,0.70%,6.10%,182.26,0.55%,"146,155" 205 | 224,HLT,43.53B,1231.14,36.94,-,8.99,-,33.79,-,-185.00%,85.90%,-24.40%,-,-9.60%,157.44,3.97%,"2,380,408" 206 | 225,HOLX,17.86B,10.56,18.34,6.21,3.25,3.94,12.57,8.19,71.00%,-25.18%,44.20%,1.70%,14.70%,70.44,0.18%,"637,202" 207 | 226,HON,131.79B,23.60,19.42,2.25,3.83,7.22,10.86,52.97,-16.30%,11.53%,2.20%,10.50%,-3.30%,189.48,1.49%,"1,305,034" 208 | 227,HPE,22.01B,6.57,7.69,0.37,0.79,1.11,5.51,8.02,3.10%,8.03%,6.70%,17.77%,-1.70%,17.43,3.35%,"3,178,774" 209 | 228,HPQ,40.36B,6.69,8.31,0.39,0.64,-,9.38,8.25,166.10%,5.33%,28.40%,17.29%,5.60%,37.31,2.18%,"3,632,493" 210 | 229,HRL,25.33B,28.59,22.48,4.03,2.22,3.69,39.90,102.78,-0.10%,7.76%,0.20%,7.10%,3.60%,47.53,0.14%,"861,628" 211 | 230,HSIC,10.53B,17.24,16.38,0.93,0.86,3.05,88.43,14.57,-40.20%,1.09%,-0.30%,18.56%,-1.00%,80.92,6.77%,"990,592" 212 | 231,HST,13.14B,-,102.46,-,6.09,2.09,11.18,-,-182.40%,152.00%,-27.70%,28.40%,-21.30%,18.57,3.57%,"5,009,285" 213 | 232,HSY,41.53B,28.60,24.06,3.23,4.63,11.71,61.48,42.39,11.90%,6.46%,21.30%,8.86%,2.00%,204.34,0.49%,"378,418" 214 | 233,HUM,54.98B,18.51,15.33,1.31,0.66,3.32,12.77,473.98,26.00%,13.42%,24.60%,14.18%,7.30%,421.71,0.49%,"404,692" 215 | 234,HWM,14.46B,58.44,18.46,1.81,2.91,4.15,19.97,1807.37,65.70%,31.95%,23.60%,32.25%,-15.80%,35.18,3.26%,"1,043,057" 216 | 235,IBM,117.45B,25.02,12.31,1.52,2.05,5.25,14.58,-,-59.10%,6.75%,-20.30%,16.50%,-7.60%,130.21,0.05%,"2,067,565" 217 | 236,ICE,70.58B,17.39,20.49,1.75,7.70,3.07,116.28,32.13,90.80%,9.16%,24.60%,9.91%,9.00%,125.62,0.62%,"927,461" 218 | 237,IDXX,43.79B,58.76,45.86,2.43,13.62,56.99,301.61,63.08,37.30%,16.30%,26.70%,24.20%,11.10%,509.30,0.75%,"221,720" 219 | 238,IEX,14.94B,32.60,25.33,2.72,5.40,5.34,18.53,43.31,-11.10%,9.80%,6.40%,12.00%,3.10%,191.94,0.14%,"249,044" 220 | 239,IFF,34.14B,103.71,19.47,18.72,4.22,1.56,50.81,69.62,-20.60%,15.55%,-9.30%,5.54%,11.00%,134.36,2.09%,"326,181" 221 | 240,ILMN,55.72B,65.32,61.74,65.32,12.31,4.73,44.05,62.05,-34.10%,26.99%,7.40%,1.00%,7.90%,340.39,3.32%,"454,597" 222 | 241,INCY,14.64B,15.45,13.97,1.03,4.90,3.87,6.24,25.76,415.00%,31.29%,51.40%,15.00%,22.00%,67.45,2.17%,"1,124,452" 223 | 242,INFO,43.99B,35.90,27.36,3.23,9.44,4.54,150.08,50.37,38.70%,11.02%,46.00%,11.12%,11.20%,109.08,1.19%,"799,141" 224 | 243,INTC,198.70B,9.79,12.77,2.90,2.51,2.03,6.99,8.73,-1.60%,5.28%,18.10%,3.38%,5.90%,48.13,1.16%,"17,689,858" 225 | 244,INTU,155.90B,69.95,38.73,4.02,15.11,14.84,47.97,59.62,9.20%,16.76%,20.00%,17.40%,15.50%,524.34,-0.89%,"1,193,274" 226 | 245,IP,17.92B,13.72,9.82,0.71,0.85,1.89,8.45,-,-81.10%,8.26%,-22.10%,19.20%,-3.20%,46.83,1.30%,"1,151,912" 227 | 246,IPG,14.22B,14.70,12.42,2.63,1.39,4.35,5.71,7.66,-46.80%,6.28%,-4.00%,5.60%,3.50%,36.24,3.31%,"1,794,717" 228 | 247,IPGP,8.22B,30.16,24.84,1.19,5.74,2.86,5.41,30.37,-11.40%,15.72%,-8.10%,25.40%,5.90%,135.88,-7.37%,"700,466" 229 | 248,IQV,46.98B,61.03,23.65,2.72,3.47,7.88,29.85,19.84,49.50%,13.79%,-14.20%,22.47%,14.60%,226.66,-5.52%,"1,765,322" 230 | 249,IR,22.76B,44.50,23.18,2.08,4.34,2.56,11.19,31.12,-111.40%,16.52%,45.70%,21.39%,18.20%,55.17,2.55%,"1,660,143" 231 | 250,IRM,12.74B,19.92,26.41,3.10,2.90,12.99,78.91,-,27.80%,10.20%,15.40%,6.44%,6.60%,44.08,0.99%,"552,734" 232 | 251,ISRG,103.89B,60.32,47.47,3.16,18.19,8.45,23.93,59.85,58.60%,18.04%,17.40%,19.11%,16.10%,288.50,2.62%,"589,619" 233 | 252,IT,23.93B,31.27,34.21,1.45,5.05,72.14,31.26,20.37,15.60%,17.68%,7.50%,21.60%,13.60%,295.14,2.27%,"249,354" 234 | 253,ITW,69.46B,25.75,21.86,2.33,4.81,19.75,34.96,74.37,-14.40%,9.56%,5.20%,11.03%,-1.30%,221.05,0.86%,"472,709" 235 | 254,IVZ,10.79B,7.62,7.14,0.48,1.56,0.96,6.08,10.98,-11.60%,8.20%,-12.90%,15.86%,3.60%,23.47,2.83%,"1,971,972" 236 | 255,J,15.96B,54.80,14.82,4.45,1.13,2.57,-,23.54,17.10%,14.63%,12.50%,12.33%,5.10%,123.21,2.11%,"254,738" 237 | 256,JBHT,20.38B,26.96,20.31,0.96,1.67,6.93,38.48,61.70,-0.60%,10.22%,5.30%,28.04%,9.30%,194.40,0.99%,"246,220" 238 | 257,JCI,48.05B,30.43,16.97,1.58,1.99,2.72,39.81,46.34,150.60%,19.45%,13.90%,19.20%,2.60%,68.06,2.35%,"2,266,097" 239 | 258,JKHY,12.34B,36.53,32.82,2.61,6.62,9.84,424.22,42.03,6.80%,8.29%,5.70%,14.00%,5.40%,169.25,-0.55%,"212,314" 240 | 259,JNJ,440.40B,21.20,15.08,3.31,4.70,6.20,14.21,37.33,-4.20%,4.41%,-0.30%,6.40%,3.30%,167.25,1.00%,"3,062,733" 241 | 260,JNPR,11.17B,44.40,15.00,4.75,2.36,2.50,8.39,34.99,-22.40%,13.56%,-13.50%,9.35%,-1.80%,34.68,2.63%,"1,236,352" 242 | 261,JPM,456.59B,9.94,12.27,0.88,7.89,1.79,0.27,-,-17.20%,11.41%,8.10%,11.30%,4.80%,155.06,1.69%,"5,439,134" 243 | 262,K,21.99B,14.95,15.01,5.43,1.55,6.34,-,66.65,32.90%,4.94%,16.60%,2.75%,0.40%,64.91,0.25%,"1,251,251" 244 | 263,KEY,24.43B,9.90,11.06,-,5.59,1.56,10.75,25.08,-21.90%,8.52%,3.50%,-1.92%,12.30%,26.53,2.41%,"3,118,501" 245 | 264,KEYS,31.10B,34.69,22.18,2.89,6.29,8.11,15.15,27.09,44.10%,8.43%,19.70%,12.00%,11.10%,169.43,2.11%,"453,362" 246 | 265,KHC,41.80B,19.31,13.27,-,1.59,0.85,18.39,33.79,-85.80%,-5.99%,24.70%,-4.17%,7.40%,34.63,0.12%,"3,457,422" 247 | 266,KIM,14.48B,15.41,30.30,3.35,10.61,1.29,29.94,79.02,181.30%,15.81%,2.40%,4.60%,-1.90%,23.88,2.47%,"3,264,827" 248 | 267,KLAC,58.09B,18.79,15.32,0.91,7.11,13.64,20.67,30.01,73.60%,15.60%,24.40%,20.70%,18.30%,384.15,5.20%,"769,521" 249 | 268,KMB,44.11B,24.70,18.61,3.00,2.27,86.52,163.36,213.08,-22.00%,20.18%,-2.20%,8.22%,1.20%,132.29,-0.06%,"547,454" 250 | 269,KMI,38.22B,22.07,15.71,-,2.30,1.27,33.53,19.27,48.90%,3.80%,25.80%,-3.62%,4.90%,17.08,-0.61%,"8,019,831" 251 | 270,KMX,18.29B,15.30,14.82,0.93,0.62,3.52,292.15,-,-15.10%,1.97%,8.30%,16.40%,4.60%,112.93,1.78%,"468,281" 252 | 271,KO,266.84B,26.91,23.04,3.72,6.90,11.81,17.95,103.31,-13.30%,7.60%,1.40%,7.23%,-5.70%,61.10,0.69%,"7,478,575" 253 | 272,KR,32.80B,34.30,13.23,5.21,0.24,3.56,14.33,14.10,60.60%,-1.60%,9.70%,6.58%,3.80%,46.50,1.77%,"2,696,904" 254 | 273,L,15.29B,10.10,-,0.72,1.04,0.86,24.62,7.36,282.60%,-,25.70%,14.03%,2.20%,61.67,0.88%,"274,210" 255 | 274,LDOS,12.09B,16.16,12.75,1.71,0.90,2.99,20.60,27.61,-5.20%,3.18%,5.80%,9.45%,21.10%,84.76,-2.98%,"1,127,655" 256 | 275,LEN,26.65B,6.33,5.30,0.27,0.98,1.31,9.12,12.35,81.30%,7.40%,29.40%,23.70%,19.90%,92.00,1.56%,"738,416" 257 | 276,LH,26.65B,11.19,14.80,-,1.65,2.50,13.09,9.40,90.00%,-4.36%,29.60%,-12.49%,10.00%,265.29,-2.71%,"1,054,983" 258 | 277,LHX,41.63B,24.15,14.94,3.89,2.34,2.25,36.98,24.87,41.10%,8.11%,1.30%,6.20%,24.90%,217.76,-0.94%,"696,341" 259 | 278,LIN,157.65B,40.06,22.44,2.31,5.12,3.41,33.54,55.88,17.40%,10.97%,-2.60%,17.32%,20.40%,302.01,2.90%,"901,530" 260 | 279,LKQ,16.02B,15.62,13.46,0.47,1.25,2.68,39.78,10.85,20.40%,3.36%,8.80%,33.50%,10.10%,55.09,2.45%,"495,350" 261 | 280,LLY,228.22B,38.29,24.40,3.61,8.06,27.42,59.66,85.14,36.90%,12.11%,24.60%,10.60%,4.20%,244.40,4.14%,"1,412,425" 262 | 281,LMT,102.52B,16.99,13.81,2.07,1.53,9.64,28.45,21.54,-7.10%,5.41%,13.50%,8.20%,7.20%,385.12,-0.48%,"1,107,261" 263 | 282,LNC,13.07B,9.60,6.81,0.27,0.68,0.63,5.00,-,-44.70%,22.30%,-12.10%,35.73%,5.00%,72.91,2.78%,"1,526,177" 264 | 283,LNT,14.18B,22.44,20.76,3.68,3.99,2.38,709.17,-,5.90%,4.02%,7.90%,6.10%,1.00%,56.63,-0.41%,"297,955" 265 | 284,LOW,153.24B,19.62,17.46,1.17,1.61,-,-,30.75,41.20%,8.23%,23.20%,16.80%,8.70%,228.90,1.31%,"922,768" 266 | 285,LRCX,82.73B,17.39,14.61,1.09,5.01,12.12,15.52,25.37,78.10%,16.03%,38.80%,15.94%,20.00%,589.04,5.52%,"675,713" 267 | 286,LUMN,10.89B,5.20,8.66,-,0.55,0.94,17.15,4.51,76.80%,-22.39%,-22.20%,-,3.00%,10.06,1.54%,"12,647,043" 268 | 287,LUV,27.47B,28.31,13.89,-,1.74,2.59,1.77,11.86,129.50%,187.93%,-14.20%,-,-4.90%,47.21,4.03%,"4,380,141" 269 | 288,LVS,36.47B,-,19.90,-,8.61,17.70,19.67,-,20.00%,374.85%,-22.10%,-1.75%,-17.80%,47.55,2.90%,"3,403,905" 270 | 289,LW,9.49B,49.57,23.44,3.95,2.44,26.15,15.26,31.69,-13.10%,78.32%,2.40%,12.55%,4.20%,66.78,2.14%,"236,058" 271 | 290,LYB,33.43B,5.83,6.54,3.76,0.81,2.83,17.33,29.35,-55.80%,1.41%,-15.00%,1.55%,-3.20%,102.11,1.96%,"622,290" 272 | 291,LYV,26.61B,-,133.72,-,7.00,-,5.75,34.66,67.00%,130.60%,22.50%,-,-23.80%,118.93,3.18%,"1,134,487" 273 | 292,MA,372.23B,42.71,29.01,1.69,19.71,50.22,47.15,50.89,37.40%,23.99%,18.90%,25.24%,11.90%,382.24,2.16%,"2,723,635" 274 | 293,MAA,24.69B,61.07,53.83,8.72,14.43,4.03,828.37,516.43,-25.90%,14.29%,-13.00%,7.00%,10.00%,209.81,1.07%,"123,365" 275 | 294,MAR,57.38B,121.17,32.68,-,4.95,61.19,74.32,94.21,-121.60%,80.63%,-17.70%,-,-6.10%,179.39,4.70%,"2,761,541" 276 | 295,MAS,13.86B,34.99,12.30,2.27,1.66,-,14.97,23.46,-46.90%,11.28%,1.90%,15.40%,2.60%,58.23,1.71%,"1,169,423" 277 | 296,MCD,190.61B,25.25,22.80,1.95,8.21,-,-,58.35,-21.00%,9.51%,5.60%,12.97%,-5.40%,255.05,0.66%,"970,429" 278 | 297,MCHP,41.58B,37.29,13.82,1.82,6.45,6.81,131.79,23.57,16.00%,14.13%,11.60%,20.50%,20.10%,74.42,4.54%,"1,321,895" 279 | 298,MCK,40.90B,30.23,11.76,2.33,0.16,-,14.85,10.18,-667.60%,-3.70%,-37.30%,12.96%,4.50%,274.52,1.42%,"488,167" 280 | 299,MCO,63.36B,27.45,23.00,2.17,10.19,24.77,27.04,33.14,26.60%,11.03%,15.20%,12.67%,9.00%,330.13,2.06%,"307,948" 281 | 300,MDLZ,91.92B,21.74,20.05,2.63,3.20,3.26,25.92,68.09,23.40%,8.48%,24.00%,8.25%,2.10%,65.98,-0.24%,"2,513,946" 282 | 301,MDT,140.09B,29.46,16.68,2.57,4.41,2.65,13.13,55.63,-26.10%,8.34%,0.80%,11.46%,0.90%,103.71,1.37%,"3,151,263" 283 | 302,MET,58.55B,9.60,8.73,1.91,0.82,0.87,3.09,5.31,-6.20%,11.12%,10.50%,5.02%,2.00%,71.69,2.22%,"1,587,446" 284 | 303,MGM,21.68B,-,30.56,-,3.32,3.13,3.89,-,-152.00%,64.90%,-19.60%,-,-10.90%,44.94,0.64%,"2,800,609" 285 | 304,MHK,10.28B,9.23,8.27,0.42,0.93,1.13,9.11,8.96,-29.90%,12.90%,-2.80%,22.10%,3.40%,149.52,3.96%,"426,221" 286 | 305,MKC,26.78B,35.87,29.44,4.98,4.24,6.09,76.15,143.22,0.80%,7.23%,8.70%,7.20%,7.40%,100.37,-0.03%,"420,614" 287 | 306,MKTX,13.78B,54.72,44.46,3.82,19.71,13.17,31.84,96.95,45.40%,12.39%,25.20%,14.34%,17.90%,381.51,3.02%,"100,388" 288 | 307,MLM,23.50B,32.90,21.46,1.83,4.34,3.62,9.87,40.62,18.50%,22.18%,21.90%,17.97%,6.00%,384.62,4.22%,"229,398" 289 | 308,MMC,77.25B,24.75,20.44,3.21,3.90,7.89,55.26,33.59,15.50%,10.63%,5.70%,7.70%,6.00%,153.42,1.13%,"741,093" 290 | 309,MMM,90.35B,15.62,14.27,2.09,2.56,6.04,18.96,37.17,8.10%,6.92%,4.40%,7.47%,3.30%,157.96,-0.03%,"1,750,442" 291 | 310,MNST,44.23B,28.92,28.10,2.08,8.33,6.99,15.06,33.82,30.00%,13.57%,22.70%,13.92%,11.10%,82.45,-0.15%,"2,353,628" 292 | 311,MO,91.67B,20.37,9.74,3.80,3.47,-,31.00,-,470.60%,6.11%,-2.00%,5.36%,0.60%,50.30,0.42%,"2,721,753" 293 | 312,MOS,16.57B,9.60,5.80,1.37,1.51,1.63,19.66,28.10,160.60%,48.14%,-9.50%,7.00%,-0.50%,45.63,2.26%,"4,122,875" 294 | 313,MPC,47.86B,37.97,15.16,1.26,0.40,1.77,3.62,32.23,-716.80%,5.73%,-39.20%,30.11%,-0.60%,78.92,-0.30%,"2,604,238" 295 | 314,MRK,192.96B,15.72,10.68,1.64,3.96,5.40,-,-,-28.00%,-1.78%,12.20%,9.57%,4.00%,77.74,1.66%,"6,228,084" 296 | 315,MRNA,57.44B,8.75,5.03,0.52,4.86,5.69,6.45,5.04,-26.10%,6.47%,-,16.80%,-,149.66,5.05%,"8,237,499" 297 | 316,MRO,15.92B,-,9.74,-,3.55,1.55,-,11.64,-409.20%,64.05%,6.10%,-2.40%,-8.60%,20.55,-3.11%,"14,712,959" 298 | 317,MS,189.33B,12.77,12.08,1.72,3.10,1.86,1.53,-,24.60%,11.56%,17.30%,7.44%,6.60%,103.70,1.10%,"3,859,462" 299 | 318,MSCI,44.83B,61.29,40.03,4.41,21.94,-,34.90,74.86,6.90%,16.83%,27.50%,13.90%,9.50%,542.64,1.81%,"204,058" 300 | 319,MSFT,2266.60B,31.39,27.37,1.80,12.26,13.84,18.08,52.23,39.70%,15.33%,25.70%,17.40%,13.00%,298.91,1.33%,"14,709,564" 301 | 320,MSI,37.09B,29.83,19.27,2.09,4.54,-,22.44,31.84,10.30%,12.58%,11.40%,14.28%,5.40%,221.17,3.44%,"852,212" 302 | 321,MTB,23.32B,13.87,12.43,2.73,5.79,1.47,0.57,15.55,-27.70%,29.24%,6.70%,5.08%,5.70%,183.55,1.74%,"291,563" 303 | 322,MTCH,32.68B,137.08,34.36,8.57,10.95,-,62.46,40.82,5.00%,27.54%,23.50%,16.00%,21.30%,117.48,3.25%,"743,774" 304 | 323,MTD,34.62B,44.39,33.32,2.49,9.57,205.23,188.48,44.53,10.90%,12.15%,14.80%,17.80%,5.20%,1437.93,1.54%,"53,906" 305 | 324,MU,102.04B,13.90,7.72,0.58,3.44,2.19,10.65,27.07,116.20%,29.77%,84.30%,23.80%,17.40%,94.60,5.27%,"16,451,141" 306 | 325,NCLH,9.28B,-,-,-,54.56,2.71,4.80,-,-466.60%,99.70%,-60.00%,-,-21.70%,22.44,6.40%,"13,862,442" 307 | 326,NDAQ,29.55B,24.38,20.36,2.40,5.02,4.54,60.56,80.75,20.60%,7.31%,17.50%,10.18%,10.60%,174.92,1.74%,"324,719" 308 | 327,NEE,147.96B,41.37,24.83,4.51,8.67,4.01,213.82,32.07,-23.10%,8.06%,0.20%,9.17%,0.60%,75.35,0.57%,"4,555,630" 309 | 328,NEM,48.64B,26.18,20.38,-,3.98,2.26,10.15,34.37,-15.30%,7.31%,-,-,13.60%,63.27,-1.68%,"3,596,290" 310 | 329,NFLX,182.79B,37.14,27.85,2.20,6.16,11.10,30.33,-,81.30%,29.84%,90.50%,16.86%,27.50%,407.10,2.65%,"3,157,282" 311 | 330,NI,11.06B,25.30,19.59,7.19,2.35,2.34,287.17,15.46,-121.70%,6.93%,-18.40%,3.52%,0.10%,28.53,0.42%,"1,942,044" 312 | 331,NKE,231.31B,37.12,29.49,2.33,5.00,15.01,15.32,49.06,123.10%,29.64%,10.50%,15.96%,6.60%,146.01,3.12%,"2,831,410" 313 | 332,NLOK,17.44B,18.84,15.54,1.52,6.34,-,9.79,25.06,29.00%,9.15%,24.10%,12.40%,-6.70%,28.96,-1.76%,"1,916,730" 314 | 333,NLSN,6.61B,18.80,9.92,3.55,1.55,2.08,12.20,11.25,98.60%,5.91%,-15.00%,5.30%,0.40%,18.46,2.84%,"982,828" 315 | 334,NOC,58.33B,8.96,14.46,1.87,1.64,4.75,16.52,49.90,128.80%,8.73%,30.90%,4.80%,7.60%,386.41,-1.07%,"390,631" 316 | 335,NOW,121.22B,511.09,62.09,19.58,20.56,31.26,36.69,67.38,93.40%,26.49%,19.60%,26.10%,33.50%,587.11,1.30%,"529,302" 317 | 336,NRG,9.58B,3.89,11.25,0.10,0.44,2.32,36.97,5.60,-86.70%,-63.53%,16.10%,37.90%,-5.90%,38.86,0.46%,"554,492" 318 | 337,NSC,66.53B,22.46,17.84,1.70,5.97,4.83,79.30,37.87,54.50%,10.04%,16.60%,13.18%,2.40%,275.80,1.30%,"487,341" 319 | 338,NTAP,19.73B,21.30,15.85,2.42,3.26,25.82,4.34,22.73,-8.10%,9.49%,33.20%,8.80%,0.70%,90.21,2.76%,"613,797" 320 | 339,NTRS,25.66B,17.03,13.43,1.29,3.99,2.30,6.12,-,-17.60%,18.15%,6.50%,13.16%,5.20%,125.34,3.15%,"312,750" 321 | 340,NUE,34.44B,9.22,15.80,0.24,1.23,2.54,17.12,33.39,-42.90%,-61.46%,57.10%,37.75%,4.10%,121.63,3.65%,"962,856" 322 | 341,NVDA,654.17B,74.92,47.05,1.90,26.95,25.49,33.90,96.79,52.50%,18.71%,44.90%,39.37%,27.20%,262.92,8.34%,"48,664,252" 323 | 342,NVR,17.77B,15.50,10.23,3.23,1.98,5.88,6.57,16.75,4.10%,8.64%,20.70%,4.80%,7.90%,5032.04,1.09%,"45,522" 324 | 343,NWL,9.54B,17.65,12.12,4.18,0.91,2.61,19.32,13.56,-513.60%,10.12%,-31.30%,4.22%,9.70%,25.86,3.79%,"2,960,492" 325 | 344,NWS,13.30B,27.23,-,-,1.36,1.63,-,-,-,-,-,-,-,23.33,3.23%,"157,596" 326 | 345,NWSA,13.52B,26.71,19.22,1.27,1.35,1.57,6.19,16.49,125.80%,20.60%,14.90%,21.06%,2.40%,23.00,3.25%,"2,038,405" 327 | 346,NXPI,52.69B,27.24,13.51,1.62,4.76,7.35,22.88,26.61,-78.40%,6.77%,-50.40%,16.83%,7.10%,194.13,4.44%,"1,091,044" 328 | 347,O,37.71B,52.88,39.00,9.70,20.75,1.97,72.93,170.78,-17.10%,26.94%,1.10%,5.45%,10.00%,67.54,0.97%,"1,478,379" 329 | 348,ODFL,35.12B,33.06,24.51,1.14,6.68,9.92,62.20,65.96,11.20%,10.85%,19.00%,28.91%,6.20%,297.57,1.23%,"288,113" 330 | 349,OGN,8.65B,6.10,5.99,-,1.10,-,8.58,3.37,-32.90%,-10.92%,-,-5.50%,-,35.12,2.15%,"1,120,495" 331 | 350,OKE,27.41B,19.71,16.63,2.00,2.00,4.81,122.20,-,-53.90%,11.20%,3.50%,9.86%,1.90%,62.58,-0.54%,"1,012,641" 332 | 351,OMC,18.03B,13.28,12.00,1.25,1.26,5.50,-,26.24,45.80%,7.23%,6.00%,10.60%,-1.50%,86.00,1.49%,"785,301" 333 | 352,ORCL,221.51B,22.92,15.03,2.38,5.35,-,9.70,58.71,47.80%,8.87%,17.10%,9.64%,1.80%,79.67,0.91%,"2,935,068" 334 | 353,ORLY,43.89B,21.25,18.22,1.28,3.29,-,97.68,17.23,31.60%,12.08%,20.70%,16.60%,7.80%,675.97,2.26%,"335,013" 335 | 354,OTIS,34.70B,27.61,21.63,2.36,2.43,-,22.17,28.90,38.50%,12.27%,-,11.68%,-,79.50,-0.31%,"1,863,962" 336 | 355,OXY,36.45B,-,11.57,-,1.63,4.23,17.70,5.89,155.00%,63.94%,-8.00%,37.40%,7.30%,39.61,-3.92%,"16,501,244" 337 | 356,PAYC,21.63B,119.30,49.80,4.70,23.22,24.26,93.68,133.78,-20.40%,26.40%,47.10%,25.40%,30.20%,347.30,0.46%,"153,814" 338 | 357,PAYX,43.27B,33.60,30.36,2.72,9.99,13.70,42.75,100.02,-0.40%,7.58%,7.70%,12.37%,6.60%,119.73,1.06%,"681,929" 339 | 358,PBCT,8.91B,14.89,16.91,1.39,5.56,1.16,1.06,10.44,-61.80%,1.83%,-10.80%,10.74%,11.20%,21.12,1.93%,"1,563,441" 340 | 359,PCAR,32.34B,17.49,11.70,0.76,1.37,2.85,8.56,24.50,-45.60%,14.15%,-3.70%,23.11%,-0.40%,95.03,2.20%,"586,432" 341 | 360,PEAK,17.16B,150.70,65.24,51.97,9.05,2.66,108.42,-,-20.10%,29.13%,-22.50%,2.90%,-2.30%,32.15,0.17%,"1,539,485" 342 | 361,PEG,32.70B,-,18.58,-,3.61,2.32,18.06,-,12.50%,-3.99%,2.60%,3.30%,-1.60%,64.88,0.17%,"1,578,752" 343 | 362,PENN,8.34B,21.35,18.71,-,1.56,2.45,3.06,9.85,154.60%,31.63%,36.33%,-,4.70%,49.78,4.12%,"1,746,529" 344 | 363,PEP,230.20B,29.65,22.92,3.83,2.90,14.40,38.44,195.75,9.90%,8.38%,5.20%,7.75%,4.80%,166.23,-0.28%,"1,827,047" 345 | 364,PFE,278.53B,12.76,9.39,1.31,3.43,3.69,9.38,-,-36.50%,-24.11%,1.20%,9.77%,-3.10%,49.51,-0.59%,"18,676,933" 346 | 365,PFG,20.33B,11.93,10.91,0.87,1.46,1.24,6.46,9.71,1.70%,3.50%,4.50%,13.73%,4.20%,76.00,2.43%,"536,685" 347 | 366,PG,377.83B,27.70,24.44,3.90,4.82,8.65,32.73,60.34,10.90%,8.56%,9.50%,7.10%,3.10%,157.42,0.44%,"3,451,837" 348 | 367,PGR,62.32B,18.75,17.88,-,1.31,3.44,230.31,12.76,43.90%,27.19%,35.00%,-10.10%,15.40%,106.07,-0.13%,"1,106,827" 349 | 368,PH,39.19B,21.74,15.11,1.91,2.56,4.42,79.98,26.30,44.10%,8.90%,17.80%,11.37%,4.80%,308.52,2.45%,"357,130" 350 | 369,PHM,12.06B,6.38,4.20,0.27,0.87,1.61,6.78,15.39,43.50%,11.17%,33.50%,23.70%,12.70%,49.01,2.49%,"885,582" 351 | 370,PKG,14.05B,16.64,14.10,4.19,1.82,3.84,7.85,21.74,-34.00%,2.42%,1.70%,3.97%,3.00%,148.90,1.28%,"290,111" 352 | 371,PKI,23.33B,22.40,25.29,0.59,4.60,2.98,47.87,17.30,212.40%,2.99%,31.30%,37.90%,12.40%,180.26,-0.48%,"289,948" 353 | 372,PLD,109.11B,36.87,46.67,-,22.93,3.22,196.21,113.73,96.40%,18.49%,11.70%,-6.05%,13.40%,146.37,0.71%,"1,027,903" 354 | 373,PM,165.51B,18.75,15.47,1.67,5.27,-,36.81,45.48,13.00%,11.97%,5.40%,11.22%,3.30%,109.37,0.12%,"3,318,058" 355 | 374,PNC,87.82B,15.60,12.80,-,8.18,1.55,1.04,34.41,-33.50%,14.47%,-3.00%,-3.80%,3.90%,206.85,1.11%,"1,577,360" 356 | 375,PNR,10.01B,17.76,14.74,2.02,2.66,4.18,57.79,20.75,0.50%,6.64%,-0.60%,8.80%,-8.20%,59.89,1.57%,"356,057" 357 | 376,PNW,7.69B,14.87,17.24,148.66,2.05,1.27,299.12,-,20.50%,-24.65%,2.50%,0.10%,0.50%,68.24,-0.23%,"220,035" 358 | 377,POOL,18.37B,30.52,26.70,1.80,3.60,18.35,219.96,80.59,40.20%,11.18%,25.40%,17.00%,10.70%,458.86,1.76%,"141,852" 359 | 378,PPG,36.36B,25.17,16.56,1.52,2.16,5.68,27.88,24.18,-14.90%,19.59%,-1.50%,16.60%,-0.60%,152.28,2.02%,"403,526" 360 | 379,PPL,21.39B,132.48,17.80,-,3.43,1.49,4.49,-,-19.40%,35.81%,-4.40%,-,-0.20%,28.41,0.19%,"1,636,136" 361 | 380,PRU,44.33B,6.39,8.74,1.37,0.69,0.72,2.84,-,-113.60%,11.33%,-16.10%,4.65%,-0.10%,118.21,2.09%,"811,372" 362 | 381,PSA,62.53B,42.51,38.21,2.50,19.23,12.43,65.25,86.91,-13.80%,5.15%,0.70%,17.00%,4.10%,354.29,-0.38%,"168,346" 363 | 382,PSX,38.09B,-,11.49,-,0.40,2.20,13.15,-,-232.00%,3.02%,-26.00%,13.00%,-8.30%,89.12,-1.55%,"1,534,299" 364 | 383,PTC,13.57B,26.60,22.16,2.34,7.39,6.72,-,36.91,258.40%,16.65%,60.00%,11.35%,9.60%,112.39,0.43%,"287,831" 365 | 384,PVH,7.08B,13.96,9.70,-,0.80,1.33,5.45,11.51,-385.30%,7.70%,-34.00%,-6.04%,-2.30%,100.63,3.51%,"513,839" 366 | 385,PWR,14.59B,26.15,16.31,1.66,1.22,3.01,8.60,58.49,12.60%,27.36%,37.80%,15.74%,8.10%,103.66,4.22%,"503,672" 367 | 386,PXD,52.62B,44.03,10.56,-,3.68,2.36,72.58,15.20,-126.30%,64.94%,7.50%,-,19.50%,217.67,-2.85%,"1,952,839" 368 | 387,PYPL,137.25B,32.49,19.73,1.75,5.41,6.17,14.45,25.27,-0.70%,24.10%,25.00%,18.60%,18.50%,115.35,1.08%,"11,177,115" 369 | 388,QCOM,196.76B,18.93,13.12,1.29,5.46,16.38,17.40,44.90,74.00%,6.24%,15.60%,14.68%,7.30%,171.99,4.15%,"4,828,481" 370 | 389,QRVO,14.74B,13.07,9.83,0.90,3.24,3.04,14.91,17.02,125.60%,10.60%,101.40%,14.50%,9.00%,134.65,4.13%,"685,725" 371 | 390,RCL,24.47B,-,13.39,-,15.97,3.26,7.44,-,-402.20%,102.40%,-61.40%,-,-23.30%,85.84,3.73%,"2,228,048" 372 | 391,RE,11.40B,8.23,7.48,-,1.01,1.15,10.67,3.84,-51.60%,15.84%,-11.50%,-,10.10%,300.48,2.51%,"101,015" 373 | 392,REG,11.77B,33.48,30.42,3.68,10.44,1.83,32.74,41.47,-81.40%,10.07%,-27.90%,9.10%,12.30%,67.15,3.05%,"517,082" 374 | 393,REGN,65.54B,8.65,13.22,-,4.08,3.53,11.51,10.04,135.80%,1.22%,56.40%,-,27.00%,629.04,0.88%,"338,972" 375 | 394,RF,23.46B,9.85,10.81,0.39,5.75,1.38,0.85,16.41,-31.50%,9.67%,6.30%,25.10%,3.40%,25.36,3.45%,"4,055,383" 376 | 395,RHI,13.50B,22.30,18.36,1.92,2.09,10.02,21.30,63.26,-30.80%,7.74%,0.10%,11.60%,0.10%,122.46,2.41%,"451,209" 377 | 396,RJF,23.21B,15.10,12.13,1.77,2.22,2.63,2.82,10.92,71.00%,20.07%,22.20%,8.54%,12.40%,112.44,2.70%,"346,086" 378 | 397,RL,9.00B,18.37,13.73,-,1.50,3.29,3.01,14.37,-143.50%,8.25%,-18.30%,-,-9.90%,128.54,4.90%,"637,704" 379 | 398,RMD,34.22B,65.81,33.55,2.58,9.94,10.84,175.95,149.45,-24.10%,13.77%,5.40%,25.50%,11.70%,233.57,-0.02%,"243,335" 380 | 399,ROK,32.23B,31.30,22.33,2.72,4.42,12.43,59.62,119.68,32.10%,11.47%,15.80%,11.52%,3.50%,273.18,1.79%,"281,610" 381 | 400,ROL,15.27B,43.25,36.58,5.27,6.30,13.77,129.77,68.95,28.70%,11.66%,11.40%,8.20%,7.80%,31.07,0.75%,"569,568" 382 | 401,ROP,47.12B,40.91,26.28,5.45,8.16,4.11,133.67,25.42,-46.60%,8.42%,5.60%,7.50%,9.10%,442.97,0.18%,"238,631" 383 | 402,ROST,34.12B,21.03,17.63,-,1.88,8.31,6.49,28.01,-94.80%,11.19%,-37.40%,-,1.00%,95.62,1.44%,"1,338,115" 384 | 403,RSG,39.33B,29.35,23.09,2.62,3.48,4.26,-,41.99,-9.30%,10.64%,7.20%,11.20%,2.20%,118.79,0.18%,"850,129" 385 | 404,RTX,139.74B,36.23,16.14,2.24,2.17,1.97,18.69,415.91,-156.40%,20.88%,-20.20%,16.20%,0.20%,94.53,1.03%,"2,423,825" 386 | 405,SBAC,34.31B,119.62,77.01,-,15.25,-,-,42.46,-83.40%,65.79%,16.60%,-,4.90%,310.81,0.47%,"218,015" 387 | 406,SBNY,21.24B,26.16,13.22,4.14,10.63,2.56,0.73,22.58,-8.00%,28.75%,6.50%,6.32%,11.80%,342.24,3.28%,"258,335" 388 | 407,SBUX,109.54B,25.26,23.95,2.22,3.61,-,27.00,47.73,351.00%,17.17%,13.30%,11.40%,6.40%,95.03,1.47%,"3,715,799" 389 | 408,SCHW,172.84B,31.06,18.17,1.43,9.10,3.49,5.04,29.48,-20.60%,26.54%,15.60%,21.70%,13.20%,89.88,2.44%,"2,892,373" 390 | 409,SEDG,13.84B,94.01,36.00,3.33,7.82,10.51,20.29,114.32,-8.20%,37.18%,9.00%,28.22%,24.40%,259.57,4.15%,"469,478" 391 | 410,SEE,9.48B,21.24,15.28,1.83,1.77,74.48,24.08,25.22,102.00%,16.38%,32.60%,11.60%,2.10%,64.83,2.40%,"307,424" 392 | 411,SHW,72.69B,38.82,24.09,2.77,3.64,26.31,232.02,27.10,33.90%,17.76%,14.70%,14.01%,10.10%,272.73,0.83%,"535,361" 393 | 412,SIVB,37.35B,19.68,15.41,2.46,11.36,2.93,1.74,28.35,5.20%,31.45%,28.10%,8.00%,16.50%,643.20,3.49%,"166,069" 394 | 413,SJM,14.56B,19.66,15.21,12.18,1.84,1.79,93.72,39.30,14.00%,5.46%,6.20%,1.61%,0.50%,136.02,-1.03%,"282,260" 395 | 414,SLB,53.18B,29.84,15.00,0.61,2.32,3.68,16.94,18.92,117.40%,33.33%,25.10%,48.55%,-3.80%,39.97,1.70%,"9,509,920" 396 | 415,SNA,11.43B,14.11,12.99,2.82,2.48,2.80,15.54,14.92,-7.80%,5.37%,7.20%,5.00%,1.90%,215.22,2.14%,"170,608" 397 | 416,SNPS,47.69B,61.25,32.70,4.11,11.34,8.52,30.17,34.09,12.80%,15.50%,22.80%,14.90%,11.70%,302.21,2.46%,"312,491" 398 | 417,SO,68.91B,23.46,18.61,3.78,3.07,2.44,33.16,-,-34.90%,4.46%,2.50%,6.20%,3.10%,65.34,-0.77%,"2,934,442" 399 | 418,SPG,46.67B,20.47,20.63,2.38,9.12,13.78,106.45,34.25,-47.30%,3.67%,-9.40%,8.60%,-2.60%,141.97,1.48%,"696,832" 400 | 419,SPGI,93.87B,30.43,23.68,2.90,11.31,45.11,14.42,33.29,29.40%,10.27%,9.50%,10.50%,7.90%,385.62,1.29%,"664,389" 401 | 420,SRE,43.02B,37.49,15.97,8.72,3.53,1.82,49.28,27.18,9.20%,2.38%,4.00%,4.30%,2.20%,135.30,0.13%,"298,586" 402 | 421,STE,23.02B,77.88,28.01,7.79,5.42,3.43,64.11,89.48,-2.80%,2.16%,24.40%,10.00%,6.80%,230.56,1.77%,"151,683" 403 | 422,STT,36.92B,13.73,9.46,0.96,18.78,1.35,0.25,-,17.60%,23.17%,7.20%,14.29%,0.80%,100.46,1.80%,"525,538" 404 | 423,STX,23.52B,13.33,10.67,0.53,1.96,39.90,23.74,49.11,41.60%,10.92%,45.50%,25.02%,-0.90%,109.75,3.42%,"584,335" 405 | 424,STZ,44.17B,-,20.20,-,5.09,3.92,122.25,33.54,-0.90%,15.66%,12.00%,9.61%,5.60%,221.69,-5.20%,"1,380,991" 406 | 425,SWK,27.08B,17.11,12.21,1.59,1.73,2.48,92.53,39.38,12.70%,10.57%,3.90%,10.77%,3.20%,166.37,1.24%,"501,327" 407 | 426,SWKS,23.38B,16.18,10.45,1.27,4.58,4.17,23.07,25.87,87.00%,11.41%,11.60%,12.70%,9.20%,139.08,3.23%,"556,414" 408 | 427,SYF,23.38B,6.01,7.67,0.17,1.53,1.83,2.80,3.54,222.90%,2.57%,22.10%,35.92%,0.70%,45.01,2.21%,"2,761,966" 409 | 428,SYK,95.90B,48.03,22.86,4.18,5.61,6.66,36.34,46.42,-23.30%,11.80%,2.20%,11.49%,7.60%,259.40,3.57%,"903,074" 410 | 429,SYY,41.79B,53.80,19.83,1.05,0.69,34.31,30.41,-,143.50%,30.25%,-9.10%,51.24%,0.40%,83.75,2.15%,"1,149,389" 411 | 430,T,172.60B,8.71,7.46,2.38,1.02,1.05,8.11,12.60,-139.60%,3.00%,-18.30%,3.66%,3.20%,24.41,1.50%,"18,112,891" 412 | 431,TAP,10.65B,-,12.16,-,1.07,0.81,17.27,11.64,-492.80%,-3.42%,-32.50%,2.87%,22.00%,49.69,0.57%,"338,439" 413 | 432,TDG,35.58B,49.47,29.98,1.91,7.28,-,7.39,46.03,27.50%,33.11%,0.00%,25.90%,8.60%,654.98,3.84%,"136,016" 414 | 433,TDY,19.61B,42.05,21.26,1.81,4.25,2.62,35.54,30.18,-1.20%,9.18%,14.30%,23.27%,6.10%,422.52,1.34%,"48,296" 415 | 434,TECH,16.42B,80.71,45.46,5.38,15.95,9.55,58.86,63.61,-40.40%,14.50%,4.40%,15.00%,13.30%,415.08,0.35%,"137,520" 416 | 435,TEL,48.01B,19.50,17.86,1.88,3.15,4.26,48.89,40.11,968.00%,11.40%,6.20%,10.36%,5.60%,148.04,3.14%,"860,458" 417 | 436,TER,18.99B,20.21,16.56,1.43,5.13,7.27,14.47,31.34,64.50%,39.94%,34.60%,14.16%,13.70%,116.94,4.13%,"952,237" 418 | 437,TFC,85.47B,14.09,11.46,12.93,6.21,1.35,2.69,25.82,-17.10%,14.16%,3.80%,1.09%,19.70%,64.48,2.35%,"1,959,561" 419 | 438,TFX,15.04B,34.66,22.56,3.15,5.45,4.06,31.26,30.00,-27.60%,6.11%,7.60%,11.00%,7.00%,327.15,3.09%,"107,980" 420 | 439,TGT,101.01B,15.35,15.60,1.10,0.98,7.33,17.56,22.46,36.30%,0.89%,10.50%,13.99%,4.90%,207.85,-0.35%,"2,566,037" 421 | 440,TJX,83.39B,31.19,20.26,-,1.83,12.66,12.28,189.27,-97.20%,12.77%,-46.30%,-,0.80%,68.72,1.07%,"3,206,130" 422 | 441,TMO,226.60B,28.84,23.10,2.65,5.78,5.71,-,29.17,73.80%,7.84%,26.50%,10.87%,13.70%,555.53,-1.01%,"697,038" 423 | 442,TMUS,157.59B,52.04,21.32,0.74,1.97,2.29,38.86,754.01,-40.80%,137.63%,23.60%,70.08%,16.40%,126.50,0.79%,"1,334,601" 424 | 443,TPR,11.17B,13.20,9.57,0.94,1.72,3.62,6.78,11.51,211.60%,13.08%,9.60%,14.00%,5.00%,40.67,4.16%,"1,772,811" 425 | 444,TRMB,17.05B,33.89,20.03,3.39,4.66,4.27,33.23,22.77,-24.00%,13.61%,27.00%,10.00%,6.60%,68.14,3.48%,"662,669" 426 | 445,TROW,33.20B,10.98,11.22,0.90,4.33,3.96,9.71,35.93,14.70%,5.05%,16.60%,12.20%,8.10%,147.74,2.50%,"927,588" 427 | 446,TRV,42.18B,11.98,11.82,1.34,1.23,1.49,51.56,6.60,6.00%,12.87%,-0.70%,8.94%,3.60%,171.67,0.53%,"514,883" 428 | 447,TSCO,24.93B,25.31,21.25,1.86,1.96,12.32,22.43,43.49,36.90%,9.04%,16.30%,13.60%,11.30%,220.39,1.13%,"354,320" 429 | 448,TSLA,879.49B,177.93,69.73,8.20,16.34,29.39,49.67,76.71,669.20%,22.06%,48.60%,21.70%,50.40%,917.69,4.79%,"14,097,725" 430 | 449,TSN,34.35B,8.89,11.93,1.19,0.69,1.87,11.62,17.91,48.00%,-5.09%,13.00%,7.50%,5.00%,94.32,-0.59%,"949,565" 431 | 450,TT,36.29B,25.41,19.32,1.35,2.57,5.74,16.81,45.13,48.30%,11.00%,1.60%,18.78%,0.90%,154.48,2.00%,"591,283" 432 | 451,TTWO,19.47B,37.06,26.51,2.53,5.70,5.25,7.90,-,43.60%,28.58%,121.30%,14.63%,19.00%,169.48,1.44%,"773,865" 433 | 452,TWTR,29.53B,-,29.62,-,5.81,3.97,3.98,109.11,-177.30%,30.27%,-12.90%,-,10.90%,36.62,2.59%,"7,516,554" 434 | 453,TXN,155.76B,19.66,17.32,1.97,8.49,11.24,15.99,64.69,38.50%,3.01%,18.90%,10.00%,6.50%,165.88,2.10%,"3,069,580" 435 | 454,TXT,15.31B,20.78,14.52,1.66,1.24,2.54,7.02,11.55,-61.50%,19.39%,-11.60%,12.50%,-2.80%,70.42,2.71%,"434,128" 436 | 455,TYL,19.78B,122.01,57.53,12.20,13.72,8.68,69.79,61.62,28.40%,15.83%,21.50%,10.00%,13.60%,475.64,1.79%,"48,862" 437 | 456,UA,6.83B,15.99,18.89,0.73,1.23,3.64,-,-,338.50%,29.00%,-,21.80%,-,15.64,3.51%,"2,779,171" 438 | 457,UAA,8.55B,18.85,18.68,0.68,1.54,4.08,6.82,15.41,-711.50%,16.60%,-26.00%,27.80%,2.50%,17.86,3.90%,"4,166,034" 439 | 458,UAL,15.93B,-,7.02,-,0.65,2.84,0.82,-,-318.50%,113.10%,-33.70%,-,-16.50%,50.10,6.76%,"12,280,634" 440 | 459,UDR,17.32B,116.94,142.21,-,13.42,5.33,15749.03,90.46,-67.80%,36.65%,-8.80%,-,6.80%,55.24,1.15%,"640,852" 441 | 460,UHS,10.71B,10.65,10.80,1.30,0.86,1.73,56.44,-,20.40%,4.06%,10.20%,8.21%,5.00%,134.68,1.86%,"236,558" 442 | 461,ULTA,20.27B,23.21,20.36,0.37,2.50,9.91,-,24.64,-74.40%,3.82%,-9.00%,62.03%,9.40%,379.07,4.53%,"289,380" 443 | 462,UNH,454.84B,26.23,19.20,1.79,1.58,6.37,21.57,33.46,11.90%,14.17%,21.70%,14.63%,10.40%,476.47,0.44%,"1,402,536" 444 | 463,UNP,156.62B,24.34,18.91,1.45,7.18,10.97,155.69,47.52,26.40%,11.05%,14.50%,16.75%,1.80%,249.29,2.78%,"1,668,741" 445 | 464,UPS,192.25B,14.56,15.85,1.04,1.98,15.46,18.21,42.35,-69.80%,5.25%,-22.00%,14.03%,7.70%,219.31,2.49%,"1,442,685" 446 | 465,URI,23.61B,16.47,10.29,0.77,2.43,3.79,163.98,6.77,56.00%,13.01%,24.20%,21.27%,11.00%,322.02,2.80%,"421,655" 447 | 466,USB,86.78B,11.35,11.05,1.14,6.43,1.80,1.36,14.00,-26.40%,20.59%,-0.70%,9.93%,3.70%,58.71,1.45%,"2,070,174" 448 | 467,V,474.39B,44.77,26.49,2.44,18.62,14.30,29.80,38.49,15.00%,18.99%,13.60%,18.37%,9.80%,228.52,1.41%,"3,912,201" 449 | 468,VFC,24.00B,19.67,16.49,0.44,2.07,6.40,17.99,-,-32.40%,13.36%,-18.70%,44.77%,-3.50%,61.70,3.02%,"2,004,002" 450 | 469,VIAC,22.73B,7.40,9.40,-,0.85,1.10,4.71,52.73,-26.30%,1.75%,3.30%,-6.49%,14.80%,35.62,1.68%,"6,517,884" 451 | 470,VLO,35.84B,-,12.31,-,0.38,2.09,10.25,75.61,-160.10%,4.88%,-19.50%,-13.80%,-5.90%,88.86,-0.95%,"2,148,919" 452 | 471,VMC,24.66B,37.67,29.13,2.06,4.81,3.80,181.69,59.69,-5.40%,26.82%,20.70%,18.25%,7.30%,189.37,2.98%,"340,883" 453 | 472,VNO,7.82B,-,57.14,-,5.06,1.53,3.67,25.89,-111.30%,18.05%,-22.50%,17.33%,-5.10%,43.56,6.92%,"1,538,757" 454 | 473,VRSK,31.20B,44.83,32.07,4.51,10.59,11.40,103.27,40.22,59.60%,13.86%,8.30%,9.95%,9.60%,193.96,1.12%,"230,462" 455 | 474,VRSN,23.56B,30.45,29.60,3.81,17.74,-,19.65,37.40,-2.40%,14.56%,20.20%,8.00%,3.60%,215.85,1.07%,"175,186" 456 | 475,VRTX,59.37B,25.62,15.19,2.17,7.84,5.83,7.89,24.65,-12.50%,7.09%,85.00%,11.80%,34.80%,232.18,0.41%,"618,936" 457 | 476,VTR,20.20B,95.35,-,-,5.42,1.68,140.50,97.32,-0.40%,-85.70%,0.10%,-,2.90%,50.98,1.84%,"1,301,117" 458 | 477,VTRS,18.42B,-,4.02,-,1.07,0.86,21.81,9.12,-6.10%,0.73%,-21.60%,-0.40%,4.80%,15.28,1.70%,"2,838,766" 459 | 478,VZ,219.39B,10.02,9.49,3.47,1.64,2.86,22.08,19.49,-7.60%,2.56%,-0.30%,2.88%,-0.50%,53.51,0.45%,"6,263,639" 460 | 479,WAB,16.73B,36.34,17.97,4.98,2.15,1.62,36.65,19.08,18.10%,14.41%,-11.90%,7.30%,18.00%,90.04,2.93%,"440,682" 461 | 480,WAT,19.83B,28.45,24.46,2.84,7.12,66.12,30.26,30.54,-3.30%,9.15%,8.20%,10.00%,3.00%,321.57,1.11%,"146,350" 462 | 481,WBA,41.32B,6.88,9.21,1.85,0.31,1.56,9.99,16.99,0.60%,2.02%,-9.70%,3.73%,2.50%,48.38,2.15%,"2,409,278" 463 | 482,WDC,16.65B,8.33,5.72,0.45,0.88,1.37,6.58,14.16,416.70%,14.46%,21.60%,18.50%,5.40%,55.42,4.84%,"1,984,780" 464 | 483,WEC,28.52B,21.80,19.59,3.57,3.43,2.59,1096.83,-,5.90%,6.49%,10.10%,6.10%,4.10%,89.51,-0.13%,"1,020,041" 465 | 484,WELL,34.92B,1106.53,87.36,85.12,7.67,2.02,114.88,157.60,-122.00%,13.43%,-16.80%,13.00%,3.60%,81.21,1.93%,"986,577" 466 | 485,WFC,233.59B,11.68,11.95,-,5.88,1.39,0.47,-,-89.80%,23.25%,-36.90%,-,-0.60%,58.65,1.37%,"9,594,959" 467 | 486,WHR,12.18B,6.93,6.99,1.12,0.55,2.45,4.00,9.28,66.50%,3.90%,19.60%,6.20%,1.20%,204.47,3.99%,"388,007" 468 | 487,WM,59.80B,32.98,23.56,2.69,3.33,8.29,515.48,37.56,-9.90%,11.51%,16.30%,12.25%,3.30%,142.52,0.53%,"795,723" 469 | 488,WMB,35.87B,36.33,22.84,18.16,3.79,3.28,167.62,36.68,-75.90%,7.42%,17.30%,2.00%,1.00%,29.95,-0.43%,"3,069,070" 470 | 489,WMT,373.62B,46.90,20.00,5.65,0.65,4.53,23.19,29.29,-8.50%,4.36%,0.80%,8.30%,3.00%,134.38,0.32%,"3,814,134" 471 | 490,WRB,16.15B,16.33,14.40,1.81,1.71,2.49,7.81,10.06,-20.20%,12.37%,1.70%,9.00%,2.30%,90.27,0.87%,"254,447" 472 | 491,WRK,12.11B,14.15,8.82,0.72,0.63,1.04,41.56,16.19,217.50%,10.90%,39.90%,19.63%,5.80%,47.64,4.04%,"1,537,044" 473 | 492,WST,29.03B,47.67,42.36,1.73,10.83,12.91,42.19,101.18,42.50%,6.65%,28.70%,27.60%,8.90%,383.57,-0.03%,"207,136" 474 | 493,WTW,27.94B,13.09,13.83,-,3.10,2.48,12.92,138.29,1.20%,16.47%,8.50%,-,19.60%,223.72,2.22%,"575,213" 475 | 494,WY,30.84B,11.79,23.31,2.36,3.02,2.96,13.26,11.77,160.50%,-27.30%,8.60%,5.00%,7.50%,41.99,2.63%,"2,538,139" 476 | 495,WYNN,10.91B,-,-,-,3.20,-,4.41,-,69.30%,93.00%,-64.60%,-,-12.50%,95.48,3.71%,"2,016,054" 477 | 496,XEL,35.83B,22.43,19.47,3.25,2.67,2.36,56.79,-,5.70%,7.33%,7.60%,6.90%,0.90%,66.03,-0.56%,"2,604,974" 478 | 497,XLNX,53.77B,52.51,44.99,2.79,14.63,13.15,14.52,55.65,-15.90%,7.36%,5.00%,18.83%,7.30%,194.87,0.00%,0 479 | 498,XOM,326.16B,14.65,12.79,2.52,1.16,2.10,68.40,883.89,-265.10%,-5.98%,-27.50%,5.81%,-5.70%,78.07,-1.16%,"16,344,922" 480 | 499,XRAY,11.78B,28.21,16.77,1.09,2.77,2.29,41.92,24.52,-132.30%,10.30%,-17.20%,25.84%,4.60%,56.02,4.63%,"1,126,798" 481 | 500,XYL,16.56B,37.93,26.98,2.02,3.19,5.20,-,33.94,-36.60%,22.97%,-5.60%,18.77%,5.90%,91.30,2.29%,"534,907" 482 | 501,YUM,36.19B,23.30,21.87,1.86,5.50,-,36.16,37.82,-28.80%,13.31%,7.10%,12.52%,-2.50%,122.74,1.10%,"2,426,940" 483 | 502,ZBH,24.98B,57.35,15.86,5.84,3.19,1.92,27.16,20.91,-117.60%,7.43%,-23.70%,9.82%,3.20%,121.77,4.09%,"849,521" 484 | 503,ZBRA,24.07B,27.46,19.25,2.75,4.28,7.64,72.50,23.83,66.10%,12.10%,51.00%,10.00%,9.50%,436.94,2.47%,"308,014" 485 | 504,ZION,11.46B,10.87,12.53,-,5.02,1.58,0.88,66.25,-27.30%,15.75%,20.30%,-,5.20%,74.44,2.87%,"978,333" 486 | 505,ZTS,93.17B,47.31,37.67,3.49,12.23,19.90,28.48,69.58,9.90%,11.67%,38.30%,13.57%,7.00%,197.99,0.79%,"1,947,882" 487 | 505,ZTS,93.17B,47.31,37.67,3.49,12.23,19.90,28.48,69.58,9.90%,11.67%,38.30%,13.57%,7.00%,197.99,0.79%,"1,947,882" 488 | 505,ZTS,93.17B,47.31,37.67,3.49,12.23,19.90,28.48,69.58,9.90%,11.67%,38.30%,13.57%,7.00%,197.99,0.79%,"1,947,882" 489 | 505,ZTS,93.17B,47.31,37.67,3.49,12.23,19.90,28.48,69.58,9.90%,11.67%,38.30%,13.57%,7.00%,197.99,0.79%,"1,947,882" 490 | 1,A,41.93B,34.33,25.55,2.45,6.64,7.55,26.62,39.52,71.00%,10.16%,22.90%,14.00%,8.50%,136.08,0.64%,"1,047,860" 491 | 2,AAL,11.99B,-,8.06,-,0.40,-,0.82,-,-583.80%,200.50%,-29.60%,16.09%,-15.80%,18.67,7.14%,"28,098,806" 492 | 3,AAP,13.97B,22.70,16.89,1.26,1.27,4.41,23.11,21.22,4.40%,11.28%,2.20%,18.00%,0.70%,224.79,0.23%,"1,293,061" 493 | 4,AAPL,2812.90B,28.04,25.72,1.89,7.44,38.47,44.01,32.23,71.40%,6.56%,22.00%,14.85%,11.10%,171.71,1.68%,"36,128,826" 494 | 5,ABBV,254.05B,34.04,11.72,8.30,4.60,18.67,20.74,23.66,-48.50%,-13.83%,-2.80%,4.10%,14.90%,144.07,0.74%,"4,775,198" 495 | 6,ABC,29.59B,18.20,12.11,1.76,0.13,120.84,8.35,16.46,144.40%,7.21%,3.20%,10.34%,7.80%,142.29,1.51%,"482,521" 496 | 7,ABMD,13.77B,100.32,62.90,17.18,13.73,9.22,20.57,56.00,11.40%,5.87%,42.20%,5.84%,20.80%,305.76,5.28%,"209,545" 497 | 8,ABT,221.04B,31.05,23.77,2.36,5.13,6.33,22.81,38.37,24.50%,6.39%,7.80%,13.18%,11.10%,123.84,0.86%,"2,599,786" 498 | 9,ACN,223.32B,33.92,27.69,2.76,4.16,10.13,39.57,45.15,16.00%,11.61%,7.30%,12.28%,7.70%,328.43,0.71%,"1,132,638" 499 | 10,ADBE,233.52B,47.33,29.14,3.08,14.79,15.18,40.28,33.93,-7.60%,17.96%,34.00%,15.35%,21.90%,476.39,0.50%,"1,843,209" 500 | 11,ADI,85.04B,41.77,18.11,2.83,11.62,1.96,43.00,66.33,5.60%,12.61%,4.70%,14.78%,16.40%,160.81,4.44%,"1,741,992" 501 | 12,ADM,42.57B,15.91,14.64,2.41,0.50,1.95,39.31,-,24.80%,0.19%,1.00%,6.60%,-1.00%,76.96,1.10%,"798,787" 502 | 13,ADP,85.57B,31.28,26.61,2.28,5.45,16.79,48.49,62.62,6.80%,11.18%,13.30%,13.71%,5.20%,203.66,0.83%,"470,111" 503 | 14,ADSK,52.41B,38.21,33.42,1.33,12.44,38.99,29.25,37.62,440.10%,35.23%,41.70%,28.84%,8.60%,232.28,2.37%,"692,058" 504 | 15,AEE,21.89B,22.29,21.04,2.82,3.54,2.26,3127.07,21.54,4.50%,5.39%,8.10%,7.90%,-1.00%,85.12,-0.01%,"387,798" 505 | 16,AEP,43.28B,18.45,17.34,3.24,2.65,1.93,27.20,18.60,11.60%,5.97%,3.80%,5.70%,-1.90%,85.78,-0.46%,"1,218,845" 506 | 17,AES,14.84B,28.02,13.14,3.76,1.36,6.24,9.39,-,-85.80%,7.79%,-32.60%,7.45%,-3.00%,21.85,1.82%,"1,263,797" 507 | 18,AFL,42.64B,10.06,11.68,3.18,1.93,1.28,6.87,8.75,50.70%,4.51%,17.90%,3.16%,1.00%,64.87,1.01%,"1,326,842" 508 | 19,AIG,50.17B,9.26,11.10,0.30,1.05,0.78,18.59,16.51,-286.60%,12.44%,-43.90%,30.69%,-5.80%,60.64,2.80%,"1,931,831" 509 | 20,AIZ,9.27B,16.01,11.62,0.94,0.91,1.67,4.57,7.34,35.70%,16.10%,31.00%,17.00%,-1.50%,166.58,2.83%,"253,778" 510 | -------------------------------------------------------------------------------- /config.cfg: -------------------------------------------------------------------------------- 1 | [BINANCE] 2 | KEY = 3 | SECRET = -------------------------------------------------------------------------------- /dashboard.py: -------------------------------------------------------------------------------- 1 | # home page, background ticker loading and such 2 | 3 | from dash import Dash, dcc, html, Input, Output, callback 4 | from pages import backtest, optimise 5 | 6 | 7 | app = Dash(__name__, suppress_callback_exceptions=True) 8 | server = app.server 9 | 10 | app.layout = html.Div([ 11 | dcc.Location(id='url', refresh=False), 12 | html.Div(id='page-content', 13 | children=[ 14 | html.Div( 15 | children=[ 16 | html.H1( 17 | children="pyine dashboard", className="header-title" 18 | ), 19 | html.P( 20 | children="Analyse & optimise your trading strategies, powered by pyine", 21 | className="header-description", 22 | ), 23 | ], 24 | className="header", 25 | ), 26 | html.Div( 27 | children=[ 28 | html.Div( 29 | children=[ 30 | html.Div(children="Backtester", className="menu-title"), 31 | html.Button('', id='submit-val', n_clicks=0), 32 | ] 33 | ), 34 | html.Div( 35 | children=[ 36 | html.Div(children="Optimiser", className="menu-title"), 37 | html.Button('', id='optimiser', n_clicks=0), 38 | ] 39 | ), 40 | ], 41 | className="menu", 42 | ), 43 | ], 44 | ), 45 | ]) 46 | 47 | 48 | @callback(Output('page-content', 'children'), 49 | Input('url', 'pathname')) 50 | def display_page(pathname): 51 | if pathname == '/optimiser': 52 | return optimise.layout 53 | elif pathname == '/backtester': 54 | return backtest.layout 55 | else: 56 | return app.layout 57 | 58 | if __name__ == '__main__': 59 | app.run_server(debug=True) -------------------------------------------------------------------------------- /display.py: -------------------------------------------------------------------------------- 1 | import dash 2 | from dash import * 3 | import pandas as pd 4 | import numpy as np 5 | from dash.dependencies import Output, Input 6 | from dist import strategies 7 | from pyfinviz.screener import Screener 8 | 9 | from dist import data 10 | from dist.engine import optimise, backtest, abstraction 11 | from dist.data import * 12 | from dist.strategies import examples 13 | from dist.utils import listclasses 14 | 15 | from threading import Thread 16 | 17 | import yfinance as yf 18 | 19 | t = [] 20 | 21 | options = [Screener.IndexOption.SANDP_500] 22 | screener = Screener(filter_options=options, view_option=Screener.ViewOption.VALUATION, pages=[x for x in range(1, 30)]) 23 | k = screener.data_frames 24 | l = pd.concat([k[i] for i in k]) 25 | 26 | f = listclasses.get_file_list('dist/strategies') 27 | h = listclasses.get_classes('dist/strategies', f) 28 | g = h[0] 29 | 30 | external_stylesheets = [ 31 | { 32 | "href": "https://fonts.googleapis.com/css2?" 33 | "family=Lato:wght@400;700&display=swap", 34 | "rel": "stylesheet", 35 | }, 36 | ] 37 | app = dash.Dash(__name__, external_stylesheets=external_stylesheets) 38 | app.title = "pyine" 39 | 40 | 41 | app.layout = html.Div( 42 | children=[ 43 | html.Div( 44 | children=[ 45 | html.H1( 46 | children="pyine dashboard", className="header-title" 47 | ), 48 | html.P( 49 | children="Analyse & optimise your trading strategies, powered by pyine", 50 | className="header-description", 51 | ), 52 | ], 53 | className="header", 54 | ), 55 | html.Div( 56 | children=[ 57 | html.Div( 58 | children=[ 59 | html.Div(children="Ticker", className="menu-title"), 60 | dcc.Dropdown( 61 | id="ticker-filter", 62 | options=[ 63 | {"label": ticker, "value": ticker} 64 | for ticker in np.sort(list(l['Ticker'])) 65 | ], 66 | value="AAPL", 67 | clearable=False, 68 | className="dropdown", 69 | ), 70 | ] 71 | ), 72 | html.Div( 73 | children=[ 74 | html.Div(children="Interval", className="menu-title"), 75 | dcc.Dropdown( 76 | id="interval-filter", 77 | options=[ 78 | {"label": interval, "value": interval} 79 | for interval in ['1m','2m','5m','15m','30m','60m','90m','1h','1d','5d','1wk','1mo','3mo']], 80 | value='5m', 81 | clearable=False, 82 | className="dropdown", 83 | ), 84 | ] 85 | ), 86 | html.Div( 87 | children=[ 88 | html.Div(children="Strategy", className="menu-title"), 89 | dcc.Dropdown( 90 | id="strategy-filter", 91 | options=[ 92 | {"label": strategy, "value": strategy} 93 | for strategy in g 94 | ], 95 | value = g[0], 96 | clearable=False, 97 | className="dropdown", 98 | ), 99 | ], 100 | ), 101 | ], 102 | className="menu", 103 | ), 104 | html.Div( 105 | children=[ 106 | html.Div( 107 | children=dcc.Graph( 108 | id="price-chart", config={"displayModeBar": False}, 109 | ), 110 | className="card", 111 | ), 112 | ], 113 | className="wrapper", 114 | ), 115 | ] 116 | ) 117 | 118 | 119 | @app.callback( 120 | [Output("price-chart", "figure"),], 121 | [ 122 | Input("ticker-filter", "value"), 123 | Input("interval-filter", "value"), 124 | Input("strategy-filter", "value"), 125 | ], 126 | ) 127 | def update_charts(ticker, interval, strategy): 128 | strategy = eval(h[-1][strategy]) 129 | 130 | ## data abstraction 131 | #p = abstraction.piston() 132 | #spark = p.spark(interval) 133 | #data = yf.download(ticker, period="5d", interval=spark) 134 | #data = p.crank(data, interval) 135 | 136 | data = pd.read_csv('MNQ 03-22.Last.txt', sep=";", header=None) 137 | data.columns = ["Time", "Open", "High", "Low", "Close", "Volume"] 138 | l = [True for i in range(len(data['Close']))] 139 | data['ABS'] = l 140 | 141 | ## backtest 142 | bt = backtest.piston(strategy, data) 143 | bt.run({'tp':3, 'sl':2}) 144 | 145 | price_chart_figure = { 146 | "data": [ 147 | { 148 | "x": [str(i) for i in range(len(bt.balance_history))], 149 | "y": [i for i in bt.balance_history], 150 | "type": "lines", 151 | "hovertemplate": "$%{y:.2f}", 152 | }, 153 | ], 154 | "layout": { 155 | "title": { 156 | "text": "Average Price of Avocados", 157 | "x": 0.05, 158 | "xanchor": "left", 159 | }, 160 | "xaxis": {"fixedrange": True}, 161 | "yaxis": {"tickprefix": "$", "fixedrange": True}, 162 | "colorway": ["#17B897"], 163 | }, 164 | } 165 | 166 | return [price_chart_figure] 167 | 168 | 169 | if __name__ == "__main__": 170 | app.run_server(debug=True) -------------------------------------------------------------------------------- /dist/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/__init__.py -------------------------------------------------------------------------------- /dist/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /dist/data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/data/__init__.py -------------------------------------------------------------------------------- /dist/data/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/data/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /dist/data/__pycache__/random.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/data/__pycache__/random.cpython-310.pyc -------------------------------------------------------------------------------- /dist/data/crypto.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/data/crypto.py -------------------------------------------------------------------------------- /dist/data/forex.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/data/forex.py -------------------------------------------------------------------------------- /dist/data/random.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | def data(i): 4 | return [random.randint(0,100) for x in range(i)] 5 | -------------------------------------------------------------------------------- /dist/data/stock.py: -------------------------------------------------------------------------------- 1 | class abstract: 2 | def __init__(self, abstraction): 3 | self.conversion 4 | self.valid = ['1m','2m','5m','15m','30m','60m','90m','1h','1d','5d','1wk','1mo','3mo'] 5 | self.abstraction = abstraction 6 | 7 | def _nz(self, x): 8 | return 0 if x <= 0 else x 9 | 10 | def _ab(self, interval): 11 | t = self.valid.index(interval) 12 | return self.valid[self._nz(t-self.abstraction)] 13 | 14 | def download(self, ticker): 15 | pass -------------------------------------------------------------------------------- /dist/data/tickers.py: -------------------------------------------------------------------------------- 1 | tickers = -------------------------------------------------------------------------------- /dist/engine/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/engine/__init__.py -------------------------------------------------------------------------------- /dist/engine/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/engine/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /dist/engine/__pycache__/abstraction.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/engine/__pycache__/abstraction.cpython-310.pyc -------------------------------------------------------------------------------- /dist/engine/__pycache__/backtest.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/engine/__pycache__/backtest.cpython-310.pyc -------------------------------------------------------------------------------- /dist/engine/__pycache__/btv2.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/engine/__pycache__/btv2.cpython-310.pyc -------------------------------------------------------------------------------- /dist/engine/__pycache__/optimise.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/engine/__pycache__/optimise.cpython-310.pyc -------------------------------------------------------------------------------- /dist/engine/abstraction.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from numpy import invert 3 | 4 | import yfinance as yf 5 | 6 | class piston: 7 | def __init__(self, abstraction=1): 8 | self.conversion = { 9 | '1m':60, 10 | '2m':120, 11 | '5m':300, 12 | '15m':900, 13 | '30m':1800, 14 | '60m':3600, 15 | '90m':5400, 16 | '1h':3600, 17 | '1d':86400, 18 | '5d':432000, 19 | '1wk':604800, 20 | '1mo':2592000, 21 | '3mo':7776000, 22 | } 23 | 24 | self.valid = ['1m','2m','5m','15m','30m','60m','90m','1h','1d','5d','1wk','1mo','3mo'] 25 | self.abstraction = abstraction 26 | 27 | self.data = {} 28 | 29 | def crank(self, d, interval): 30 | r = list(d.index.values) 31 | l = lambda x: True if datetime.timestamp(datetime.utcfromtimestamp(x.tolist()/1e9)) % self.conversion[interval] == 0 else False 32 | d['ABS'] = [True if l(r[i]) else False for i in range(len(list(d.index.values)))] 33 | return d 34 | 35 | def _nz(self, x): 36 | return 0 if x <= 0 else x 37 | 38 | def _ab(self, interval): 39 | t = self.valid.index(interval) 40 | return self.valid[self._nz(t-self.abstraction)] 41 | 42 | def spark(self, interval='5m'): 43 | return self._ab(interval) 44 | 45 | -------------------------------------------------------------------------------- /dist/engine/aliases.py: -------------------------------------------------------------------------------- 1 | assignment= { 2 | '==': 'TEQUAL', 3 | } -------------------------------------------------------------------------------- /dist/engine/backtest.py: -------------------------------------------------------------------------------- 1 | #from data import * 2 | import random 3 | import math 4 | 5 | from numpy import NaN 6 | 7 | 8 | class cylinder: 9 | def __init__(self, strategy): 10 | self.strategy = strategy 11 | self.contract = {'O':'', 'C':'', 'R':0} 12 | self.state = 'NEW' 13 | self.res = '' 14 | 15 | def prime(self, data, hist, ABS=True): 16 | if ABS: 17 | x = self.strategy.A(data, hist) 18 | if x: 19 | self.contract = {'O':data, 'C':'', 'R':0, 'D':x} 20 | self.state = 'PRIMED' 21 | 22 | def rotate(self, data, O, params={}): 23 | x = self.strategy.B(data, O, self.contract) 24 | if x: 25 | self.state = 'CLOSED' 26 | self.res = x 27 | self.contract['C'] = data 28 | if self.contract['D'] == 1: 29 | self.contract['R'] = data['Close'] - self.contract['O']['Close'] 30 | elif self.contract['D'] == -1: 31 | self.contract['R'] = self.contract['O']['Close'] - data['Close'] 32 | return True 33 | 34 | class piston: 35 | def __init__(self, strategy, data, balance = 100, target='Close'): 36 | self.strategy = strategy 37 | self.balance = balance 38 | self.data = data 39 | self.target = target 40 | self.history = [] 41 | self.balance_history = [] 42 | 43 | def value(self, portfolio): 44 | b = 0 45 | for i in portfolio: 46 | b += i['R'] 47 | return b 48 | 49 | def run(self, params={}): 50 | c = cylinder 51 | 52 | portfolio = [] 53 | closed = [{'R':0}] 54 | 55 | hist = self.data 56 | 57 | for row in self.data.iterrows(): 58 | #print(row[1]) 59 | d = row[1] 60 | ABS = row[1]['ABS'] 61 | 62 | try: 63 | if portfolio[-1].state != 'NEW': 64 | portfolio.append(c(self.strategy(params))) 65 | except: 66 | portfolio.append(c(self.strategy(params))) 67 | 68 | #print(balance) 69 | if d['Close'] > self.balance: pass 70 | 71 | for i in portfolio: 72 | if i.state == 'NEW': 73 | i.prime(d, hist, ABS) 74 | elif i.state == 'PRIMED': 75 | O = i.contract['O'] 76 | i.rotate(d, O) 77 | 78 | closed = [i.contract for i in portfolio if i.state == 'CLOSED'] 79 | 80 | self.balance_history.append(self.balance) 81 | 82 | for i in closed: 83 | self.balance += i['R'] 84 | self.balance = round(self.balance, 2) 85 | i['BAL'] = round(self.balance,2) 86 | self.history.append(i) 87 | self.balance_history.append(round(self.balance,2)) 88 | 89 | return round(self.balance, 2) 90 | 91 | 92 | 93 | #print([i.contract for i in portfolio]) 94 | 95 | 96 | -------------------------------------------------------------------------------- /dist/engine/btv2.py: -------------------------------------------------------------------------------- 1 | # imports 2 | import itertools 3 | from struct import pack 4 | from numpy import isin, take 5 | import pandas_ta as ta 6 | 7 | 8 | # strategy builder class 9 | import functools 10 | 11 | from dist import data 12 | 13 | # util functions 14 | class Series: 15 | def __init__(self, l=[]): 16 | self.arr = l 17 | 18 | def __repr__(self): # return 19 | return f"{self.arr[-1]}" 20 | 21 | def __str__(self): # print 22 | return f"{self.arr[-1]}" 23 | 24 | def __getitem__(self, item): 25 | item += 1 26 | if item <= len(self.arr): 27 | return self.arr[-item] 28 | else: 29 | raise IndexError(f"There are only {len(self.arr)} elements in the series") 30 | 31 | def __len__(self): 32 | return len(self.arr) 33 | 34 | def __add__(self, other): 35 | return self.arr[-1] + float(other) 36 | 37 | def __sub__(self, other): 38 | return self.arr[-1] - float(other) 39 | 40 | def __mul__(self, other): 41 | if isinstance(other, (int, float, Series)): # Scalar multiplication 42 | return self.arr[-1] * float(other) 43 | else: 44 | raise TypeError("operand must be Series, int, or float") 45 | 46 | def __truediv__(self, other): 47 | if isinstance(other, (int, float, Series)): # Scalar multiplication 48 | return self.arr[-1] / float(other) 49 | else: 50 | raise TypeError("operand must be Series, int, or float") 51 | 52 | # __lt__, __le__, __gt__, __ge__, __eq__ and __ne__ 53 | def __lt__(self, other): 54 | if isinstance(other, (int, float)): # Scalar multiplication 55 | return self.arr[-1] < float(other) 56 | elif isinstance(other, Series): 57 | return self.arr[-1] < other.arr[-1] 58 | else: 59 | raise TypeError("operand must be Series, int, or float") 60 | 61 | def __lte__(self, other): 62 | if isinstance(other, (int, float)): # Scalar multiplication 63 | return self.arr[-1] <= other 64 | elif isinstance(other, Series): 65 | return self.arr[-1] <= other.arr[-1] 66 | else: 67 | raise TypeError("operand must be Series, int, or float") 68 | 69 | def __gt__(self, other): 70 | if isinstance(other, (int, float)): # Scalar multiplication 71 | return self.arr[-1] > float(other) 72 | elif isinstance(other, Series): 73 | return self.arr[-1] > other.arr[-1] 74 | else: 75 | raise TypeError("operand must be Series, int, or float") 76 | 77 | def __ge__(self, other): 78 | if isinstance(other, (int, float)): # Scalar multiplication 79 | return self.arr[-1] >= float(other) 80 | elif isinstance(other, Series): 81 | return self.arr[-1] >= other.arr[-1] 82 | else: 83 | raise TypeError("operand must be Series, int, or float") 84 | 85 | def __eq__(self, other): 86 | if isinstance(other, (int, float)): # Scalar multiplication 87 | return self.arr[-1] == float(other) 88 | elif isinstance(other, Series): 89 | return self.arr[-1] == other.arr[-1] 90 | else: 91 | raise TypeError("operand must be Series, int, or float") 92 | 93 | def __ne__(self, other): 94 | if isinstance(other, (int, float)): # Scalar multiplication 95 | return self.arr[-1] != float(other) 96 | elif isinstance(other, Series): 97 | return self.arr[-1] != other.arr[-1] 98 | else: 99 | raise TypeError("operand must be Series, int, or float") 100 | 101 | # alternative for := 102 | def __iadd__(self, other): 103 | if isinstance(other, Series): 104 | self.arr.append(other.arr[-1]) 105 | else: 106 | self.arr.append(other) 107 | return Series(self.arr) 108 | 109 | def __pow__(self, other): 110 | if isinstance(other, (int, float)): # Scalar multiplication 111 | return self.arr[-1] ** float(other) 112 | elif isinstance(other, Series): 113 | return self.arr[-1] ** other.arr[-1] 114 | else: 115 | raise TypeError("operand must be Series, int, or float") 116 | 117 | 118 | 119 | 120 | 121 | class engine(): 122 | open = Series([]) 123 | high = Series([]) 124 | low = Series([]) 125 | close = Series([]) 126 | volume = Series([]) 127 | 128 | 129 | def __init__(self, strategy, data): 130 | self.strategy = strategy() 131 | self.data = data 132 | 133 | self.open = {} 134 | self.closed = {} 135 | 136 | def create_order(self, x): 137 | self.orders[x['id']] = x 138 | 139 | def iterate(self, data): 140 | engine.open += data['Open'] 141 | engine.high += data['High'] 142 | engine.low += data['Low'] 143 | engine.close += data['Close'] 144 | engine.volume += data['Volume'] 145 | 146 | self.strategy.body(engine.open, engine.high, engine.low, engine.close, engine.volume) 147 | 148 | def run(self): 149 | for row in self.data.iterrows(): 150 | self.iterate(row[1]) 151 | 152 | 153 | 154 | 155 | 156 | 157 | class strategy: 158 | def __init__(self, engine): 159 | self.engine = engine 160 | 161 | def close(self, id, when=True): 162 | if when: 163 | if id in self.engine.orders: 164 | self.engine.closed[self.engine.index] = self.engine.orders[id] 165 | del self.engine.orders[id] 166 | self.engine.index += 1 167 | 168 | def entry(self, id="", type="long", when=True, stoploss=0, takeprofit=0, qty=1): 169 | if when: 170 | if id in self.engine.orders: 171 | self.close(id, when=True) 172 | self.engine.create_order({'id':id, 'type':type, 'stoploss':stoploss, 'takeprofit':takeprofit, 'qty':qty, 'at':engine.close}) 173 | 174 | 175 | 176 | 177 | 178 | def crossover(a,b): 179 | if (len(a) < 2) or (len(b) < 2): return 180 | return (a > b) and (a[1] < b[1]) 181 | 182 | def crossunder(a,b): 183 | if (len(a) < 2) or (len(b) < 2): return 184 | return (a < b) and (a[1] > b[1]) 185 | 186 | 187 | 188 | # get strategy class 189 | class a: 190 | def __init__(self): 191 | self.long_length = 21 192 | self.short_length = 10 193 | 194 | def body(self, open, high, low, close, volume): 195 | 196 | long_EMA = Series(ta.ema(close, self.long_length)) 197 | short_EMA = Series(ta.ema(close, self.short_length)) 198 | print(long_EMA) 199 | 200 | strategy.entry(id="long", when=crossover(long_EMA, short_EMA)) 201 | 202 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /dist/engine/conversion.py: -------------------------------------------------------------------------------- 1 | import js2py 2 | 3 | def functions(s): 4 | l = s.split('=>') 5 | name = s.split('=>')[0].split('(')[0] 6 | args = s.split('=>')[0].split('(')[-1].split(')')[0] 7 | f = l[-1] 8 | x = "{} = function $({})".format(name, args) + "{return" + f + "}" 9 | return x -------------------------------------------------------------------------------- /dist/engine/optimise.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | from itertools import permutations, islice 3 | from os import X_OK 4 | import threading 5 | import math 6 | import random 7 | import tqdm 8 | 9 | try: 10 | import backtest as bt 11 | except: 12 | import dist.engine.backtest as bt 13 | 14 | 15 | 16 | class piston(): 17 | def __init__(self, strategy, params={}): 18 | self.strategy = strategy 19 | s_params = strategy().params 20 | 21 | l = [i for i in params] 22 | for i in l: 23 | s_params[i] = params[i] 24 | 25 | self.params = s_params 26 | 27 | for i in self.params: 28 | if not isinstance(self.params[i], list): 29 | self.params[i] = [self.params[i]] 30 | if len(self.params[i]) < 3: 31 | self.params[i] = self._util(self.params[i]) 32 | 33 | for i in self.params: 34 | self.params[i] = self._a(self.params[i]) 35 | 36 | self.basis = [i for i in self.params] 37 | self.d = {} 38 | for i in self.basis: 39 | self.d[i] = self.basis.index(i) 40 | self.par = list(itertools.product(*[self.params[i] for i in self.params])) 41 | 42 | self.results = [] 43 | 44 | def _util(self, l): 45 | x = l[0] 46 | return [x,x,x] 47 | 48 | def _a(self, l): 49 | x = l[0] 50 | y = l[1] 51 | z = l[2] 52 | l = [i for i in range(x, y+1, z)] 53 | return l 54 | 55 | def cp(self, lsts): 56 | return list(itertools.product(*lsts)) 57 | 58 | def chunks(self, l, n): 59 | out = [] 60 | a = len(l) 61 | n = a if n > a else n 62 | x = math.floor(a/n) 63 | ##print(x) 64 | for i in range(n-1): 65 | out.append(l[i*x:(i+1)*x]) 66 | ##print(out) 67 | out.append(l[(n-1)*x:]) 68 | return out 69 | 70 | def check_engine(self): 71 | d = [i for i in self.results if type(i) is dict] 72 | srt = sorted(d, key=lambda x: x['result']) 73 | return srt, srt[-1]['result'] 74 | 75 | def motor(self, data, q, status=False): 76 | ##print('#####', q) 77 | if status: 78 | for params in tqdm.tqdm(q): 79 | ##print(params) 80 | BT = bt.piston(self.strategy, data, balance = 100) 81 | res = BT.run(params=params[1]) 82 | results = {} 83 | results['result'] = res 84 | results['hist'] = BT.balance_history 85 | results['param'] = params 86 | self.results.append(results) 87 | else: 88 | for params in q: 89 | #print(params) 90 | BT = bt.piston(self.strategy, data, balance = 100) 91 | res = BT.run(params) 92 | results = {} 93 | results['result'] = res 94 | results['hist'] = BT.balance_history 95 | results['param'] = params 96 | self.results.append(results) 97 | 98 | 99 | def crank(self, data=[], num_threads=4, status=False): 100 | g = [] 101 | k = self.d 102 | for b in range(len(self.par)): 103 | p = {} 104 | ##print(b) 105 | j = self.par[b] 106 | ##print(j) 107 | for i in k: 108 | ##print(j[i]) 109 | p[i] = j[k[i]] 110 | ##print(p) 111 | g.append(p) 112 | 113 | ##print(g) 114 | param = self.chunks(g, 4) 115 | ##print(param) 116 | 117 | oil = [threading.Thread(target=self.motor, args=(data, i, status)) for i in param] 118 | ##print(len(oil)) 119 | 120 | for spark in oil: 121 | spark.start() 122 | for spark in oil: 123 | spark.join() 124 | 125 | return self.check_engine() 126 | 127 | 128 | -------------------------------------------------------------------------------- /dist/strategies/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | l = [i.name.split('.')[0] for i in os.scandir('dist/strategies') if '__' not in i.name] 4 | 5 | for i in l: 6 | exec('from .{} import *'.format(i)) 7 | -------------------------------------------------------------------------------- /dist/strategies/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/strategies/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /dist/strategies/__pycache__/examples.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/strategies/__pycache__/examples.cpython-310.pyc -------------------------------------------------------------------------------- /dist/strategies/__pycache__/t.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/strategies/__pycache__/t.cpython-310.pyc -------------------------------------------------------------------------------- /dist/strategies/examples.py: -------------------------------------------------------------------------------- 1 | import pandas_ta as ta 2 | 3 | from dist.utils.calculators import * 4 | 5 | 6 | class s: 7 | def __init__(self, params): 8 | self.params = params 9 | self.src = 'Close' 10 | 11 | def A(self, data): 12 | if data[self.src] >= 17: return True 13 | 14 | def B(self, data, O, params={}): 15 | a = data[self.src] 16 | O = O['Close'] 17 | tp = O + self.params['tp'] 18 | sl = O - self.params['sl'] 19 | #print(a, tp) 20 | if a >= tp: 21 | return 'PROFIT' 22 | elif a <= sl: 23 | return 'STOP' 24 | -------------------------------------------------------------------------------- /dist/strategies/t.py: -------------------------------------------------------------------------------- 1 | class a: 2 | pass -------------------------------------------------------------------------------- /dist/utils/__pycache__/calculators.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/utils/__pycache__/calculators.cpython-310.pyc -------------------------------------------------------------------------------- /dist/utils/__pycache__/listclasses.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/utils/__pycache__/listclasses.cpython-310.pyc -------------------------------------------------------------------------------- /dist/utils/__pycache__/series.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/dist/utils/__pycache__/series.cpython-310.pyc -------------------------------------------------------------------------------- /dist/utils/calculators.py: -------------------------------------------------------------------------------- 1 | def crossover(a,b): 2 | if a[len(a)-1] > b[len(b)-1] and a[len(a)-2] < b[len(b)-2]: 3 | return True 4 | 5 | 6 | def mktbuy(): 7 | return 1 8 | 9 | def mktsell(): 10 | return -1 -------------------------------------------------------------------------------- /dist/utils/get_ticker_list.py: -------------------------------------------------------------------------------- 1 | from pyfinviz.screener import Screener 2 | import pandas as pd 3 | 4 | def SANDP500(): 5 | options = [Screener.IndexOption.SANDP_500] 6 | screener = Screener(filter_options=options, view_option=Screener.ViewOption.VALUATION, pages=[x for x in range(1, 30)]) 7 | k = screener.data_frames 8 | l = pd.concat([k[i] for i in k]) 9 | l.to_csv('assets/tickers.csv', encoding='utf-8', index=False) 10 | 11 | 12 | -------------------------------------------------------------------------------- /dist/utils/listclasses.py: -------------------------------------------------------------------------------- 1 | import ast 2 | import os 3 | 4 | def get_file_list(path): 5 | directories = os.listdir( path ) 6 | return [file for file in directories if '__' not in file] 7 | 8 | def show_info(functionNode): 9 | print("Function name:", functionNode.name) 10 | print("Args:") 11 | for arg in functionNode.args.args: 12 | #import pdb; pdb.set_trace() 13 | print("\tParameter name:", arg.arg) 14 | 15 | def get_classes(path, l): 16 | c = [] 17 | d = {} 18 | for i in l: 19 | with open(path+'/{}'.format(i)) as file: 20 | node = ast.parse(file.read()) 21 | classes = [n for n in node.body if isinstance(n, ast.ClassDef)] 22 | for class_ in classes: 23 | c.append(class_.name) 24 | d[class_.name] = i.strip('.py')+'.{}'.format(class_.name) 25 | return c, d 26 | -------------------------------------------------------------------------------- /dist/utils/series.py: -------------------------------------------------------------------------------- 1 | class Series: 2 | def __init__(self, l=[]): 3 | self.arr = l 4 | 5 | def __repr__(self): # return 6 | return f"{self.arr[-1]}" 7 | 8 | def __str__(self): # print 9 | return f"{self.arr[-1]}" 10 | 11 | def __getitem__(self, item): 12 | item += 1 13 | if item <= len(self.arr): 14 | return self.arr[-item] 15 | else: 16 | raise IndexError(f"There are only {len(self.arr)} elements in the series") 17 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import random 2 | from dist import data 3 | from dist.engine import optimise, backtest, abstraction 4 | from dist.data import * 5 | from dist.strategies import examples 6 | 7 | import yfinance as yf 8 | 9 | strategy = examples.MovingAverageCrossover 10 | 11 | ## data abstraction 12 | p = abstraction.piston() 13 | interval = '15m' 14 | spark = p.spark(interval) 15 | data = yf.download("TSLA", period="5d", interval=spark) 16 | data = p.crank(data, interval) 17 | 18 | ## backtest 19 | bt = backtest.piston(strategy, data) 20 | backtest_result = bt.run({'tp':3, 'sl':2}) 21 | 22 | opp = [backtest.piston(strategy, data).__class__(strategy,data).run({'tp':i+1, 'sl':2}) for i in range(3)] 23 | 24 | ## optimise 25 | op = optimise.piston(strategy, {'tp':[1,3,1]}) 26 | optimise_result = op.crank(data, num_threads=4, status=False) 27 | -------------------------------------------------------------------------------- /pages/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/pages/__init__.py -------------------------------------------------------------------------------- /pages/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/pages/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /pages/__pycache__/backtest.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/pages/__pycache__/backtest.cpython-310.pyc -------------------------------------------------------------------------------- /pages/__pycache__/optimise.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomCallan/pyine/a791c6c9c45075d44a22f47d08b4b27e8ec482c7/pages/__pycache__/optimise.cpython-310.pyc -------------------------------------------------------------------------------- /pages/backtest.py: -------------------------------------------------------------------------------- 1 | import dash 2 | from dash import * 3 | from dash.dependencies import Output, Input 4 | 5 | import math 6 | import json 7 | import pandas as pd 8 | import numpy as np 9 | 10 | from dist import strategies 11 | from dist import data 12 | from dist.engine import backtest, abstraction 13 | from dist.utils import listclasses 14 | from dist.strategies import * 15 | 16 | import yfinance as yf 17 | 18 | 19 | l = pd.read_csv('assets/tickers.csv') 20 | 21 | f = listclasses.get_file_list('dist/strategies') 22 | h = listclasses.get_classes('dist/strategies', f) 23 | g = h[0] 24 | 25 | d = {} 26 | 27 | external_stylesheets = [ 28 | { 29 | "href": "https://fonts.googleapis.com/css2?" 30 | "family=Lato:wght@400;700&display=swap", 31 | "rel": "stylesheet", 32 | }, 33 | ] 34 | 35 | layout = html.Div( 36 | children=[ 37 | html.Div( 38 | children=[ 39 | html.H1( 40 | children="backtester", className="header-title" 41 | ), 42 | html.P( 43 | children="Analyse & optimise your trading strategies, powered by pyine", 44 | className="header-description", 45 | ), 46 | ], 47 | className="header", 48 | ), 49 | html.Div( 50 | children=[ 51 | html.Div( 52 | children=[ 53 | html.Div(children="Ticker", className="menu-title"), 54 | dcc.Dropdown( 55 | id="ticker-filter", 56 | options=[ 57 | {"label": ticker, "value": ticker} 58 | for ticker in np.sort(list(l['Ticker'])) 59 | ], 60 | value="AAPL", 61 | clearable=False, 62 | className="dropdown", 63 | ), 64 | ] 65 | ), 66 | html.Div( 67 | children=[ 68 | html.Div(children="Interval", className="menu-title"), 69 | dcc.Dropdown( 70 | id="interval-filter", 71 | options=[ 72 | {"label": interval, "value": interval} 73 | for interval in ['1m','2m','5m','15m','30m','60m','90m','1h','1d','5d','1wk','1mo','3mo']], 74 | value='5m', 75 | clearable=False, 76 | className="dropdown", 77 | ), 78 | ] 79 | ), 80 | html.Div( 81 | children=[ 82 | html.Div(children="Strategy", className="menu-title"), 83 | dcc.Dropdown( 84 | id="strategy-filter", 85 | options=[ 86 | {"label": strategy, "value": strategy} 87 | for strategy in g 88 | ], 89 | value = g[0], 90 | clearable=False, 91 | className="dropdown", 92 | ), 93 | ], 94 | ), 95 | ], 96 | className="menu", 97 | ), 98 | 99 | html.Div( 100 | children=[ 101 | html.Div( 102 | children=[ 103 | html.Div(children="Parameters", className="menu-title"), 104 | dcc.Dropdown( 105 | id="param-filter", 106 | className="dropdown" 107 | ), 108 | ], 109 | ), 110 | html.Div( 111 | children=[ 112 | html.Div(children="Input", className="menu-title"), 113 | dcc.Input( 114 | id="param-input", 115 | className="input", 116 | debounce=True, 117 | ), 118 | ], 119 | ), 120 | html.Div( 121 | children=[ 122 | html.Div(children="Out", className="menu-title"), 123 | html.Div( 124 | html.P( 125 | id="params-output", 126 | ), 127 | className="output" 128 | ), 129 | ], 130 | ), 131 | ], 132 | className="menu2", 133 | ), 134 | 135 | html.Div( 136 | children=[ 137 | html.Div( 138 | children=dcc.Graph( 139 | id="price-chart", config={"displayModeBar": False}, 140 | ), 141 | className="card", 142 | ), 143 | html.Div( 144 | children=[ 145 | html.Div( 146 | html.P( 147 | id="profit", 148 | ), 149 | className="output card stats" 150 | ), 151 | html.Div( 152 | html.P( 153 | id="drawdown", 154 | ), 155 | className="output card stats" 156 | ), 157 | html.Div( 158 | html.P( 159 | id="sharpe", 160 | ), 161 | className="output card stats" 162 | ), 163 | ], 164 | className="menu3", 165 | ), 166 | ], 167 | className="wrapper", 168 | ), 169 | ] 170 | ) 171 | 172 | 173 | @callback( 174 | [Output("param-filter", "options")], 175 | [ 176 | Input("strategy-filter", "value") 177 | ] 178 | ) 179 | def update_params(strat): 180 | global d 181 | d = {} 182 | strategy = eval(h[-1][strat])() 183 | params = [i for i in strategy.params] 184 | fig = [{"label":i, "value":i} for i in params] 185 | return [fig] 186 | 187 | 188 | 189 | @callback( 190 | [Output("price-chart", "figure"), Output("param-input", "value"), Output("params-output", "children"), Output("profit", "children"), Output("drawdown", "children"), Output("sharpe", "children")], 191 | [ 192 | Input("ticker-filter", "value"), 193 | Input("interval-filter", "value"), 194 | Input("strategy-filter", "value"), 195 | Input("param-filter", "value"), 196 | Input("param-input", "value"), 197 | ], 198 | ) 199 | def update_charts(ticker, interval, strat, param, paramval): 200 | global d 201 | 202 | strategy = eval(h[-1][strat]) 203 | strat = strategy() 204 | 205 | if paramval and param: d[param] = paramval 206 | 207 | params = strat.params 208 | 209 | for param in d: 210 | params[param] = d[param] 211 | 212 | print(params) 213 | 214 | strat = '' 215 | 216 | ## data abstraction 217 | p = abstraction.piston() 218 | spark = p.spark(interval) 219 | data = yf.download(ticker, period="5d", interval=spark) 220 | data = p.crank(data, interval) 221 | 222 | ## backtest 223 | bt = backtest.piston(strategy, data) 224 | out = bt.run(params) 225 | 226 | drawdown=abs(min(bt.balance_history)) 227 | profit=out 228 | sharpe=0 229 | 230 | 231 | price_chart_figure = { 232 | "data": [ 233 | { 234 | "x": [str(i) for i in range(len(bt.balance_history))], 235 | "y": [i for i in bt.balance_history], 236 | "type": "lines", 237 | "hovertemplate": "$%{y:.2f}", 238 | }, 239 | ], 240 | "layout": { 241 | "xaxis": {"fixedrange": True}, 242 | "yaxis": {"tickprefix": "$", "fixedrange": True}, 243 | "colorway": ["#17B897"], 244 | }, 245 | } 246 | 247 | return [price_chart_figure, '', ["{} : {} | ".format(i, d[i]) for i in d] if d else '',["Total Profit : {}".format(profit)],["Max Drawdown : {}".format(drawdown)],["Sharpe Ratio : {}".format(sharpe)]] 248 | -------------------------------------------------------------------------------- /pages/optimise.py: -------------------------------------------------------------------------------- 1 | import dash 2 | from dash import * 3 | from dash.dependencies import Output, Input 4 | 5 | import math 6 | import json 7 | import pandas as pd 8 | import numpy as np 9 | 10 | from dist import strategies 11 | from dist import data 12 | from dist.engine import backtest, optimise, abstraction 13 | from dist.utils import listclasses 14 | from dist.strategies import * 15 | 16 | import yfinance as yf 17 | 18 | 19 | l = pd.read_csv('assets/tickers.csv') 20 | 21 | f = listclasses.get_file_list('dist/strategies') 22 | h = listclasses.get_classes('dist/strategies', f) 23 | g = h[0] 24 | 25 | d = {} 26 | 27 | external_stylesheets = [ 28 | { 29 | "href": "https://fonts.googleapis.com/css2?" 30 | "family=Lato:wght@400;700&display=swap", 31 | "rel": "stylesheet", 32 | }, 33 | ] 34 | 35 | layout = html.Div( 36 | children=[ 37 | html.Div( 38 | children=[ 39 | html.H1( 40 | children="optimiser", className="header-title" 41 | ), 42 | html.P( 43 | children="Analyse & optimise your trading strategies, powered by pyine", 44 | className="header-description", 45 | ), 46 | ], 47 | className="header", 48 | ), 49 | html.Div( 50 | children=[ 51 | html.Div( 52 | children=[ 53 | html.Div(children="Ticker", className="menu-title"), 54 | dcc.Dropdown( 55 | id="o-ticker-filter", 56 | options=[ 57 | {"label": ticker, "value": ticker} 58 | for ticker in np.sort(list(l['Ticker'])) 59 | ], 60 | value="AAPL", 61 | clearable=False, 62 | className="dropdown", 63 | ), 64 | ] 65 | ), 66 | html.Div( 67 | children=[ 68 | html.Div(children="Interval", className="menu-title"), 69 | dcc.Dropdown( 70 | id="o-interval-filter", 71 | options=[ 72 | {"label": interval, "value": interval} 73 | for interval in ['1m','2m','5m','15m','30m','60m','90m','1h','1d','5d','1wk','1mo','3mo']], 74 | value='5m', 75 | clearable=False, 76 | className="dropdown", 77 | ), 78 | ] 79 | ), 80 | html.Div( 81 | children=[ 82 | html.Div(children="Strategy", className="menu-title"), 83 | dcc.Dropdown( 84 | id="o-strategy-filter", 85 | options=[ 86 | {"label": strategy, "value": strategy} 87 | for strategy in g 88 | ], 89 | value = g[0], 90 | clearable=False, 91 | className="dropdown", 92 | ), 93 | ], 94 | ), 95 | ], 96 | className="menu", 97 | ), 98 | 99 | html.Div( 100 | children=[ 101 | html.Div( 102 | children=[ 103 | html.Div(children="Parameters", className="menu-title"), 104 | dcc.Dropdown( 105 | id="o-param-filter", 106 | className="dropdown" 107 | ), 108 | ], 109 | ), 110 | html.Div( 111 | children=[ 112 | html.Div(children="Input", className="menu-title"), 113 | dcc.Input( 114 | id="o-param-input", 115 | className="input", 116 | debounce=True, 117 | ), 118 | ], 119 | ), 120 | html.Div( 121 | children=[ 122 | html.Div(children="Out", className="menu-title"), 123 | html.Div( 124 | html.P( 125 | id="o-params-output", 126 | ), 127 | className="output" 128 | ), 129 | ], 130 | ), 131 | ], 132 | className="menu2", 133 | ), 134 | 135 | html.Div( 136 | children=[ 137 | html.Div( 138 | children=dcc.Graph( 139 | id="o-price-chart", config={"displayModeBar": False}, 140 | ), 141 | className="card", 142 | ), 143 | html.Div( 144 | children=[ 145 | html.Div( 146 | html.P( 147 | id="o_profit", 148 | ), 149 | className="output card stats" 150 | ), 151 | html.Div( 152 | html.P( 153 | id="o_drawdown", 154 | ), 155 | className="output card stats" 156 | ), 157 | html.Div( 158 | html.P( 159 | id="o_sharpe", 160 | ), 161 | className="output card stats" 162 | ), 163 | ], 164 | className="menu3", 165 | ), 166 | ], 167 | className="wrapper", 168 | ), 169 | ] 170 | ) 171 | 172 | 173 | @callback( 174 | [Output("o-param-filter", "options")], 175 | [ 176 | Input("o-strategy-filter", "value") 177 | ] 178 | ) 179 | def update_params(strat): 180 | global d 181 | d = {} 182 | strategy = eval(h[-1][strat])() 183 | params = [i for i in strategy.params] 184 | fig = [{"label":i, "value":i} for i in params] 185 | return [fig] 186 | 187 | 188 | 189 | @callback( 190 | [Output("o-price-chart", "figure"), Output("o-param-input", "value"), Output("o-params-output", "children"), Output("o_profit", "children"), Output("o_drawdown", "children"), Output("o_sharpe", "children")], 191 | [ 192 | Input("o-ticker-filter", "value"), 193 | Input("o-interval-filter", "value"), 194 | Input("o-strategy-filter", "value"), 195 | Input("o-param-filter", "value"), 196 | Input("o-param-input", "value"), 197 | ], 198 | ) 199 | def update_charts(ticker, interval, strat, param, paramval): 200 | global d 201 | 202 | strategy = eval(h[-1][strat]) 203 | strat = strategy() 204 | 205 | if paramval and param: d[param] = paramval 206 | 207 | params = strat.params 208 | 209 | for param in d: 210 | params[param] = [int(i) for i in d[param].split(',')] 211 | 212 | print(params) 213 | 214 | strat = '' 215 | 216 | ## data abstraction 217 | p = abstraction.piston() 218 | spark = p.spark(interval) 219 | data = yf.download(ticker, period="5d", interval=spark) 220 | data = p.crank(data, interval) 221 | 222 | ## backtest 223 | par = [i for i in params] 224 | 225 | op = optimise.piston(strategy, params) 226 | optimise_result = op.crank(data, num_threads=4, status=False) 227 | 228 | 229 | best = optimise_result[0][-1]['param'] 230 | 231 | 232 | bt = backtest.piston(strategy, data) 233 | out = bt.run(best) 234 | 235 | 236 | o_sharpe = 0 237 | o_profit = optimise_result[-1] - optimise_result[0][-1]['hist'][0] 238 | o_drawdown = min(optimise_result[0][-1]['hist']) - optimise_result[0][-1]['hist'][0] 239 | 240 | price_chart_figure = { 241 | "data": [ 242 | { 243 | "x": [str(i) for i in range(len(res['hist']))], 244 | "y": res['hist'], 245 | "type": "lines", 246 | "hovertemplate": "$%{y:.2f} : "+str(res['param']), 247 | } for res in optimise_result[0][-10::] 248 | ], 249 | "layout": { 250 | "xaxis": {"fixedrange": True}, 251 | "yaxis": {"tickprefix": "$", "fixedrange": True}, 252 | "colorway": ["#17B897"], 253 | }, 254 | } 255 | 256 | return [price_chart_figure, '', ["{}".format(best)] if best else '',["Total Profit : ${}".format(round(o_profit, 2))],["Max Drawdown : ${}".format(round(o_drawdown),2)],["Sharpe Ratio : {}".format(o_sharpe)]] 257 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [Development](https://discord.gg/QEw3mpE8t3) 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.10.0 2 | Brotli==1.0.9 3 | certifi==2021.10.8 4 | charset-normalizer==2.0.10 5 | click==8.0.3 6 | colorama==0.4.4 7 | dash==2.1.0 8 | dash-core-components==2.0.0 9 | dash-html-components==2.0.0 10 | dash-table==5.0.0 11 | decorator==5.1.1 12 | distlib==0.3.4 13 | filelock==3.4.2 14 | Flask==2.0.2 15 | Flask-Compress==1.10.1 16 | free-proxy==1.0.6 17 | idna==3.3 18 | itsdangerous==2.0.1 19 | Jinja2==3.0.3 20 | Js2Py==0.71 21 | lxml==4.7.1 22 | MarkupSafe==2.0.1 23 | multitasking==0.0.10 24 | numpy==1.22.2 25 | pandas==1.3.5 26 | pandas-ta==0.3.14b0 27 | platformdirs==2.4.1 28 | plotly==5.6.0 29 | pyfinviz==0.7 30 | pyjsparser==2.7.1 31 | python-dateutil==2.8.2 32 | pytz==2021.3 33 | pytz-deprecation-shim==0.1.0.post0 34 | requests==2.27.1 35 | six==1.16.0 36 | soupsieve==2.3.1 37 | tenacity==8.0.1 38 | tqdm==4.62.3 39 | tzdata==2021.5 40 | tzlocal==4.1 41 | urllib3==1.26.8 42 | validators==0.18.2 43 | virtualenv==20.13.0 44 | Werkzeug==2.0.3 45 | yfinance==0.1.69 -------------------------------------------------------------------------------- /t.py: -------------------------------------------------------------------------------- 1 | import js2py 2 | from series import Series 3 | 4 | def functions(s): 5 | l = s.split('=>') 6 | name = s.split('=>')[0].split('(')[0] 7 | args = s.split('=>')[0].split('(')[-1].split(')')[0] 8 | f = l[-1] 9 | x = "{} = function $({})".format(name, args) + "{return" + f + "}" 10 | return x 11 | 12 | #for line in file: 13 | # # relace math with Math 14 | # if "?" and ":" in line: 15 | # js2py.eval_js(line) 16 | # if "=>": 17 | # functions(s) 18 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | import random 2 | from re import X 3 | from dist import data 4 | from dist.engine import optimise, backtest, abstraction, btv2 5 | from dist.data import * 6 | from dist.strategies import examples 7 | 8 | import yfinance as yf 9 | 10 | ## data abstraction 11 | p = abstraction.piston() 12 | interval = '15m' 13 | spark = p.spark(interval) 14 | data = yf.download("TSLA", period="5d", interval=spark) 15 | data = p.crank(data, interval) 16 | 17 | ## declare environment 18 | engine = btv2.engine(data) 19 | strategy = btv2.strategy(engine) 20 | 21 | #a = btv2.a() 22 | 23 | #engine.iterate(a) 24 | 25 | 26 | 27 | def t(): 28 | global x 29 | print(x) 30 | x+=random.randint(0,10) 31 | 32 | 33 | class a: 34 | x = btv2.Series([1]) 35 | 36 | def c(self): 37 | print(a.x) 38 | a.x+=random.randint(0,10) --------------------------------------------------------------------------------