Skip to content

Commit

Permalink
ma state
Browse files Browse the repository at this point in the history
  • Loading branch information
foolcage committed Mar 21, 2020
1 parent 5110dba commit ad33b34
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 16 deletions.
109 changes: 109 additions & 0 deletions examples/reports/report_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# -*- coding: utf-8 -*-
import datetime
import logging
import time

import eastmoneypy
from apscheduler.schedulers.background import BackgroundScheduler

from zvdata.api import get_entities
from zvdata.utils.time_utils import to_pd_timestamp
from zvt import init_log
from zvt.domain import Stock1dKdata, StockValuation, Stock
from zvt.factors import TargetSelector
from zvt.factors.ma.ma_factor import VolumeUpMa250Factor
from zvt.factors.ma.ma_stats import MaStateStatsFactor
from zvt.informer.informer import EmailInformer

logger = logging.getLogger(__name__)

sched = BackgroundScheduler()


@sched.scheduled_job('cron', hour=17, minute=30, day_of_week='mon-fri')
def report_state():
while True:
error_count = 0
email_action = EmailInformer(ssl=True)

try:
latest_day: Stock1dKdata = Stock1dKdata.query_data(order=Stock1dKdata.timestamp.desc(), limit=1,
return_type='domain')
# target_date = latest_day[0].timestamp
target_date = to_pd_timestamp('2020-01-02')

# 计算均线
my_selector = TargetSelector(start_timestamp='2018-01-01', end_timestamp=target_date)
# add the factors
factor1 = VolumeUpMa250Factor(start_timestamp='2018-01-01', end_timestamp=target_date)

my_selector.add_filter_factor(factor1)

my_selector.run()

long_stocks = my_selector.get_open_long_targets(timestamp=target_date)

msg = 'no targets'
# 过滤亏损股
# check StockValuation data
pe_date = target_date - datetime.timedelta(10)
if StockValuation.query_data(start_timestamp=pe_date, limit=1, return_type='domain'):
positive_df = StockValuation.query_data(provider='joinquant', entity_ids=long_stocks,
start_timestamp=pe_date,
filters=[StockValuation.pe > 0],
columns=['entity_id'])
bad_stocks = set(long_stocks) - set(positive_df['entity_id'].tolist())
if bad_stocks:
stocks = get_entities(provider='joinquant', entity_schema=Stock, entity_ids=bad_stocks,
return_type='domain')
info = [f'{stock.name}({stock.code})' for stock in stocks]
msg = '亏损股:' + ' '.join(info) + '\n'

long_stocks = set(positive_df['entity_id'].tolist())

if long_stocks:
ma_state = MaStateStatsFactor(entity_ids=long_stocks, start_timestamp='2016-01-01',
end_timestamp=target_date, persist_factor=False)
for entity_id, df in ma_state.factor_df.groupby(level=0):
if df['current_pct'].max() >= 0.3:
long_stocks.remove(entity_id)

if long_stocks:
stocks = get_entities(provider='joinquant', entity_schema=Stock, entity_ids=long_stocks,
return_type='domain')
# add them to eastmoney
try:
try:
eastmoneypy.del_group('real')
except:
pass
eastmoneypy.create_group('real')
for stock in stocks:
eastmoneypy.add_to_group(stock.code, group_name='real')
except Exception as e:
email_action.send_message("[email protected]", f'report state error',
'report state error:{}'.format(e))

info = [f'{stock.name}({stock.code})' for stock in stocks]
msg = msg + '盈利股:' + ' '.join(info) + '\n'

logger.info(msg)
email_action.send_message('[email protected]', f'{target_date} 放量突破年线state选股结果', msg)
break
except Exception as e:
logger.exception('report state error:{}'.format(e))
time.sleep(60 * 3)
error_count = error_count + 1
if error_count == 10:
email_action.send_message("[email protected]", f'report state error',
'report state error:{}'.format(e))


if __name__ == '__main__':
init_log('report_state.log')

report_state()

sched.start()

sched._thread.join()
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
zvdata == 1.2.2
zvdata == 1.2.3
requests == 2.20.1
SQLAlchemy == 1.2.14
pandas == 0.24.2
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
# For a discussion on single-sourcing the version across setup.py and the
# project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version='0.7.7', # Required
version='0.7.8', # Required

# This is a one-line description or tagline of what your project does. This
# corresponds to the "Summary" metadata field:
Expand Down Expand Up @@ -119,7 +119,7 @@
# For an analysis of "install_requires" vs pip's requirements files see:
# https://packaging.python.org/en/latest/requirements.html

install_requires=['zvdata>=1.2.2', 'requests>=2.20.1', 'SQLAlchemy>=1.2.14', 'pandas>=0.24.2',
install_requires=['zvdata>=1.2.3', 'requests>=2.20.1', 'SQLAlchemy>=1.2.14', 'pandas>=0.24.2',
'arrow>=0.11.0', 'marshmallow >= 3.2.2', 'tzlocal>=1.5.1', 'xlrd>=1.1.0', 'apscheduler>=3.4.0',
'jqdatasdk', 'demjson>=2.2.4', 'marshmallow-sqlalchemy>=0.19.0', 'ccxt>=1.17.191',
'plotly>=4.1.0', 'simplejson>=3.16.0',
Expand Down
2 changes: 1 addition & 1 deletion zvt/domain/factors/stock_1d_ma_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Stock1dMaStateStats(Stock1dMaStateStatsBase, Mixin):
# 此轮维持状态的最大值,即切换点
total_count = Column(Integer)
# 涨跌幅
total_pct = Column(Integer)
# total_pct = Column(Integer)


register_schema(providers=['zvt'], db_name='stock_1d_ma_stats', schema_base=Stock1dMaStateStatsBase)
33 changes: 26 additions & 7 deletions zvt/drawer/drawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,34 @@
import plotly.graph_objs as go
from plotly.subplots import make_subplots

from zvdata.api import decode_entity_id, get_data
from zvdata.api import decode_entity_id
from zvdata.normal_data import NormalData
from zvdata.reader import DataReader
from zvdata.utils.pd_utils import pd_is_not_null
from zvdata.utils.time_utils import now_time_str, TIME_FORMAT_ISO8601
from zvt import zvt_env
from zvt.domain import Stock1dKdata, Stock1dMaStateStats
from zvt.domain import Stock1dKdata, Stock1dMaStateStats, Stock


class Drawer(object):
def __init__(self,
main_df: pd.DataFrame = None,
factor_df: pd.DataFrame = None,
sub_df: pd.DataFrame = None,
main_data: NormalData = None,
factor_data: NormalData = None,
sub_data: NormalData = None,
annotation_df: pd.DataFrame = None) -> None:
# 主图数据
if main_data is None:
main_data = NormalData(main_df)
self.main_data: NormalData = main_data

# 主图因子
if factor_data is None:
factor_data = NormalData(factor_df)
self.factor_data: NormalData = factor_data

# 副图数据
if sub_data is None:
sub_data = NormalData(sub_df)
Expand All @@ -36,7 +44,7 @@ def __init__(self,
def _draw(self,
main_chart='kline',
sub_chart='bar',
mode='markers',
mode='lines',
width=None,
height=None,
title=None,
Expand Down Expand Up @@ -66,6 +74,16 @@ def _draw(self,
ydata = df[col].values.tolist()
traces.append(go.Scatter(x=df.index, y=ydata, mode=mode, name=trace_name, **kwargs))

# 绘制幅图
factor_df = self.factor_data.entity_map_df.get(entity_id)
if pd_is_not_null(factor_df):
for col in factor_df.columns:
trace_name = '{}_{}'.format(code, col)
ydata = factor_df[col].values.tolist()

line = go.Scatter(x=df.index, y=ydata, mode=mode, name=trace_name, **kwargs)
traces.append(line)

if subplot:
# 绘制幅图
sub_df = self.sub_data.entity_map_df.get(entity_id)
Expand Down Expand Up @@ -256,9 +274,10 @@ def to_annotations(annotation_df: pd.DataFrame):


if __name__ == '__main__':
df = get_data(data_schema=Stock1dKdata, provider='joinquant', entity_ids=['stock_sz_000001', 'stock_sz_000002'])
df1 = get_data(data_schema=Stock1dMaStateStats, provider='zvt', entity_ids=['stock_sz_000001', 'stock_sz_000002'],
columns=['current_count'])
data_reader1 = DataReader(codes=['002223'], data_schema=Stock1dKdata, entity_schema=Stock)
data_reader2 = DataReader(codes=['002223'], data_schema=Stock1dMaStateStats, entity_schema=Stock,
columns=['ma5', 'ma10', 'current_count', 'current_pct'])

drawer = Drawer(df, df1[['current_count']])
drawer = Drawer(main_df=data_reader1.data_df, factor_df=data_reader2.data_df[['ma5', 'ma10']],
sub_df=data_reader2.data_df[['current_pct']])
drawer.draw_kline()
19 changes: 15 additions & 4 deletions zvt/factors/ma/ma_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from zvdata import IntervalLevel, EntityMixin
from zvdata.utils.pd_utils import pd_is_not_null
from zvdata.utils.time_utils import now_pd_timestamp
from zvt.api import get_entities, Stock
from zvt.api.common import get_ma_state_stats_schema
from zvt.factors.algorithm import MaTransformer
Expand Down Expand Up @@ -88,13 +87,22 @@ def acc(self, input_df, acc_df) -> pd.DataFrame:
# up
if acc_col_current > 0 and (current_state == 'up'):
count = acc_col_current + 1

pct = acc_df.loc[(entity_id,)].iloc[-1]["current_pct"]
pct = (1 + pct) * (1 + df['change_pct'][index]) - 1

# down
elif acc_col_current < 0 and (current_state == 'down'):
count = acc_col_current - 1

pct = acc_df.loc[(entity_id,)].iloc[-1]["current_pct"]
pct = (1 + pct) * (1 + df['change_pct'][index]) - 1

# state has changed
else:
pre_timestamp = acc_df.loc[(entity_id,), 'timestamp'][-1]
acc_df.loc[(entity_id, pre_timestamp), self.total_col] = acc_col_current

check_acc = True

# 设置目前状态
Expand Down Expand Up @@ -148,8 +156,8 @@ def __init__(self, entity_schema: EntityMixin = Stock, provider: str = None, ent
parser = argparse.ArgumentParser()
parser.add_argument('--level', help='trading level', default='1d',
choices=[item.value for item in IntervalLevel])
parser.add_argument('--start', help='start code', default='000338')
parser.add_argument('--end', help='end code', default='000339')
parser.add_argument('--start', help='start code', default='002223')
parser.add_argument('--end', help='end code', default='002224')

args = parser.parse_args()

Expand All @@ -163,6 +171,9 @@ def __init__(self, entity_schema: EntityMixin = Stock, provider: str = None, ent
codes = entities.index.to_list()

factor = MaStateStatsFactor(codes=codes, start_timestamp='2005-01-01',
end_timestamp=now_pd_timestamp(), persist_factor=False,
end_timestamp='2020-04-01', persist_factor=True,
level=level)
print(factor.factor_df)

for entity_id, df in factor.factor_df.groupby(level=0):
print(df['current_pct'].max)
2 changes: 1 addition & 1 deletion zvt/trader/trader.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def on_finish(self):
import plotly.io as pio
pio.renderers.default = "browser"
reader = AccountReader(trader_names=[self.trader_name])
df = reader.data_df.reset_index()
df = reader.data_df
drawer = Drawer(main_data=NormalData(df.copy()[['trader_name', 'timestamp', 'all_value']],
category_field='trader_name'))
drawer.draw_line()
Expand Down

0 comments on commit ad33b34

Please sign in to comment.