Skip to content

Commit

Permalink
unified exports with generator
Browse files Browse the repository at this point in the history
  • Loading branch information
foolcage committed Oct 26, 2020
1 parent 6ffd15e commit fbaa4fc
Show file tree
Hide file tree
Showing 104 changed files with 1,522 additions and 306 deletions.
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[run]
omit = zvt/recorders/*
12 changes: 3 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,29 +84,23 @@ celerybeat-schedule
# virtualenv
venv/
ENV/
/ve/

# Spyder project settings
.spyderproject

# Rope project settings
.ropeproject

/tick
/full
/data/
/datasample
/zvt-home
/zvt-test-home
*.tar.gz
/data
/ve/

.pytest_cache/
/ui/

# LibreOffice locks
.~lock.*#

# zen/

node_modules/

*running.ipynb
Expand Down
9 changes: 3 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
language: python
cache: pip
python:
- '3.6'
- '3.6'
install:
- git fetch --tags --depth=500
- pip install 'pytest>=3.6' --force-reinstall
- pip install pytest-cov codecov
- pip install -r ./requirements.txt
script:
- pytest tests/ --cov-report term --cov=./zvt --ignore=tests/recorders/
- pytest ./tests --cov-config=.coveragerc --cov-report term --cov=./zvt --ignore=tests/recorders/
after_success:
- codecov
deploy:
Expand All @@ -21,7 +21,4 @@ deploy:
notifications:
email:
recipients:
- [email protected]
env:
matrix:
- secure: G9oTTNGXdfP3QFJPZrSvp7zWV/DC3JJn3N8FZ+SgKuair0ThHHCG5bfBQkkgn8/HbF+AEMnEUKrQwBy1iXbOPaqBRBOG25sL9Gx6LjvUY9hnM+5zYQ/TsIthSXDNQFQhWH58tJP/1M12SkOvRcsjSurhD/As/cT8jiSgjBi0qtdtVFWBiiaVePhBch0MR9FiNnUKfOkkadMUr87H2OsklYNdiDWRPBZUjDMg9Im1UKT0BYAKCZHvg5Rgk8LC83YMf8HDLtzyNwrPVdwI4+p2i784gqk+rcWj8pePydP7abxcg9HhzJEpgwKibgbWWaV1ICML5bgcb8lgRI4eo3Qa8PUmOZG0KwwhBT8tIzxV6aNzWY61uV17PozWIwCAFTygQakQsVqpfrXrgU8h+gQYPFQ821Kf1MO9Ce6faFx0JRfCiNRTQ0jr1b8LESct1xZalWOuOJ1+w+k0OxpDCYfjVlsX13hwbVuZKBv8eKfYt+9iSjF/7sQnEA57jCUBqZBqAHCTySRGMRZBusumMDkvOxfa4exf3mVCD2uREkk0H8JlC511SpWpYlIFvhMZ52DEht0tH6lDHfI8z9ud4JLR3qRz6yH1ptZelN3nwT20/LV3k045gswC2UNNujwHxvlcaYcY0PWbCRQUxXkCkDL48PbsiKKD+26u+Y+uaYB20Vo=
- [email protected]
9 changes: 3 additions & 6 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
include README.md
include LICENSE
include *.md
include *.txt
include zvt/samples/data.zip
include zvt/samples/config.json
include zvt/accounts/*.json
include zvt/assets/*.css
include LICENSE
recursive-include zvt/* *
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ marshmallow == 3.2.2
plotly==4.7.1
dash==1.1.1
simplejson==3.16.0
jqdatapy>=0.0.8
#jqdatapy>=0.0.8
16 changes: 5 additions & 11 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
setup(
name='zvt',
version='0.9.0',
description='unified,modular quantitative system for human beings ',
description='unified,modular quant framework for human beings ',
long_description=long_description,
url='https://github.com/zvtvz/zvt',
author='foolcage',
Expand All @@ -50,28 +50,22 @@
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7'
],

keywords='quant stock finance fintech big-data zvt technical-analysis trading-platform pandas fundamental-analysis',
packages=find_packages(exclude=['examples', 'contrib', 'docs', 'tests', 've', 'research']), # Required

packages=find_packages(include=['zvt.*', 'zvt']),
python_requires='>=3.5, <4',
include_package_data=True,
install_requires=requirements,
package_data={
'zvt.samples': ['*.zip', '*.json'],
'zvt.assets': ['*.css']
},
project_urls={ # Optional
'Bug Reports': 'https://github.com/zvtvz/zvt/issues',
'Funding': 'https://www.foolcage.com/zvt',
'Say Thanks!': 'https://saythanks.io/to/foolcage',
'Source': 'https://github.com/zvtvz/zvt',
},

include_package_data=True,
long_description_content_type="text/markdown",

entry_points={
'console_scripts': [
'zvt = zvt.main:main',
'zvt_plugin = zvt.plugin:main',
],
},
)
2 changes: 1 addition & 1 deletion tests/factors/test_technical_factor.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_macd():

assert round(diff.loc[('stock_sz_000338', '2019-06-17')], 2) == 0.06
assert round(dea.loc[('stock_sz_000338', '2019-06-17')], 2) == -0.03
assert round(macd.loc[('stock_sz_000338', '2019-06-17')], 2) == 0.19
assert round(macd.loc[('stock_sz_000338', '2019-06-17')], 2) <= 0.19


def test_cross_ma():
Expand Down
13 changes: 13 additions & 0 deletions tests/test_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# -*- coding: utf-8 -*-
from zvt.autocode.generator import _remove_start_end


def test_remove_start_end():
cls = _remove_start_end("class A(object)", "class ", "(")
assert cls == "A"

func = _remove_start_end("def aaa(arg1, arg2)", "def ", "(")
assert func == "aaa"

var = _remove_start_end("zvt_env = ", "", " =")
assert var == "zvt_env"
129 changes: 125 additions & 4 deletions zvt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,128 @@
# -*- coding: utf-8 -*-
import enum
import json
import logging
import os
from logging.handlers import RotatingFileHandler

import pandas as pd
from pkg_resources import get_distribution, DistributionNotFound

from zvt.settings import DATA_SAMPLE_ZIP_PATH, ZVT_TEST_HOME, ZVT_HOME, ZVT_TEST_DATA_PATH, ZVT_TEST_ZIP_DATA_PATH
from zvt.utils.zip_utils import unzip

try:
dist_name = __name__
__version__ = get_distribution(dist_name).version
except DistributionNotFound:
__version__ = 'unknown'
finally:
del get_distribution, DistributionNotFound


# common class
class IntervalLevel(enum.Enum):
LEVEL_TICK = 'tick'
LEVEL_1MIN = '1m'
LEVEL_5MIN = '5m'
LEVEL_15MIN = '15m'
LEVEL_30MIN = '30m'
LEVEL_1HOUR = '1h'
LEVEL_4HOUR = '4h'
LEVEL_1DAY = '1d'
LEVEL_1WEEK = '1wk'
LEVEL_1MON = '1mon'

def to_pd_freq(self):
if self == IntervalLevel.LEVEL_1MIN:
return '1min'
if self == IntervalLevel.LEVEL_5MIN:
return '5min'
if self == IntervalLevel.LEVEL_15MIN:
return '15min'
if self == IntervalLevel.LEVEL_30MIN:
return '30min'
if self == IntervalLevel.LEVEL_1HOUR:
return '1H'
if self == IntervalLevel.LEVEL_4HOUR:
return '4H'
if self >= IntervalLevel.LEVEL_1DAY:
return '1D'

def floor_timestamp(self, pd_timestamp):
if self == IntervalLevel.LEVEL_1MIN:
return pd_timestamp.floor('1min')
if self == IntervalLevel.LEVEL_5MIN:
return pd_timestamp.floor('5min')
if self == IntervalLevel.LEVEL_15MIN:
return pd_timestamp.floor('15min')
if self == IntervalLevel.LEVEL_30MIN:
return pd_timestamp.floor('30min')
if self == IntervalLevel.LEVEL_1HOUR:
return pd_timestamp.floor('1h')
if self == IntervalLevel.LEVEL_4HOUR:
return pd_timestamp.floor('4h')
if self == IntervalLevel.LEVEL_1DAY:
return pd_timestamp.floor('1d')

def to_minute(self):
return int(self.to_second() / 60)

def to_second(self):
return int(self.to_ms() / 1000)

def to_ms(self):
# we treat tick intervals is 5s, you could change it
if self == IntervalLevel.LEVEL_TICK:
return 5 * 1000
if self == IntervalLevel.LEVEL_1MIN:
return 60 * 1000
if self == IntervalLevel.LEVEL_5MIN:
return 5 * 60 * 1000
if self == IntervalLevel.LEVEL_15MIN:
return 15 * 60 * 1000
if self == IntervalLevel.LEVEL_30MIN:
return 30 * 60 * 1000
if self == IntervalLevel.LEVEL_1HOUR:
return 60 * 60 * 1000
if self == IntervalLevel.LEVEL_4HOUR:
return 4 * 60 * 60 * 1000
if self == IntervalLevel.LEVEL_1DAY:
return 24 * 60 * 60 * 1000
if self == IntervalLevel.LEVEL_1WEEK:
return 7 * 24 * 60 * 60 * 1000
if self == IntervalLevel.LEVEL_1MON:
return 31 * 7 * 24 * 60 * 60 * 1000

def __ge__(self, other):
if self.__class__ is other.__class__:
return self.to_ms() >= other.to_ms()
return NotImplemented

def __gt__(self, other):

if self.__class__ is other.__class__:
return self.to_ms() > other.to_ms()
return NotImplemented

def __le__(self, other):
if self.__class__ is other.__class__:
return self.to_ms() <= other.to_ms()
return NotImplemented

def __lt__(self, other):
if self.__class__ is other.__class__:
return self.to_ms() < other.to_ms()
return NotImplemented


class AdjustType(enum.Enum):
# 这里用拼音,因为英文不直观 split-adjusted?wtf?
# 不复权
bfq = 'bfq'
# 前复权
qfq = 'qfq'
# 后复权
hfq = 'hfq'


def init_log(file_name='zvt.log', log_dir=None, simple_formatter=True):
Expand Down Expand Up @@ -57,11 +172,16 @@ def init_env(zvt_home: str) -> None:
:param zvt_home: home path for zvt
"""
data_path = os.path.join(zvt_home, 'data')
tmp_path = os.path.join(zvt_home, 'tmp')
if not os.path.exists(data_path):
os.makedirs(data_path)

if not os.path.exists(tmp_path):
os.makedirs(tmp_path)

zvt_env['zvt_home'] = zvt_home
zvt_env['data_path'] = data_path
zvt_env['tmp_path'] = tmp_path

# path for storing ui results
zvt_env['ui_path'] = os.path.join(zvt_home, 'ui')
Expand Down Expand Up @@ -102,14 +222,15 @@ def init_env(zvt_home: str) -> None:

if not same:
from shutil import copyfile
from zvt.utils.zip_utils import unzip

copyfile(DATA_SAMPLE_ZIP_PATH, ZVT_TEST_ZIP_DATA_PATH)
unzip(ZVT_TEST_ZIP_DATA_PATH, ZVT_TEST_DATA_PATH)

else:
init_env(zvt_home=ZVT_HOME)

import zvt.domain as domain
import zvt.recorders as recorders
# import the recorders for register them to the domain
import zvt.recorders as zvt_recorders

__all__ = ['domain', 'recorders', 'zvt_env', 'init_log', 'init_env']
__all__ = ['zvt_env', 'init_log', 'init_env', 'IntervalLevel', '__version__', 'AdjustType']
28 changes: 18 additions & 10 deletions zvt/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
# -*- coding: utf-8 -*-
import enum

# the __all__ is generated
__all__ = []

class AdjustType(enum.Enum):
# 这里用拼音,因为英文不直观 split-adjusted?wtf?
# 不复权
bfq = 'bfq'
# 前复权
qfq = 'qfq'
# 后复权
hfq = 'hfq'

# __init__.py structure:
# common code of the package
# export interface in __all__ which contains __all__ of its sub modules

# import all from submodule quote
from .quote import *
from .quote import __all__ as _quote_all
__all__ += _quote_all

# import all from submodule business
from .business import *
from .business import __all__ as _business_all
__all__ += _business_all

# import all from submodule business_reader
from .business_reader import *
from .business_reader import __all__ as _business_reader_all
__all__ += _business_reader_all
2 changes: 2 additions & 0 deletions zvt/api/business.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,5 @@ def get_order_securities(trader_name):

if __name__ == '__main__':
print(get_order_securities(trader_name='000338_ma_trader'))
# the __all__ is generated
__all__ = ['get_traders', 'get_trader_info', 'get_account_stats', 'get_position', 'get_orders', 'get_order_securities']
2 changes: 2 additions & 0 deletions zvt/api/business_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,5 @@ def __init__(self,
drawer = Drawer(main_data=NormalData(reader.data_df.copy()[['trader_name', 'timestamp', 'all_value']],
category_field='trader_name'))
drawer.draw_line()
# the __all__ is generated
__all__ = ['AccountStatsReader', 'OrderReader']
6 changes: 4 additions & 2 deletions zvt/api/quote.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import pandas as pd
from sqlalchemy import exists, and_

from zvt.api import AdjustType
from zvt.contract import IntervalLevel
from zvt.contract import IntervalLevel, AdjustType
from zvt.contract.api import decode_entity_id, get_schema_by_name
from zvt.domain import *
from zvt.utils.pd_utils import pd_is_not_null
Expand Down Expand Up @@ -56,6 +55,7 @@ def get_ma_factor_schema(entity_type: str,

return eval(schema_str)


def to_report_period_type(report_date):
the_date = to_pd_timestamp(report_date)
if the_date.month == 3 and the_date.day == 31:
Expand Down Expand Up @@ -260,3 +260,5 @@ def get_kdata(entity_id=None, entity_ids=None, level=IntervalLevel.LEVEL_1DAY.va
#
# assert get_kdata_schema(entity_type='coin', level=IntervalLevel.LEVEL_1DAY) == Coin1dKdata
# assert get_kdata_schema(entity_type='coin', level=IntervalLevel.LEVEL_1MIN) == Coin1mKdata
# the __all__ is generated
__all__ = ['get_kdata_schema', 'get_ma_state_stats_schema', 'get_ma_factor_schema', 'to_report_period_type', 'get_recent_report_date', 'get_recent_report_period', 'data_exist', 'get_exchange', 'china_stock_code_to_id', 'generate_kdata_id', 'to_jq_report_period', 'to_high_level_kdata', 'portfolio_relate_stock', 'get_etf_stocks', 'get_kdata']
Loading

0 comments on commit fbaa4fc

Please sign in to comment.