diff --git a/app.py b/app.py index a65ef30..eeecaa4 100644 --- a/app.py +++ b/app.py @@ -7,6 +7,7 @@ parser.add_argument("--host", type=str, default="0.0.0.0", help="host address") parser.add_argument("--debug", action="store_true", help="debug mode") app = flask.Flask(__name__) +app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 @app.route("/dist/") def distServe(m:str): @@ -17,8 +18,6 @@ def index(): import pages return flask.render_template("index.html", pages = pages.GenLists) - - if __name__ == '__main__': args = parser.parse_args() app.run(host=args.host, port=args.port, debug=args.debug) diff --git a/db.py b/db.py index 25384ce..ab7a1a4 100644 --- a/db.py +++ b/db.py @@ -109,7 +109,7 @@ def update_krx(nday:int = 90): ClosingMonth = ?, Representative = ?, Homepage = ?, - AddressArea = ?, + AddressArea = ? WHERE Code = ?; """,(row["name"],row["업종"],row["주요제품"],row["상장일"],row["결산월"],row["대표자명"],row["홈페이지"],row["지역"],code )) diff --git a/gen.py b/gen.py index e4646c6..7518403 100644 --- a/gen.py +++ b/gen.py @@ -17,6 +17,19 @@ class DataStore: def getAllKRXCorp(self) -> List[database.KRXCorp]: return database.GetAllKRXCorp(self.db) + def _getCorpsInCorpGroup(self, table_name: str) -> List[database.KRXCorp]: + cursor = self.db.execute(f"select c.* from {table_name} as k INNER JOIN KRXCorp as c on k.Name = c.Name") + return [database.KRXCorp.from_db(r) for r in cursor] + + def getKosdaq(self) -> List[database.KRXCorp]: + return self._getCorpsInCorpGroup("KOSDAQ") + + def getKospi(self) -> List[database.KRXCorp]: + return self._getCorpsInCorpGroup("KOSPI") + + def getKosdaqAndKospi(self) -> List[database.KRXCorp]: + return self.getKospi() + self.getKosdaq() + def getStockPrice(self,code,length) -> pd.DataFrame: if code in self.pricesCache and len(self.pricesCache[code]) >= length: return self.pricesCache[code] @@ -85,6 +98,16 @@ def isDiffGreaterThan(a:pd.Series,b:pd.Series, nday:int) -> bool: """a is bigger than b""" return (a.iloc[nday] > b.iloc[nday]) +def calc_rsi(price: pd.Series, period: int = 14): + delta = price.diff() + up, down = delta.copy(), delta.copy() + up[up < 0] = 0 + down[down > 0] = 0 + roll_up1 = up.rolling(period).mean() + roll_down1 = down.abs().rolling(period).mean() + RS1 = roll_up1 / roll_down1 + return pd.Series(100 - (100 / (1 + RS1)), name='RSI') + def prepareCollector(collector: OutputCollector) -> None: import pages for item in pages.GenLists: @@ -97,76 +120,139 @@ def every(f, xs): return True def collect(data: DataStore, collector: OutputCollector, corp: database.KRXCorp -, nday: int) -> None: - stock = data.getStockPrice(corp.Code,120) - if len(stock) < 120: - return - if (stock.iloc[nday]['VOLUME'] <= 0): +, ndays: List[int]) -> None: + stock = data.getStockPrice(corp.Code,250) + if len(stock) <= 245: return + for nday in ndays: + if (stock.iloc[nday]['VOLUME'] <= 0): + return close = stock["CLOSE"] - d5 = stock["CLOSE"].loc[::-1].rolling(window=5 - ).mean().dropna().loc[::-1] - d10 = stock["CLOSE"].loc[::-1].rolling(window=10 - ).mean().dropna().loc[::-1] - d20 = stock["CLOSE"].loc[::-1].rolling(window=20 - ).mean().dropna().loc[::-1] - d30 = stock["CLOSE"].loc[::-1].rolling(window=30 - ).mean().dropna().loc[::-1] - d60 = stock["CLOSE"].loc[::-1].rolling(window=60 + openv = stock["OPEN"] + #high = stock["HIGH"] + #low = stock["LOW"] + #d3 = close.loc[::-1].rolling(window=3 + # ).mean().dropna().loc[::-1] + fetch_len = len(ndays) + 10 + def d(n): + return close.iloc[:(n+fetch_len)].loc[::-1].rolling(window=n ).mean().dropna().loc[::-1] - a = [d5, d10, d20, d30, d60] - if every(lambda i: isRelativeDiffLessThan(i,close,0.05,nday), a): - collector.collect("뭉침", corp, stock.index[nday]) - if every(lambda i: isRelativeDiffLessThan(i,close,0.01,nday), a): - collector.collect("뭉침01", corp, stock.index[nday]) - if every(lambda i: isRelativeDiffLessThan(i,close,0.03,nday), a): - collector.collect("뭉침03", corp, stock.index[nday]) - - if (isRelativeDiffLessThan(d5, d20, 0.01, nday) and - isRelativeDiffLessThan(d5, d60, 0.01, nday)): - collector.collect("cross 2", corp, stock.index[nday]) - if (isVolumeNTimes(stock, 3, 0) and - isVolumeMulPriceGreaterThan(stock, 100000, nday)): - collector.collect("cross 3", corp, stock.index[nday]) - - if (isRelativeDiffLessThan(d20, d60, 0.01, nday) and - isVolumeMulPriceGreaterThan(stock, 1000000, nday)): - collector.collect("cross 4", corp, stock.index[nday]) - - if (isDiffGreaterThan(d5, d20, nday)): - collector.collect("d20d5", corp, stock.index[nday]) + def d_std(n): + return close.iloc[:(n+fetch_len)].loc[::-1].rolling(window=n + ).std().dropna().loc[::-1] + d5 = d(5) + d20 = d(20) + d25 = d(25) + d30 = d(30) + d45 = d(45) + d60 = d(60) + d120 = d(120) + d240 = d(240) + + # 표준편차 + d_std25 = d_std(25) + + bollinger_upperband = d25 + 2* d_std25 + + a = [d20, d30, d60, d120] + for nday in ndays: + if openv[nday] <= d20[nday] and d20[nday] <= close[nday]: + collector.collect("양봉사이20일선", corp, stock.index[nday]) + + if bollinger_upperband[nday] <= close[nday]: + collector.collect("볼린저 밴드 25", corp, stock.index[nday]) + + if every(lambda i: isRelativeDiffLessThan(i,close,0.05,nday), a): + collector.collect("뭉침", corp, stock.index[nday]) + if d120[nday + 1] < d120[nday]: + collector.collect("뭉침5% 120선 상승", corp, stock.index[nday]) + + if every(lambda i: isRelativeDiffLessThan(i,close,0.01,nday), a): + collector.collect("뭉침01", corp, stock.index[nday]) + if every(lambda i: isRelativeDiffLessThan(i,close,0.03,nday), a): + collector.collect("뭉침03", corp, stock.index[nday]) + if d120[nday + 1] < d120[nday]: + collector.collect("뭉침3% 120선 상승", corp, stock.index[nday]) + + if every(lambda i: isRelativeDiffLessThan(i,close,0.05,nday), [d20, d30, d60, d120, d240]): + collector.collect("뭉침 240선까지", corp, stock.index[nday]) + + if (d5[nday] > d20[nday] and d5[nday + 1] < d20[nday + 1]): + collector.collect("cross d20 and d5", corp, stock.index[nday]) + + if (isDiffGreaterThan(d5, d20, nday)): + collector.collect("d20d5", corp, stock.index[nday]) + if (isVolumeNTimes(stock, 5, nday)): + collector.collect("d20d5VolumeX5", corp, stock.index[nday]) + + if (isVolumeNTimes(stock, 3, nday)): + collector.collect("volume", corp, stock.index[nday]) + + if (isVolumeMulPriceGreaterThan(stock, 50000000, nday)): + collector.collect("volume5", corp, stock.index[nday]) + if (isVolumeNTimes(stock, 5, nday)): - collector.collect("d20d5VolumeX5", corp, stock.index[nday]) - - if (isRelativeDiffLessThan(d5, d20, 0.03, nday) and - isRelativeDiffLessThan(d5, d60, 0.03, nday) and - isVolumeNTimes(stock, 3, nday)): - collector.collect("DiffDistance", corp, stock.index[nday]) + collector.collect("volumeX5", corp, stock.index[nday]) + D240BiggerThanYesterDay = d240[nday + 1] <= d240[nday] + D240Bounce = d240[nday + 2] >= d240[nday + 1] and D240BiggerThanYesterDay + D120Bounce = d120[nday + 2] >= d120[nday + 1] and d120[nday + 1] <= d120[nday] + # D240Cross = low[nday] <= d240[nday] and d240[nday] <= high[nday] + if (D240Bounce): + collector.collect("240일선 반등",corp,stock.index[nday]) + if (D120Bounce): + collector.collect("120일선 반등",corp,stock.index[nday]) + + if (D240BiggerThanYesterDay): + collector.collect("240일 증가", corp, stock.index[nday]) - if (isVolumeNTimes(stock, 3, nday)): - collector.collect("volume", corp, stock.index[nday]) - - if (isVolumeMulPriceGreaterThan(stock, 50000000, nday)): - collector.collect("volume5", corp, stock.index[nday]) - - if (isVolumeNTimes(stock, 5, nday)): - collector.collect("volumeX5", corp, stock.index[nday]) + if (d60[nday + 1] < d60[nday]): + collector.collect("정배열60", corp, stock.index[nday]) + if (d20[nday + 1] < d20[nday]): + collector.collect("정배열20", corp, stock.index[nday]) + if (D240BiggerThanYesterDay): + collector.collect("정배열240", corp, stock.index[nday]) + if(d5[nday + 1] <= d5[nday] and + d120[nday + 1] <= d120[nday]): + collector.collect("모두 정배열", corp, stock.index[nday]) + + if (d5[nday + 1] < d20[nday + 1] and d20[nday] < d5[nday]): + collector.collect("d20d5돌파", corp, stock.index[nday]) - ewm5 = stock["CLOSE"].loc[::-1].ewm(span=5).mean().loc[::-1] - ewm10 = stock["CLOSE"].loc[::-1].ewm(span=10).mean().loc[::-1] + ewm5 = close.loc[::-1].ewm(span=5).mean().loc[::-1] + ewm10 = close.loc[::-1].ewm(span=10).mean().loc[::-1] macd = (ewm5 - ewm10) signal = macd.loc[::-1].ewm(span=4).mean().loc[::-1] - if (isMACDCrossSignal(macd, signal, nday)): - collector.collect("macd", corp, stock.index[nday]) + rsi = calc_rsi(close.loc[::-1],14).dropna().loc[::-1] + rsi.reset_index(drop = True, inplace = True) + + for nday in ndays: + if (isMACDCrossSignal(macd, signal, nday)): + collector.collect("macd", corp, stock.index[nday]) + + if (d45[2+nday] > d45[1+nday] and d45[1+nday] < d45[nday]): + collector.collect("45일선 반등",corp, stock.index[nday]) + + if(d60[10+nday] <= d60[nday]): + collector.collect("60일 10일 반등", corp, stock.index[nday]) + + if(d20[2+nday] > d20[1+nday] and d20[1+nday] < d20[nday]): + collector.collect("20일선 반등",corp, stock.index[nday]) + + for nday in ndays: + if(rsi[nday] < 30): + collector.collect("RSI 30 이하", corp, stock.index[nday]) + + #rsi_signal = macd.loc[::-1].ewm(span=7).mean().loc[::-1] parser = argparse.ArgumentParser(description="주식 검색 정보를 출력합니다.") parser.add_argument("--format", "-f", choices=["json", "html"], default="html", help="출력 포맷을 지정합니다. 기본값은 html입니다.") parser.add_argument("--dir", "-d", default=".", help="출력할 폴더를 지정합니다.") -parser.add_argument("--corp", "-c", help="주식 코드를 지정합니다. 지정하지 않으면 모든 주식을 검색합니다.") +parser.add_argument("--corp", "-c", help="주식 코드를 지정합니다. 지정하지 않으면 kosdaq과 kospi만 검색합니다.") +parser.add_argument("--fullSearch", help="모든 주식을 검색합니다.", action='store_true') parser.add_argument("--printStdout", action="store_true", help="출력한 결과를 표준 출력으로 출력합니다.") parser.add_argument("--version", "-v", action="version", version="%(prog)s 1.0") parser.add_argument("--verbose", "-V", action="store_true", help="출력할 내용을 자세히 표시합니다.") @@ -174,7 +260,11 @@ parser.add_argument("--verbose", "-V", action="store_true", help="출력할 내 if __name__ == "__main__": args = parser.parse_args() dataStore = DataStore() - krx_corps = dataStore.getAllKRXCorp() + if args.fullSearch: + krx_corps = dataStore.getAllKRXCorp() + else: + krx_corps = dataStore.getKosdaqAndKospi() + if args.corp: krx_corps = [corp for corp in krx_corps if corp.Code == args.corp] @@ -186,8 +276,8 @@ if __name__ == "__main__": prepareCollector(collector) for corp in tqdm.tqdm(krx_corps): - for nday in range(0, 5): - collect(dataStore, collector, corp, nday) + ndays = [nday for nday in range(0, 5)] + collect(dataStore, collector, corp, ndays) dataStore.clearCache() for k,v in collector.data.items(): diff --git a/kosdaq.csv b/kosdaq.csv new file mode 100644 index 0000000..5f80312 --- /dev/null +++ b/kosdaq.csv @@ -0,0 +1,150 @@ +000250,삼천당제약 +003380,하림지주 +005290,동진쎄미켐 +006730,서부T&D +007390,네이처셀 +015750,성우하이텍 +018000,유니슨 +022100,포스코 ICT +023410,유진기업 +025900,동화기업 +025980,아난티 +027360,아주IB투자 +028150,GS홈쇼핑 +028300,에이치엘비 +029960,코엔텍 +030190,NICE평가정보 +030530,원익홀딩스 +031390,녹십자셀 +032190,다우데이타 +032500,케이엠더블유 +033290,코웰패션 +033640,네패스 +034230,파라다이스 +035600,KG이니시스 +035760,CJ ENM +035900,JYP Ent. +036490,SK머티리얼즈 +036540,SFA반도체 +036810,에프에스티 +036830,솔브레인홀딩스 +036930,주성엔지니어링 +038500,삼표시멘트 +038540,상상인 +039030,이오테크닉스 +039200,오스코텍 +041190,우리기술투자 +041510,에스엠 +041960,코미팜 +042000,카페24 +044340,위닉스 +045390,대아티아이 +046890,서울반도체 +048260,오스템임플란트 +048410,현대바이오 +048530,인트론바이오 +053030,바이넥스 +053800,안랩 +056190,에스에프에이 +058470,리노공업 +058820,CMG제약 +060150,인선이엔티 +060250,NHN한국사이버결제 +060720,KH바텍 +061970,엘비세미콘 +064760,티씨케이 +066970,엘앤에프 +067160,아프리카TV +067630,에이치엘비생명과학 +068240,다원시스 +068760,셀트리온제약 +069080,웹젠 +078020,이베스트투자증권 +078070,유비쿼스홀딩스 +078130,국일제지 +078160,메디포스트 +078340,컴투스 +078600,대주전자재료 +082270,젬백스 +083790,크리스탈지노믹스 +084370,유진테크 +084850,아이티엠반도체 +084990,헬릭스미스 +085660,차바이오텍 +086450,동국제약 +086520,에코프로 +086900,메디톡스 +088800,에이스테크 +089980,상아프론테크 +090460,비에이치 +091700,파트론 +091990,셀트리온헬스케어 +092040,아미코젠 +092190,서울바이오시스 +095610,테스 +095700,제넥신 +096530,씨젠 +097520,엠씨넥스 +098460,고영 +100090,삼강엠앤티 +100130,동국S&C +101490,에스앤에스텍 +102710,이엔에프테크놀로지 +104830,원익머트리얼즈 +108230,톱텍 +108320,실리콘웍스 +112040,위메이드 +115450,지트리비앤티 +119860,다나와 +122870,와이지엔터테인먼트 +122990,와이솔 +131290,티에스이 +131370,알서포트 +131970,테스나 +137400,피엔티 +138080,오이솔루션 +140410,메지온 +140860,파크시스템스 +141080,레고켐바이오 +144510,녹십자랩셀 +145020,휴젤 +166090,하나머티리얼즈 +175250,아이큐어 +178320,서진시스템 +178920,PI첨단소재 +182400,엔케이맥스 +183490,엔지켐생명과학 +192440,슈피겐코리아 +194480,데브시스터즈 +196170,알테오젠 +200130,콜마비앤에이치 +200230,텔콘RF제약 +204270,제이앤티씨 +213420,덕산네오룩스 +214150,클래시스 +214450,파마리서치 +215200,메가스터디교육 +218410,RFHIC +222080,씨아이에스 +222800,심텍 +230360,에코마케팅 +235980,메드팩토 +237690,에스티팜 +240810,원익IPS +243070,휴온스 +247540,에코프로비엠 +253450,스튜디오드래곤 +263050,유틸렉스 +263750,펄어비스 +265520,AP시스템 +267980,매일유업 +268600,셀리버리 +272290,이녹스첨단소재 +278280,천보 +290510,코리아센터 +290650,엘앤씨바이오 +293490,카카오게임즈 +294140,레몬 +298380,에이비엘바이오 +323990,박셀바이오 +357780,솔브레인 \ No newline at end of file diff --git a/kospi.csv b/kospi.csv new file mode 100644 index 0000000..058d83e --- /dev/null +++ b/kospi.csv @@ -0,0 +1,200 @@ +000070,삼양홀딩스 +000080,하이트진로 +000100,유한양행 +000120,CJ대한통운 +000150,두산 +000210,DL +000240,한국앤컴퍼니 +000270,기아 +000660,SK하이닉스 +000670,영풍 +000720,현대건설 +000810,삼성화재 +000880,한화 +000990,DB하이텍 +001040,CJ +001060,JW중외제약 +001120,LG상사 +001230,동국제강 +001440,대한전선 +001450,현대해상 +001680,대상 +001740,SK네트웍스 +001800,오리온홀딩스 +002350,넥센타이어 +002380,KCC +002790,아모레G +003000,부광약품 +003090,대웅 +003230,삼양식품 +003240,태광산업 +003410,쌍용C&E +003490,대한항공 +003520,영진약품 +003550,LG +003670,포스코케미칼 +003850,보령제약 +004000,롯데정밀화학 +004020,현대제철 +004170,신세계 +004370,농심 +004490,세방전지 +004800,효성 +004990,롯데지주 +005250,녹십자홀딩스 +005300,롯데칠성 +005380,현대차 +005440,현대그린푸드 +005490,POSCO +005830,DB손해보험 +005930,삼성전자 +005940,NH투자증권 +006040,동원산업 +006120,SK디스커버리 +006260,LS +006280,녹십자 +006360,GS건설 +006400,삼성SDI +006650,대한유화 +006800,미래에셋증권 +007070,GS리테일 +007310,오뚜기 +007570,일양약품 +007700,F&F 홀딩스 +008560,메리츠증권 +008770,호텔신라 +008930,한미사이언스 +009150,삼성전기 +009240,한샘 +009420,한올바이오파마 +009540,한국조선해양 +009830,한화솔루션 +010060,OCI +010120,LS ELECTRIC +010130,고려아연 +010140,삼성중공업 +010620,현대미포조선 +010780,아이에스동서 +010950,S-Oil +011070,LG이노텍 +011170,롯데케미칼 +011200,HMM +011210,현대위아 +011780,금호석유 +011790,SKC +012330,현대모비스 +012450,한화에어로스페이스 +012630,HDC +012750,에스원 +013890,지누스 +014680,한솔케미칼 +014820,동원시스템즈 +015760,한국전력 +016360,삼성증권 +016380,KG동부제철 +017670,SK텔레콤 +017800,현대엘리베이 +018260,삼성에스디에스 +018880,한온시스템 +019170,신풍제약 +020000,한섬 +020150,일진머티리얼즈 +020560,아시아나항공 +021240,코웨이 +023530,롯데쇼핑 +024110,기업은행 +026960,동서 +028050,삼성엔지니어링 +028260,삼성물산 +028670,팬오션 +029780,삼성카드 +030000,제일기획 +030200,KT +031430,신세계인터내셔날 +032350,롯데관광개발 +032640,LG유플러스 +032830,삼성생명 +033780,KT&G +034020,두산중공업 +034220,LG디스플레이 +034730,SK +035250,강원랜드 +035420,NAVER +035720,카카오 +036460,한국가스공사 +036570,엔씨소프트 +039490,키움증권 +042660,대우조선해양 +042670,두산인프라코어 +047040,대우건설 +047050,포스코인터내셔널 +047810,한국항공우주 +049770,동원F&B +051600,한전KPS +051900,LG생활건강 +051910,LG화학 +052690,한전기술 +055550,신한지주 +057050,현대홈쇼핑 +064350,현대로템 +064960,SNT모티브 +066570,LG전자 +068270,셀트리온 +069260,휴켐스 +069620,대웅제약 +069960,현대백화점 +071050,한국금융지주 +071840,롯데하이마트 +073240,금호타이어 +078930,GS +079160,CJ CGV +079550,LIG넥스원 +081660,휠라홀딩스 +086280,현대글로비스 +086790,하나금융지주 +088350,한화생명 +090430,아모레퍼시픽 +093370,후성 +096770,SK이노베이션 +097950,CJ제일제당 +103140,풍산 +105560,KB금융 +105630,한세실업 +108670,LG하우시스 +111770,영원무역 +112610,씨에스윈드 +114090,GKL +115390,락앤락 +120110,코오롱인더 +128940,한미약품 +138930,BNK금융지주 +139480,이마트 +161390,한국타이어앤테크놀로지 +161890,한국콜마 +180640,한진칼 +185750,종근당 +192080,더블유게임즈 +192400,쿠쿠홀딩스 +192820,코스맥스 +204320,만도 +207940,삼성바이오로직스 +214320,이노션 +241560,두산밥캣 +241590,화승엔터프라이즈 +251270,넷마블 +267250,현대중공업지주 +271560,오리온 +272210,한화시스템 +282330,BGF리테일 +284740,쿠쿠홈시스 +285130,SK케미칼 +294870,HDC현대산업개발 +298020,효성티앤씨 +298050,효성첨단소재 +302440,SK바이오사이언스 +316140,우리금융지주 +326030,SK바이오팜 +336260,두산퓨얼셀 +352820,하이브 +375500,DL이앤씨 +383800,LX홀딩스 \ No newline at end of file diff --git a/meta.py b/meta.py new file mode 100644 index 0000000..659b174 --- /dev/null +++ b/meta.py @@ -0,0 +1,58 @@ +import sqlite3 +import argparse +from typing import Literal + +KOSPI = "KOSPI" +KOSDAQ = "KOSDAQ" + +def queryAllCorpGroup(db: sqlite3.Connection, table: Literal["KOSPI", "KOSDAQ"]) -> list[tuple[str, str]]: + assert table in [KOSPI, KOSDAQ] + cursor = db.execute("SELECT Code, Name from "+ table) + return [ (record[0],record[1]) for record in cursor] + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument("--create", action="store_true", help="create db schema") + parser.add_argument("--read", action="store", help="read csv and commit in db") + parser.add_argument("--clean", action="store_true", help="clean db") + parser.add_argument("--table-name", required=True, choices=["KOSPI", "KOSDAQ"]) + args = parser.parse_args() + if args.create: + db = sqlite3.connect("./stock.db") + db.execute(f""" + CREATE TABLE IF NOT EXISTS "{args.table_name}" ( + "Code" TEXT, + "Name" TEXT, + PRIMARY KEY("Code"), + FOREIGN KEY("Code") REFERENCES "KRXCorp"("Code") + ) + """) + db.close() + elif args.read: + path = args.read + import csv + with open(path, "r", encoding='UTF-8') as fp: + reader = csv.reader(fp) + #next(reader) # skip header + # header not exist + # collect data + data = [ (row[0], row[1]) for row in reader] + + codeDict = { code:name for code, name in data} + db = sqlite3.connect("./stock.db") + dbData = {code:name for code, name in queryAllCorpGroup(db, args.table_name)} + # remove common code + commonCode = set(dbData.keys()) & set(codeDict.keys()) + for code in commonCode: + del codeDict[code] + del dbData[code] + db.execute("BEGIN") + # insert new code + db.executemany(f"INSERT INTO {args.table_name} (Code, Name) VALUES (?, ?)", codeDict.items()) + # delete old code + db.executemany(f"DELETE FROM {args.table_name} WHERE code = ?", dbData.keys()) + db.execute("COMMIT") + db.commit() + db.close() \ No newline at end of file diff --git a/pages.py b/pages.py index 498a094..dcb203a 100644 --- a/pages.py +++ b/pages.py @@ -2,28 +2,51 @@ name = "name" desc = "description" GenLists = [ - {name:"cross 2", desc:"""\ -5일선과 20일선이 서로 만나는 시점 즉 상대 오차가 1% 이하이고 -5일선과 60일선이 서로 만나는 시점을 찾습니다. -"""}, - {name:"cross 3",desc: """\ -cross 2의 조건에서 더해서 거래량이 이전 날짜보다 3배 증가하고 -100000 이상인 시점을 찾습니다. -"""}, - {name:"cross 4",desc: """\ -20일선과 60일선이 서로 만나는 시점 즉 상대 오차가 1% 이하이고 -거래량이 1000000 이상인 시점을 찾습니다. -"""}, +{ + name:"cross d20 and d5", + desc:"""\ +5일선이 20일 선과 교차한 시점을 찾습니다.""" +}, +{ + name:"정배열60", + desc:"""\ +60일선이 어제보다 오늘이 더 큼""" +}, +{ + name:"정배열20", + desc:"""\ +60일선이 어제보다 오늘이 더 크고 20일선 증가""" +}, +{ + name:"정배열240", + desc:"""\ +60일선이 어제보다 오늘이 더 크고 20일선도 증가, 그리고 240일 선도 증가""" +}, +{ + name:"모두 정배열", + desc:"""\ +5일, 20일, 60일, 120일, 240일 모두 증가 +""" +}, +{ + name:"20일선 반등", + desc:"""\ +20일선 반등""" +}, +{ + name:"120일선 반등", + desc:"""\ +120일선 반등""" +}, +{ + name:"240일선 반등", + desc:"""240일선 반등""" +}, {name:"d20d5",desc: """\ 5일선이 20선보다 큰 시점을 찾습니다. """}, {name:"d20d5VolumeX5",desc: """\ d20d5의 조건에서 더해서 거래량이 이전 날짜보다 5배 증가한 시점을 찾습니다. -"""}, - {name:"DiffDistance",desc: """\ -5일선과 20일선이 서로 만나는 시점 즉 상대 오차가 3% 이하이고 -5일선과 60일선이 서로 만나고 거래량이 이전 날짜보다 3배 증가한 - 시점을 찾습니다. """}, {name:"volume",desc: """\ 거래량이 이전 날짜보다 3배 증가한 시점을 찾습니다. @@ -40,9 +63,43 @@ macd가 아래로 내려가는 시점을 찾습니다. macd 는 5일선과 10일 시그널을 구하기 위한 이동 평균은 4일입니다. """}, {name:"뭉침", desc: """\ -5 10 20 30 60 만난것""" }, +20 30 60 120 만난것 종가 5% 이내""" }, {name:"뭉침01", desc: """\ -5 10 20 30 60 만난것""" }, +20 30 60 120 만난것 종가 1% 이내""" }, {name:"뭉침03", desc: """\ -5 10 20 30 60 만난것""" } +20 30 60 120 만난것 종가 3% 이내""" }, + {name:"뭉침 240선까지", desc: """\ +20 30 60 120 240 만난것 종가 5% 이내""" }, + {name:"45일선 반등", desc:"""\ +45일 선반등""" + }, + { + name:"뭉침5% 120선 상승", + desc:"""뭉침5% 120선 상승""" + }, + { + name:"뭉침3% 120선 상승", + desc:"""뭉침3% 120선 상승""" + }, + {name:"60일 10일 반등", + desc:"""60일선이 10일 전보다 크면"""}, + {name:"RSI 30 이하", + desc:"""RSI 14일 이 30이하""" + }, + { + name: "d20d5돌파", + desc:"""이전날에는 20일선이 위에 있다가 5일선이 더 커졌을 때""" + }, + { + name:"240일 증가", + desc:"""240일선이 증가하는 것.""" + }, + { + name:"볼린저 밴드 25", + desc:"볼린저 밴드(25일선 ,표준편차 2배)의 위 밴드 값을 넘었을 때 표시. 시장 상황이 않 좋으면 평균 59개" + }, + { + name:"양봉사이20일선", + desc:"""Open과 Close 사이 20일 선""" + } ] \ No newline at end of file