Compare commits
No commits in common. "9c88d4c246cd82038f67f667f961a6861675d587" and "a20aba2f0cbd8bac6e1a906f1e39c99ae24a007f" have entirely different histories.
9c88d4c246
...
a20aba2f0c
8
.gitignore
vendored
8
.gitignore
vendored
@ -3,10 +3,4 @@ stock/**/*
|
|||||||
__pycache__/**/*
|
__pycache__/**/*
|
||||||
dist/**/*
|
dist/**/*
|
||||||
stock.db
|
stock.db
|
||||||
|
krx.csv
|
||||||
# dotenv environment variable files
|
|
||||||
.env
|
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
.env.local
|
|
3
app.py
3
app.py
@ -7,7 +7,6 @@ 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):
|
||||||
@ -18,6 +17,8 @@ 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)
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
import { JSX } from "preact";
|
|
||||||
import { IS_BROWSER } from "$fresh/runtime.ts";
|
|
||||||
|
|
||||||
export function Button(props: JSX.HTMLAttributes<HTMLButtonElement>) {
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
{...props}
|
|
||||||
disabled={!IS_BROWSER || props.disabled}
|
|
||||||
class="px-2 py-1 border-gray-500 border-2 rounded bg-white hover:bg-gray-200 transition-colors"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
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
|
||||||
))
|
))
|
||||||
|
32
deno.json
32
deno.json
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"lock": false,
|
|
||||||
"tasks": {
|
|
||||||
"start": "deno run -A --watch=static/,routes/ dev.ts",
|
|
||||||
"update": "deno run -A -r https://fresh.deno.dev/update ."
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"rules": {
|
|
||||||
"tags": [
|
|
||||||
"fresh",
|
|
||||||
"recommended"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"imports": {
|
|
||||||
"$fresh/": "https://deno.land/x/fresh@1.3.1/",
|
|
||||||
"preact": "https://esm.sh/preact@10.15.1",
|
|
||||||
"preact/": "https://esm.sh/preact@10.15.1/",
|
|
||||||
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@6.2.0",
|
|
||||||
"@preact/signals": "https://esm.sh/*@preact/signals@1.1.3",
|
|
||||||
"@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.2.3",
|
|
||||||
"auto-animate": "https://esm.sh/@formkit/auto-animate@0.7.0",
|
|
||||||
"auto-animate/": "https://esm.sh/@formkit/auto-animate@0.7.0/",
|
|
||||||
"twind": "https://esm.sh/twind@0.16.19",
|
|
||||||
"twind/": "https://esm.sh/twind@0.16.19/",
|
|
||||||
"$std/": "https://deno.land/std@0.193.0/"
|
|
||||||
},
|
|
||||||
"compilerOptions": {
|
|
||||||
"jsx": "react-jsx",
|
|
||||||
"jsxImportSource": "preact"
|
|
||||||
}
|
|
||||||
}
|
|
5
dev.ts
5
dev.ts
@ -1,5 +0,0 @@
|
|||||||
#!/usr/bin/env -S deno run -A --watch=static/,routes/
|
|
||||||
|
|
||||||
import dev from "$fresh/dev.ts";
|
|
||||||
|
|
||||||
await dev(import.meta.url, "./main.ts");
|
|
38
fresh.gen.ts
38
fresh.gen.ts
@ -1,38 +0,0 @@
|
|||||||
// DO NOT EDIT. This file is generated by fresh.
|
|
||||||
// This file SHOULD be checked into source version control.
|
|
||||||
// This file is automatically updated during development when running `dev.ts`.
|
|
||||||
|
|
||||||
import * as $0 from "./routes/_404.tsx";
|
|
||||||
import * as $1 from "./routes/_app.tsx";
|
|
||||||
import * as $2 from "./routes/api/joke.ts";
|
|
||||||
import * as $3 from "./routes/api/kosdaq.ts";
|
|
||||||
import * as $4 from "./routes/api/kospi.ts";
|
|
||||||
import * as $5 from "./routes/api/pages/[name].ts";
|
|
||||||
import * as $6 from "./routes/api/pages/index.ts";
|
|
||||||
import * as $7 from "./routes/greet/[name].tsx";
|
|
||||||
import * as $8 from "./routes/index.tsx";
|
|
||||||
import * as $9 from "./routes/pages/[name].tsx";
|
|
||||||
import * as $$0 from "./islands/Counter.tsx";
|
|
||||||
import * as $$1 from "./islands/StockList.tsx";
|
|
||||||
|
|
||||||
const manifest = {
|
|
||||||
routes: {
|
|
||||||
"./routes/_404.tsx": $0,
|
|
||||||
"./routes/_app.tsx": $1,
|
|
||||||
"./routes/api/joke.ts": $2,
|
|
||||||
"./routes/api/kosdaq.ts": $3,
|
|
||||||
"./routes/api/kospi.ts": $4,
|
|
||||||
"./routes/api/pages/[name].ts": $5,
|
|
||||||
"./routes/api/pages/index.ts": $6,
|
|
||||||
"./routes/greet/[name].tsx": $7,
|
|
||||||
"./routes/index.tsx": $8,
|
|
||||||
"./routes/pages/[name].tsx": $9,
|
|
||||||
},
|
|
||||||
islands: {
|
|
||||||
"./islands/Counter.tsx": $$0,
|
|
||||||
"./islands/StockList.tsx": $$1,
|
|
||||||
},
|
|
||||||
baseUrl: import.meta.url,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default manifest;
|
|
158
gen.py
158
gen.py
@ -17,19 +17,6 @@ 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]
|
||||||
@ -98,16 +85,6 @@ 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:
|
||||||
@ -120,73 +97,54 @@ 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
|
||||||
, ndays: List[int]) -> None:
|
, nday: int) -> None:
|
||||||
stock = data.getStockPrice(corp.Code,250)
|
stock = data.getStockPrice(corp.Code,120)
|
||||||
if len(stock) <= 245:
|
if len(stock) < 120:
|
||||||
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"]
|
||||||
openv = stock["OPEN"]
|
d5 = stock["CLOSE"].loc[::-1].rolling(window=5
|
||||||
#high = stock["HIGH"]
|
).mean().dropna().loc[::-1]
|
||||||
#low = stock["LOW"]
|
d10 = stock["CLOSE"].loc[::-1].rolling(window=10
|
||||||
#d3 = close.loc[::-1].rolling(window=3
|
).mean().dropna().loc[::-1]
|
||||||
# ).mean().dropna().loc[::-1]
|
d20 = stock["CLOSE"].loc[::-1].rolling(window=20
|
||||||
fetch_len = len(ndays) + 10
|
).mean().dropna().loc[::-1]
|
||||||
def d(n):
|
d30 = stock["CLOSE"].loc[::-1].rolling(window=30
|
||||||
return close.iloc[:(n+fetch_len)].loc[::-1].rolling(window=n
|
).mean().dropna().loc[::-1]
|
||||||
|
d60 = stock["CLOSE"].loc[::-1].rolling(window=60
|
||||||
).mean().dropna().loc[::-1]
|
).mean().dropna().loc[::-1]
|
||||||
|
|
||||||
def d_std(n):
|
a = [d5, d10, d20, d30, d60]
|
||||||
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 = [d5, d20, d45, d60]
|
|
||||||
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 d120[nday + 1] < d120[nday]:
|
|
||||||
collector.collect("뭉침1% 120선 상승", 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 (d5[nday] > d20[nday] and d5[nday + 1] < d20[nday + 1]):
|
if (isRelativeDiffLessThan(d5, d20, 0.01, nday) and
|
||||||
collector.collect("cross d20 and d5", corp, stock.index[nday])
|
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)):
|
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])
|
||||||
|
|
||||||
@ -195,64 +153,20 @@ 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])
|
|
||||||
|
|
||||||
if (D240BiggerThanYesterDay):
|
ewm5 = stock["CLOSE"].loc[::-1].ewm(span=5).mean().loc[::-1]
|
||||||
collector.collect("240일 증가", corp, stock.index[nday])
|
ewm10 = stock["CLOSE"].loc[::-1].ewm(span=10).mean().loc[::-1]
|
||||||
|
|
||||||
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="주식 코드를 지정합니다. 지정하지 않으면 kosdaq과 kospi만 검색합니다.")
|
parser.add_argument("--corp", "-c", help="주식 코드를 지정합니다. 지정하지 않으면 모든 주식을 검색합니다.")
|
||||||
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="출력할 내용을 자세히 표시합니다.")
|
||||||
@ -260,11 +174,7 @@ 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]
|
||||||
|
|
||||||
@ -276,8 +186,8 @@ if __name__ == "__main__":
|
|||||||
prepareCollector(collector)
|
prepareCollector(collector)
|
||||||
|
|
||||||
for corp in tqdm.tqdm(krx_corps):
|
for corp in tqdm.tqdm(krx_corps):
|
||||||
ndays = [nday for nday in range(0, 5)]
|
for nday in range(0, 5):
|
||||||
collect(dataStore, collector, corp, ndays)
|
collect(dataStore, collector, corp, nday)
|
||||||
dataStore.clearCache()
|
dataStore.clearCache()
|
||||||
|
|
||||||
for k,v in collector.data.items():
|
for k,v in collector.data.items():
|
||||||
@ -287,7 +197,7 @@ if __name__ == "__main__":
|
|||||||
print(k)
|
print(k)
|
||||||
print(data)
|
print(data)
|
||||||
else:
|
else:
|
||||||
with open(os.path.join(args.dir, k + ".json"), "w", encoding="UTF-8") as f:
|
with open(os.path.join(args.dir, k + ".json", encoding="UTF-8"), "w") as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
else:
|
else:
|
||||||
template = env.get_template("Lists.html")
|
template = env.get_template("Lists.html")
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import type { Signal } from "@preact/signals";
|
|
||||||
import { Button } from "../components/Button.tsx";
|
|
||||||
|
|
||||||
interface CounterProps {
|
|
||||||
count: Signal<number>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Counter(props: CounterProps) {
|
|
||||||
return (
|
|
||||||
<div class="flex gap-8 py-6">
|
|
||||||
<Button onClick={() => props.count.value -= 1}>-1</Button>
|
|
||||||
<p class="text-3xl">{props.count}</p>
|
|
||||||
<Button onClick={() => props.count.value += 1}>+1</Button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,235 +0,0 @@
|
|||||||
import { Button } from "../components/Button.tsx";
|
|
||||||
import { useEffect, useRef } from "preact/hooks";
|
|
||||||
import { ComponentChildren } from "preact";
|
|
||||||
import { Signal, useSignal } from "@preact/signals";
|
|
||||||
import { IS_BROWSER } from "$fresh/runtime.ts";
|
|
||||||
import { mapValues } from "$std/collections/map_values.ts";
|
|
||||||
|
|
||||||
interface StockProps {
|
|
||||||
pageName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ToggleButtonProps {
|
|
||||||
disabled?: boolean;
|
|
||||||
toggle: Signal<boolean>;
|
|
||||||
children?: ComponentChildren;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ToggleButton(props: ToggleButtonProps) {
|
|
||||||
const { disabled, toggle, ...rest } = props;
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
{...rest}
|
|
||||||
disabled={!IS_BROWSER || disabled}
|
|
||||||
onClick={() => toggle.value = !toggle.value}
|
|
||||||
class={"px-2 py-1 border-2 rounded transition-colors" + (
|
|
||||||
toggle.value
|
|
||||||
? "border-gray-500 bg-white hover:bg-gray-200"
|
|
||||||
: "border-gray-200 bg-gray-800 hover:bg-gray-500 text-white"
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryStatus<T> = {
|
|
||||||
type: "loading";
|
|
||||||
} | {
|
|
||||||
type: "complete";
|
|
||||||
data: T;
|
|
||||||
} | {
|
|
||||||
type: "error";
|
|
||||||
err: Error;
|
|
||||||
};
|
|
||||||
|
|
||||||
function useAsync<T>(fn: () => Promise<T>): Signal<QueryStatus<T>> {
|
|
||||||
const state = useSignal({
|
|
||||||
type: "loading",
|
|
||||||
} as QueryStatus<T>);
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
try {
|
|
||||||
const data = await fn();
|
|
||||||
state.value = {
|
|
||||||
type: "complete",
|
|
||||||
data: data,
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
state.value = {
|
|
||||||
type: "error",
|
|
||||||
err: err,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}, []);
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Coperation {
|
|
||||||
Name: string;
|
|
||||||
Code: string;
|
|
||||||
Sector: string;
|
|
||||||
Product: string;
|
|
||||||
ListingDay: string;
|
|
||||||
ClosingMonth: string;
|
|
||||||
Representative: string;
|
|
||||||
Homepage: string;
|
|
||||||
AddressArea: string;
|
|
||||||
LastUpdate: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PageCorpsInfo {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
corpListByDate: Record<string, Coperation[]>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CorpSimple {
|
|
||||||
code: string;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function StockListByDate({prevSet, rows, name}:{prevSet:Set<string>,
|
|
||||||
rows:Coperation[],
|
|
||||||
name: string}){
|
|
||||||
const parent = useRef<HTMLDivElement>(null);
|
|
||||||
useEffect(()=>{
|
|
||||||
(async ()=>{
|
|
||||||
const {default:autoAnimate} = await import("https://esm.sh/@formkit/auto-animate@0.7.0");
|
|
||||||
parent.current && autoAnimate(parent.current)
|
|
||||||
})();
|
|
||||||
},[parent]);
|
|
||||||
|
|
||||||
return <div ref={parent}>
|
|
||||||
<h2 class="text-lg">{name}</h2>
|
|
||||||
{rows.map((row) => {
|
|
||||||
const firstOccur = !prevSet.has(row.Code);
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={row.Code}
|
|
||||||
class={[
|
|
||||||
"bg-white",
|
|
||||||
firstOccur ? "text-[#ff5454]" : "text-black",
|
|
||||||
].join(" ")}
|
|
||||||
>
|
|
||||||
<a href={`https://stockplus.com/m/stocks/KOREA-A${row.Code}`}>
|
|
||||||
{row.Name}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
function StockList({ data }: { data: PageCorpsInfo }) {
|
|
||||||
console.log("data");
|
|
||||||
|
|
||||||
const corpListByDate = data.corpListByDate;
|
|
||||||
const keys = Object.keys(corpListByDate).sort().reverse().slice(0, 5)
|
|
||||||
.reverse();
|
|
||||||
const sets = keys.map((x) => new Set(corpListByDate[x].map((y) => y.Code)));
|
|
||||||
//const rows = data.corpListbyDate;
|
|
||||||
return (
|
|
||||||
<div class="flex">
|
|
||||||
{keys.map((x, i) => {
|
|
||||||
const prevSet = i == 0 ? new Set<string>() : sets[i - 1];
|
|
||||||
const rows = corpListByDate[x];
|
|
||||||
return (
|
|
||||||
<StockListByDate key={x} name={x} prevSet={prevSet} rows={rows}></StockListByDate>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type FilterInfoOption = {
|
|
||||||
list: {
|
|
||||||
items: CorpSimple[];
|
|
||||||
include: boolean;
|
|
||||||
}[];
|
|
||||||
otherwise: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
function filterInfo(info: Coperation[], filterList: FilterInfoOption) {
|
|
||||||
const checkMap = new Map<string, boolean>();
|
|
||||||
for (const l of filterList.list) {
|
|
||||||
for (const i of l.items) {
|
|
||||||
checkMap.set(i.code, l.include);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return info.filter((x) => {
|
|
||||||
const v = checkMap.get(x.Code);
|
|
||||||
if (v === undefined) {
|
|
||||||
return filterList.otherwise;
|
|
||||||
} else {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function StockListUI(props: StockProps) {
|
|
||||||
const sig = useAsync<[PageCorpsInfo, CorpSimple[], CorpSimple[]]>(async () => {
|
|
||||||
const res = await Promise.all([
|
|
||||||
fetch("/api/pages/" + props.pageName),
|
|
||||||
fetch("/api/kospi"),
|
|
||||||
fetch("/api/kosdaq"),
|
|
||||||
]);
|
|
||||||
const corpsInfo = await res[0].json() as PageCorpsInfo;
|
|
||||||
const kospi = await res[1].json();
|
|
||||||
const kosdaq = await res[2].json();
|
|
||||||
return [corpsInfo, kospi, kosdaq];
|
|
||||||
});
|
|
||||||
const viewKospi = useSignal(true);
|
|
||||||
const viewKosdaq = useSignal(false);
|
|
||||||
const viewOtherwise = useSignal(false);
|
|
||||||
return (
|
|
||||||
<div class="my-2">
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<ToggleButton toggle={viewKospi}>Kospi</ToggleButton>
|
|
||||||
<ToggleButton toggle={viewKosdaq}>Kosdaq</ToggleButton>
|
|
||||||
<ToggleButton toggle={viewOtherwise}>Otherwise</ToggleButton>
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-8 py-6 flex-col">
|
|
||||||
{sig.value.type == "loading"
|
|
||||||
? (new Array(20).fill(0).map((_) => (
|
|
||||||
<div class="animate-pulse bg-gray-300 p-2"></div>
|
|
||||||
)))
|
|
||||||
: (
|
|
||||||
<div>
|
|
||||||
{sig.value.type == "error"
|
|
||||||
? (
|
|
||||||
<div>
|
|
||||||
<p>File Loading Failed</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
: <StockList data={applyFilter(sig.value.data[0], sig.value.data[1], sig.value.data[2])}></StockList>}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
function applyFilter(data: PageCorpsInfo, kospi: CorpSimple[], kosdaq: CorpSimple[]): PageCorpsInfo{
|
|
||||||
const filter = getFilters(kospi,kosdaq);
|
|
||||||
return {
|
|
||||||
name: data.name,
|
|
||||||
description: data.description,
|
|
||||||
corpListByDate: mapValues(data.corpListByDate, (it: Coperation[])=>{
|
|
||||||
return filterInfo(it, filter);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function getFilters(kospi: CorpSimple[], kosdaq: CorpSimple[]): FilterInfoOption{
|
|
||||||
return {
|
|
||||||
otherwise: viewOtherwise.value,
|
|
||||||
list: [{
|
|
||||||
include: viewKospi.value,
|
|
||||||
items: kospi
|
|
||||||
},
|
|
||||||
{
|
|
||||||
include: viewKosdaq.value,
|
|
||||||
items: kosdaq
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
15
main.ts
15
main.ts
@ -1,15 +0,0 @@
|
|||||||
/// <reference no-default-lib="true" />
|
|
||||||
/// <reference lib="dom" />
|
|
||||||
/// <reference lib="dom.iterable" />
|
|
||||||
/// <reference lib="dom.asynciterable" />
|
|
||||||
/// <reference lib="deno.ns" />
|
|
||||||
|
|
||||||
import "$std/dotenv/load.ts";
|
|
||||||
|
|
||||||
import { start } from "$fresh/server.ts";
|
|
||||||
import manifest from "./fresh.gen.ts";
|
|
||||||
|
|
||||||
import twindPlugin from "$fresh/plugins/twind.ts";
|
|
||||||
import twindConfig from "./twind.config.ts";
|
|
||||||
|
|
||||||
await start(manifest, { plugins: [twindPlugin(twindConfig)] });
|
|
58
meta.py
58
meta.py
@ -1,58 +0,0 @@
|
|||||||
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()
|
|
44
notebook.py
44
notebook.py
@ -1,44 +0,0 @@
|
|||||||
# %%
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
# %%
|
|
||||||
import gen
|
|
||||||
# %%
|
|
||||||
dataStore = gen.DataStore()
|
|
||||||
stock = dataStore.getStockPrice("108320",250)
|
|
||||||
close = stock["CLOSE"]
|
|
||||||
|
|
||||||
d45 = close.loc[::-1].rolling(window=45).mean().dropna().loc[::-1]
|
|
||||||
rsi = gen.calc_rsi(close.loc[::-1],14).dropna().loc[::-1]
|
|
||||||
rsi.reset_index(drop = True, inplace = True)
|
|
||||||
# %%
|
|
||||||
|
|
||||||
|
|
||||||
# %%
|
|
||||||
|
|
||||||
krxCrops = dataStore.getAllKRXCorp()
|
|
||||||
krxCrops
|
|
||||||
# %%
|
|
||||||
krxCrops[0]
|
|
||||||
# %%
|
|
||||||
# %%
|
|
||||||
#%%time
|
|
||||||
lst = []
|
|
||||||
for entry in krxCrops:
|
|
||||||
data = dataStore.getStockPrice(entry.Code, 120)
|
|
||||||
lst.append(data)
|
|
||||||
print("a")
|
|
||||||
# %%
|
|
||||||
lst
|
|
||||||
# %%
|
|
||||||
#%%time
|
|
||||||
|
|
||||||
lst_mean = [ s["CLOSE"].mean() for s in lst]
|
|
||||||
|
|
||||||
# %%
|
|
||||||
len(krxCrops)
|
|
||||||
# %%
|
|
||||||
|
|
||||||
RANGE = 50
|
|
||||||
plt.plot(d45.iloc[:RANGE].loc[::-1])
|
|
||||||
plt.plot(close.iloc[:RANGE].loc[::-1])
|
|
||||||
plt.show()
|
|
49
pages.py
49
pages.py
@ -1,7 +1,48 @@
|
|||||||
import yaml
|
|
||||||
|
|
||||||
name = "name"
|
name = "name"
|
||||||
desc = "description"
|
desc = "description"
|
||||||
|
|
||||||
with open("pages.yaml", "r", encoding='utf-8') as fp:
|
GenLists = [
|
||||||
GenLists = yaml.safe_load(fp)
|
{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:"d20d5",desc: """\
|
||||||
|
5일선이 20선보다 큰 시점을 찾습니다.
|
||||||
|
"""},
|
||||||
|
{name:"d20d5VolumeX5",desc: """\
|
||||||
|
d20d5의 조건에서 더해서 거래량이 이전 날짜보다 5배 증가한 시점을 찾습니다.
|
||||||
|
"""},
|
||||||
|
{name:"DiffDistance",desc: """\
|
||||||
|
5일선과 20일선이 서로 만나는 시점 즉 상대 오차가 3% 이하이고
|
||||||
|
5일선과 60일선이 서로 만나고 거래량이 이전 날짜보다 3배 증가한
|
||||||
|
시점을 찾습니다.
|
||||||
|
"""},
|
||||||
|
{name:"volume",desc: """\
|
||||||
|
거래량이 이전 날짜보다 3배 증가한 시점을 찾습니다.
|
||||||
|
"""},
|
||||||
|
{name:"volume5",desc: """\
|
||||||
|
거래량과 가격의 곱이 50,000,000,000 이상인 시점을 찾습니다.
|
||||||
|
"""},
|
||||||
|
{name:"volumeX5",desc: """\
|
||||||
|
거래량이 이전 날짜보다 5배 증가한 시점을 찾습니다.
|
||||||
|
"""},
|
||||||
|
{name:"macd",desc: """\
|
||||||
|
signal과 macd가 서로 교차한 시점을 찾습니다. 즉 signal이 올라가고
|
||||||
|
macd가 아래로 내려가는 시점을 찾습니다. macd 는 5일선과 10일선으로 이루어지고
|
||||||
|
시그널을 구하기 위한 이동 평균은 4일입니다.
|
||||||
|
"""},
|
||||||
|
{name:"뭉침", desc: """\
|
||||||
|
5 10 20 30 60 만난것""" },
|
||||||
|
{name:"뭉침01", desc: """\
|
||||||
|
5 10 20 30 60 만난것""" },
|
||||||
|
{name:"뭉침03", desc: """\
|
||||||
|
5 10 20 30 60 만난것""" }
|
||||||
|
]
|
46
pages.ts
46
pages.ts
@ -1,46 +0,0 @@
|
|||||||
import { parse } from "https://deno.land/std@0.195.0/yaml/mod.ts";
|
|
||||||
import { join, fromFileUrl } from "https://deno.land/std@0.193.0/path/mod.ts";
|
|
||||||
|
|
||||||
export const PAGES_PATH = join(fromFileUrl(import.meta.url), "../pages.yaml");
|
|
||||||
|
|
||||||
export interface PageDescription {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function readPagesDescription() {
|
|
||||||
const pagesText = await Deno.readTextFile(PAGES_PATH);
|
|
||||||
const pages = parse(pagesText) as PageDescription[];
|
|
||||||
return pages;
|
|
||||||
}
|
|
||||||
|
|
||||||
function watchFile(
|
|
||||||
path: string,
|
|
||||||
callback: () => void | Promise<void>,
|
|
||||||
) {
|
|
||||||
const watcherRef = Deno.watchFs(path);
|
|
||||||
(async () => {
|
|
||||||
for await (const event of watcherRef) {
|
|
||||||
if (event.kind == "modify") {
|
|
||||||
await callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
Deno.addSignalListener("SIGINT", () => {
|
|
||||||
watcherRef.close();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let pages_meta: PageDescription[] = [];
|
|
||||||
let mtime = 0;
|
|
||||||
export async function get_pages_meta(): Promise<[PageDescription[],number]>{
|
|
||||||
if (pages_meta) {
|
|
||||||
pages_meta = await readPagesDescription();
|
|
||||||
mtime = Date.now();
|
|
||||||
watchFile(PAGES_PATH, async () => {
|
|
||||||
pages_meta = await readPagesDescription();
|
|
||||||
mtime = Date.now();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return [pages_meta, mtime];
|
|
||||||
}
|
|
66
pages.yaml
66
pages.yaml
@ -1,66 +0,0 @@
|
|||||||
- name: cross d20 and d5
|
|
||||||
description: 5일선이 20일 선과 교차한 시점을 찾습니다.
|
|
||||||
- name: 정배열60
|
|
||||||
description: 60일선이 어제보다 오늘이 더 큼
|
|
||||||
- name: 정배열20
|
|
||||||
description: 60일선이 어제보다 오늘이 더 크고 20일선 증가
|
|
||||||
- name: 정배열240
|
|
||||||
description: '60일선이 어제보다 오늘이 더 크고 20일선도 증가, 그리고 240일 선도 증가'
|
|
||||||
- name: 모두 정배열
|
|
||||||
description: |
|
|
||||||
5일, 20일, 60일, 120일, 240일 모두 증가
|
|
||||||
- name: 20일선 반등
|
|
||||||
description: 20일선 반등
|
|
||||||
- name: 120일선 반등
|
|
||||||
description: 120일선 반등
|
|
||||||
- name: 240일선 반등
|
|
||||||
description: 240일선 반등
|
|
||||||
- name: d20d5
|
|
||||||
description: |
|
|
||||||
5일선이 20선보다 큰 시점을 찾습니다.
|
|
||||||
- name: d20d5VolumeX5
|
|
||||||
description: |
|
|
||||||
d20d5의 조건에서 더해서 거래량이 이전 날짜보다 5배 증가한 시점을 찾습니다.
|
|
||||||
- name: volume
|
|
||||||
description: |
|
|
||||||
거래량이 이전 날짜보다 3배 증가한 시점을 찾습니다.
|
|
||||||
- name: volume5
|
|
||||||
description: |
|
|
||||||
거래량과 가격의 곱이 50,000,000,000 이상인 시점을 찾습니다.
|
|
||||||
- name: volumeX5
|
|
||||||
description: |
|
|
||||||
거래량이 이전 날짜보다 5배 증가한 시점을 찾습니다.
|
|
||||||
- name: macd
|
|
||||||
description: |
|
|
||||||
signal과 macd가 서로 교차한 시점을 찾습니다. 즉 signal이 올라가고
|
|
||||||
macd가 아래로 내려가는 시점을 찾습니다. macd 는 5일선과 10일선으로 이루어지고
|
|
||||||
시그널을 구하기 위한 이동 평균은 4일입니다.
|
|
||||||
- name: 뭉침
|
|
||||||
description: d5, d20, d45, d60 만난것 종가 5% 이내
|
|
||||||
- name: 뭉침01
|
|
||||||
description: d5, d20, d45, d60 만난것 종가 1% 이내
|
|
||||||
- name: 뭉침03
|
|
||||||
description: d5, d20, d45, d60 만난것 종가 3% 이내
|
|
||||||
|
|
||||||
- name: 45일선 반등
|
|
||||||
description: 45일 선반등
|
|
||||||
|
|
||||||
- name: 뭉침5% 120선 상승
|
|
||||||
description: 뭉침5% 120선 상승
|
|
||||||
- name: 뭉침3% 120선 상승
|
|
||||||
description: 뭉침3% 120선 상승
|
|
||||||
- name: 뭉침1% 120선 상승
|
|
||||||
description: 뭉침1% 120선 상승
|
|
||||||
|
|
||||||
- name: 60일 10일 반등
|
|
||||||
description: 60일선이 10일 전보다 크면
|
|
||||||
- name: RSI 30 이하
|
|
||||||
description: RSI 14일 이 30이하
|
|
||||||
- name: d20d5돌파
|
|
||||||
description: 이전날에는 20일선이 위에 있다가 5일선이 더 커졌을 때
|
|
||||||
- name: 240일 증가
|
|
||||||
description: 240일선이 증가하는 것.
|
|
||||||
- name: 볼린저 밴드 25
|
|
||||||
description: '볼린저 밴드(25일선 ,표준편차 2배)의 위 밴드 값을 넘었을 때 표시.'
|
|
||||||
- name: 양봉사이20일선
|
|
||||||
description: Open과 Close 사이 20일 선
|
|
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@ -1,28 +0,0 @@
|
|||||||
|
|
||||||
import { Head } from "$fresh/runtime.ts";
|
|
||||||
|
|
||||||
export default function Error404() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>404 - Page not found</title>
|
|
||||||
</Head>
|
|
||||||
<div class="px-4 py-8 mx-auto bg-[#86efac]">
|
|
||||||
<div class="max-w-screen-md mx-auto flex flex-col items-center justify-center">
|
|
||||||
<img
|
|
||||||
class="my-6"
|
|
||||||
src="/logo.svg"
|
|
||||||
width="128"
|
|
||||||
height="128"
|
|
||||||
alt="the fresh logo: a sliced lemon dripping with juice"
|
|
||||||
/>
|
|
||||||
<h1 class="text-4xl font-bold">404 - Page not found</h1>
|
|
||||||
<p class="my-4">
|
|
||||||
The page you were looking for doesn't exist.
|
|
||||||
</p>
|
|
||||||
<a href="/" class="underline">Go back home</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
import { AppProps } from "$fresh/server.ts";
|
|
||||||
|
|
||||||
export default function App({ Component }: AppProps) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Component />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import { HandlerContext } from "$fresh/server.ts";
|
|
||||||
|
|
||||||
// Jokes courtesy of https://punsandoneliners.com/randomness/programmer-jokes/
|
|
||||||
const JOKES = [
|
|
||||||
"Why do Java developers often wear glasses? They can't C#.",
|
|
||||||
"A SQL query walks into a bar, goes up to two tables and says “can I join you?”",
|
|
||||||
"Wasn't hard to crack Forrest Gump's password. 1forrest1.",
|
|
||||||
"I love pressing the F5 key. It's refreshing.",
|
|
||||||
"Called IT support and a chap from Australia came to fix my network connection. I asked “Do you come from a LAN down under?”",
|
|
||||||
"There are 10 types of people in the world. Those who understand binary and those who don't.",
|
|
||||||
"Why are assembly programmers often wet? They work below C level.",
|
|
||||||
"My favourite computer based band is the Black IPs.",
|
|
||||||
"What programme do you use to predict the music tastes of former US presidential candidates? An Al Gore Rhythm.",
|
|
||||||
"An SEO expert walked into a bar, pub, inn, tavern, hostelry, public house.",
|
|
||||||
];
|
|
||||||
|
|
||||||
export const handler = (_req: Request, _ctx: HandlerContext): Response => {
|
|
||||||
const randomIndex = Math.floor(Math.random() * JOKES.length);
|
|
||||||
const body = JOKES[randomIndex];
|
|
||||||
return new Response(body);
|
|
||||||
};
|
|
@ -1,17 +0,0 @@
|
|||||||
import { Handlers } from "$fresh/server.ts";
|
|
||||||
import {DB} from "https://deno.land/x/sqlite/mod.ts";
|
|
||||||
|
|
||||||
export const handler: Handlers = {
|
|
||||||
async GET(req, _ctx): Promise<Response> {
|
|
||||||
const headers = new Headers({
|
|
||||||
"content-type": "application/json"
|
|
||||||
});
|
|
||||||
const db = new DB("stock.db");
|
|
||||||
const conn = db.query("SELECT Code,Name FROM KOSDAQ");
|
|
||||||
const body = conn.map(row=>({
|
|
||||||
code: row[0],
|
|
||||||
name: row[1]
|
|
||||||
}))
|
|
||||||
return new Response(JSON.stringify(body), {headers});
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
import { Handlers } from "$fresh/server.ts";
|
|
||||||
import {DB} from "https://deno.land/x/sqlite/mod.ts";
|
|
||||||
|
|
||||||
export const handler: Handlers = {
|
|
||||||
async GET(req, _ctx): Promise<Response> {
|
|
||||||
const headers = new Headers({
|
|
||||||
"content-type": "application/json"
|
|
||||||
});
|
|
||||||
const db = new DB("stock.db");
|
|
||||||
const conn = db.query("SELECT Code,Name FROM KOSPI");
|
|
||||||
const body = conn.map(row=>({
|
|
||||||
code: row[0],
|
|
||||||
name: row[1]
|
|
||||||
}))
|
|
||||||
return new Response(JSON.stringify(body), {headers});
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
import { Handlers } from "$fresh/server.ts";
|
|
||||||
import { Status, STATUS_TEXT } from "https://deno.land/std@0.195.0/http/mod.ts";
|
|
||||||
import { fromFileUrl, join } from "$std/path/mod.ts";
|
|
||||||
|
|
||||||
|
|
||||||
export const handler: Handlers = {
|
|
||||||
async GET(req, ctx): Promise<Response> {
|
|
||||||
const headers = new Headers({
|
|
||||||
"content-type": "application/json"
|
|
||||||
});
|
|
||||||
const path = join(fromFileUrl(import.meta.url), "../../../../dist", `${ctx.params.name}.json`);
|
|
||||||
console.log("path : ",path)
|
|
||||||
let stat;
|
|
||||||
try {
|
|
||||||
stat = await Deno.stat(path);
|
|
||||||
}
|
|
||||||
catch(err){
|
|
||||||
if(err instanceof Deno.errors.NotFound){
|
|
||||||
return await ctx.renderNotFound();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const mtime = stat.mtime ?? new Date(0);
|
|
||||||
const body = await Deno.readTextFile(path);
|
|
||||||
headers.set("last-modified", mtime.toUTCString());
|
|
||||||
|
|
||||||
const ifModifiedSinceValue = req.headers.get("if-modified-since");
|
|
||||||
if ( ifModifiedSinceValue &&
|
|
||||||
mtime.getTime() != new Date(ifModifiedSinceValue).getTime()
|
|
||||||
){
|
|
||||||
return new Response(null, {
|
|
||||||
status: Status.NotModified,
|
|
||||||
statusText: STATUS_TEXT[Status.NotModified]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return new Response(body, {headers});
|
|
||||||
},
|
|
||||||
};
|
|
@ -1,24 +0,0 @@
|
|||||||
import { Handlers } from "$fresh/server.ts";
|
|
||||||
import { get_pages_meta } from "../../../pages.ts";
|
|
||||||
import { Status, STATUS_TEXT } from "https://deno.land/std@0.195.0/http/mod.ts";
|
|
||||||
|
|
||||||
export const handler: Handlers = {
|
|
||||||
async GET(req, _ctx): Promise<Response> {
|
|
||||||
const headers = new Headers({
|
|
||||||
"content-type": "application/json"
|
|
||||||
});
|
|
||||||
const [body, mtime] = await get_pages_meta();
|
|
||||||
headers.set("last-modified", new Date(mtime).toUTCString());
|
|
||||||
console.log("aaa");
|
|
||||||
const ifModifiedSinceValue = req.headers.get("if-modified-since");
|
|
||||||
if ( ifModifiedSinceValue &&
|
|
||||||
mtime != new Date(ifModifiedSinceValue).getTime()
|
|
||||||
){
|
|
||||||
return new Response(null, {
|
|
||||||
status: Status.NotModified,
|
|
||||||
statusText: STATUS_TEXT[Status.NotModified]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return new Response(JSON.stringify(body), {headers});
|
|
||||||
},
|
|
||||||
};
|
|
@ -1,5 +0,0 @@
|
|||||||
import { PageProps } from "$fresh/server.ts";
|
|
||||||
|
|
||||||
export default function Greet(props: PageProps) {
|
|
||||||
return <div>Hello {props.params.name}</div>;
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
import { Head } from "$fresh/runtime.ts";
|
|
||||||
import { useSignal } from "@preact/signals";
|
|
||||||
import {Button} from "../components/Button.tsx";
|
|
||||||
import { PageDescription, get_pages_meta } from "../pages.ts";
|
|
||||||
import { Handlers, PageProps } from "$fresh/server.ts";
|
|
||||||
|
|
||||||
export const handler: Handlers = {
|
|
||||||
async GET(_req, ctx){
|
|
||||||
const [pages,_] = await get_pages_meta();
|
|
||||||
return await ctx.render(pages);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Home({data}: PageProps<PageDescription[]>) {
|
|
||||||
const count = useSignal(3);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>stock-front</title>
|
|
||||||
</Head>
|
|
||||||
<div class="px-4 py-8 mx-auto bg-[#86efac]">
|
|
||||||
<div class="max-w-screen-md mx-auto flex flex-col items-center justify-center">
|
|
||||||
<img
|
|
||||||
class="my-6"
|
|
||||||
src="/logo.svg"
|
|
||||||
width="128"
|
|
||||||
height="128"
|
|
||||||
alt="the fresh logo: a sliced lemon dripping with juice"
|
|
||||||
/>
|
|
||||||
<h1 class="text-4xl font-bold">Stock</h1>
|
|
||||||
<div class="my-4">
|
|
||||||
<ul>
|
|
||||||
{
|
|
||||||
data.map(x=><li class="my-2">
|
|
||||||
<a class="p-2 block hover:bg-gray-300 bg-white rounded" href={`/pages/${x.name}`}>
|
|
||||||
{x.name}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
import { PageProps } from "$fresh/server.ts";
|
|
||||||
import { Head } from "$fresh/runtime.ts";
|
|
||||||
import StockList from "../../islands/StockList.tsx";
|
|
||||||
|
|
||||||
|
|
||||||
export default function Pages(props: PageProps) {
|
|
||||||
return <>
|
|
||||||
<Head>
|
|
||||||
<title>Stock: {props.params.name}</title>
|
|
||||||
</Head>
|
|
||||||
<div class="px-4 py-8 mx-auto bg-[#86efac]">
|
|
||||||
<div class="max-w-screen-md mx-auto flex flex-col items-center justify-center">
|
|
||||||
<img
|
|
||||||
class="my-6"
|
|
||||||
src="/stockgraph.svg"
|
|
||||||
width="128"
|
|
||||||
height="128"
|
|
||||||
alt="stock graph"
|
|
||||||
/>
|
|
||||||
<h1 class="text-4xl">{props.params.name}</h1>
|
|
||||||
<StockList pageName={props.params.name}></StockList>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
@ -1,150 +0,0 @@
|
|||||||
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
static/kospi.csv
200
static/kospi.csv
@ -1,200 +0,0 @@
|
|||||||
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홀딩스
|
|
|
2525
static/krx.csv
2525
static/krx.csv
File diff suppressed because it is too large
Load Diff
@ -1,6 +0,0 @@
|
|||||||
<svg width="40" height="40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M34.092 8.845C38.929 20.652 34.092 27 30 30.5c1 3.5-2.986 4.222-4.5 2.5-4.457 1.537-13.512 1.487-20-5C2 24.5 4.73 16.714 14 11.5c8-4.5 16-7 20.092-2.655Z" fill="#FFDB1E"/>
|
|
||||||
<path d="M14 11.5c6.848-4.497 15.025-6.38 18.368-3.47C37.5 12.5 21.5 22.612 15.5 25c-6.5 2.587-3 8.5-6.5 8.5-3 0-2.5-4-5.183-7.75C2.232 23.535 6.16 16.648 14 11.5Z" fill="#fff" stroke="#FFDB1E"/>
|
|
||||||
<path d="M28.535 8.772c4.645 1.25-.365 5.695-4.303 8.536-3.732 2.692-6.606 4.21-7.923 4.83-.366.173-1.617-2.252-1.617-1 0 .417-.7 2.238-.934 2.326-1.365.512-4.223 1.29-5.835 1.29-3.491 0-1.923-4.754 3.014-9.122.892-.789 1.478-.645 2.283-.645-.537-.773-.534-.917.403-1.546C17.79 10.64 23 8.77 25.212 8.42c.366.014.82.35.82.629.41-.14 2.095-.388 2.503-.278Z" fill="#FFE600"/>
|
|
||||||
<path d="M14.297 16.49c.985-.747 1.644-1.01 2.099-2.526.566.121.841-.08 1.29-.701.324.466 1.657.608 2.453.701-.715.451-1.057.852-1.452 2.106-1.464-.611-3.167-.302-4.39.42Z" fill="#fff"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.0 KiB |
@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
|
||||||
// 16pxls (c) by Paul mackenzie <paul@whatspauldoing.com>
|
|
||||||
//
|
|
||||||
// 16pxls is licensed under a
|
|
||||||
// Creative Commons Attribution-ShareAlike 4.0 International License.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the license along with this
|
|
||||||
// work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M0 14h16v2H0v-2zm8.5-8l4-4H11V0h5v5h-2V3.5L9.5 8l-1 1-2-2-5 5L0 10.5 6.5 4 8 5.5l.5.5z" fill-rule="evenodd"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 590 B |
@ -7,8 +7,10 @@ import sqlite3
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
def get_naver_finance_price(code,page=1):
|
def get_naver_finance_price(code,page=1):
|
||||||
|
#url = (f'https://finance.naver.com/item/sise_day.nhn?code={code}&page={page}')
|
||||||
url = 'https://finance.naver.com/item/sise_day.nhn'
|
url = 'https://finance.naver.com/item/sise_day.nhn'
|
||||||
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"}
|
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"}
|
||||||
|
# print(url)
|
||||||
html = requests.get(url,params={'code':code,'page':page},headers=headers)
|
html = requests.get(url,params={'code':code,'page':page},headers=headers)
|
||||||
if html.status_code != 200:
|
if html.status_code != 200:
|
||||||
raise UserWarning(html.status_code)
|
raise UserWarning(html.status_code)
|
||||||
@ -50,6 +52,7 @@ def croll_naver_page(code,page,date):
|
|||||||
|
|
||||||
def croll_naver_page_all(code,date) -> pd.DataFrame:
|
def croll_naver_page_all(code,date) -> pd.DataFrame:
|
||||||
html_text = get_naver_finance_price(code)
|
html_text = get_naver_finance_price(code)
|
||||||
|
#print(html_text)
|
||||||
s = bs4.BeautifulSoup(html_text,'html.parser')
|
s = bs4.BeautifulSoup(html_text,'html.parser')
|
||||||
last = int(get_last_page(s))
|
last = int(get_last_page(s))
|
||||||
r = [(code,i) for i in range(1,last+1)]
|
r = [(code,i) for i in range(1,last+1)]
|
||||||
@ -63,6 +66,9 @@ def croll_naver_page_all(code,date) -> pd.DataFrame:
|
|||||||
if len(retdata) == 0:
|
if len(retdata) == 0:
|
||||||
return []
|
return []
|
||||||
return pd.concat(retdata,ignore_index=True)
|
return pd.concat(retdata,ignore_index=True)
|
||||||
|
#with mp.Pool(CPU_COUNT) as pl:
|
||||||
|
# dl = pl.starmap(croll_naver_page,r)
|
||||||
|
# return pd.concat(dl,ignore_index=True)
|
||||||
|
|
||||||
def toSqlPos(x,code):
|
def toSqlPos(x,code):
|
||||||
return (code,x["날짜"],x["종가"],x["전일비"],x["시가"],x["고가"],x["저가"],x["거래량"])
|
return (code,x["날짜"],x["종가"],x["전일비"],x["시가"],x["고가"],x["저가"],x["거래량"])
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
export default {
|
|
||||||
content: ["./**/*.{html,tsx}"],
|
|
||||||
theme:{
|
|
||||||
extend:{},
|
|
||||||
},
|
|
||||||
plugins: [],
|
|
||||||
}
|
|
491
test.ipynb
491
test.ipynb
@ -45,7 +45,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 2,
|
"execution_count": 4,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -54,7 +54,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 3,
|
"execution_count": 12,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@ -63,7 +63,7 @@
|
|||||||
"False"
|
"False"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 3,
|
"execution_count": 12,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 4,
|
"execution_count": 5,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -83,29 +83,20 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 5,
|
"execution_count": 6,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"krxDf = pd.DataFrame([corp.toDict() for corp in krx])"
|
"krxDf = pd.DataFrame([corp.toDict() for corp in krx])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 6,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"data = GetStockPriceFrom(db,\"212310\", 61)\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 7,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"s = pd.DataFrame(data, columns=[s for s in database.STOCK_INDEX.__members__.keys()])"
|
"data = GetStockPriceFrom(db,\"042670\", 61)\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -114,7 +105,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"s.set_index(\"DATE\", inplace=True)"
|
"s = pd.DataFrame(data, columns=[s for s in database.STOCK_INDEX.__members__.keys()])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -123,13 +114,22 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"stock = s"
|
"s.set_index(\"DATE\", inplace=True)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 10,
|
"execution_count": 10,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"stock = s"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 11,
|
||||||
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
@ -173,54 +173,54 @@
|
|||||||
" </thead>\n",
|
" </thead>\n",
|
||||||
" <tbody>\n",
|
" <tbody>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-06-02</th>\n",
|
" <th>2022-06-10</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>2375</td>\n",
|
" <td>6490</td>\n",
|
||||||
" <td>75</td>\n",
|
" <td>210</td>\n",
|
||||||
" <td>2205</td>\n",
|
" <td>6670</td>\n",
|
||||||
" <td>2615</td>\n",
|
" <td>6680</td>\n",
|
||||||
" <td>2205</td>\n",
|
" <td>6470</td>\n",
|
||||||
" <td>19</td>\n",
|
" <td>1817916</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-06-01</th>\n",
|
" <th>2022-06-09</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>2300</td>\n",
|
" <td>6700</td>\n",
|
||||||
" <td>35</td>\n",
|
" <td>110</td>\n",
|
||||||
" <td>2335</td>\n",
|
" <td>6620</td>\n",
|
||||||
" <td>2645</td>\n",
|
" <td>6750</td>\n",
|
||||||
" <td>2215</td>\n",
|
" <td>6440</td>\n",
|
||||||
" <td>16</td>\n",
|
" <td>2623890</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-05-31</th>\n",
|
" <th>2022-06-08</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>2335</td>\n",
|
" <td>6590</td>\n",
|
||||||
" <td>0</td>\n",
|
" <td>160</td>\n",
|
||||||
" <td>2340</td>\n",
|
" <td>6820</td>\n",
|
||||||
" <td>2340</td>\n",
|
" <td>6860</td>\n",
|
||||||
" <td>2335</td>\n",
|
" <td>6580</td>\n",
|
||||||
" <td>145</td>\n",
|
" <td>2026670</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-05-30</th>\n",
|
" <th>2022-06-07</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>2335</td>\n",
|
" <td>6750</td>\n",
|
||||||
" <td>190</td>\n",
|
" <td>150</td>\n",
|
||||||
" <td>2275</td>\n",
|
" <td>6870</td>\n",
|
||||||
" <td>2790</td>\n",
|
" <td>6990</td>\n",
|
||||||
" <td>2275</td>\n",
|
" <td>6720</td>\n",
|
||||||
" <td>6245</td>\n",
|
" <td>3234237</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-05-26</th>\n",
|
" <th>2022-06-03</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>2525</td>\n",
|
" <td>6900</td>\n",
|
||||||
" <td>30</td>\n",
|
" <td>440</td>\n",
|
||||||
" <td>2450</td>\n",
|
" <td>6550</td>\n",
|
||||||
" <td>2780</td>\n",
|
" <td>6940</td>\n",
|
||||||
" <td>2420</td>\n",
|
" <td>6510</td>\n",
|
||||||
" <td>658</td>\n",
|
" <td>9983571</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>...</th>\n",
|
" <th>...</th>\n",
|
||||||
@ -233,54 +233,54 @@
|
|||||||
" <td>...</td>\n",
|
" <td>...</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-03-13</th>\n",
|
" <th>2022-03-21</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>3190</td>\n",
|
" <td>6770</td>\n",
|
||||||
" <td>100</td>\n",
|
" <td>120</td>\n",
|
||||||
" <td>3695</td>\n",
|
" <td>6910</td>\n",
|
||||||
" <td>3695</td>\n",
|
" <td>7030</td>\n",
|
||||||
" <td>2805</td>\n",
|
" <td>6770</td>\n",
|
||||||
" <td>2967</td>\n",
|
" <td>1314044</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-03-10</th>\n",
|
" <th>2022-03-18</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>3290</td>\n",
|
" <td>6890</td>\n",
|
||||||
" <td>15</td>\n",
|
" <td>200</td>\n",
|
||||||
" <td>3675</td>\n",
|
" <td>6750</td>\n",
|
||||||
" <td>3675</td>\n",
|
" <td>6890</td>\n",
|
||||||
" <td>3110</td>\n",
|
" <td>6650</td>\n",
|
||||||
" <td>9</td>\n",
|
" <td>1207925</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-03-09</th>\n",
|
" <th>2022-03-17</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>3275</td>\n",
|
" <td>6690</td>\n",
|
||||||
" <td>205</td>\n",
|
" <td>50</td>\n",
|
||||||
" <td>3800</td>\n",
|
" <td>6790</td>\n",
|
||||||
" <td>3800</td>\n",
|
" <td>6790</td>\n",
|
||||||
" <td>3220</td>\n",
|
" <td>6670</td>\n",
|
||||||
" <td>467</td>\n",
|
" <td>1003575</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-03-08</th>\n",
|
" <th>2022-03-16</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>3480</td>\n",
|
" <td>6640</td>\n",
|
||||||
" <td>15</td>\n",
|
" <td>60</td>\n",
|
||||||
" <td>3460</td>\n",
|
" <td>6610</td>\n",
|
||||||
" <td>3480</td>\n",
|
" <td>6680</td>\n",
|
||||||
" <td>3460</td>\n",
|
" <td>6570</td>\n",
|
||||||
" <td>289</td>\n",
|
" <td>642939</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" <tr>\n",
|
" <tr>\n",
|
||||||
" <th>2023-03-07</th>\n",
|
" <th>2022-03-15</th>\n",
|
||||||
" <td>212310</td>\n",
|
" <td>042670</td>\n",
|
||||||
" <td>3495</td>\n",
|
" <td>6580</td>\n",
|
||||||
" <td>235</td>\n",
|
" <td>260</td>\n",
|
||||||
" <td>3495</td>\n",
|
" <td>6830</td>\n",
|
||||||
" <td>3500</td>\n",
|
" <td>6840</td>\n",
|
||||||
" <td>3315</td>\n",
|
" <td>6550</td>\n",
|
||||||
" <td>125</td>\n",
|
" <td>1776057</td>\n",
|
||||||
" </tr>\n",
|
" </tr>\n",
|
||||||
" </tbody>\n",
|
" </tbody>\n",
|
||||||
"</table>\n",
|
"</table>\n",
|
||||||
@ -290,22 +290,22 @@
|
|||||||
"text/plain": [
|
"text/plain": [
|
||||||
" CODE CLOSE DIFF OPEN HIGH LOW VOLUME\n",
|
" CODE CLOSE DIFF OPEN HIGH LOW VOLUME\n",
|
||||||
"DATE \n",
|
"DATE \n",
|
||||||
"2023-06-02 212310 2375 75 2205 2615 2205 19\n",
|
"2022-06-10 042670 6490 210 6670 6680 6470 1817916\n",
|
||||||
"2023-06-01 212310 2300 35 2335 2645 2215 16\n",
|
"2022-06-09 042670 6700 110 6620 6750 6440 2623890\n",
|
||||||
"2023-05-31 212310 2335 0 2340 2340 2335 145\n",
|
"2022-06-08 042670 6590 160 6820 6860 6580 2026670\n",
|
||||||
"2023-05-30 212310 2335 190 2275 2790 2275 6245\n",
|
"2022-06-07 042670 6750 150 6870 6990 6720 3234237\n",
|
||||||
"2023-05-26 212310 2525 30 2450 2780 2420 658\n",
|
"2022-06-03 042670 6900 440 6550 6940 6510 9983571\n",
|
||||||
"... ... ... ... ... ... ... ...\n",
|
"... ... ... ... ... ... ... ...\n",
|
||||||
"2023-03-13 212310 3190 100 3695 3695 2805 2967\n",
|
"2022-03-21 042670 6770 120 6910 7030 6770 1314044\n",
|
||||||
"2023-03-10 212310 3290 15 3675 3675 3110 9\n",
|
"2022-03-18 042670 6890 200 6750 6890 6650 1207925\n",
|
||||||
"2023-03-09 212310 3275 205 3800 3800 3220 467\n",
|
"2022-03-17 042670 6690 50 6790 6790 6670 1003575\n",
|
||||||
"2023-03-08 212310 3480 15 3460 3480 3460 289\n",
|
"2022-03-16 042670 6640 60 6610 6680 6570 642939\n",
|
||||||
"2023-03-07 212310 3495 235 3495 3500 3315 125\n",
|
"2022-03-15 042670 6580 260 6830 6840 6550 1776057\n",
|
||||||
"\n",
|
"\n",
|
||||||
"[61 rows x 7 columns]"
|
"[61 rows x 7 columns]"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 10,
|
"execution_count": 11,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@ -316,190 +316,28 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 11,
|
"execution_count": 52,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"DATE\n",
|
"DATE\n",
|
||||||
"2023-06-02 2374.0\n",
|
"2022-06-03 175508\n",
|
||||||
"2023-06-01 2398.0\n",
|
"2022-06-02 350113\n",
|
||||||
"2023-05-31 2404.0\n",
|
"2022-05-31 276819\n",
|
||||||
"2023-05-30 2434.0\n",
|
"2022-05-30 191087\n",
|
||||||
"2023-05-26 2447.0\n",
|
"2022-05-27 392051\n",
|
||||||
"2023-05-25 2447.0\n",
|
|
||||||
"Name: CLOSE, dtype: float64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 11,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"close = stock[\"CLOSE\"]\n",
|
|
||||||
"d5 = stock[\"CLOSE\"].iloc[:10].loc[::-1].rolling(window=5\n",
|
|
||||||
" ).mean().dropna().loc[::-1]\n",
|
|
||||||
"d5"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 18,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"DATE\n",
|
|
||||||
"2023-06-02 88.487287\n",
|
|
||||||
"2023-06-01 103.778611\n",
|
|
||||||
"2023-05-31 97.365292\n",
|
|
||||||
"2023-05-30 93.834962\n",
|
|
||||||
"2023-05-26 80.202868\n",
|
|
||||||
"2023-05-25 80.202868\n",
|
|
||||||
"Name: CLOSE, dtype: float64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 18,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"dstd5 = close.iloc[:10].loc[::-1].rolling(window=5).std().dropna().loc[::-1]\n",
|
|
||||||
"dstd5"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 21,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"DATE\n",
|
|
||||||
"2023-06-01 2398.0\n",
|
|
||||||
"2023-05-31 2404.0\n",
|
|
||||||
"Name: CLOSE, dtype: float64"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 21,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"d5[[1,2]]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"import numpy as np\n",
|
|
||||||
"\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 51,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"(50.04, 0.2, 50.44, True)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 51,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"a = 51\n",
|
|
||||||
"arr = np.array([50]* 24 + [a])\n",
|
|
||||||
"m = arr.mean()\n",
|
|
||||||
"std = arr.std(ddof=1)\n",
|
|
||||||
"m, std , m + 2*std, m+2*std < a"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 40,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"10.0"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 40,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"(a-50)/5"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 55,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"59.082092668956086"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 55,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"krx.__len__() * ((100-95.4499736104)/100)*0.5"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 12,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"DATE\n",
|
|
||||||
"2023-05-22 27\n",
|
|
||||||
"2023-05-19 403\n",
|
|
||||||
"2023-05-18 1\n",
|
|
||||||
"2023-05-17 5\n",
|
|
||||||
"2023-05-16 3711\n",
|
|
||||||
" ... \n",
|
" ... \n",
|
||||||
"2023-02-28 1017\n",
|
"2022-03-15 2701677\n",
|
||||||
"2023-02-27 799\n",
|
"2022-03-14 4436719\n",
|
||||||
"2023-02-24 12\n",
|
"2022-03-11 997048\n",
|
||||||
"2023-02-23 688\n",
|
"2022-03-10 1754702\n",
|
||||||
"2023-02-22 4\n",
|
"2022-03-08 878964\n",
|
||||||
"Name: VOLUME, Length: 61, dtype: int64"
|
"Name: VOLUME, Length: 61, dtype: int64"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 12,
|
"execution_count": 52,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
@ -509,26 +347,6 @@
|
|||||||
"volume"
|
"volume"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 17,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"'2023-05-22'"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 17,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"stock.index[0]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 62,
|
"execution_count": 62,
|
||||||
@ -640,7 +458,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 29,
|
"execution_count": 13,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
@ -659,77 +477,20 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 30,
|
"execution_count": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": []
|
||||||
"def isRelativeDiffLessThan(a:pd.Series,b:pd.Series, threshold: float,nday:int) -> bool:\n",
|
|
||||||
" return (a.iloc[nday] - b.iloc[nday]) / b.iloc[nday] < threshold"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 15,
|
"execution_count": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
|
||||||
"def every(f, xs):\n",
|
|
||||||
" for x in xs:\n",
|
|
||||||
" if not f(x):\n",
|
|
||||||
" return False\n",
|
|
||||||
" return True"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 31,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"evert\n",
|
|
||||||
"6236.0 6290 -54.0\n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"-0.008585055643879173"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 31,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
"source": [
|
||||||
"a = [d5, d10, d20, d30, d60]\n",
|
"a = [d5, d10, d20, d30, d60]\n",
|
||||||
"if every(lambda i: isRelativeDiffLessThan(i,close,0.05,0), a):\n",
|
"if every(lambda i: isRelativeDiffLessThan(i,close,0.05,nday), a):\n",
|
||||||
" print(\"evert\")\n",
|
" print(\"evert\")"
|
||||||
"print(d5.iloc[0] , close.iloc[0],d5.iloc[0] - close.iloc[0])\n",
|
|
||||||
"(d5.iloc[0] - close.iloc[0]) / close.iloc[0]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 36,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"-0.1876921038685744"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 36,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"(d60.iloc[0] - close.iloc[0])/close.iloc[0]"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
import { Options } from "$fresh/plugins/twind.ts";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
selfURL: import.meta.url,
|
|
||||||
} as Options;
|
|
Loading…
Reference in New Issue
Block a user