init
This commit is contained in:
@@ -1,15 +1,19 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
import shutil
|
||||||
import time
|
import time
|
||||||
|
import sqlite3
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from stock.crawler.FnGuideCrawler import FnGuideCrawler
|
from stock.crawler.FnGuideCrawler import FnGuideCrawler
|
||||||
from stock.crawler.MetaCrawler import MetaCrawler
|
from stock.crawler.MetaCrawler import MetaCrawler
|
||||||
from stock.crawler.StockCrawler import StockCrawler
|
from stock.crawler.StockCrawler import StockCrawler
|
||||||
from stock.analysis.AnalyzerSqlite import AnalyzerSqlite
|
from stock.analysis.AnalyzerSqlite import AnalyzerSqlite
|
||||||
|
from stock.analysis.StockStatus import StockStatus
|
||||||
from stock.util.SlackBot import SlackBot
|
from stock.util.SlackBot import SlackBot
|
||||||
|
|
||||||
|
|
||||||
today = datetime.now().strftime("%Y-%m-%d")
|
today = datetime.now().strftime("%Y-%m-%d")
|
||||||
|
|
||||||
# DB Browser for SQLite: http://hleecaster.com/python-sqlite3/
|
# DB Browser for SQLite: http://hleecaster.com/python-sqlite3/
|
||||||
@@ -64,6 +68,7 @@ if week in (0, 1, 2, 3, 4): # 0:월, 1:화, 2:수, 3:목, 4:금, 5:토, 6:일
|
|||||||
# S: 분석까지 진행
|
# S: 분석까지 진행
|
||||||
inFileName = PROJECT_HOME + '/resources/stock.db'
|
inFileName = PROJECT_HOME + '/resources/stock.db'
|
||||||
analyzerSqlite = AnalyzerSqlite(stockFileName)
|
analyzerSqlite = AnalyzerSqlite(stockFileName)
|
||||||
|
stockStatus = StockStatus(RESOURCE_PATH)
|
||||||
|
|
||||||
analyzerSqlite.analyzeDaily()
|
analyzerSqlite.analyzeDaily()
|
||||||
analyzerSqlite.analyzeGrouping("weekly")
|
analyzerSqlite.analyzeGrouping("weekly")
|
||||||
@@ -86,7 +91,8 @@ if week in (0, 1, 2, 3, 4): # 0:월, 1:화, 2:수, 3:목, 4:금, 5:토, 6:일
|
|||||||
shutil.rmtree(outPath)
|
shutil.rmtree(outPath)
|
||||||
os.mkdir(outPath)
|
os.mkdir(outPath)
|
||||||
|
|
||||||
analyzerSqlite.findCandidate(outPath)
|
analyzerSqlite.findCandidates(outPath)
|
||||||
|
stockStatus.findCandidates(outPath)
|
||||||
|
|
||||||
slackBot.sendMsg("Done. Crawling...")
|
slackBot.sendMsg("Done. Crawling...")
|
||||||
|
|
||||||
|
|||||||
@@ -629,7 +629,7 @@ class HTS:
|
|||||||
days = []
|
days = []
|
||||||
for i in range(1, 100):
|
for i in range(1, 100):
|
||||||
last_day = (datetime.strptime(today, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
|
last_day = (datetime.strptime(today, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
|
||||||
isValid = self.isValidYMD(stock_code, last_day)
|
isValid = self.isValidYMD(stock_code=stock_code, day=last_day)
|
||||||
if isValid:
|
if isValid:
|
||||||
days.append(last_day)
|
days.append(last_day)
|
||||||
if len(days) >= n:
|
if len(days) >= n:
|
||||||
|
|||||||
@@ -286,8 +286,6 @@ class AnalyzerSqlite:
|
|||||||
self.makeDir("15", "daily_낙폭과대")
|
self.makeDir("15", "daily_낙폭과대")
|
||||||
self.makeDir("16", "daily_EV하단_내려옴")
|
self.makeDir("16", "daily_EV하단_내려옴")
|
||||||
|
|
||||||
self.makeDir("99", "daily_auto_trading")
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def writeFile(self, dir_code, dir_name, CODE, NAME, top, stock, state, final_status_count=-1):
|
def writeFile(self, dir_code, dir_name, CODE, NAME, top, stock, state, final_status_count=-1):
|
||||||
@@ -428,7 +426,7 @@ class AnalyzerSqlite:
|
|||||||
return stock
|
return stock
|
||||||
|
|
||||||
# 후보 찾기
|
# 후보 찾기
|
||||||
def findCandidate(self, outPath):
|
def findCandidates(self, outPath):
|
||||||
self.makeDirectory(outPath)
|
self.makeDirectory(outPath)
|
||||||
|
|
||||||
stockTableName = 'stock'
|
stockTableName = 'stock'
|
||||||
@@ -582,13 +580,6 @@ class AnalyzerSqlite:
|
|||||||
dir_name = "final"
|
dir_name = "final"
|
||||||
self.writeFile(dir_code, dir_name, CODE, NAME, top, stock_daily, final_status, final_status_count)
|
self.writeFile(dir_code, dir_name, CODE, NAME, top, stock_daily, final_status, final_status_count)
|
||||||
|
|
||||||
bsLine, data = self.buySellChecker.checkTransactionWithEnvelope(stock_daily, CODE, 120, isRealTime=False)
|
|
||||||
if len(data) > 10 and max(bsLine['buy'][len(bsLine['buy']) - 1:]) > 1000:
|
|
||||||
dir_code = "99"
|
|
||||||
dir_name = "daily_auto_trading"
|
|
||||||
self.writeFile(dir_code, dir_name, CODE, NAME, top, stock_daily, final_status, final_status_count)
|
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_moving_average(self, stock):
|
def get_moving_average(self, stock):
|
||||||
@@ -999,7 +990,7 @@ if __name__ == "__main__":
|
|||||||
shutil.rmtree(outPath)
|
shutil.rmtree(outPath)
|
||||||
os.mkdir(outPath)
|
os.mkdir(outPath)
|
||||||
print("print to Html...")
|
print("print to Html...")
|
||||||
analyzer.findCandidate(outPath)
|
analyzer.findCandidates(outPath)
|
||||||
|
|
||||||
|
|
||||||
print("time : %6.2f 초" % (time.time() - start))
|
print("time : %6.2f 초" % (time.time() - start))
|
||||||
|
|||||||
@@ -83,10 +83,9 @@ class StockStatus (HTS):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def fetchLastData(self, cursor, stock_code, limit=350):
|
def fetchLastData(self, cursor, stock_code, limit=350):
|
||||||
if cursor is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
stock = {"CODE": stock_code, "NAME": "", "PRICE": []}
|
stock = {"CODE": stock_code, "NAME": "", "PRICE": []}
|
||||||
|
if cursor is None:
|
||||||
|
return stock
|
||||||
|
|
||||||
sql = 'SELECT ymd, close, diff, open, high, low, volume FROM stock where CODE=? order by ymd desc '
|
sql = 'SELECT ymd, close, diff, open, high, low, volume FROM stock where CODE=? order by ymd desc '
|
||||||
sql += ' limit ' + str(limit)
|
sql += ' limit ' + str(limit)
|
||||||
@@ -558,3 +557,75 @@ class StockStatus (HTS):
|
|||||||
po.write_html(fig, file=fileName, auto_open=False)
|
po.write_html(fig, file=fileName, auto_open=False)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def getCompanyInfo(self):
|
||||||
|
self.cursor_stock.execute('SELECT distinct code, name FROM stock order by code')
|
||||||
|
all_stocks = self.cursor_stock.fetchall()
|
||||||
|
|
||||||
|
valid_company = set()
|
||||||
|
self.cursor_stock.execute(
|
||||||
|
'select CODE, NAME, max(ymd) as ymd from fnguide where type != "E" group by 1 order by total_assets desc')
|
||||||
|
items = self.cursor_stock.fetchall()
|
||||||
|
for item in items:
|
||||||
|
valid_company.add(item[0])
|
||||||
|
|
||||||
|
return all_stocks, valid_company
|
||||||
|
|
||||||
|
def findCandidates(self, outPath):
|
||||||
|
|
||||||
|
dir_name = os.path.join(outPath, "99_daily_auto_trading")
|
||||||
|
if os.path.isdir(dir_name):
|
||||||
|
os.rmdir(dir_name)
|
||||||
|
os.mkdir(dir_name)
|
||||||
|
|
||||||
|
today = datetime.today().strftime('%Y%m%d')
|
||||||
|
|
||||||
|
stockTableName = 'stock'
|
||||||
|
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, self.dbFileName))
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('SELECT distinct code, name FROM ' + stockTableName + ' order by code')
|
||||||
|
items = cursor.fetchall()
|
||||||
|
|
||||||
|
analyzed_day = 120
|
||||||
|
for idx, item in enumerate(items):
|
||||||
|
stock_code = item[0]
|
||||||
|
stock_name = item[1]
|
||||||
|
if stock_name.find('스팩') >= 0:
|
||||||
|
continue
|
||||||
|
print(idx, stock_code, stock_name, ", CODE: ", stock_code, ", NAME: ", stock_name)
|
||||||
|
|
||||||
|
stock = self.fetchLastData(cursor, stock_code, limit=350)
|
||||||
|
data = self.analyze(stock, analyzed_day)
|
||||||
|
# 분석일 데이터만 활용한다 (이전 데이터는 제거)
|
||||||
|
data.drop(data.index[:len(data) - analyzed_day], inplace=True)
|
||||||
|
|
||||||
|
# print logs
|
||||||
|
# for i in range(len(data.index)):
|
||||||
|
# print (i, data.index[i], data['macd'][i], data['slow_k'][i], data['gradients_low'][i], data['gradients_avg5'][i], data['gradients_avg20'][i], data['gradients_avg60'][i], data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity'][i], data['disparity_type'][i])
|
||||||
|
|
||||||
|
bsLine, data = self.buySellChecker.checkTransactionWithEnvelope(data, stock_code, 120, isRealTime=False)
|
||||||
|
|
||||||
|
# 그래프를 그린다.
|
||||||
|
if len(data.index) > 10 and bsLine['buy'][len(bsLine['buy'])-1] > 0:
|
||||||
|
self.writeFile(dir_name, stock_code, stock_name, today, data, bsLine)
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__))))))
|
||||||
|
RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources")
|
||||||
|
|
||||||
|
outPath = os.path.join(PROJECT_HOME, "resources", "analysis")
|
||||||
|
if not os.path.isdir(outPath):
|
||||||
|
os.mkdir(outPath)
|
||||||
|
day = datetime.today().strftime("%Y%m%d")
|
||||||
|
outPath = os.path.join(outPath, day)
|
||||||
|
if os.path.isdir(outPath):
|
||||||
|
shutil.rmtree(outPath)
|
||||||
|
os.mkdir(outPath)
|
||||||
|
|
||||||
|
stockStatus = StockStatus(RESOURCE_PATH)
|
||||||
|
stockStatus.findCandidates(outPath)
|
||||||
Reference in New Issue
Block a user