chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:10:28 +08:00
commit c2acfb5f2d
267 changed files with 15542 additions and 0 deletions
+182
View File
@@ -0,0 +1,182 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import libs.common as common
import sys
import time
import pandas as pd
import numpy as np
from sqlalchemy.types import NVARCHAR
from sqlalchemy import inspect
import datetime
import akshare as ak
import traceback
import MySQLdb
# 600开头的股票是上证A股,属于大盘股
# 600开头的股票是上证A股,属于大盘股,其中6006开头的股票是最早上市的股票,
# 6016开头的股票为大盘蓝筹股;900开头的股票是上证B股;
# 000开头的股票是深证A股,001、002开头的股票也都属于深证A股,
# 其中002开头的股票是深证A股中小企业股票;
# 200开头的股票是深证B股;
# 300开头的股票是创业板股票;400开头的股票是三板市场股票。
def stock_a(code):
# print(code)
# print(type(code))
# 上证A股 # 深证A股
if code.startswith('600') or code.startswith('6006') or code.startswith('601') or code.startswith('000') or code.startswith('001') or code.startswith('002'):
return True
else:
return False
# 过滤掉 st 股票。
def stock_a_filter_st(name):
# print(code)
# print(type(code))
# 上证A股 # 深证A股
if name.find("ST") == -1:
return True
else:
return False
# 过滤价格,如果没有基本上是退市了。
def stock_a_filter_price(latest_price):
# float 在 pandas 里面判断 空。
if np.isnan(latest_price):
return False
else:
return True
####### 3.pdf 方法。宏观经济数据
# 接口全部有错误。只专注股票数据。
def stat_all(tmp_datetime):
datetime_str = (tmp_datetime).strftime("%Y-%m-%d")
datetime_int = (tmp_datetime).strftime("%Y%m%d")
print("datetime_str:", datetime_str)
print("datetime_int:", datetime_int)
# 股票列表
try:
data = ak.stock_zh_a_spot_em()
# print(data.index)
# 解决ESP 小数问题。
# data["esp"] = data["esp"].round(2) # 数据保留2位小数
data.columns = ['index', 'code', 'name', 'last_price', 'change_percent', 'change_amount',
'volume', 'turnover', 'amplitude', 'high', 'low', 'open', 'closed', 'volume_ratio',
'turnover_rate', 'pe_ratio','pb_ratio', 'market_cap','circulating_market_cap','rise_speed',
'change_5min', 'change_ercent_60day','ytd_change_percent']
data = data.loc[data["code"].apply(stock_a)].loc[data["name"].apply(stock_a_filter_st)].loc[
data["last_price"].apply(stock_a_filter_price)]
print(data)
data['date'] = datetime_int # 修改时间成为int类型。
# 删除老数据。
del_sql = " DELETE FROM `stock_zh_a_spot_em` where `date` = '%s' " % datetime_int
common.insert(del_sql)
data.set_index('code', inplace=True)
data.drop('index', axis=1, inplace=True)
print(data)
# 删除index,然后和原始数据合并。
common.insert_db(data, "stock_zh_a_spot_em", True, "`date`,`code`")
except Exception as e:
print("error :", e)
traceback.print_exc()
# 龙虎榜-个股上榜统计
# 接口: stock_lhb_ggtj_sina
#
# 目标地址: http://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/ggtj/index.phtml
#
# 描述: 获取新浪财经-龙虎榜-个股上榜统计
#
try:
stock_lhb_ggtj_sina = ak.stock_lhb_ggtj_sina(symbol="5")
print(stock_lhb_ggtj_sina)
stock_lhb_ggtj_sina.columns = ['code', 'name', 'ranking_times', 'sum_buy', 'sum_sell', 'net_amount', 'buy_seat',
'sell_seat']
stock_lhb_ggtj_sina = stock_lhb_ggtj_sina.loc[stock_lhb_ggtj_sina["code"].apply(stock_a)].loc[
stock_lhb_ggtj_sina["name"].apply(stock_a_filter_st)]
stock_lhb_ggtj_sina.set_index('code', inplace=True)
# data_sina_lhb.drop('index', axis=1, inplace=True)
# 删除老数据。
stock_lhb_ggtj_sina['date'] = datetime_int # 修改时间成为int类型。
# 删除老数据。
del_sql = " DELETE FROM `stock_lhb_ggtj_sina` where `date` = '%s' " % datetime_int
common.insert(del_sql)
common.insert_db(stock_lhb_ggtj_sina, "stock_lhb_ggtj_sina", True, "`date`,`code`")
except Exception as e:
print("error :", e)
traceback.print_exc()
# 每日统计
# 接口: stock_dzjy_mrtj
#
# 目标地址: http://data.eastmoney.com/dzjy/dzjy_mrtj.aspx
#
# 描述: 获取东方财富网-数据中心-大宗交易-每日统计
# https://akshare.akfamily.xyz/data/stock/stock.html#id318
# import akshare as ak
# stock_dzjy_mrtj_df = ak.stock_dzjy_mrtj(start_date='20220105', end_date='20220105')
# print(stock_dzjy_mrtj_df)
try:
print("################ tmp_datetime : " + datetime_int)
# 格式要 int类型日期
stock_dzjy_mrtj = ak.stock_dzjy_mrtj(start_date=datetime_int, end_date=datetime_int)
print(stock_dzjy_mrtj)
stock_dzjy_mrtj.columns = ['index', 'trade_date', 'code', 'name', 'quote_change', 'close_price', 'average_price',
'overflow_rate', 'trade_number', 'sum_volume', 'sum_turnover',
'turnover_market_rate']
stock_dzjy_mrtj.set_index('code', inplace=True)
# data_sina_lhb.drop('index', axis=1, inplace=True)
# 删除老数据。
stock_dzjy_mrtj['date'] = datetime_int # 修改时间成为int类型。
stock_dzjy_mrtj.drop('trade_date', axis=1, inplace=True)
stock_dzjy_mrtj.drop('index', axis=1, inplace=True)
# 数据保留2位小数
try:
stock_dzjy_mrtj = stock_dzjy_mrtj.loc[stock_dzjy_mrtj["code"].apply(stock_a)].loc[
stock_dzjy_mrtj["name"].apply(stock_a_filter_st)]
stock_dzjy_mrtj["average_price"] = stock_dzjy_mrtj["average_price"].round(2)
stock_dzjy_mrtj["overflow_rate"] = stock_dzjy_mrtj["overflow_rate"].round(4)
stock_dzjy_mrtj["turnover_market_rate"] = stock_dzjy_mrtj["turnover_market_rate"].round(6)
except Exception as e:
print("round error :", e)
traceback.print_exc()
# 删除老数据。
del_sql = " DELETE FROM `stock_dzjy_mrtj` where `date` = '%s' " % datetime_int
common.insert(del_sql)
print(stock_dzjy_mrtj)
common.insert_db(stock_dzjy_mrtj, "stock_dzjy_mrtj", True, "`date`,`code`")
except Exception as e:
print("error :", e)
traceback.print_exc()
# main函数入口
if __name__ == '__main__':
# 执行数据初始化。
# 使用方法传递。
tmp_datetime = common.run_with_args(stat_all)
+4
View File
@@ -0,0 +1,4 @@
1,计算每日买全部推荐买。
2,计算每日全部推荐卖数据。
3,设置个人账号,设置购买和卖的数据。进行关联查询。
4,最重要的沪深300,中正500数据。进行大盘股分析。
+24
View File
@@ -0,0 +1,24 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
from pytz import utc
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.executors.pool import ProcessPoolExecutor
import libs.common as common
# doc : http://apscheduler.readthedocs.io/en/latest/modules/jobstores/sqlalchemy.html
jobstores = {
'default': SQLAlchemyJobStore(url=common.MYSQL_CONN_URL, tablename='apscheduler_jobs')
}
executors = {
'default': {'type': 'threadpool', 'max_workers': 20},
'processpool': ProcessPoolExecutor(max_workers=5)
}
job_defaults = {
'coalesce': False,
'max_instances': 3
}
scheduler = BlockingScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
scheduler.start()
print("start ...")
+33
View File
@@ -0,0 +1,33 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import libs.common as common
import MySQLdb
# 创建新数据库。
def create_new_database():
with MySQLdb.connect(common.MYSQL_HOST, common.MYSQL_USER, common.MYSQL_PWD, "mysql", charset="utf8") as db:
try:
create_sql = " CREATE DATABASE IF NOT EXISTS %s CHARACTER SET utf8 COLLATE utf8_general_ci " % common.MYSQL_DB
print(create_sql)
db.autocommit(on=True)
db.cursor().execute(create_sql)
except Exception as e:
print("error CREATE DATABASE :", e)
# main函数入口
if __name__ == '__main__':
# 检查,如果执行 select 1 失败,说明数据库不存在,然后创建一个新的数据库。
try:
with MySQLdb.connect(common.MYSQL_HOST, common.MYSQL_USER, common.MYSQL_PWD, common.MYSQL_DB,
charset="utf8") as db:
db.autocommit(on=True)
db.cursor().execute(" select 1 ")
print("########### db exists ###########")
except Exception as e:
print("check MYSQL_DB error and create new one :", e)
# 检查数据库失败,
create_new_database()
# 执行数据初始化。
+28
View File
@@ -0,0 +1,28 @@
#!/bin/sh
mkdir -p /data/logs
DATETIME=`date +%Y-%m-%d:%H:%M:%S`
DATE=`date +%Y-%m-%d`
export PYTHONIOENCODING=utf-8
export LANG=zh_CN.UTF-8
export PYTHONPATH=/data/stock
export LC_CTYPE=zh_CN.UTF-8
echo "###################"$DATETIME"###################" >> /data/logs/daily.${DATE}.log
#增加获得今日全部数据和大盘数据
/usr/local/bin/python3 /data/stock/jobs/18h_daily_job.py >> /data/logs/daily.${DATE}.log
echo "###################"$DATETIME"###################" >> /data/logs/daily.${DATE}.log
#使用股票指标预测。
/usr/local/bin/python3 /data/stock/jobs/guess_indicators_daily_job.py >> /data/logs/daily.${DATE}.log
/usr/local/bin/python3 /data/stock/jobs/guess_indicators_daily_buy_job.py >> /data/logs/daily.${DATE}.log
#清除前3天数据。
DATE_20=`date -d '-20 days' +%Y-%m-%d`
MONTH_20=`date -d '-20 days' +%Y-%m`
echo "rm -f /data/cache/hist_data_cache/${MONTH_20}/${DATETIME_20}"
rm -f /data/cache/hist_data_cache/${MONTH_20}/${DATETIME_20}
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh
mkdir -p /data/logs
DATE=`date +%Y-%m-%d:%H:%M:%S`
echo $DATE >> /data/logs/hourly.log
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
mkdir -p /data/logs
DATE=`date +%Y-%m-%d:%H:%M:%S`
echo $DATE >> /data/logs/1min.log
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh
mkdir -p /data/logs
DATE=`date +%Y-%m-%d:%H:%M:%S`
echo $DATE >> /data/logs/monthly.log
+6
View File
@@ -0,0 +1,6 @@
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/1 * * * * /bin/run-parts /etc/cron.minutely
10 * * * * /bin/run-parts /etc/cron.hourly
30 16 * * * /bin/run-parts /etc/cron.daily
30 17 1,10,20 * * /bin/run-parts /etc/cron.monthly
+49
View File
@@ -0,0 +1,49 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import libs.common as common
import sys
import os
import time
import pandas as pd
import tushare as ts
from sqlalchemy.types import NVARCHAR
from sqlalchemy import inspect
import datetime
import shutil
####### 使用 5.pdf,先做 基本面数据 的数据,然后在做交易数据。
#
def stat_all(tmp_datetime):
datetime_str = (tmp_datetime).strftime("%Y-%m-%d")
datetime_int = (tmp_datetime).strftime("%Y%m%d")
cache_dir = common.bash_stock_tmp % (datetime_str[0:7], datetime_str)
if os.path.exists(cache_dir):
shutil.rmtree(cache_dir)
print("remove cache dir force :", cache_dir)
print("datetime_str:", datetime_str)
print("datetime_int:", datetime_int)
data = ts.top_list(datetime_str)
# 处理重复数据,保存最新一条数据。最后一步处理,否则concat有问题。
#
if not data is None and len(data) > 0:
# 插入数据库。
# del data["reason"]
data["date"] = datetime_int # 修改时间成为int类型。
data = data.drop_duplicates(subset="code", keep="last")
data.head(n=1)
common.insert_db(data, "ts_top_list", False, "`date`,`code`")
else:
print("no data .")
print(datetime_str)
# main函数入口
if __name__ == '__main__':
# 使用方法传递。
tmp_datetime = common.run_with_args(stat_all)
@@ -0,0 +1,77 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import libs.common as common
import pandas as pd
import numpy as np
import math
import datetime
import stockstats
from sqlalchemy import text
### 对每日指标数据,进行筛选。将符合条件的。二次筛选出来。
### 只是做简单筛选
def stat_all_lite_buy(tmp_datetime):
datetime_str = (tmp_datetime).strftime("%Y-%m-%d")
datetime_int = (tmp_datetime).strftime("%Y%m%d")
print("datetime_str:", datetime_str)
print("datetime_int:", datetime_int)
# 查询参数
params = {"datetime": datetime_int}
sql_kdjk = text(" SELECT avg(`kdjk`) as avg_kdjk FROM guess_indicators_daily ")
data_kdjk = pd.read_sql(sql=sql_kdjk, con=common.engine(), params=params)
kdjk = data_kdjk["avg_kdjk"][0]
sql_kdjd = text(" SELECT avg(`kdjd`) as avg_kdjd FROM guess_indicators_daily ")
data_kdjd = pd.read_sql(sql=sql_kdjd, con=common.engine(), params=params)
kdjd = data_kdjd["avg_kdjd"][0]
sql_kdjj = text(" SELECT avg(`kdjj`) as avg_kdjj FROM guess_indicators_daily ")
data_kdjj = pd.read_sql(sql=sql_kdjj, con=common.engine(), params=params)
kdjj = data_kdjj["avg_kdjj"][0]
# K值在80以上,D值在70以上,J值大于90时为超买。
# J大于100时为超买,小于10时为超卖。
# 当六日指标上升到达80时,表示股市已有超买现象
# 当CCI>﹢100 时,表明股价已经进入非常态区间——超买区间,股价的异动现象应多加关注。
params_1 = {"datetime": datetime_int, "kdjk": kdjk, "kdjd": kdjd, "kdjj": kdjj}
sql_1 = text("""
SELECT `date`,`code`,`name`,`last_price`,`change_percent`,`change_amount`,`volume`,`turnover`,
`amplitude`,`high`,`low`,`open`,`closed`,`volume_ratio`,`turnover_rate`,
`pe_ratio`,`pb_ratio`,`market_cap`,`circulating_market_cap`,`rise_speed`,
`change_5min`,`change_ercent_60day`,`ytd_change_percent`,
`boll`, `boll_lb`, `boll_ub`, `kdjd`, `kdjj`, `kdjk`, `macd`, `macdh`,
`macds`, `pdi`,`trix`, `trix_9_sma`, `vr`, `vr_6_sma`, `wr_10`, `wr_6`
FROM stock_data.guess_indicators_daily WHERE `date` = :datetime
and kdjk >= :kdjk and kdjd >= :kdjd and kdjj >= :kdjj
""") # and kdjj > 100 and rsi_6 > 80 and cci > 100 # 调整参数,提前获得股票增长。
try:
# 删除老数据。
del_sql = " DELETE FROM `stock_data`.`guess_indicators_lite_buy_daily` WHERE `date`= '%s' " % datetime_int
common.insert(del_sql)
except Exception as e:
print("error :", e)
print(f"sql_1 : {sql_1}")
data = pd.read_sql(sql=sql_1, con=common.engine(), params=params_1)
data = data.drop_duplicates(subset="code", keep="last")
print("######## stat_all_lite_buy len data ########:", len(data))
try:
common.insert_db(data, "guess_indicators_lite_buy_daily", False, "`date`,`code`")
except Exception as e:
print("error :", e)
# main函数入口
if __name__ == '__main__':
# 使用方法传递。
# 二次筛选数据。直接计算买卖股票数据。
tmp_datetime = common.run_with_args(stat_all_lite_buy)
+278
View File
@@ -0,0 +1,278 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import libs.common as common
import pandas as pd
import numpy as np
import math
import datetime
import stockstats
# 批处理数据。
def stat_all_batch(tmp_datetime):
datetime_str = (tmp_datetime).strftime("%Y-%m-%d")
datetime_int = (tmp_datetime).strftime("%Y%m%d")
print("datetime_str:", datetime_str)
print("datetime_int:", datetime_int)
try:
# 删除老数据。
del_sql = " DELETE FROM `guess_indicators_daily` WHERE `date`= %s " % datetime_int
common.insert(del_sql)
except Exception as e:
print("error :", e)
sql_count = """
SELECT count(1) FROM stock_zh_a_spot_em WHERE `date` = %s and `open` > 0
"""
# 修改逻辑,增加中小板块计算。 中小板:002,创业板:300 。已经是经过筛选的数据了。
count = common.select_count(sql_count, params=[datetime_int])
print("count :", count)
batch_size = 100
end = int(math.ceil(float(count) / batch_size) * batch_size)
print(end)
for i in range(0, end, batch_size):
print("loop :", i)
# 查询今日满足股票数据。剔除数据:创业板股票数据,中小板股票数据,所有st股票
# #`code` not like '002%' and `code` not like '300%' and `name` not like '%st%'
sql_1 = """
SELECT `date`,`code`,`name`,`last_price`,`change_percent`,`change_amount`,`volume`,`turnover`,
`amplitude`,`high`,`low`,`open`,`closed`,`volume_ratio`,`turnover_rate`,
`pe_ratio`,`pb_ratio`,`market_cap`,`circulating_market_cap`,`rise_speed`,
`change_5min`,`change_ercent_60day`,`ytd_change_percent`
FROM stock_zh_a_spot_em WHERE `date` = %s and `open` > 0 limit %s , %s
"""
sql_2 = sql_1 % (datetime_int, i, batch_size)
print(sql_2)
# data = pd.read_sql(sql=sql_1, con=common.engine(), params=[datetime_int, '002%', '300%', '%st%', i, batch_size])
data = pd.read_sql(sql=sql_2, con=common.engine())
data = data.drop_duplicates(subset="code", keep="last")
print("########data[last_price]########:", len(data))
stat_index_all(data, i)
# 分批执行。
def stat_index_all(data, idx):
# print(data["last_price"])
# 1), n天涨跌百分百计算
# open price change (in percent) between today and the day before yesterday r stands for rate.
# stock[close_-2_r]
# 可以看到,-n天数据和今天数据的百分比。
# 2), CR指标
# http://wiki.mbalib.com/wiki/CR%E6%8C%87%E6%A0%87 价格动量指标
# CR跌穿a、b、c、d四条线,再由低点向上爬升160时,为短线获利的一个良机,应适当卖出股票。
# CR跌至40以下时,是建仓良机。而CR高于300~400时,应注意适当减仓。
# 3), KDJ指标
# http://wiki.mbalib.com/wiki/%E9%9A%8F%E6%9C%BA%E6%8C%87%E6%A0%87
# 随机指标(KDJ)一般是根据统计学的原理,通过一个特定的周期(常为9日、9周等)内出现过的最高价、
# 最低价及最后一个计算周期的收盘价及这三者之间的比例关系,来计算最后一个计算周期的未成熟随机值RSV,
# 然后根据平滑移动平均线的方法来计算K值、D值与J值,并绘成曲线图来研判股票走势。
# (3)在使用中,常有J线的指标,即3乘以K值减2乘以D值(3K-2D=J),其目的是求出K值与D值的最大乖离程度,
# 以领先KD值找出底部和头部。J大于100时为超买,小于10时为超卖。
# 4), MACD指标
# http://wiki.mbalib.com/wiki/MACD
# 平滑异同移动平均线(Moving Average Convergence Divergence,简称MACD指标),也称移动平均聚散指标
# MACD 则可发挥其应有的功能,但当市场呈牛皮盘整格局,股价不上不下时,MACD买卖讯号较不明显。
# 当用MACD作分析时,亦可运用其他的技术分析指标如短期 K,D图形作为辅助工具,而且也可对买卖讯号作双重的确认。
# 5), BOLL指标
# http://wiki.mbalib.com/wiki/BOLL
# 布林线指标(Bollinger Bands)
# 6), RSI指标
# http://wiki.mbalib.com/wiki/RSI
# 相对强弱指标(Relative Strength Index,简称RSI),也称相对强弱指数、相对力度指数
# (2)强弱指标保持高于50表示为强势市场,反之低于50表示为弱势市场。
# (3)强弱指标多在70与30之间波动。当六日指标上升到达80时,表示股市已有超买现象,
# 如果一旦继续上升,超过90以上时,则表示已到严重超买的警戒区,股价已形成头部,极可能在短期内反转回转。
# 7), W%R指标
# http://wiki.mbalib.com/wiki/%E5%A8%81%E5%BB%89%E6%8C%87%E6%A0%87
# 威廉指数(Williams%Rate)该指数是利用摆动点来度量市场的超买超卖现象。
# 8), CCI指标
# http://wiki.mbalib.com/wiki/%E9%A1%BA%E5%8A%BF%E6%8C%87%E6%A0%87
# 顺势指标又叫CCI指标,其英文全称为“Commodity Channel Index”,
# 是由美国股市分析家唐纳德·蓝伯特(Donald Lambert)所创造的,是一种重点研判股价偏离度的股市分析工具。
# 1、当CCI指标从下向上突破﹢100线而进入非常态区间时,表明股价脱离常态而进入异常波动阶段,
# 中短线应及时买入,如果有比较大的成交量配合,买入信号则更为可靠。
#   2、当CCI指标从上向下突破﹣100线而进入另一个非常态区间时,表明股价的盘整阶段已经结束,
# 将进入一个比较长的寻底过程,投资者应以持币观望为主。
# CCI, default to 14 days
# 9), TR、ATR指标
# http://wiki.mbalib.com/wiki/%E5%9D%87%E5%B9%85%E6%8C%87%E6%A0%87
# 均幅指标(Average True Ranger,ATR
# 均幅指标(ATR)是取一定时间周期内的股价波动幅度的移动平均值,主要用于研判买卖时机。
# 10), DMA指标
# http://wiki.mbalib.com/wiki/DMA
#  DMA指标(Different of Moving Average)又叫平行线差指标,是目前股市分析技术指标中的一种中短期指标,它常用于大盘指数和个股的研判。
# DMA, difference of 10 and 50 moving average
# stock[dma]
# 11), DMI+DI-DIDXADXADXR指标
# http://wiki.mbalib.com/wiki/DMI
# 动向指数Directional Movement Index,DMI
# http://wiki.mbalib.com/wiki/ADX
# 平均趋向指标(Average Directional Indicator,简称ADX
# http://wiki.mbalib.com/wiki/%E5%B9%B3%E5%9D%87%E6%96%B9%E5%90%91%E6%8C%87%E6%95%B0%E8%AF%84%E4%BC%B0
# 平均方向指数评估(ADXR)实际是今日ADX与前面某一日的ADX的平均值。ADXR在高位与ADX同步下滑,可以增加对ADX已经调头的尽早确认。
# ADXR是ADX的附属产品,只能发出一种辅助和肯定的讯号,并非入市的指标,而只需同时配合动向指标(DMI)的趋势才可作出买卖策略。
# 在应用时,应以ADX为主,ADXR为辅。
# 12), TRIXMATRIX指标
# http://wiki.mbalib.com/wiki/TRIX
# TRIX指标又叫三重指数平滑移动平均指标(Triple Exponentially Smoothed Average
# 13), VRMAVR指标
# http://wiki.mbalib.com/wiki/%E6%88%90%E4%BA%A4%E9%87%8F%E6%AF%94%E7%8E%87
# 成交量比率(Volumn Ratio,VR)(简称VR),是一项通过分析股价上升日成交额(或成交量,下同)与股价下降日成交额比值,
# 从而掌握市场买卖气势的中期技术指标。
#stock_column = ['adx', 'adxr', 'boll', 'boll_lb', 'boll_ub', 'cci', 'cci_20', 'close_-1_r',
# 'close_-2_r', 'code', 'cr', 'cr-ma1', 'cr-ma2', 'cr-ma3', 'date', 'dma', 'dx',
# 'kdjd', 'kdjj', 'kdjk', 'macd', 'macdh', 'macds', 'pdi',
# 'rsi_12', 'rsi_6', 'trix', 'trix_9_sma', 'vr', 'vr_6_sma', 'wr_10', 'wr_6']
stock_column = ['date','code', 'boll', 'boll_lb', 'boll_ub',
'kdjd', 'kdjj', 'kdjk', 'macd', 'macdh', 'macds', 'pdi',
'trix', 'trix_9_sma', 'vr', 'vr_6_sma', 'wr_10', 'wr_6']
# code cr cr-ma1 cr-ma2 cr-ma3 date
data_new = concat_guess_data(stock_column, data)
data_new = data_new.round(2) # 数据保留2位小数
# print(data_new.head())
print("########insert db guess_indicators_daily idx :########:", idx)
try:
common.insert_db(data_new, "guess_indicators_daily", False, "`date`,`code`")
except Exception as e:
print("error :", e)
# 链接guess 数据。
def concat_guess_data(stock_column, data):
# 使用 trade 填充数据
print("stock_column:", stock_column)
tmp_dic = {}
# 循环增加临时数据。如果要是date,和code,
for col in stock_column:
if col == 'date':
tmp_dic[col] = data["date"]
elif col == 'code':
tmp_dic[col] = data["code"]
else:
tmp_dic[col] = data["last_price"]
# print("##########tmp_dic: ", tmp_dic)
print("########################## BEGIN ##########################")
stock_guess = pd.DataFrame(tmp_dic, index=data.index.values)
print(stock_guess.columns.values)
# print(stock_guess.head())
stock_guess = stock_guess.apply(apply_guess, stock_column=stock_column, axis=1) # , axis=1)
print(stock_guess.head())
# stock_guess.astype('float32', copy=False)
stock_guess.drop('date', axis=1, inplace=True) # 删除日期字段,然后和原始数据合并。
# print(stock_guess["5d"])
data_new = pd.merge(data, stock_guess, on=['code'], how='left')
print("#############")
return data_new
# 带参数透传。
def apply_guess(tmp, stock_column):
# print("apply_guess columns args:", stock_column)
# print("apply_guess data :", type(tmp))
date = tmp["date"]
code = tmp["code"]
date_end = datetime.datetime.strptime(date, "%Y%m%d")
date_start = (date_end + datetime.timedelta(days=-100)).strftime("%Y-%m-%d")
date_end = date_end.strftime("%Y-%m-%d")
# print(code, date_start, date_end)
# open, high, close, low, volume, price_change, p_change, ma5, ma10, ma20, v_ma5, v_ma10, v_ma20, turnover
# 使用缓存方法。加快计算速度。
stock = common.get_hist_data_cache(code, date_start, date_end)
# 设置返回数组。
stock_data_list = []
stock_name_list = []
print(f"stock_column : {stock_column}")
# 增加空判断,如果是空返回 0 数据。
if stock is None:
for col in stock_column:
if col == 'date':
stock_data_list.append(date)
stock_name_list.append('date')
elif col == 'code':
stock_data_list.append(code)
stock_name_list.append('code')
else:
stock_data_list.append(0)
stock_name_list.append(col)
return pd.Series(stock_data_list, index=stock_name_list)
# print(stock.head())
# open high close low volume
# stock = pd.DataFrame({"close": stock["close"]}, index=stock.index.values)
# stock = stock.sort_index(0) # 将数据按照日期排序下。
stock["date"] = stock.index.values # 增加日期列。
print(f"stock: {stock}")
# stock = stock.sort_index(0) # 将数据按照日期排序下。
# print(stock) [186 rows x 14 columns]
# 初始化统计类
# stockStat = stockstats.StockDataFrame.retype(pd.read_csv('002032.csv'))
stockStat = stockstats.StockDataFrame.retype(stock)
print(f"stockStat : {stockStat}")
print("########################## print result ##########################")
for col in stock_column:
if col == 'date':
stock_data_list.append(date)
stock_name_list.append('date')
elif col == 'code':
stock_data_list.append(code)
stock_name_list.append('code')
else:
# 将数据的最后一个返回。
print(col)
print(stockStat[col])
print(stockStat[col].values[1])
#print(stockStat[col].head(1))
tmp_val = stockStat[col].values[1]
if np.isinf(tmp_val): # 解决值中存在INF问题。
tmp_val = 0
if np.isnan(tmp_val): # 解决值中存在NaN问题。
tmp_val = 0
# print("col name : ", col, tmp_val)
stock_data_list.append(tmp_val)
stock_name_list.append(col)
# print(stock_data_list)
return pd.Series(stock_data_list, index=stock_name_list)
# print(stock["mov_vol"].tail())
# print(stock["return"].tail())
# print("stock[10d].tail(1)", stock["10d"].tail(1).values[0])
# 10d 20d 5-10d 5-20d 5d 60d code date mov_vol return
# tmp = list([stock["10d"].tail(1).values[0], stock["20d"].tail(1).values[0], stock["5-10d"].tail(1).values[0],
# stock["5-20d"].tail(1).values[0], stock["5d"].tail(1).values[0], stock["60d"].tail(1).values[0],
# code, date, stock["mov_vol"].tail(1).values[0], stock["return"].tail(1).values[0]])
# # print(tmp)
# return tmp
# main函数入口
if __name__ == '__main__':
# 使用方法传递。
tmp_datetime = common.run_with_args(stat_all_batch)
# 二次筛选数据。直接计算买卖股票数据。
@@ -0,0 +1,61 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import libs.common as common
import pandas as pd
import numpy as np
import math
import datetime
import stockstats
from sqlalchemy import text
# 设置卖出数据。
def stat_all_lite_sell(tmp_datetime):
datetime_str = (tmp_datetime).strftime("%Y-%m-%d")
datetime_int = (tmp_datetime).strftime("%Y%m%d")
print("datetime_str:", datetime_str)
print("datetime_int:", datetime_int)
# 超卖区:K值在20以下,D值在30以下为超卖区。一般情况下,股价有可能上涨,反弹的可能性增大。局内人不应轻易抛出股票,局外人可寻机入场。
# J大于100时为超买,小于10时为超卖。
# 当六日强弱指标下降至20时,表示股市有超卖现象
# 当CCI<﹣100时,表明股价已经进入另一个非常态区间——超卖区间,投资者可以逢低吸纳股票。
sql_1 = text("""
SELECT `date`,`code`,`name`,`last_price`,`change_percent`,`change_amount`,`volume`,`turnover`,
`amplitude`,`high`,`low`,`open`,`closed`,`volume_ratio`,`turnover_rate`,
`pe_ratio`,`pb_ratio`,`market_cap`,`circulating_market_cap`,`rise_speed`,
`change_5min`,`change_ercent_60day`,`ytd_change_percent`,
`boll`, `boll_lb`, `boll_ub`, `kdjd`, `kdjj`, `kdjk`, `macd`, `macdh`,
`macds`, `pdi`,`trix`, `trix_9_sma`, `vr`, `vr_6_sma`, `wr_10`, `wr_6`
FROM stock_data.guess_indicators_daily WHERE `date` = :datetime
and kdjk <= 20 and kdjd <= 30 and kdjj <= 10
""")
try:
# 删除老数据。
del_sql = " DELETE FROM `stock_data`.`guess_indicators_lite_sell_daily` WHERE `date`= '%s' " % datetime_int
common.insert(del_sql)
except Exception as e:
print("error :", e)
# 查询参数
params = {"datetime": datetime_int}
print(sql_1)
data = pd.read_sql(sql=sql_1, con=common.engine(), params=params)
data = data.drop_duplicates(subset="code", keep="last")
print("######## stat_all_lite_sell len data ########:", len(data))
try:
common.insert_db(data, "guess_indicators_lite_sell_daily", False, "`date`,`code`")
except Exception as e:
print("error :", e)
# main函数入口
if __name__ == '__main__':
# 使用方法传递。
# 二次筛选数据。直接计算买卖股票数据。
tmp_datetime = common.run_with_args(stat_all_lite_sell)
+480
View File
@@ -0,0 +1,480 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import libs.common as common
import pandas as pd
import numpy as np
import math
import datetime
import stockstats
### 对每日指标数据,进行筛选。将符合条件的。二次筛选出来。
### 只是做简单筛选
def stat_all_lite_buy(tmp_datetime):
datetime_str = (tmp_datetime).strftime("%Y-%m-%d")
datetime_int = (tmp_datetime).strftime("%Y%m%d")
print("datetime_str:", datetime_str)
print("datetime_int:", datetime_int)
# K值在80以上,D值在70以上,J值大于90时为超买。
# J大于100时为超买,小于10时为超卖。
# 当六日指标上升到达80时,表示股市已有超买现象
# 当CCI>﹢100 时,表明股价已经进入非常态区间——超买区间,股价的异动现象应多加关注。
sql_1 = """
SELECT `date`, `code`, `name`, `changepercent`, `trade`, `open`, `high`, `low`,
`settlement`, `volume`, `turnoverratio`, `amount`, `per`, `pb`, `mktcap`,
`nmc` ,`kdjj`,`rsi_6`,`cci`
FROM stock_data.guess_indicators_daily WHERE `date` = %s
and kdjk >= 80 and kdjd >= 70 and kdjj >= 100 and rsi_6 >= 80 and cci >= 100
""" # and kdjj > 100 and rsi_6 > 80 and cci > 100 # 调整参数,提前获得股票增长。
try:
# 删除老数据。
del_sql = " DELETE FROM `stock_data`.`guess_indicators_lite_buy_daily` WHERE `date`= '%s' " % datetime_int
common.insert(del_sql)
except Exception as e:
print("error :", e)
data = pd.read_sql(sql=sql_1, con=common.engine(), params=[datetime_int])
data = data.drop_duplicates(subset="code", keep="last")
print("######## len data ########:", len(data))
try:
common.insert_db(data, "guess_indicators_lite_buy_daily", False, "`date`,`code`")
except Exception as e:
print("error :", e)
# 设置卖出数据。
def stat_all_lite_sell(tmp_datetime):
datetime_str = (tmp_datetime).strftime("%Y-%m-%d")
datetime_int = (tmp_datetime).strftime("%Y%m%d")
print("datetime_str:", datetime_str)
print("datetime_int:", datetime_int)
# 超卖区:K值在20以下,D值在30以下为超卖区。一般情况下,股价有可能上涨,反弹的可能性增大。局内人不应轻易抛出股票,局外人可寻机入场。
# J大于100时为超买,小于10时为超卖。
# 当六日强弱指标下降至20时,表示股市有超卖现象
# 当CCI<﹣100时,表明股价已经进入另一个非常态区间——超卖区间,投资者可以逢低吸纳股票。
sql_1 = """
SELECT `date`, `code`, `name`, `changepercent`, `trade`, `open`, `high`, `low`,
`settlement`, `volume`, `turnoverratio`, `amount`, `per`, `pb`, `mktcap`,
`nmc` ,`kdjj`,`rsi_6`,`cci`
FROM stock_data.guess_indicators_daily WHERE `date` = %s
and kdjk <= 20 and kdjd <= 30 and kdjj <= 10 and rsi_6 <= 20 and cci <= -100
"""
try:
# 删除老数据。
del_sql = " DELETE FROM `stock_data`.`guess_indicators_lite_sell_daily` WHERE `date`= '%s' " % datetime_int
common.insert(del_sql)
except Exception as e:
print("error :", e)
data = pd.read_sql(sql=sql_1, con=common.engine(), params=[datetime_int])
data = data.drop_duplicates(subset="code", keep="last")
print("######## len data ########:", len(data))
try:
common.insert_db(data, "guess_indicators_lite_sell_daily", False, "`date`,`code`")
except Exception as e:
print("error :", e)
# 批处理数据。
def stat_all_batch(tmp_datetime):
datetime_str = (tmp_datetime).strftime("%Y-%m-%d")
datetime_int = (tmp_datetime).strftime("%Y%m%d")
print("datetime_str:", datetime_str)
print("datetime_int:", datetime_int)
try:
# 删除老数据。
del_sql = " DELETE FROM `stock_data`.`guess_indicators_daily` WHERE `date`= %s " % datetime_int
common.insert(del_sql)
except Exception as e:
print("error :", e)
sql_count = """
SELECT count(1) FROM stock_data.ts_today_all WHERE `date` = %s and `trade` > 0 and `open` > 0 and trade <= 20
and `code` not like %s and `name` not like %s
"""
# 修改逻辑,增加中小板块计算。 中小板:002,创业板:300 。and `code` not like %s and `code` not like %s and `name` not like %s
# count = common.select_count(sql_count, params=[datetime_int, '002%', '300%', '%st%'])
count = common.select_count(sql_count, params=[datetime_int, '300%', '%st%'])
print("count :", count)
batch_size = 100
end = int(math.ceil(float(count) / batch_size) * batch_size)
print(end)
for i in range(0, end, batch_size):
print("loop :", i)
# 查询今日满足股票数据。剔除数据:创业板股票数据,中小板股票数据,所有st股票
# #`code` not like '002%' and `code` not like '300%' and `name` not like '%st%'
sql_1 = """
SELECT `date`, `code`, `name`, `changepercent`, `trade`, `open`, `high`, `low`,
`settlement`, `volume`, `turnoverratio`, `amount`, `per`, `pb`, `mktcap`, `nmc`
FROM stock_data.ts_today_all WHERE `date` = %s and `trade` > 0 and `open` > 0 and trade <= 20
and `code` not like %s and `name` not like %s limit %s , %s
"""
print(sql_1)
# data = pd.read_sql(sql=sql_1, con=common.engine(), params=[datetime_int, '002%', '300%', '%st%', i, batch_size])
data = pd.read_sql(sql=sql_1, con=common.engine(), params=[datetime_int, '300%', '%st%', i, batch_size])
data = data.drop_duplicates(subset="code", keep="last")
print("########data[trade]########:", len(data))
stat_index_all(data, i)
# 分批执行。
def stat_index_all(data, idx):
# print(data["trade"])
# 1), n天涨跌百分百计算
# open price change (in percent) between today and the day before yesterday r stands for rate.
# stock[close_-2_r]
# 可以看到,-n天数据和今天数据的百分比。
# 2), CR指标
# http://wiki.mbalib.com/wiki/CR%E6%8C%87%E6%A0%87 价格动量指标
# CR跌穿a、b、c、d四条线,再由低点向上爬升160时,为短线获利的一个良机,应适当卖出股票。
# CR跌至40以下时,是建仓良机。而CR高于300~400时,应注意适当减仓。
# 3), KDJ指标
# http://wiki.mbalib.com/wiki/%E9%9A%8F%E6%9C%BA%E6%8C%87%E6%A0%87
# 随机指标(KDJ)一般是根据统计学的原理,通过一个特定的周期(常为9日、9周等)内出现过的最高价、
# 最低价及最后一个计算周期的收盘价及这三者之间的比例关系,来计算最后一个计算周期的未成熟随机值RSV,
# 然后根据平滑移动平均线的方法来计算K值、D值与J值,并绘成曲线图来研判股票走势。
# (3)在使用中,常有J线的指标,即3乘以K值减2乘以D值(3K-2D=J),其目的是求出K值与D值的最大乖离程度,
# 以领先KD值找出底部和头部。J大于100时为超买,小于10时为超卖。
# 4), MACD指标
# http://wiki.mbalib.com/wiki/MACD
# 平滑异同移动平均线(Moving Average Convergence Divergence,简称MACD指标),也称移动平均聚散指标
# MACD 则可发挥其应有的功能,但当市场呈牛皮盘整格局,股价不上不下时,MACD买卖讯号较不明显。
# 当用MACD作分析时,亦可运用其他的技术分析指标如短期 K,D图形作为辅助工具,而且也可对买卖讯号作双重的确认。
# 5), BOLL指标
# http://wiki.mbalib.com/wiki/BOLL
# 布林线指标(Bollinger Bands)
# 6), RSI指标
# http://wiki.mbalib.com/wiki/RSI
# 相对强弱指标(Relative Strength Index,简称RSI),也称相对强弱指数、相对力度指数
# (2)强弱指标保持高于50表示为强势市场,反之低于50表示为弱势市场。
# (3)强弱指标多在70与30之间波动。当六日指标上升到达80时,表示股市已有超买现象,
# 如果一旦继续上升,超过90以上时,则表示已到严重超买的警戒区,股价已形成头部,极可能在短期内反转回转。
# 7), W%R指标
# http://wiki.mbalib.com/wiki/%E5%A8%81%E5%BB%89%E6%8C%87%E6%A0%87
# 威廉指数(Williams%Rate)该指数是利用摆动点来度量市场的超买超卖现象。
# 8), CCI指标
# http://wiki.mbalib.com/wiki/%E9%A1%BA%E5%8A%BF%E6%8C%87%E6%A0%87
# 顺势指标又叫CCI指标,其英文全称为“Commodity Channel Index”,
# 是由美国股市分析家唐纳德·蓝伯特(Donald Lambert)所创造的,是一种重点研判股价偏离度的股市分析工具。
# 1、当CCI指标从下向上突破﹢100线而进入非常态区间时,表明股价脱离常态而进入异常波动阶段,
# 中短线应及时买入,如果有比较大的成交量配合,买入信号则更为可靠。
#   2、当CCI指标从上向下突破﹣100线而进入另一个非常态区间时,表明股价的盘整阶段已经结束,
# 将进入一个比较长的寻底过程,投资者应以持币观望为主。
# CCI, default to 14 days
# 9), TR、ATR指标
# http://wiki.mbalib.com/wiki/%E5%9D%87%E5%B9%85%E6%8C%87%E6%A0%87
# 均幅指标(Average True Ranger,ATR
# 均幅指标(ATR)是取一定时间周期内的股价波动幅度的移动平均值,主要用于研判买卖时机。
# 10), DMA指标
# http://wiki.mbalib.com/wiki/DMA
#  DMA指标(Different of Moving Average)又叫平行线差指标,是目前股市分析技术指标中的一种中短期指标,它常用于大盘指数和个股的研判。
# DMA, difference of 10 and 50 moving average
# stock[dma]
# 11), DMI+DI-DIDXADXADXR指标
# http://wiki.mbalib.com/wiki/DMI
# 动向指数Directional Movement Index,DMI
# http://wiki.mbalib.com/wiki/ADX
# 平均趋向指标(Average Directional Indicator,简称ADX
# http://wiki.mbalib.com/wiki/%E5%B9%B3%E5%9D%87%E6%96%B9%E5%90%91%E6%8C%87%E6%95%B0%E8%AF%84%E4%BC%B0
# 平均方向指数评估(ADXR)实际是今日ADX与前面某一日的ADX的平均值。ADXR在高位与ADX同步下滑,可以增加对ADX已经调头的尽早确认。
# ADXR是ADX的附属产品,只能发出一种辅助和肯定的讯号,并非入市的指标,而只需同时配合动向指标(DMI)的趋势才可作出买卖策略。
# 在应用时,应以ADX为主,ADXR为辅。
# 12), TRIXMATRIX指标
# http://wiki.mbalib.com/wiki/TRIX
# TRIX指标又叫三重指数平滑移动平均指标(Triple Exponentially Smoothed Average
# 13), VRMAVR指标
# http://wiki.mbalib.com/wiki/%E6%88%90%E4%BA%A4%E9%87%8F%E6%AF%94%E7%8E%87
# 成交量比率(Volumn Ratio,VR)(简称VR),是一项通过分析股价上升日成交额(或成交量,下同)与股价下降日成交额比值,
# 从而掌握市场买卖气势的中期技术指标。
stock_column = ['adx', 'adxr', 'boll', 'boll_lb', 'boll_ub', 'cci', 'cci_20', 'close_-1_r',
'close_-2_r', 'code', 'cr', 'cr-ma1', 'cr-ma2', 'cr-ma3', 'date', 'dma', 'dx',
'kdjd', 'kdjj', 'kdjk', 'macd', 'macdh', 'macds', 'mdi', 'pdi',
'rsi_12', 'rsi_6', 'trix', 'trix_9_sma', 'vr', 'vr_6_sma', 'wr_10', 'wr_6']
# code cr cr-ma1 cr-ma2 cr-ma3 date
data_new = concat_guess_data(stock_column, data)
data_new = data_new.round(2) # 数据保留2位小数
# print(data_new.head())
print("########insert db guess_indicators_daily idx :########:", idx)
try:
common.insert_db(data_new, "guess_indicators_daily", False, "`date`,`code`")
except Exception as e:
print("error :", e)
# 链接guess 数据。
def concat_guess_data(stock_column, data):
# 使用 trade 填充数据
print("stock_column:", stock_column)
tmp_dic = {}
# 循环增加临时数据。如果要是date,和code,
for col in stock_column:
if col == 'date':
tmp_dic[col] = data["date"]
elif col == 'code':
tmp_dic[col] = data["code"]
else:
tmp_dic[col] = data["trade"]
# print("##########tmp_dic: ", tmp_dic)
print("########################## BEGIN ##########################")
stock_guess = pd.DataFrame(tmp_dic, index=data.index.values)
print(stock_guess.columns.values)
# print(stock_guess.head())
stock_guess = stock_guess.apply(apply_guess, stock_column=stock_column, axis=1) # , axis=1)
print(stock_guess.head())
# stock_guess.astype('float32', copy=False)
stock_guess.drop('date', axis=1, inplace=True) # 删除日期字段,然后和原始数据合并。
# print(stock_guess["5d"])
data_new = pd.merge(data, stock_guess, on=['code'], how='left')
print("#############")
return data_new
# 带参数透传。
def apply_guess(tmp, stock_column):
# print("apply_guess columns args:", stock_column)
# print("apply_guess data :", type(tmp))
date = tmp["date"]
code = tmp["code"]
date_end = datetime.datetime.strptime(date, "%Y%m%d")
date_start = (date_end + datetime.timedelta(days=-100)).strftime("%Y-%m-%d")
date_end = date_end.strftime("%Y-%m-%d")
# print(code, date_start, date_end)
# open, high, close, low, volume, price_change, p_change, ma5, ma10, ma20, v_ma5, v_ma10, v_ma20, turnover
# 使用缓存方法。加快计算速度。
stock = common.get_hist_data_cache(code, date_start, date_end)
# 设置返回数组。
stock_data_list = []
stock_name_list = []
# 增加空判断,如果是空返回 0 数据。
if stock is None:
for col in stock_column:
if col == 'date':
stock_data_list.append(date)
stock_name_list.append('date')
elif col == 'code':
stock_data_list.append(code)
stock_name_list.append('code')
else:
stock_data_list.append(0)
stock_name_list.append(col)
return pd.Series(stock_data_list, index=stock_name_list)
# print(stock.head())
# open high close low volume
# stock = pd.DataFrame({"close": stock["close"]}, index=stock.index.values)
stock = stock.sort_index(0) # 将数据按照日期排序下。
stock["date"] = stock.index.values # 增加日期列。
stock = stock.sort_index(0) # 将数据按照日期排序下。
# print(stock) [186 rows x 14 columns]
# 初始化统计类
# stockStat = stockstats.StockDataFrame.retype(pd.read_csv('002032.csv'))
stockStat = stockstats.StockDataFrame.retype(stock)
print("########################## print result ##########################")
for col in stock_column:
if col == 'date':
stock_data_list.append(date)
stock_name_list.append('date')
elif col == 'code':
stock_data_list.append(code)
stock_name_list.append('code')
else:
# 将数据的最后一个返回。
tmp_val = stockStat[col].tail(1).values[0]
if np.isinf(tmp_val): # 解决值中存在INF问题。
tmp_val = 0
if np.isnan(tmp_val): # 解决值中存在NaN问题。
tmp_val = 0
# print("col name : ", col, tmp_val)
stock_data_list.append(tmp_val)
stock_name_list.append(col)
# print(stock_data_list)
return pd.Series(stock_data_list, index=stock_name_list)
# print(stock["mov_vol"].tail())
# print(stock["return"].tail())
# print("stock[10d].tail(1)", stock["10d"].tail(1).values[0])
# 10d 20d 5-10d 5-20d 5d 60d code date mov_vol return
# tmp = list([stock["10d"].tail(1).values[0], stock["20d"].tail(1).values[0], stock["5-10d"].tail(1).values[0],
# stock["5-20d"].tail(1).values[0], stock["5d"].tail(1).values[0], stock["60d"].tail(1).values[0],
# code, date, stock["mov_vol"].tail(1).values[0], stock["return"].tail(1).values[0]])
# # print(tmp)
# return tmp
# main函数入口
if __name__ == '__main__':
# 使用方法传递。
tmp_datetime = common.run_with_args(stat_all_batch)
# 二次筛选数据。直接计算买卖股票数据。
tmp_datetime = common.run_with_args(stat_all_lite_buy)
tmp_datetime = common.run_with_args(stat_all_lite_sell)
####################### 老方法,弃用了。#######################
def stat_index_all_no_use(tmp_datetime):
datetime_str = (tmp_datetime).strftime("%Y-%m-%d")
datetime_int = (tmp_datetime).strftime("%Y%m%d")
print("datetime_str:", datetime_str)
print("datetime_int:", datetime_int)
# 查询今日满足股票数据。剔除数据:创业板股票数据,中小板股票数据,所有st股票
# #`code` not like '002%' and `code` not like '300%' and `name` not like '%st%'
sql_1 = """
SELECT `date`, `code`, `name`, `changepercent`, `trade`, `open`, `high`, `low`,
`settlement`, `volume`, `turnoverratio`, `amount`, `per`, `pb`, `mktcap`, `nmc`
FROM stock_data.ts_today_all WHERE `date` = %s and `trade` > 0 and `open` > 0 and trade <= 20
and `code` not like %s and `code` not like %s and `name` not like %s
"""
print(sql_1)
data = pd.read_sql(sql=sql_1, con=common.engine(), params=[datetime_int, '002%', '300%', '%st%'])
data = data.drop_duplicates(subset="code", keep="last")
print("########data[trade]########:", len(data))
# print(data["trade"])
# 1), n天涨跌百分百计算
# open price change (in percent) between today and the day before yesterday r stands for rate.
# stock[close_-2_r]
# 可以看到,-n天数据和今天数据的百分比。
stock_column = ['close_-1_r', 'close_-2_r', 'code', 'date'] # close_-1_r close_-2_r code date
data_new = concat_guess_data(stock_column, data)
# 2), CR指标
# http://wiki.mbalib.com/wiki/CR%E6%8C%87%E6%A0%87 价格动量指标
# CR跌穿a、b、c、d四条线,再由低点向上爬升160时,为短线获利的一个良机,应适当卖出股票。
# CR跌至40以下时,是建仓良机。而CR高于300~400时,应注意适当减仓。
stock_column = ['code', 'cr', 'cr-ma1', 'cr-ma2', 'cr-ma3', 'date'] # code cr cr-ma1 cr-ma2 cr-ma3 date
data_new = concat_guess_data(stock_column, data_new)
# 3), KDJ指标
# http://wiki.mbalib.com/wiki/%E9%9A%8F%E6%9C%BA%E6%8C%87%E6%A0%87
# 随机指标(KDJ)一般是根据统计学的原理,通过一个特定的周期(常为9日、9周等)内出现过的最高价、
# 最低价及最后一个计算周期的收盘价及这三者之间的比例关系,来计算最后一个计算周期的未成熟随机值RSV,
# 然后根据平滑移动平均线的方法来计算K值、D值与J值,并绘成曲线图来研判股票走势。
# (3)在使用中,常有J线的指标,即3乘以K值减2乘以D值(3K-2D=J),其目的是求出K值与D值的最大乖离程度,
# 以领先KD值找出底部和头部。J大于100时为超买,小于10时为超卖。
stock_column = ['code', 'date', 'kdjd', 'kdjj', 'kdjk'] # code date kdjd kdjj kdjk
data_new = concat_guess_data(stock_column, data_new)
# 4), MACD指标
# http://wiki.mbalib.com/wiki/MACD
# 平滑异同移动平均线(Moving Average Convergence Divergence,简称MACD指标),也称移动平均聚散指标
# MACD 则可发挥其应有的功能,但当市场呈牛皮盘整格局,股价不上不下时,MACD买卖讯号较不明显。
# 当用MACD作分析时,亦可运用其他的技术分析指标如短期 K,D图形作为辅助工具,而且也可对买卖讯号作双重的确认。
stock_column = ['code', 'date', 'macd', 'macdh', 'macds'] # code date macd macdh macds
data_new = concat_guess_data(stock_column, data_new)
# 5), BOLL指标
# http://wiki.mbalib.com/wiki/BOLL
# 布林线指标(Bollinger Bands)
stock_column = ['boll', 'boll_lb', 'boll_ub', 'code', 'date'] # boll boll_lb boll_ub code date
data_new = concat_guess_data(stock_column, data_new)
# 6), RSI指标
# http://wiki.mbalib.com/wiki/RSI
# 相对强弱指标(Relative Strength Index,简称RSI),也称相对强弱指数、相对力度指数
# (2)强弱指标保持高于50表示为强势市场,反之低于50表示为弱势市场。
# (3)强弱指标多在70与30之间波动。当六日指标上升到达80时,表示股市已有超买现象,
# 如果一旦继续上升,超过90以上时,则表示已到严重超买的警戒区,股价已形成头部,极可能在短期内反转回转。
stock_column = ['code', 'date', 'rsi_12', 'rsi_6'] # code date rsi_12 rsi_6
data_new = concat_guess_data(stock_column, data_new)
# 7), W%R指标
# http://wiki.mbalib.com/wiki/%E5%A8%81%E5%BB%89%E6%8C%87%E6%A0%87
# 威廉指数(Williams%Rate)该指数是利用摆动点来度量市场的超买超卖现象。
stock_column = ['code', 'date', 'wr_10', 'wr_6'] # code date wr_10 wr_6
data_new = concat_guess_data(stock_column, data_new)
# 8), CCI指标
# http://wiki.mbalib.com/wiki/%E9%A1%BA%E5%8A%BF%E6%8C%87%E6%A0%87
# 顺势指标又叫CCI指标,其英文全称为“Commodity Channel Index”,
# 是由美国股市分析家唐纳德·蓝伯特(Donald Lambert)所创造的,是一种重点研判股价偏离度的股市分析工具。
# 1、当CCI指标从下向上突破﹢100线而进入非常态区间时,表明股价脱离常态而进入异常波动阶段,
# 中短线应及时买入,如果有比较大的成交量配合,买入信号则更为可靠。
#   2、当CCI指标从上向下突破﹣100线而进入另一个非常态区间时,表明股价的盘整阶段已经结束,
# 将进入一个比较长的寻底过程,投资者应以持币观望为主。
# CCI, default to 14 days
stock_column = ['cci', 'cci_20', 'code', 'date'] # cci cci_20 code date
data_new = concat_guess_data(stock_column, data_new)
# 9), TR、ATR指标
# http://wiki.mbalib.com/wiki/%E5%9D%87%E5%B9%85%E6%8C%87%E6%A0%87
# 均幅指标(Average True Ranger,ATR
# 均幅指标(ATR)是取一定时间周期内的股价波动幅度的移动平均值,主要用于研判买卖时机。
stock_column = ['cci', 'cci_20', 'code', 'date'] # cci cci_20 code date
data_new = concat_guess_data(stock_column, data_new)
# 10), DMA指标
# http://wiki.mbalib.com/wiki/DMA
#  DMA指标(Different of Moving Average)又叫平行线差指标,是目前股市分析技术指标中的一种中短期指标,它常用于大盘指数和个股的研判。
# DMA, difference of 10 and 50 moving average
# stock[dma]
stock_column = ['code', 'date', 'dma'] # code date dma
data_new = concat_guess_data(stock_column, data_new)
# 11), DMI+DI-DIDXADXADXR指标
# http://wiki.mbalib.com/wiki/DMI
# 动向指数Directional Movement Index,DMI
# http://wiki.mbalib.com/wiki/ADX
# 平均趋向指标(Average Directional Indicator,简称ADX
# http://wiki.mbalib.com/wiki/%E5%B9%B3%E5%9D%87%E6%96%B9%E5%90%91%E6%8C%87%E6%95%B0%E8%AF%84%E4%BC%B0
# 平均方向指数评估(ADXR)实际是今日ADX与前面某一日的ADX的平均值。ADXR在高位与ADX同步下滑,可以增加对ADX已经调头的尽早确认。
# ADXR是ADX的附属产品,只能发出一种辅助和肯定的讯号,并非入市的指标,而只需同时配合动向指标(DMI)的趋势才可作出买卖策略。
# 在应用时,应以ADX为主,ADXR为辅。
stock_column = ['adx', 'adxr', 'code', 'date', 'dx', 'mdi',
'pdi'] # adx adxr code date dx mdi pdi
data_new = concat_guess_data(stock_column, data_new)
# 12), TRIXMATRIX指标
# http://wiki.mbalib.com/wiki/TRIX
# TRIX指标又叫三重指数平滑移动平均指标(Triple Exponentially Smoothed Average
stock_column = ['code', 'date', 'trix', 'trix_9_sma'] # code date trix trix_9_sma
data_new = concat_guess_data(stock_column, data_new)
# 13), VRMAVR指标
# http://wiki.mbalib.com/wiki/%E6%88%90%E4%BA%A4%E9%87%8F%E6%AF%94%E7%8E%87
# 成交量比率(Volumn Ratio,VR)(简称VR),是一项通过分析股价上升日成交额(或成交量,下同)与股价下降日成交额比值,
# 从而掌握市场买卖气势的中期技术指标。
stock_column = ['code', 'date', 'vr', 'vr_6_sma'] # code date vr vr_6_sma
data_new = concat_guess_data(stock_column, data_new)
data_new = data_new.round(2) # 数据保留2位小数
# 删除老数据。
del_sql = " DELETE FROM `stock_data`.`guess_indicators_daily` WHERE `date`= %s " % datetime_int
common.insert(del_sql)
# print(data_new.head())
# data_new["down_rate"] = (data_new["trade"] - data_new["wave_mean"]) / data_new["wave_base"]
common.insert_db(data_new, "guess_indicators_daily", False, "`date`,`code`")
# 进行左连接.
# tmp = pd.merge(tmp, tmp2, on=['company_id'], how='left')
+89
View File
@@ -0,0 +1,89 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import libs.common as common
import sys
import time
import pandas as pd
import tushare as ts
from sqlalchemy.types import NVARCHAR
from sqlalchemy import inspect
import datetime
# 增加一个新quarter列,用来存储季度信息。
def concat_quarter(year, quarter, data_array):
print(len(data_array))
quarter_str = str(year) + str("%02d" % quarter) # 格式化季度数据。2位。
# 增加到列。
quarter_col = pd.DataFrame([quarter_str for _ in range(len(data_array))], columns=["quarter"])
return pd.concat([quarter_col, data_array], axis=1)
#############################基本面数据 http://tushare.org/fundamental.html
def stat_all(tmp_datetime):
# 返回 31 天前的数据,做上个季度数据统计。
tmp_datetime_1month = tmp_datetime + datetime.timedelta(days=-31)
year = int((tmp_datetime_1month).strftime("%Y"))
quarter = int(pd.Timestamp(tmp_datetime_1month).quarter) # 获得上个季度的数据。
print("############ year %d, quarter %d", year, quarter)
# 业绩报告(主表)
data = ts.get_report_data(year, quarter)
# 增加季度字段。
data = concat_quarter(year, quarter, data)
# 处理重复数据,保存最新一条数据。最后一步处理,否则concat有问题。
data = data.drop_duplicates(subset="code", keep="last")
# 插入数据库。
common.insert_db(data, "ts_report_data", False, "`quarter`,`code`")
# 盈利能力
data = ts.get_profit_data(year, quarter)
# 增加季度字段。
data = concat_quarter(year, quarter, data)
# 处理重复数据,保存最新一条数据。
data = data.drop_duplicates(subset="code", keep="last")
# 插入数据库。
common.insert_db(data, "ts_profit_data", False, "`quarter`,`code`")
# 营运能力
data = ts.get_operation_data(year, quarter)
# 增加季度字段。
data = concat_quarter(year, quarter, data)
# 处理重复数据,保存最新一条数据。最后一步处理,否则concat有问题。
data = data.drop_duplicates(subset="code", keep="last")
# 插入数据库。
common.insert_db(data, "ts_operation_data", False, "`quarter`,`code`")
# 成长能力
data = ts.get_growth_data(year, quarter)
# 增加季度字段。
data = concat_quarter(year, quarter, data)
# 处理重复数据,保存最新一条数据。最后一步处理,否则concat有问题。
data = data.drop_duplicates(subset="code", keep="last")
# 插入数据库。
common.insert_db(data, "ts_growth_data", False, "`quarter`,`code`")
# 偿债能力
data = ts.get_debtpaying_data(year, quarter)
# 增加季度字段。
data = concat_quarter(year, quarter, data)
# 处理重复数据,保存最新一条数据。最后一步处理,否则concat有问题。
data = data.drop_duplicates(subset="code", keep="last")
# 插入数据库。
common.insert_db(data, "ts_debtpaying_data", False, "`quarter`,`code`")
# 现金流量
data = ts.get_cashflow_data(year, quarter)
# 增加季度字段。
data = concat_quarter(year, quarter, data)
# 处理重复数据,保存最新一条数据。最后一步处理,否则concat有问题。
data = data.drop_duplicates(subset="code", keep="last")
# 插入数据库。
common.insert_db(data, "ts_cashflow_data", False, "`quarter`,`code`")
# main函数入口
if __name__ == '__main__':
# 使用方法传递。
tmp_datetime = common.run_with_args(stat_all)
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
ps -ef | grep 'tensorflow_model_server' | grep -v grep | awk '{print$2}' | xargs kill -9
echo "" > /data/logs/mnist_serving.log
nohup tensorflow_model_server --model_name=mnist --model_base_path=/data/mnist_model >> /data/logs/mnist_serving.log &
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
ps -ef | grep python3 | grep '/data/stock/web/main.py' | awk '{print$2}' | xargs kill -9
echo "restart web ... " > /data/logs/tornado.log
+25
View File
@@ -0,0 +1,25 @@
#!/bin/sh
export PYTHONIOENCODING=utf-8
export LANG=zh_CN.UTF-8
export PYTHONPATH=/data/stock
export LC_CTYPE=zh_CN.UTF-8
mkdir -p /data/logs/tensorflow
DATE=`date +%Y-%m-%d:%H:%M:%S`
echo $DATE >> /data/logs/run_cron.log
# 解决定时任务不启动问题,因为权限导致
chmod 755 /etc/cron.minutely/* && chmod 755 /etc/cron.hourly/*
chmod 755 /etc/cron.daily/* && chmod 755 /etc/cron.monthly/*
# 配置文件每次都设置权限
chmod 600 /var/spool/cron/crontabs/root
chown root:root /var/spool/cron/crontabs/root
#启动cron服务。在前台
/usr/sbin/cron -f
+29
View File
@@ -0,0 +1,29 @@
#!/bin/sh
export PYTHONIOENCODING=utf-8
export LANG=zh_CN.UTF-8
export PYTHONPATH=/data/stock
export LC_CTYPE=zh_CN.UTF-8
mkdir -p /data/logs/tensorflow
DATE=`date +%Y-%m-%d:%H:%M:%S`
echo $DATE >> /data/logs/run_init.log
echo "wait 120 second , mysqldb is starting ." >> /data/logs/run_init.log
sleep 120
/usr/local/bin/python3 /data/stock/jobs/basic_job.py >> /data/logs/run_init.log
# https://stackoverflow.com/questions/27771781/how-can-i-access-docker-set-environment-variables-from-a-cron-job
# 解决环境变量输出问题。
printenv | grep -v "no_proxy" >> /etc/environment
# 第一次后台执行日数据。
nohup bash /data/stock/jobs/cron.daily/run_daily &
#防止 supervisor 重复执行
sleep 999999d
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh
mkdir -p /data/notebooks
/usr/local/bin/jupyter notebook --NotebookApp.notebook_dir='/data/notebooks' --ip=0.0.0.0 \
--allow-root >> /data/logs/jupyter-notebook.log
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
export PYTHONIOENCODING=utf-8
export LANG=zh_CN.UTF-8
export PYTHONPATH=/data/stock
export LC_CTYPE=zh_CN.UTF-8
echo "" > /data/logs/web.log
/usr/local/bin/python3 /data/stock/web/main.py -log_file_prefix=/data/logs/web.log
+12
View File
@@ -0,0 +1,12 @@
#!/bin/sh
DATE=`date +%Y-%m-%d:%H:%M:%S`
echo $DATE
if [ ! -d "/data/mariadb" ]; then
mkdir -p /data/mariadb
/usr/bin/mysql_install_db
fi
/usr/bin/mysqld_safe >> /data/logs/start_mariadb.log
@@ -0,0 +1,27 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import akshare as ak
import libs.common as common
print(ak.__version__)
# 历史行情数据
# 日频率
# 接口: stock_zh_a_daily
# 目标地址: https://finance.sina.com.cn/realstock/company/sh600006/nc.shtml(示例)
# 描述: A 股数据是从新浪财经获取的数据, 历史数据按日频率更新; 注意其中的 sh689009 为 CDR, 请 通过 stock_zh_a_cdr_daily 接口获取
# 限量: 单次返回指定 A 股上市公司指定日期间的历史行情日频率数据
# adjust=""; 默认为空: 返回不复权的数据; qfq: 返回前复权后的数据; hfq: 返回后复权后的数据;
stock_zh_a_daily_qfq_df = ak.stock_zh_a_daily(symbol="sz000002", adjust="")
print(stock_zh_a_daily_qfq_df)
stock_zh_a_daily_qfq_df = ak.stock_zh_a_daily(symbol="sz000002", start_date="20200101", end_date="20210101", adjust="")
print(stock_zh_a_daily_qfq_df)
# 插入到 MySQL 数据库中
common.insert_db(stock_zh_a_daily_qfq_df, "stock_zh_a_daily", True, "`symbol`")
@@ -0,0 +1,19 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import akshare as ak
import libs.common as common
print(ak.__version__)
# 实时行情数据
# 接口: stock_zh_a_spot
# 目标地址: http://vip.stock.finance.sina.com.cn/mkt/#hs_a
# 描述: A 股数据是从新浪财经获取的数据, 重复运行本函数会被新浪暂时封 IP, 建议增加时间间隔
# 限量: 单次返回所有 A 股上市公司的实时行情数据
stock_zh_a_spot_df = ak.stock_zh_a_spot()
print(stock_zh_a_spot_df)
# 插入到 MySQL 数据库中
common.insert_db(stock_zh_a_spot_df, "stock_zh_a_spot", True, "`symbol`")
@@ -0,0 +1,20 @@
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import akshare as ak
import libs.common as common
print(ak.__version__)
#stock_sse_summary_df = ak.stock_sse_summary()
#print(stock_sse_summary_df)
# 接口: stock_zh_index_spot
# 目标地址: http://vip.stock.finance.sina.com.cn/mkt/#hs_s
# 描述: 中国股票指数数据, 注意该股票指数指新浪提供的国内股票指数
# 限量: 单次返回所有指数的实时行情数据
stock_zh_index_spot_df = ak.stock_zh_index_spot()
print(stock_zh_index_spot_df)
# 插入到 MySQL 数据库中
common.insert_db(stock_zh_index_spot_df, "stock_zh_index_spot_df", True, "`symbol`")