changes
This commit is contained in:
parent
a20aba2f0c
commit
c394dc1780
3
app.py
3
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")
|
parser.add_argument("--debug", action="store_true", help="debug mode")
|
||||||
|
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
|
||||||
|
|
||||||
@app.route("/dist/<m>")
|
@app.route("/dist/<m>")
|
||||||
def distServe(m:str):
|
def distServe(m:str):
|
||||||
@ -17,8 +18,6 @@ def index():
|
|||||||
import pages
|
import pages
|
||||||
return flask.render_template("index.html", pages = pages.GenLists)
|
return flask.render_template("index.html", pages = pages.GenLists)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
app.run(host=args.host, port=args.port, debug=args.debug)
|
app.run(host=args.host, port=args.port, debug=args.debug)
|
||||||
|
2
db.py
2
db.py
@ -109,7 +109,7 @@ def update_krx(nday:int = 90):
|
|||||||
ClosingMonth = ?,
|
ClosingMonth = ?,
|
||||||
Representative = ?,
|
Representative = ?,
|
||||||
Homepage = ?,
|
Homepage = ?,
|
||||||
AddressArea = ?,
|
AddressArea = ?
|
||||||
WHERE Code = ?;
|
WHERE Code = ?;
|
||||||
""",(row["name"],row["업종"],row["주요제품"],row["상장일"],row["결산월"],row["대표자명"],row["홈페이지"],row["지역"],code
|
""",(row["name"],row["업종"],row["주요제품"],row["상장일"],row["결산월"],row["대표자명"],row["홈페이지"],row["지역"],code
|
||||||
))
|
))
|
||||||
|
154
gen.py
154
gen.py
@ -17,6 +17,19 @@ class DataStore:
|
|||||||
def getAllKRXCorp(self) -> List[database.KRXCorp]:
|
def getAllKRXCorp(self) -> List[database.KRXCorp]:
|
||||||
return database.GetAllKRXCorp(self.db)
|
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:
|
def getStockPrice(self,code,length) -> pd.DataFrame:
|
||||||
if code in self.pricesCache and len(self.pricesCache[code]) >= length:
|
if code in self.pricesCache and len(self.pricesCache[code]) >= length:
|
||||||
return self.pricesCache[code]
|
return self.pricesCache[code]
|
||||||
@ -85,6 +98,16 @@ def isDiffGreaterThan(a:pd.Series,b:pd.Series, nday:int) -> bool:
|
|||||||
"""a is bigger than b"""
|
"""a is bigger than b"""
|
||||||
return (a.iloc[nday] > b.iloc[nday])
|
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:
|
def prepareCollector(collector: OutputCollector) -> None:
|
||||||
import pages
|
import pages
|
||||||
for item in pages.GenLists:
|
for item in pages.GenLists:
|
||||||
@ -97,54 +120,73 @@ def every(f, xs):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def collect(data: DataStore, collector: OutputCollector, corp: database.KRXCorp
|
def collect(data: DataStore, collector: OutputCollector, corp: database.KRXCorp
|
||||||
, nday: int) -> None:
|
, ndays: List[int]) -> None:
|
||||||
stock = data.getStockPrice(corp.Code,120)
|
stock = data.getStockPrice(corp.Code,250)
|
||||||
if len(stock) < 120:
|
if len(stock) <= 245:
|
||||||
return
|
return
|
||||||
|
for nday in ndays:
|
||||||
if (stock.iloc[nday]['VOLUME'] <= 0):
|
if (stock.iloc[nday]['VOLUME'] <= 0):
|
||||||
return
|
return
|
||||||
|
|
||||||
close = stock["CLOSE"]
|
close = stock["CLOSE"]
|
||||||
d5 = stock["CLOSE"].loc[::-1].rolling(window=5
|
openv = stock["OPEN"]
|
||||||
).mean().dropna().loc[::-1]
|
#high = stock["HIGH"]
|
||||||
d10 = stock["CLOSE"].loc[::-1].rolling(window=10
|
#low = stock["LOW"]
|
||||||
).mean().dropna().loc[::-1]
|
#d3 = close.loc[::-1].rolling(window=3
|
||||||
d20 = stock["CLOSE"].loc[::-1].rolling(window=20
|
# ).mean().dropna().loc[::-1]
|
||||||
).mean().dropna().loc[::-1]
|
fetch_len = len(ndays) + 10
|
||||||
d30 = stock["CLOSE"].loc[::-1].rolling(window=30
|
def d(n):
|
||||||
).mean().dropna().loc[::-1]
|
return close.iloc[:(n+fetch_len)].loc[::-1].rolling(window=n
|
||||||
d60 = stock["CLOSE"].loc[::-1].rolling(window=60
|
|
||||||
).mean().dropna().loc[::-1]
|
).mean().dropna().loc[::-1]
|
||||||
|
|
||||||
a = [d5, d10, d20, d30, d60]
|
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):
|
if every(lambda i: isRelativeDiffLessThan(i,close,0.05,nday), a):
|
||||||
collector.collect("뭉침", corp, stock.index[nday])
|
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):
|
if every(lambda i: isRelativeDiffLessThan(i,close,0.01,nday), a):
|
||||||
collector.collect("뭉침01", corp, stock.index[nday])
|
collector.collect("뭉침01", corp, stock.index[nday])
|
||||||
if every(lambda i: isRelativeDiffLessThan(i,close,0.03,nday), a):
|
if every(lambda i: isRelativeDiffLessThan(i,close,0.03,nday), a):
|
||||||
collector.collect("뭉침03", corp, stock.index[nday])
|
collector.collect("뭉침03", corp, stock.index[nday])
|
||||||
|
if d120[nday + 1] < d120[nday]:
|
||||||
|
collector.collect("뭉침3% 120선 상승", corp, stock.index[nday])
|
||||||
|
|
||||||
if (isRelativeDiffLessThan(d5, d20, 0.01, nday) and
|
if every(lambda i: isRelativeDiffLessThan(i,close,0.05,nday), [d20, d30, d60, d120, d240]):
|
||||||
isRelativeDiffLessThan(d5, d60, 0.01, nday)):
|
collector.collect("뭉침 240선까지", corp, stock.index[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
|
if (d5[nday] > d20[nday] and d5[nday + 1] < d20[nday + 1]):
|
||||||
isVolumeMulPriceGreaterThan(stock, 1000000, nday)):
|
collector.collect("cross d20 and d5", corp, stock.index[nday])
|
||||||
collector.collect("cross 4", corp, stock.index[nday])
|
|
||||||
|
|
||||||
if (isDiffGreaterThan(d5, d20, nday)):
|
if (isDiffGreaterThan(d5, d20, nday)):
|
||||||
collector.collect("d20d5", corp, stock.index[nday])
|
collector.collect("d20d5", corp, stock.index[nday])
|
||||||
if (isVolumeNTimes(stock, 5, nday)):
|
if (isVolumeNTimes(stock, 5, nday)):
|
||||||
collector.collect("d20d5VolumeX5", corp, stock.index[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])
|
|
||||||
|
|
||||||
if (isVolumeNTimes(stock, 3, nday)):
|
if (isVolumeNTimes(stock, 3, nday)):
|
||||||
collector.collect("volume", corp, stock.index[nday])
|
collector.collect("volume", corp, stock.index[nday])
|
||||||
|
|
||||||
@ -153,20 +195,64 @@ def collect(data: DataStore, collector: OutputCollector, corp: database.KRXCorp
|
|||||||
|
|
||||||
if (isVolumeNTimes(stock, 5, nday)):
|
if (isVolumeNTimes(stock, 5, nday)):
|
||||||
collector.collect("volumeX5", 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])
|
||||||
|
|
||||||
ewm5 = stock["CLOSE"].loc[::-1].ewm(span=5).mean().loc[::-1]
|
if (D240BiggerThanYesterDay):
|
||||||
ewm10 = stock["CLOSE"].loc[::-1].ewm(span=10).mean().loc[::-1]
|
collector.collect("240일 증가", 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 = close.loc[::-1].ewm(span=5).mean().loc[::-1]
|
||||||
|
ewm10 = close.loc[::-1].ewm(span=10).mean().loc[::-1]
|
||||||
macd = (ewm5 - ewm10)
|
macd = (ewm5 - ewm10)
|
||||||
signal = macd.loc[::-1].ewm(span=4).mean().loc[::-1]
|
signal = macd.loc[::-1].ewm(span=4).mean().loc[::-1]
|
||||||
|
|
||||||
|
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)):
|
if (isMACDCrossSignal(macd, signal, nday)):
|
||||||
collector.collect("macd", corp, stock.index[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 = argparse.ArgumentParser(description="주식 검색 정보를 출력합니다.")
|
||||||
parser.add_argument("--format", "-f", choices=["json", "html"], default="html",
|
parser.add_argument("--format", "-f", choices=["json", "html"], default="html",
|
||||||
help="출력 포맷을 지정합니다. 기본값은 html입니다.")
|
help="출력 포맷을 지정합니다. 기본값은 html입니다.")
|
||||||
parser.add_argument("--dir", "-d", default=".", help="출력할 폴더를 지정합니다.")
|
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("--printStdout", action="store_true", help="출력한 결과를 표준 출력으로 출력합니다.")
|
||||||
parser.add_argument("--version", "-v", action="version", version="%(prog)s 1.0")
|
parser.add_argument("--version", "-v", action="version", version="%(prog)s 1.0")
|
||||||
parser.add_argument("--verbose", "-V", action="store_true", help="출력할 내용을 자세히 표시합니다.")
|
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__":
|
if __name__ == "__main__":
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
dataStore = DataStore()
|
dataStore = DataStore()
|
||||||
|
if args.fullSearch:
|
||||||
krx_corps = dataStore.getAllKRXCorp()
|
krx_corps = dataStore.getAllKRXCorp()
|
||||||
|
else:
|
||||||
|
krx_corps = dataStore.getKosdaqAndKospi()
|
||||||
|
|
||||||
if args.corp:
|
if args.corp:
|
||||||
krx_corps = [corp for corp in krx_corps if corp.Code == args.corp]
|
krx_corps = [corp for corp in krx_corps if corp.Code == args.corp]
|
||||||
|
|
||||||
@ -186,8 +276,8 @@ if __name__ == "__main__":
|
|||||||
prepareCollector(collector)
|
prepareCollector(collector)
|
||||||
|
|
||||||
for corp in tqdm.tqdm(krx_corps):
|
for corp in tqdm.tqdm(krx_corps):
|
||||||
for nday in range(0, 5):
|
ndays = [nday for nday in range(0, 5)]
|
||||||
collect(dataStore, collector, corp, nday)
|
collect(dataStore, collector, corp, ndays)
|
||||||
dataStore.clearCache()
|
dataStore.clearCache()
|
||||||
|
|
||||||
for k,v in collector.data.items():
|
for k,v in collector.data.items():
|
||||||
|
150
kosdaq.csv
Normal file
150
kosdaq.csv
Normal file
@ -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,솔브레인
|
|
200
kospi.csv
Normal file
200
kospi.csv
Normal file
@ -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홀딩스
|
|
58
meta.py
Normal file
58
meta.py
Normal file
@ -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()
|
97
pages.py
97
pages.py
@ -2,28 +2,51 @@ name = "name"
|
|||||||
desc = "description"
|
desc = "description"
|
||||||
|
|
||||||
GenLists = [
|
GenLists = [
|
||||||
{name:"cross 2", desc:"""\
|
{
|
||||||
5일선과 20일선이 서로 만나는 시점 즉 상대 오차가 1% 이하이고
|
name:"cross d20 and d5",
|
||||||
5일선과 60일선이 서로 만나는 시점을 찾습니다.
|
desc:"""\
|
||||||
"""},
|
5일선이 20일 선과 교차한 시점을 찾습니다."""
|
||||||
{name:"cross 3",desc: """\
|
},
|
||||||
cross 2의 조건에서 더해서 거래량이 이전 날짜보다 3배 증가하고
|
{
|
||||||
100000 이상인 시점을 찾습니다.
|
name:"정배열60",
|
||||||
"""},
|
desc:"""\
|
||||||
{name:"cross 4",desc: """\
|
60일선이 어제보다 오늘이 더 큼"""
|
||||||
20일선과 60일선이 서로 만나는 시점 즉 상대 오차가 1% 이하이고
|
},
|
||||||
거래량이 1000000 이상인 시점을 찾습니다.
|
{
|
||||||
"""},
|
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: """\
|
{name:"d20d5",desc: """\
|
||||||
5일선이 20선보다 큰 시점을 찾습니다.
|
5일선이 20선보다 큰 시점을 찾습니다.
|
||||||
"""},
|
"""},
|
||||||
{name:"d20d5VolumeX5",desc: """\
|
{name:"d20d5VolumeX5",desc: """\
|
||||||
d20d5의 조건에서 더해서 거래량이 이전 날짜보다 5배 증가한 시점을 찾습니다.
|
d20d5의 조건에서 더해서 거래량이 이전 날짜보다 5배 증가한 시점을 찾습니다.
|
||||||
"""},
|
|
||||||
{name:"DiffDistance",desc: """\
|
|
||||||
5일선과 20일선이 서로 만나는 시점 즉 상대 오차가 3% 이하이고
|
|
||||||
5일선과 60일선이 서로 만나고 거래량이 이전 날짜보다 3배 증가한
|
|
||||||
시점을 찾습니다.
|
|
||||||
"""},
|
"""},
|
||||||
{name:"volume",desc: """\
|
{name:"volume",desc: """\
|
||||||
거래량이 이전 날짜보다 3배 증가한 시점을 찾습니다.
|
거래량이 이전 날짜보다 3배 증가한 시점을 찾습니다.
|
||||||
@ -40,9 +63,43 @@ macd가 아래로 내려가는 시점을 찾습니다. macd 는 5일선과 10일
|
|||||||
시그널을 구하기 위한 이동 평균은 4일입니다.
|
시그널을 구하기 위한 이동 평균은 4일입니다.
|
||||||
"""},
|
"""},
|
||||||
{name:"뭉침", desc: """\
|
{name:"뭉침", desc: """\
|
||||||
5 10 20 30 60 만난것""" },
|
20 30 60 120 만난것 종가 5% 이내""" },
|
||||||
{name:"뭉침01", desc: """\
|
{name:"뭉침01", desc: """\
|
||||||
5 10 20 30 60 만난것""" },
|
20 30 60 120 만난것 종가 1% 이내""" },
|
||||||
{name:"뭉침03", desc: """\
|
{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일 선"""
|
||||||
|
}
|
||||||
]
|
]
|
Loading…
Reference in New Issue
Block a user