Skip to content

Commit

Permalink
1)add factor examples basing on dragon tiger data 2)add research exam…
Browse files Browse the repository at this point in the history
…ple 3)add selecting stocks example with multiple condition
  • Loading branch information
foolcage committed May 10, 2022
1 parent a6832ae commit 34bbc8f
Show file tree
Hide file tree
Showing 14 changed files with 277 additions and 112 deletions.
2 changes: 1 addition & 1 deletion docs/source/drawer/drawer_concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ intent as compare, distribute and composite.

We could analyze the entity itself or look at it in the whole market by
comparing with others. :ref:`NormalData<factor.normal_data>` uses
different structure to express different intent.s
different structure to express different intents.

Compare
------------------------------
Expand Down
7 changes: 7 additions & 0 deletions examples/report_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def report_targets(
end_timestamp=target_date,
adjust_type=adjust_type,
pct=0.4,
data_provider=data_provider,
)
current_entity_pool = vol_df.index.tolist()
logger.info(f"current_entity_pool({len(current_entity_pool)}): {current_entity_pool}")
Expand All @@ -92,6 +93,12 @@ def report_targets(
start_timestamp=start_timestamp, end_timestamp=target_date, select_mode=SelectMode.condition_or
)
entity_schema = get_entity_schema(entity_type=entity_type)
if "entity_ids" in factor_kv:
if current_entity_pool:
current_entity_pool = set(current_entity_pool) & set(factor_kv.pop("entity_ids"))
else:
current_entity_pool = set(factor_kv.pop("entity_ids"))

tech_factor = factor_cls(
entity_schema=entity_schema,
entity_provider=entity_provider,
Expand Down
43 changes: 42 additions & 1 deletion examples/reports/report_vol_up.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,32 @@

from examples.report_utils import report_targets
from zvt import init_log
from zvt.api.kdata import get_latest_kdata_date
from zvt.contract import AdjustType
from zvt.domain import Stock1dHfqKdata
from zvt.factors import VolumeUpMaFactor
from zvt.utils import to_pd_timestamp

logger = logging.getLogger(__name__)

sched = BackgroundScheduler()


def get_by_cap(
timestamp,
cap_start=4000000000,
cap_end=15000000000,
provider="em",
):
df = Stock1dHfqKdata.query_data(
provider=provider,
filters=[Stock1dHfqKdata.timestamp == to_pd_timestamp(timestamp)],
index="entity_id",
)
df["cap"] = df["turnover"] / df["turnover_rate"]
return df.loc[(df["cap"] >= cap_start) & (df["cap"] <= cap_end)].index.tolist()


@sched.scheduled_job("cron", hour=17, minute=0, day_of_week="mon-fri")
def report_vol_up():
report_targets(
Expand All @@ -34,14 +52,37 @@ def report_vol_up():
turnover_rate_threshold=0.02,
)

target_date = get_latest_kdata_date(entity_type="stock", adjust_type=AdjustType.hfq, provider="em")

entity_ids = get_by_cap(timestamp=target_date)
report_targets(
factor_cls=VolumeUpMaFactor,
entity_provider="em",
data_provider="em",
em_group="强势板块",
title="小市值年线股票",
entity_type="stock",
em_group_over_write=True,
filter_by_volume=False,
adjust_type=AdjustType.hfq,
start_timestamp="2019-01-01",
# factor args
windows=[120, 250],
over_mode="or",
up_intervals=120,
turnover_threshold=100000000,
turnover_rate_threshold=0.02,
entity_ids=entity_ids,
)

report_targets(
factor_cls=VolumeUpMaFactor,
entity_provider="em",
data_provider="em",
em_group="强势板块",
title="放量突破(半)年线板块",
entity_type="block",
em_group_over_write=True,
em_group_over_write=False,
filter_by_volume=False,
adjust_type=AdjustType.qfq,
start_timestamp="2019-01-01",
Expand Down
86 changes: 2 additions & 84 deletions examples/reports/subscriber_emails.json
Original file line number Diff line number Diff line change
@@ -1,86 +1,4 @@
[
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected] ",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected] ",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
"[email protected]",
"[email protected]"
]
1 change: 1 addition & 0 deletions examples/research/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# -*- coding: utf-8 -*-
41 changes: 41 additions & 0 deletions examples/research/top_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
from zvt.api import get_top_performance_by_month
from zvt.domain import Stock1dHfqKdata
from zvt.utils import next_date, month_end_date, is_same_date

# 每月涨幅前30,市值90%分布在100亿以下
# 重复上榜的有1/4左右
# 连续两个月上榜的1/10左右
def top_tags(data_provider="em", start_timestamp="2010-01-01"):
records = []
for timestamp, df in get_top_performance_by_month(
start_timestamp=start_timestamp, list_days=250, data_provider=data_provider
):
for entity_id in df.index[:30]:
query_timestamp = timestamp
while True:
kdata = Stock1dHfqKdata.query_data(
provider=data_provider,
entity_id=entity_id,
start_timestamp=query_timestamp,
order=Stock1dHfqKdata.timestamp.asc(),
limit=1,
return_type="domain",
)
if not kdata or kdata[0].turnover_rate == 0:
if is_same_date(query_timestamp, month_end_date(query_timestamp)):
break
query_timestamp = next_date(query_timestamp)
continue
cap = kdata[0].turnover / kdata[0].turnover_rate
break

records.append(
{"entity_id": entity_id, "timestamp": timestamp, "cap": cap, "score": df.loc[entity_id, "score"]}
)

return records


if __name__ == "__main__":
print(top_tags())
106 changes: 106 additions & 0 deletions examples/trader/dragon_and_tiger_trader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# -*- coding: utf-8 -*-
from typing import List, Union

import pandas as pd

from zvt.contract import IntervalLevel
from zvt.contract.factor import Factor, Transformer, Accumulator
from zvt.domain import Stock, DragonAndTiger
from zvt.factors import TargetSelector
from zvt.trader import StockTrader


class DragonTigerFactor(Factor):
def __init__(
self,
provider: str = "em",
entity_provider: str = "em",
entity_ids: List[str] = None,
exchanges: List[str] = None,
codes: List[str] = None,
start_timestamp: Union[str, pd.Timestamp] = None,
end_timestamp: Union[str, pd.Timestamp] = None,
columns: List = None,
filters: List = [DragonAndTiger.dep1 == "机构专用"],
order: object = None,
limit: int = None,
level: Union[str, IntervalLevel] = IntervalLevel.LEVEL_1DAY,
category_field: str = "entity_id",
time_field: str = "timestamp",
computing_window: int = None,
keep_all_timestamp: bool = False,
fill_method: str = "ffill",
effective_number: int = None,
transformer: Transformer = None,
accumulator: Accumulator = None,
need_persist: bool = False,
only_compute_factor: bool = False,
factor_name: str = None,
clear_state: bool = False,
only_load_factor: bool = False,
) -> None:
super().__init__(
DragonAndTiger,
Stock,
provider,
entity_provider,
entity_ids,
exchanges,
codes,
start_timestamp,
end_timestamp,
columns,
filters,
order,
limit,
level,
category_field,
time_field,
computing_window,
keep_all_timestamp,
fill_method,
effective_number,
transformer,
accumulator,
need_persist,
only_compute_factor,
factor_name,
clear_state,
only_load_factor,
)

def compute_result(self):
self.factor_df["filter_result"] = True
super().compute_result()


class MyTrader(StockTrader):
def init_selectors(
self, entity_ids, entity_schema, exchanges, codes, start_timestamp, end_timestamp, adjust_type=None
):
myselector = TargetSelector(
entity_ids=entity_ids,
entity_schema=entity_schema,
exchanges=exchanges,
codes=codes,
start_timestamp=start_timestamp,
end_timestamp=end_timestamp,
provider="em",
)

myselector.add_factor(
DragonTigerFactor(
entity_ids=entity_ids,
exchanges=exchanges,
codes=codes,
start_timestamp=start_timestamp,
end_timestamp=end_timestamp,
)
)

self.selectors.append(myselector)


if __name__ == "__main__":
trader = MyTrader(start_timestamp="2020-01-01", end_timestamp="2022-05-01")
trader.run()
27 changes: 15 additions & 12 deletions src/zvt/api/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
from zvt.contract.api import decode_entity_id, get_entity_schema, get_entity_ids
from zvt.contract.drawer import Drawer
from zvt.domain import FundStock, StockValuation, BlockStock, Block
from zvt.factors import TechnicalFactor
from zvt.utils import now_pd_timestamp, next_date, pd_is_not_null
from zvt.utils.time_utils import month_start_end_ranges, to_time_str
from zvt.utils.time_utils import month_start_end_ranges, to_time_str, pre_month_end_date

logger = logging.getLogger(__name__)

Expand All @@ -34,6 +35,7 @@ def get_top_performance_by_month(
start_timestamp="2015-01-01",
end_timestamp=now_pd_timestamp(),
list_days=None,
data_provider=None,
):
ranges = month_start_end_ranges(start_date=start_timestamp, end_date=end_timestamp)

Expand All @@ -45,6 +47,7 @@ def get_top_performance_by_month(
start_timestamp=start_timestamp,
end_timestamp=end_timestamp,
list_days=list_days,
data_provider=data_provider,
)

yield (end_timestamp, top)
Expand Down Expand Up @@ -404,17 +407,17 @@ def show_industry_composition(entity_ids, timestamp):
if __name__ == "__main__":
df = get_performance_stats_by_month()
print(df)
# dfs = []
# for timestamp, df in got_top_performance_by_month(start_timestamp="2012-01-01", list_days=250):
# if pd_is_not_null(df):
# entity_ids = df.index.tolist()
# the_date = pre_month_end_date(timestamp)
# show_industry_composition(entity_ids=entity_ids, timestamp=timestamp)
# for entity_id in df.index:
# from zvt.utils.time_utils import month_end_date, pre_month_start_date
#
# end_date = month_end_date(pre_month_start_date(timestamp))
# TechnicalFactor(entity_ids=[entity_id], end_timestamp=end_date).draw(show=True)
dfs = []
for timestamp, df in get_top_performance_by_month(start_timestamp="2012-01-01", list_days=250):
if pd_is_not_null(df):
entity_ids = df.index.tolist()
the_date = pre_month_end_date(timestamp)
show_industry_composition(entity_ids=entity_ids, timestamp=timestamp)
for entity_id in df.index:
from zvt.utils.time_utils import month_end_date, pre_month_start_date

end_date = month_end_date(pre_month_start_date(timestamp))
TechnicalFactor(entity_ids=[entity_id], end_timestamp=end_date).draw(show=True)

# the __all__ is generated
__all__ = [
Expand Down
Loading

0 comments on commit 34bbc8f

Please sign in to comment.