├── .gitignore ├── .idea ├── Code.iml ├── dictionaries │ └── baileicheng.xml ├── inspectionProfiles │ └── Project_Default.xml ├── modules.xml ├── other.xml └── vcs.xml ├── LICENSE ├── README.md ├── bin └── temp.txt ├── chzhshch ├── __init__.py ├── external_package │ ├── __init__.py │ ├── line_helper.py │ └── tushare_helper.py ├── feature │ ├── __init__.py │ ├── daily_trend_classfication.py │ ├── ma_sys_kiss.py │ └── year_ma.py ├── inner_package │ ├── __init__.py │ ├── chzhshch_central.py │ ├── frequency_enum.py │ ├── ma_kiss.py │ ├── show.py │ └── standardized.py ├── main.py └── tests │ ├── __init__.py │ ├── plot_fill_between.py │ ├── plot_scipy_test001.py │ ├── plot_test.py │ ├── plot_test001.py │ └── range_test001.py ├── docs └── temp.txt └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | .static_storage/ 56 | .media/ 57 | local_settings.py 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | .idea/ChZhShCh_Python.iml 106 | .idea/workspace.xml 107 | .idea/misc.xml 108 | .vscode/settings.json 109 | -------------------------------------------------------------------------------- /.idea/Code.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 16 | -------------------------------------------------------------------------------- /.idea/dictionaries/baileicheng.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | classfication 5 | tushare 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/other.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ChZhShCh 2 | 部分缠论技术的程序化实践 3 | 4 | 《缠中说禅博客》地址: http://blog.sina.com.cn/chzhshch 5 | 6 | --- 7 | ### 1、K包含处理 8 | 9 | ### 2、找顶底 10 | 11 | ### 3、划笔 12 | 13 | > TODO: 14 | ### 4、线段划分 15 | 16 | ### 5、均线选股 17 | 18 | ### 6、均线轮动和板块强弱指标 19 | 20 | -------- 21 | 22 | TODO: 23 | 每日走势分类(30分钟8根K线) 24 | -------------------------------------------------------------------------------- /bin/temp.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xbfighting/ChZhShCh/52e75c4827240998222f6b5e6b89a20c8b7e645c/bin/temp.txt -------------------------------------------------------------------------------- /chzhshch/__init__.py: -------------------------------------------------------------------------------- 1 | from . import feature 2 | from . import external_package 3 | from . import inner_package -------------------------------------------------------------------------------- /chzhshch/external_package/__init__.py: -------------------------------------------------------------------------------- 1 | from . import line_helper 2 | from . import tushare_helper -------------------------------------------------------------------------------- /chzhshch/external_package/line_helper.py: -------------------------------------------------------------------------------- 1 | 2 | # -*- coding: utf-8 -*- 3 | class Point(object): 4 | x =0 5 | y= 0 6 | # 定义构造方法 7 | def __init__(self, x=0, y=0): 8 | self.x = x 9 | self.y = y 10 | 11 | class Line(object): 12 | # a=0 13 | # b=0 14 | # c=0 15 | def __init__(self, p1, p2): 16 | self.p1 = p1 17 | self.p2 = p2 18 | 19 | 20 | def GetLinePara(line): 21 | line.a =line.p1.y - line.p2.y 22 | line.b = line.p2.x - line.p1.x 23 | line.c = line.p1.x *line.p2.y - line.p2.x * line.p1.y 24 | 25 | 26 | def GetCrossPoint(l1,l2): 27 | 28 | GetLinePara(l1) 29 | GetLinePara(l2) 30 | d = l1.a * l2.b - l2.a * l1.b 31 | p=Point() 32 | p.x = (l1.b * l2.c - l2.b * l1.c)*1.0 / d 33 | p.y = (l1.c * l2.a - l2.c * l1.a)*1.0 / d 34 | return p 35 | 36 | 37 | # TEST 38 | 39 | # p1=Point(1,1) 40 | # p2=Point(3,3) 41 | # line1=Line(p1,p2) 42 | # 43 | # p3=Point(2,3.1) 44 | # p4=Point(3.1,2) 45 | # line2=Line(p3,p4) 46 | # Pc = GetCrossPoint(line1,line2) 47 | # print("Cross point:", Pc.x, Pc.y) -------------------------------------------------------------------------------- /chzhshch/external_package/tushare_helper.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import tushare as ts 3 | from datetime import datetime, date, time 4 | 5 | # 单例 6 | class Singleton(object): 7 | _instance = None 8 | 9 | def __new__(cls, *args, **kw): 10 | if not cls._instance: 11 | cls._instance = super(Singleton, cls).__new__(cls) 12 | return cls._instance 13 | 14 | 15 | class TushareConn(Singleton): 16 | conn = ts.get_apis() 17 | 18 | class TushareHelper(object): 19 | def __init__(self, code, start, end, freq, ma = [5, 10], asset = ''): 20 | self.self = self 21 | self.code = code 22 | self.start = start 23 | self.end = end 24 | self.freq = freq 25 | self.ma = ma 26 | 27 | if asset is None or asset == '': 28 | self.asset = 'INDEX' 29 | else: 30 | self.asset = asset 31 | # 原始api数据 pandas data_frame 32 | self.data_frame = {} 33 | # 34 | self.data_original = [] 35 | self.data_original_ex = [] 36 | self.date_tickers = [] 37 | 38 | # MA 接口数据 39 | self.data_frame_ma = {} 40 | # 简版数据 41 | self.data_frame_ma_mini = {"index":[], "index_date":[], "short":[], "long":[]} 42 | def __bar(self): 43 | self.data_frame = ts.bar(code=self.code, conn=TushareConn.conn, start_date=self.start, end_date=self.end, 44 | freq=self.freq, asset=self.asset) 45 | def data_transfer(self): 46 | self.__bar() 47 | list_index = 0 48 | # data_frame 按照 index 倒叙排序 49 | for index, row in self.data_frame.sort_index().iterrows(): 50 | date_time = datetime.strptime(str(index), '%Y-%m-%d %H:%M:%S') 51 | row["index"] = str(date_time) 52 | row["is_up"] = row["open"] <= row["close"] 53 | self.data_original_ex.append((list_index, row['open'], row['high'], row['low'], row['close'])) 54 | self.data_original.append(row) 55 | self.date_tickers.append(str(row['index'])) 56 | list_index += 1 57 | 58 | # MA 59 | def __ma(self): 60 | self.data_frame_ma = ts.bar(code=self.code, conn=TushareConn.conn, start_date=self.start, end_date=self.end, 61 | freq=self.freq, ma=self.ma ) 62 | # ma transfer 63 | def data_transfer_ma(self): 64 | self.__ma() 65 | ma_short = "ma" + str(self.ma[0]) 66 | ma_long = "ma" + str(self.ma[1]) 67 | list_index = 0 68 | 69 | # data_frame 按照 index 倒叙排序 70 | for index, row in self.data_frame_ma.sort_index().iterrows(): 71 | date_time = datetime.strptime(str(index), '%Y-%m-%d %H:%M:%S') 72 | self.data_frame_ma_mini["index"].append(list_index) 73 | self.data_frame_ma_mini["index_date"].append((str(date_time))) 74 | self.data_frame_ma_mini["short"].append(row[ma_short]) 75 | self.data_frame_ma_mini["long"].append(row[ma_long]) 76 | list_index += 1 77 | -------------------------------------------------------------------------------- /chzhshch/feature/__init__.py: -------------------------------------------------------------------------------- 1 | from . import daily_trend_classfication 2 | from . import ma_sys_kiss 3 | from . import year_ma -------------------------------------------------------------------------------- /chzhshch/feature/daily_trend_classfication.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import os 3 | import sys 4 | import datetime 5 | 6 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),os.path.pardir))) 7 | from inner_package import chzhshch_central as central 8 | from external_package import tushare_helper as th 9 | 10 | class DailyClassfication(object): 11 | def __init__(self, original_list): 12 | # 原始列表初始化标准列表 13 | self.standardized_list = original_list 14 | pass 15 | 16 | # 中枢判断,如果是中枢则返回区间和高低点 17 | def is_central(self, k1, k2, k3): 18 | pass 19 | 20 | # 是否在中枢区间内 21 | def is_in_central_region(self, k, central): 22 | pass 23 | 24 | # 是否是预测,小于8K则属于预测 25 | def is_predict(self): 26 | if self.standardized_list is None or self.standardized_list.length < 8 : 27 | return True 28 | else: 29 | return False 30 | 31 | # 中枢个数 32 | def get_central_count(self): 33 | pass 34 | 35 | # 零个中枢 36 | def deal_zero_central(self): 37 | pass 38 | 39 | # 一个中枢 40 | def deal_one_central(self): 41 | pass 42 | 43 | # 两个中枢 44 | def deal_two_central(self): 45 | pass 46 | 47 | 48 | original = th.TushareHelper('000001', datetime.date.today() + datetime.timedelta(days=-1), 49 | datetime.date.today() + datetime.timedelta(days=+1), '30min') 50 | original.data_transfer() 51 | 52 | dcf = DailyClassfication(original.data_original) 53 | print(dcf.standardized_list) 54 | -------------------------------------------------------------------------------- /chzhshch/feature/ma_sys_kiss.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | # 均线系统+吻 3 | import os 4 | import sys 5 | import datetime 6 | 7 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),os.path.pardir))) 8 | from external_package import tushare_helper as th 9 | from inner_package import standardized as standard 10 | from inner_package import show 11 | from inner_package import ma_kiss as mk 12 | 13 | code = "002500" 14 | original = th.TushareHelper(code, datetime.date.today() + datetime.timedelta(days=-30), datetime.date.today() + datetime.timedelta(days=1),'60min') 15 | original.data_transfer_ma() 16 | 17 | makiss = mk.MAKiss(code, original.data_frame_ma_mini) 18 | my_plot = show.PlotShow([], code) 19 | 20 | # 交点获取 21 | makiss.get_intersections() 22 | print(len(makiss.intersections)) 23 | print(makiss.intersections) 24 | 25 | # 吻获取 26 | makiss.get_lip_kiss() 27 | print(makiss.lip_kiss) 28 | 29 | # 打印 30 | my_plot.ma_kiss_show(makiss) 31 | 32 | 33 | -------------------------------------------------------------------------------- /chzhshch/feature/year_ma.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | # 根据“放量上年线,缩量回调。” 选股 3 | import sys 4 | import datetime 5 | import math 6 | import numpy as np 7 | import matplotlib.pyplot as plt 8 | import matplotlib.ticker as ticker 9 | from scipy import interpolate 10 | 11 | 12 | pass 13 | 14 | 15 | # TODO: 获取成交量 -------------------------------------------------------------------------------- /chzhshch/inner_package/__init__.py: -------------------------------------------------------------------------------- 1 | from . import chzhshch_central 2 | from . import frequency_enum 3 | from . import ma_kiss 4 | from . import show 5 | from . import standardized -------------------------------------------------------------------------------- /chzhshch/inner_package/chzhshch_central.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | # 中枢类 3 | class Central: 4 | def __init__(self, GG, DD, ZG, ZD, start, end): 5 | self.GG = GG 6 | self.DD = DD 7 | self.ZG = ZG 8 | self.ZD = ZD 9 | self.start = start 10 | self.end = end -------------------------------------------------------------------------------- /chzhshch/inner_package/frequency_enum.py: -------------------------------------------------------------------------------- 1 | from enum import Enum, unique 2 | 3 | @unique 4 | class Frequency(Enum): 5 | one_min = '1min', 6 | five_min = '5min', 7 | fifteen_min = '15min', 8 | thirty_min = '30min', 9 | sixty_min = '60min', 10 | one_day = 'D', 11 | ween = 'W', 12 | one_month = 'M', 13 | -------------------------------------------------------------------------------- /chzhshch/inner_package/ma_kiss.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import os 3 | import sys 4 | import datetime 5 | import math 6 | 7 | import matplotlib.pyplot as plt 8 | import matplotlib.ticker as ticker 9 | import numpy as np 10 | from scipy import interpolate 11 | 12 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),os.path.pardir))) 13 | 14 | from external_package import line_helper as lh 15 | from external_package import tushare_helper as th 16 | from inner_package import standardized as standard 17 | from inner_package import show 18 | 19 | 20 | class MAKiss(object): 21 | # x 轴转换 date_tickers 表示 22 | def __date_tickers_transfer(self): 23 | self.date_tickers = [] 24 | # 时间轴转换 25 | for i in self.int_tickers: 26 | index = int(i) 27 | if index == 0: 28 | self.date_tickers.append(self.x_date[int(i)]) 29 | else: 30 | self.date_tickers.append(self.x_date[int(i) - 1]) 31 | return self.date_tickers 32 | 33 | def __init__(self, code, data_frame_ma_mini): 34 | self.code = code 35 | self.data_frame_ma_mini = data_frame_ma_mini # ma 数据 36 | self.x_date = self.data_frame_ma_mini['index_date'] # x轴用日期 37 | self.x_index = self.data_frame_ma_mini['index'] # x轴用数字索引 38 | self.long = self.data_frame_ma_mini['long'] # 长期均线 39 | self.short = self.data_frame_ma_mini['short'] # 短期均线 40 | self.long_interp1d = interpolate.interp1d(self.x_index, self.long) # 长期均线差值函数 41 | self.short_interp1d = interpolate.interp1d(self.x_index, self.short) # 短期均线差值函数 42 | self.intersection = {"Postural": None, "X": 0, "Y": 0} # 交点定义 43 | self.intersections = [] # 交点集合 44 | self.intersections_ex = [] # 交点集合 ex 备用计算吻之用 45 | self.intersection_x = [] # 交点x点集 46 | self.intersection_y = [] # 交点y点集 47 | 48 | self.lip_kiss = [] # 唇吻集合 49 | self.lip_kiss_x = [] # 唇吻 x点集 50 | self.lip_kiss_y = [] # 唇吻 y点集 51 | 52 | 53 | self.int_tickers = np.linspace(0, len(self.x_index), 5) # plot int tickers 54 | self.date_tickers = self.__date_tickers_transfer() # plot date tickers 55 | 56 | self.postural_long_to_short = "1" # 男上位 57 | self.postural_short_to_long = "0" # 女上位 58 | 59 | # 单个交点计算和获取 粗略版 已经弃用 60 | def __get_intersection(self, pre_data, curr_data): 61 | pre_short = pre_data["short"] 62 | pre_long = pre_data["long"] 63 | curr_short = curr_data["short"] 64 | curr_long = curr_data["long"] 65 | 66 | # 空缺值不处理 67 | if np.isnan(pre_short) != True and np.isnan(pre_long) != True and np.isnan(curr_short) != True and np.isnan( 68 | curr_long) != True: 69 | # 交点前是男上位 70 | if pre_long - pre_short > 0 and curr_short - curr_long >= 0: 71 | intersection_index = (curr_data["index"] + pre_data["index"]) / 2 72 | y = self.long_interp1d(intersection_index) 73 | if np.isnan(y): 74 | y = self.short_interp1d(intersection_index) 75 | self.intersection = {"Postural": self.postural_long_to_short, "X": intersection_index, "Y": y} 76 | return 77 | # 交点前是女上位 78 | if pre_long - pre_short < 0 and curr_short - curr_long <= 0: 79 | intersection_index = (curr_data["index"] + pre_data["index"]) / 2 80 | y = self.long_interp1d(intersection_index) 81 | if np.isnan(y): 82 | y = self.short_interp1d(intersection_index) 83 | self.intersection = {"Postural": self.postural_short_to_long, "X": intersection_index, "Y": y} 84 | return 85 | 86 | self.intersection = {"Postural": None, "X": 0, "Y": 0} 87 | return 88 | 89 | # 单个交点计算和获取 ex 90 | def __get_intersection_ex(self, pre_data, curr_data): 91 | pre_short = pre_data["short"] 92 | pre_long = pre_data["long"] 93 | pre_index = pre_data["index"] 94 | curr_short = curr_data["short"] 95 | curr_long = curr_data["long"] 96 | curr_index = curr_data["index"] 97 | 98 | # 空缺值不处理 99 | if np.isnan(pre_short) != True and np.isnan(pre_long) != True and np.isnan(curr_short) != True and np.isnan( 100 | curr_long) != True: 101 | # 交点前是男上位 102 | if pre_long - pre_short > 0 and curr_short - curr_long >= 0: 103 | point_long1 = lh.Point(pre_index, pre_long) 104 | point_long2 = lh.Point(curr_index, curr_long) 105 | line1_long = lh.Line(point_long1, point_long2) 106 | 107 | point_short1 = lh.Point(pre_index, pre_short) 108 | point_short2 = lh.Point(curr_index, curr_short) 109 | line1_short = lh.Line(point_short1, point_short2) 110 | 111 | intersection_point = lh.GetCrossPoint(line1_long, line1_short) 112 | self.intersection = {"Postural": self.postural_long_to_short, "X": intersection_point.x, 113 | "Y": intersection_point.y} 114 | return 115 | # 交点前是女上位 116 | if pre_long - pre_short < 0 and curr_short - curr_long <= 0: 117 | point_long1 = lh.Point(pre_index, pre_long) 118 | point_long2 = lh.Point(curr_index, curr_long) 119 | line1_long = lh.Line(point_long1, point_long2) 120 | 121 | point_short1 = lh.Point(pre_index, pre_short) 122 | point_short2 = lh.Point(curr_index, curr_short) 123 | line1_short = lh.Line(point_short1, point_short2) 124 | 125 | intersection_point = lh.GetCrossPoint(line1_long, line1_short) 126 | self.intersection = {"Postural": self.postural_short_to_long, "X": intersection_point.x, 127 | "Y": intersection_point.y} 128 | return 129 | 130 | self.intersection = {"Postural": None, "X": 0, "Y": 0} 131 | return 132 | 133 | 134 | # 交点集合获取 135 | def get_intersections(self): 136 | i = 1 137 | while i < len(self.data_frame_ma_mini["index"]): 138 | ma_item_pre = {'index': 0, 'long': 0, 'short': 0} 139 | ma_item_pre["index"] = self.data_frame_ma_mini["index"][i - 1] 140 | ma_item_pre["long"] = self.data_frame_ma_mini["long"][i - 1] 141 | ma_item_pre["short"] = self.data_frame_ma_mini["short"][i - 1] 142 | 143 | ma_item_curr = {'index': 0, 'long': 0, 'short': 0} 144 | ma_item_curr["index"] = self.data_frame_ma_mini["index"][i] 145 | ma_item_curr["long"] = self.data_frame_ma_mini["long"][i] 146 | ma_item_curr["short"] = self.data_frame_ma_mini["short"][i] 147 | 148 | self.__get_intersection_ex(ma_item_pre, ma_item_curr) 149 | 150 | if self.intersection["Postural"] is not None: 151 | self.intersections.append(self.intersection) 152 | self.intersection_x.append(self.intersection["X"]) 153 | self.intersection_y.append(self.intersection["Y"]) 154 | i += 1 155 | 156 | # 获取唇吻 157 | # TODO: 排除交点附近的点 158 | # TODO: 想办法获取两个交点中断的“吻” 159 | 160 | def get_lip_kiss(self): 161 | long_short_diff = [] 162 | long_short_diff_value = [] 163 | 164 | for i in range(len(self.x_index)): 165 | if np.isnan(self.long[i]) != True and np.isnan(self.short[i]) != True: 166 | diff = self.long[i] - self.short[i] 167 | if diff > 0: 168 | long_short_diff.append({"Postural": self.postural_long_to_short, "X": self.x_index[i], "Y":self.long[i], "Diff": round(diff, 5)}) 169 | long_short_diff_value.append(round(diff, 5)) 170 | 171 | for passnum in range(len(long_short_diff_value) - 1, 0, -1): 172 | for i in range(passnum): 173 | if long_short_diff[i]["Diff"] > long_short_diff[i + 1]["Diff"]: 174 | temp = long_short_diff[i] 175 | long_short_diff[i] = long_short_diff[i + 1] 176 | long_short_diff[i + 1] = temp 177 | print(long_short_diff) 178 | for i in range(len(long_short_diff)): 179 | if i < 8: 180 | self.lip_kiss.append(long_short_diff[i]) 181 | self.lip_kiss_x.append(long_short_diff[i]["X"]) 182 | self.lip_kiss_y.append(long_short_diff[i]["Y"]) 183 | print(long_short_diff) 184 | -------------------------------------------------------------------------------- /chzhshch/inner_package/show.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import matplotlib.ticker as ticker 3 | import matplotlib.pyplot as plt 4 | import matplotlib.finance as mpf 5 | import numpy as np 6 | from pandas import Series, DataFrame 7 | # http://blog.csdn.net/xiaodongxiexie/article/details/53123371 8 | 9 | class PlotShow(object): 10 | 11 | def __init__(self, date_tickers, title): 12 | self.date_tickers = date_tickers 13 | self.xaxis_cycle = 30 14 | self.width = 0.3 15 | self.colordown ='#53c156' 16 | self.colorup = '#ff1717' 17 | self.xlabel = 'datetime' 18 | self.ylabel = 'value' 19 | self.title = title 20 | 21 | 22 | # 时间轴转换 23 | def __format_date(self, x, pos=None): 24 | if x < 0 or x > len(self.date_tickers) - 1: 25 | return '' 26 | return self.date_tickers[int(x)] 27 | 28 | # K画图 29 | def candle_show(self, stock_data, top_bottom_data): 30 | 31 | # 创建子图 32 | fig, ax = plt.subplots(figsize=(192.0 / 72, 108.0 / 72)) 33 | ax.xaxis.set_major_locator(ticker.MultipleLocator(self.xaxis_cycle)) 34 | ax.xaxis.set_major_formatter(ticker.FuncFormatter(self.__format_date)) 35 | mpf.candlestick_ohlc(ax, stock_data, width=self.width, colordown=self.colordown, colorup=self.colorup, alpha=1) 36 | 37 | # title 各种设置 38 | plt.rcParams['font.sans-serif'] = ['SimHei'] 39 | plt.rcParams['axes.unicode_minus'] = False 40 | 41 | plt.title(self.title) 42 | plt.xlabel(self.xlabel) 43 | plt.ylabel(self.ylabel) 44 | 45 | # 顶底、图例等 46 | if len(top_bottom_data) > 0: 47 | x = [] 48 | y = [] 49 | for i in top_bottom_data: 50 | x.append(i[0]) 51 | y.append(i[1]) 52 | plt.plot(x, y, '--y*', label='分笔') 53 | plt.legend() # 展示图例 54 | 55 | ax.grid(True) 56 | # plt.savefig('E:\PythonChZhShCh\\' + code + k_type + start_date + end_date + '.png') 57 | plt.show() 58 | 59 | # MA 画图 60 | def ma_kiss_show(self, ma): 61 | fig, ax = plt.subplots(1, 1, figsize=(1920 / 72, 1080 / 72), sharex=True) 62 | 63 | plt.rcParams['font.sans-serif'] = ['SimHei'] 64 | plt.rcParams['axes.unicode_minus'] = False 65 | 66 | ax.plot(ma.x_index, ma.short, color='red', linewidth=1.0, label="short") 67 | ax.plot(ma.x_index, ma.long, color='black', linewidth=1.0, label="long") 68 | 69 | # 交点打印 70 | ax.plot(ma.intersection_x, ma.intersection_y, 'o') 71 | 72 | # 吻打印 73 | ax.plot(ma.lip_kiss_x, ma.lip_kiss_y, 'o') 74 | 75 | 76 | ax.set_title(self.title) 77 | ax.set_xlabel("日期") 78 | ax.set_ylabel("price") 79 | 80 | plt.xticks(ma.int_tickers) 81 | plt.xticks(ma.int_tickers, ma.date_tickers) 82 | ax.legend() 83 | plt.show() 84 | -------------------------------------------------------------------------------- /chzhshch/inner_package/standardized.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | # K线数据标准化处理 3 | class StandardHandle(object): 4 | def __init__(self, original_list): 5 | self.candle_direction = 0 6 | self.is_merged = False 7 | # 原始列表初始化标准列表 8 | self.standardized_list = original_list 9 | self.standardized_list_ex = [] 10 | self.top_bottom_list = [] # 普通顶底 11 | self.top_bottom_list_ex = [] # 普通顶底ex 12 | self.standardized_top_bottom_list = [] # 标准顶底 13 | self.standardized_top_bottom_list_ex = [] # 标准顶底ex 14 | self.date_tickers = [] 15 | 16 | # 方向 17 | def __set_direction(self, item_pre, item_curr): 18 | high_pre = item_pre['high'] 19 | low_pre = item_pre['low'] 20 | high_curr = item_curr['high'] 21 | low_curr = item_curr['low'] 22 | if high_curr > high_pre and low_curr > low_pre: 23 | self.candle_direction = 1 24 | elif high_pre > high_curr and low_pre > low_curr: 25 | self.candle_direction = -1 26 | 27 | # 合并 28 | def __merge_candles(self, item_pre, item_curr): 29 | result = [] 30 | high_pre = item_pre['high'] 31 | low_pre = item_pre['low'] 32 | high_curr = item_curr['high'] 33 | low_curr = item_curr['low'] 34 | is_up_pre = item_pre['is_up'] 35 | is_up_curr = item_curr['is_up'] 36 | 37 | if high_curr >= high_pre and low_curr <= low_pre: 38 | if self.candle_direction == 1: 39 | item_curr['low'] = low_pre 40 | item_pre['high'] = high_curr 41 | 42 | if is_up_curr: 43 | item_curr['open'] = low_pre 44 | else: 45 | item_curr['close'] = low_pre 46 | 47 | if is_up_pre: 48 | item_pre['close'] = high_curr 49 | else: 50 | item_pre['open'] = high_curr 51 | 52 | self.is_merged = True 53 | elif self.candle_direction == -1: 54 | item_curr['high'] = high_pre 55 | item_pre['low'] = low_curr 56 | 57 | if is_up_curr: 58 | item_curr['close'] = high_pre 59 | else: 60 | item_curr['open'] = high_pre 61 | 62 | if is_up_pre: 63 | item_pre['open'] = low_curr 64 | else: 65 | item_pre['close'] = low_curr 66 | 67 | self.is_merged = True 68 | else: 69 | self.is_merged = False 70 | elif high_pre >= high_curr and low_pre <= low_curr: 71 | if self.candle_direction == 1: 72 | item_curr['high'] = high_pre 73 | item_pre['low'] = low_curr 74 | 75 | if is_up_curr: 76 | item_curr['close'] = high_pre 77 | else: 78 | item_curr['open'] = high_pre 79 | 80 | if is_up_pre: 81 | item_pre['open'] = low_curr 82 | else: 83 | item_pre['close'] = low_curr 84 | 85 | self.is_merged = True 86 | elif self.candle_direction == -1: 87 | item_curr['low'] = low_pre 88 | item_pre['high'] = high_pre 89 | 90 | if is_up_curr: 91 | item_curr['open'] = low_pre 92 | else: 93 | item_curr['close'] = low_pre 94 | 95 | if is_up_pre: 96 | item_pre['close'] = high_curr 97 | else: 98 | item_pre['open'] = high_curr 99 | 100 | self.is_merged = True 101 | else: 102 | self.is_merged = False 103 | else: 104 | self.is_merged = False 105 | 106 | result.append(item_curr) 107 | result.append(item_pre) 108 | return result 109 | 110 | # 标准化处理 111 | def deal_candle(self): 112 | i = 0 113 | while i < len(self.standardized_list): 114 | item_curr = self.standardized_list[i] 115 | if i > 0: 116 | item_pre = self.standardized_list[i - 1] 117 | self.__set_direction(item_pre, item_curr) 118 | item_curr_pre = self.__merge_candles(item_pre, item_curr) 119 | if self.is_merged: 120 | self.standardized_list[i] = item_curr_pre[0] 121 | self.standardized_list.pop(i - 1) 122 | i -= 1 123 | i += 1 124 | 125 | list_index = 0 126 | for row in self.standardized_list: 127 | self.date_tickers.append(str(row['index'])) 128 | self.standardized_list_ex.append((list_index, row['open'], row['high'], row['low'], row['close'])) 129 | list_index += 1 130 | 131 | # 获取分型类型 132 | def __get_typing(self, pre, curr, after): 133 | high_pre = pre['high'] 134 | high_curr = curr['high'] 135 | high_after = after['high'] 136 | 137 | typing = 0 # 0-无顶底,1-顶分型,-1-底分型 138 | direction = 0 # 方向类型 139 | 140 | if high_curr > high_pre: 141 | direction = 1 142 | typing = 1 143 | else: 144 | direction = -1 145 | typing = -1 146 | 147 | if high_after < high_curr: 148 | direction = direction - 1 149 | else: 150 | direction = direction + 1 151 | 152 | if direction == 0: 153 | return typing 154 | else: 155 | return 0 156 | 157 | # 思路 158 | # 1、先获取所有的顶和底,标准转向 159 | # 2、连续顶底的处理 160 | # 3、输出 161 | 162 | # 获取顶和底 163 | # UGLY!!! 需要拆分 164 | def get_top_bottom(self): 165 | s_length = len(self.standardized_list) 166 | typing = 0 167 | 168 | i = 0 169 | while i < s_length: 170 | if i > 0 and s_length - i > 1: 171 | pre = self.standardized_list[i - 1] 172 | curr = self.standardized_list[i] 173 | after = self.standardized_list[i + 1] 174 | typing = self.__get_typing(pre, curr, after) 175 | if typing != 0: 176 | curr["int_index"] = i 177 | curr["typing"] = typing 178 | if typing == 1: 179 | curr["typing_value"] = curr["high"] 180 | else: 181 | curr["typing_value"] = curr["low"] 182 | self.top_bottom_list.append(curr) 183 | i += 1 184 | 185 | print("top_bottom_list") 186 | print(len(self.top_bottom_list)) 187 | 188 | for item in self.top_bottom_list: 189 | self.top_bottom_list_ex.append([item["int_index"], item["typing_value"]]) 190 | print(item["int_index"], item["typing_value"], item["typing"]) 191 | 192 | # TODO:分型区间不能出现重合 处理 193 | # 连续顶顶或底底的情况要考虑极值的相比 194 | s_length = len(self.top_bottom_list) 195 | 196 | # 不成笔的区间 flag表示当前区间用作确认顶还是底 197 | # 顶=1 底=-1 198 | temp_rang = {"_top": None, "_bottom": None, "_flag":0} 199 | 200 | # 不足5k的顶底去除 201 | for i in range(0, s_length, 1): 202 | if s_length - i > 1: 203 | curr = self.top_bottom_list[i] 204 | after = self.top_bottom_list[i + 1] 205 | 206 | # 若不成笔区间不存在,则表示当前点和前面的点满足一笔且前点不存在争议 207 | if temp_rang["_top"] is None and temp_rang["_bottom"] is None: 208 | if after["int_index"] - curr["int_index"] >= 4: 209 | self.standardized_top_bottom_list.append(curr) 210 | else: 211 | # 如果不成笔区间未初始化 则需要重新确认不成笔区间 212 | if curr["typing"] == -1: 213 | temp_rang["_top"] = after 214 | temp_rang["_bottom"] = curr 215 | temp_rang["_flag"] = -1 216 | 217 | else: 218 | temp_rang["_top"] = curr 219 | temp_rang["_bottom"] = after 220 | temp_rang["_flag"] = 1 221 | # 分型区间存在,表示当前点和前点不足一笔 222 | else: 223 | # 确认底 224 | if temp_rang["_flag"] == -1: 225 | # 当前为顶 226 | if curr["typing"] == 1: 227 | # 当前和区间底构成一笔 则区间底确认,不够成一笔 不处理 228 | if curr["int_index"] - temp_rang["_bottom"]["int_index"] >= 4: 229 | self.standardized_top_bottom_list.append(temp_rang["_bottom"]) 230 | 231 | if after["int_index"] - curr["int_index"] >= 4: 232 | self.standardized_top_bottom_list.append(curr) 233 | # reset range 234 | temp_rang = {"_top": None, "_bottom": None, "_flag": 0} 235 | else: 236 | # 判断笔破坏 237 | if after["typing_value"] < temp_rang["_bottom"]["typing_value"]: 238 | self.standardized_top_bottom_list.pop(len(self.standardized_top_bottom_list) - 1) 239 | self.standardized_top_bottom_list.append(after) 240 | temp_rang = {"_top": None, "_bottom": None, "_flag": 0} 241 | else: 242 | # 新区间 确认顶 243 | temp_rang["_top"] = curr 244 | temp_rang["_bottom"] = after 245 | temp_rang["_flag"] = 1 246 | 247 | # 当前为底 248 | else: 249 | # 比较底和区间底,如果较小则更新区间底,在区间内不处理 250 | if curr["typing_value"] < temp_rang["_bottom"]["typing_value"]: 251 | temp_rang["_bottom"] = curr 252 | 253 | # 确认顶 254 | else: 255 | # 当前为顶 256 | if curr["typing"] == 1: 257 | # 比较顶和区间顶,如果较大则更新区间顶,在区间内不处理 258 | if curr["typing_value"] > temp_rang["_top"]["typing_value"]: 259 | temp_rang["_top"] = curr 260 | # 当前为底 261 | else: 262 | # 当前和区间顶构成一笔 则区间顶确认,不够成一笔 不处理 263 | if curr["int_index"] - temp_rang["_top"]["int_index"] >= 4: 264 | self.standardized_top_bottom_list.append(temp_rang["_top"]) 265 | 266 | if after["int_index"] - curr["int_index"] >= 4: 267 | self.standardized_top_bottom_list.append(curr) 268 | # reset range 269 | temp_rang = {"_top": None, "_bottom": None, "_flag": 0} 270 | else: 271 | # 判断笔破坏 272 | if after["typing_value"] > temp_rang["_top"]["typing_value"]: 273 | self.standardized_top_bottom_list.pop(len(self.standardized_top_bottom_list) - 1) 274 | self.standardized_top_bottom_list.append(after) 275 | 276 | # reset range 277 | temp_rang = {"_top": None, "_bottom": None, "_flag": 0} 278 | else: 279 | # 新区间 确认底 280 | temp_rang["_top"] = after 281 | temp_rang["_bottom"] = curr 282 | temp_rang["_flag"] = -1 283 | 284 | print("standardized_top_bottom_list") 285 | print(len(self.standardized_top_bottom_list)) 286 | # to simple series 287 | for item in self.standardized_top_bottom_list : 288 | self.standardized_top_bottom_list_ex.append([item["int_index"], item["typing_value"]]) 289 | print(item["int_index"], item["typing_value"], item["typing"]) 290 | 291 | -------------------------------------------------------------------------------- /chzhshch/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import datetime 3 | 4 | from external_package import tushare_helper as th 5 | from inner_package import standardized as standard 6 | from inner_package import show 7 | 8 | # original = th.TushareHelper('000001', datetime.date.today()+ datetime.timedelta(days=-1),datetime.date.today() + datetime.timedelta(days=+1),'1min') 9 | original = th.TushareHelper('000001', '2017-12-04', '2017-12-12', 'D') 10 | original.data_transfer() 11 | 12 | sta = standard.StandardHandle(original.data_original) 13 | sta.deal_candle() 14 | sta.get_top_bottom() 15 | 16 | date_tickers = original.date_tickers 17 | my_plot = show.PlotShow(date_tickers, '000001') 18 | my_plot.candle_show(original.data_original_ex, []) 19 | 20 | date_tickers = sta.date_tickers 21 | my_plot = show.PlotShow(date_tickers, '000001') 22 | # my_plot.candle_show(sta.standardized_list_ex, []) 23 | my_plot.candle_show(sta.standardized_list_ex, sta.top_bottom_list_ex) 24 | my_plot.candle_show(sta.standardized_list_ex, 25 | sta.standardized_top_bottom_list_ex) 26 | -------------------------------------------------------------------------------- /chzhshch/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xbfighting/ChZhShCh/52e75c4827240998222f6b5e6b89a20c8b7e645c/chzhshch/tests/__init__.py -------------------------------------------------------------------------------- /chzhshch/tests/plot_fill_between.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.arange(0.0, 2, 0.01) 6 | y1 = np.sin(2*np.pi*x) 7 | y2 = 1.2*np.sin(4*np.pi*x) 8 | 9 | # now fill between y1 and y2 where a logical condition is met. Note 10 | # this is different than calling 11 | # fill_between(x[where], y1[where],y2[where] 12 | # because of edge effects over multiple contiguous regions. 13 | fig, (ax, ax1) = plt.subplots(2, 1, sharex=True) 14 | ax.plot(x, y1, x, y2, color='black') 15 | ax.fill_between(x, y1, y2, where=y2 >= y1, facecolor='green', interpolate=True) 16 | ax.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', interpolate=True) 17 | ax.set_title('fill between where') 18 | 19 | # Test support for masked arrays. 20 | y2 = np.ma.masked_greater(y2, 1.0) 21 | ax1.plot(x, y1, x, y2, color='black') 22 | ax1.fill_between(x, y1, y2, where=y2 >= y1, facecolor='green', interpolate=True) 23 | ax1.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', interpolate=True) 24 | ax1.set_title('Now regions with y2>1 are masked') 25 | 26 | plt.show() -------------------------------------------------------------------------------- /chzhshch/tests/plot_scipy_test001.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from scipy import interpolate 3 | 4 | x = np.arange(0,10) 5 | y = np.exp(-x/3.0) 6 | f = interpolate.interp1d(x, y) 7 | 8 | xnew = np.arange(0,9,0.1) 9 | import matplotlib.pyplot as plt 10 | plt.plot(x,y,'o',xnew,f(xnew),'-') 11 | plt.show() -------------------------------------------------------------------------------- /chzhshch/tests/plot_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | import matplotlib.finance as mpf 5 | 6 | 7 | def candle_show(self, stock_data, scatter_data): 8 | # 创建子图 9 | fig, ax = plt.subplots(figsize=(192.0 / 72, 108.0 / 72)) 10 | mpf.candlestick_ohlc(ax, stock_data, width=self.width, colordown=self.colordown, colorup=self.colorup, alpha=1) 11 | ax.grid(True) 12 | plt.show() 13 | 14 | plt.title('0000001') 15 | plt.xlabel('datetime') 16 | plt.ylabel('index value') 17 | 18 | arr = [ [0, 3316.95], [1, 3304.58], [2, 3313.19], [3, 3303.01]] 19 | x = [] 20 | y = [] 21 | for i in arr: 22 | x.append(i[0]) 23 | y.append(i[1]) 24 | 25 | plt.plot(x, y, '--y*', label = 'bi') 26 | plt.legend() # 展示图例 27 | plt.show() -------------------------------------------------------------------------------- /chzhshch/tests/plot_test001.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | import matplotlib.pyplot as plt 4 | import matplotlib.finance as mpf 5 | from pandas import Series, DataFrame 6 | from matplotlib.pylab import date2num 7 | 8 | x = np.linspace(-3, 3, 50) 9 | y1 = 2*x + 1 10 | y2 = x**2 11 | 12 | print(y1) 13 | print(y2) 14 | plt.figure() 15 | plt.plot(x, y1) 16 | plt.plot(x, y2) 17 | plt.plot(y1, y2) 18 | plt.show() -------------------------------------------------------------------------------- /chzhshch/tests/range_test001.py: -------------------------------------------------------------------------------- 1 | 2 | for i in range(0,3,2): 3 | print (i) -------------------------------------------------------------------------------- /docs/temp.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xbfighting/ChZhShCh/52e75c4827240998222f6b5e6b89a20c8b7e645c/docs/temp.txt -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | alabaster==0.7.12 2 | anaconda-client==1.7.2 3 | anaconda-navigator==1.9.7 4 | anaconda-project==0.8.2 5 | appnope==0.1.0 6 | appscript==1.0.1 7 | asn1crypto==0.24.0 8 | astroid==2.2.5 9 | astropy==3.1.2 10 | atomicwrites==1.3.0 11 | attrs==19.1.0 12 | Babel==2.6.0 13 | backcall==0.1.0 14 | backports.os==0.1.1 15 | backports.shutil-get-terminal-size==1.0.0 16 | beautifulsoup4==4.7.1 17 | bitarray==0.8.3 18 | bkcharts==0.2 19 | bleach==3.1.0 20 | bokeh==1.0.4 21 | boto==2.49.0 22 | Bottleneck==1.2.1 23 | bs4==0.0.1 24 | certifi==2019.3.9 25 | cffi==1.12.2 26 | chardet==3.0.4 27 | Click==7.0 28 | cloudpickle==0.8.0 29 | clyent==1.2.2 30 | colorama==0.4.1 31 | conda==4.6.11 32 | conda-build==3.17.8 33 | conda-verify==3.1.1 34 | contextlib2==0.5.5 35 | cryptography==2.6.1 36 | cycler==0.10.0 37 | Cython==0.29.6 38 | cytoolz==0.9.0.1 39 | dask==1.1.4 40 | decorator==4.4.0 41 | defusedxml==0.5.0 42 | distributed==1.26.0 43 | docutils==0.14 44 | entrypoints==0.3 45 | et-xmlfile==1.0.1 46 | fastcache==1.0.2 47 | filelock==3.0.10 48 | Flask==1.0.2 49 | future==0.17.1 50 | gevent==1.4.0 51 | glob2==0.6 52 | gmpy2==2.0.8 53 | greenlet==0.4.15 54 | h5py==2.9.0 55 | heapdict==1.0.0 56 | html5lib==1.0.1 57 | idna==2.8 58 | imageio==2.5.0 59 | imagesize==1.1.0 60 | importlib-metadata==0.0.0 61 | ipykernel==5.1.0 62 | ipython==7.4.0 63 | ipython-genutils==0.2.0 64 | ipywidgets==7.4.2 65 | isort==4.3.16 66 | itsdangerous==1.1.0 67 | jdcal==1.4 68 | jedi==0.13.3 69 | Jinja2==2.10 70 | jsonschema==3.0.1 71 | jupyter==1.0.0 72 | jupyter-client==5.2.4 73 | jupyter-console==6.0.0 74 | jupyter-core==4.4.0 75 | jupyterlab==0.35.4 76 | jupyterlab-server==0.2.0 77 | keyring==18.0.0 78 | kiwisolver==1.0.1 79 | lazy-object-proxy==1.3.1 80 | libarchive-c==2.8 81 | lief==0.9.0 82 | llvmlite==0.28.0 83 | locket==0.2.0 84 | lxml==4.3.2 85 | MarkupSafe==1.1.1 86 | matplotlib==3.0.3 87 | mccabe==0.6.1 88 | mistune==0.8.4 89 | mkl-fft==1.0.10 90 | mkl-random==1.0.2 91 | more-itertools==6.0.0 92 | mpmath==1.1.0 93 | msgpack==0.6.1 94 | multipledispatch==0.6.0 95 | navigator-updater==0.2.1 96 | nbconvert==5.4.1 97 | nbformat==4.4.0 98 | networkx==2.2 99 | nltk==3.4 100 | nose==1.3.7 101 | notebook==5.7.8 102 | numba==0.43.1 103 | numexpr==2.6.9 104 | numpy==1.16.2 105 | numpydoc==0.8.0 106 | olefile==0.46 107 | openpyxl==2.6.1 108 | packaging==19.0 109 | pandas==0.24.2 110 | pandocfilters==1.4.2 111 | parso==0.3.4 112 | partd==0.3.10 113 | path.py==11.5.0 114 | pathlib2==2.3.3 115 | patsy==0.5.1 116 | pep8==1.7.1 117 | pexpect==4.6.0 118 | pickleshare==0.7.5 119 | Pillow==5.4.1 120 | pkginfo==1.5.0.1 121 | pluggy==0.9.0 122 | ply==3.11 123 | prometheus-client==0.6.0 124 | prompt-toolkit==2.0.9 125 | psutil==5.6.1 126 | ptyprocess==0.6.0 127 | py==1.8.0 128 | pycodestyle==2.5.0 129 | pycosat==0.6.3 130 | pycparser==2.19 131 | pycrypto==2.6.1 132 | pycurl==7.43.0.2 133 | pyflakes==2.1.1 134 | Pygments==2.3.1 135 | pylint==2.3.1 136 | pyodbc==4.0.26 137 | pyOpenSSL==19.0.0 138 | pyparsing==2.3.1 139 | pyrsistent==0.14.11 140 | PySocks==1.6.8 141 | pytest==4.3.1 142 | pytest-arraydiff==0.3 143 | pytest-astropy==0.5.0 144 | pytest-doctestplus==0.3.0 145 | pytest-openfiles==0.3.2 146 | pytest-remotedata==0.3.1 147 | python-dateutil==2.8.0 148 | pytz==2018.9 149 | PyWavelets==1.0.2 150 | PyYAML==5.1 151 | pyzmq==18.0.0 152 | QtAwesome==0.5.7 153 | qtconsole==4.4.3 154 | QtPy==1.7.0 155 | requests==2.21.0 156 | rope==0.12.0 157 | ruamel-yaml==0.15.46 158 | scikit-image==0.14.2 159 | scikit-learn==0.20.3 160 | scipy==1.2.1 161 | seaborn==0.9.0 162 | Send2Trash==1.5.0 163 | simplegeneric==0.8.1 164 | simplejson==3.16.0 165 | singledispatch==3.4.0.3 166 | six==1.12.0 167 | snowballstemmer==1.2.1 168 | sortedcollections==1.1.2 169 | sortedcontainers==2.1.0 170 | soupsieve==1.8 171 | Sphinx==1.8.5 172 | sphinxcontrib-websupport==1.1.0 173 | spyder==3.3.3 174 | spyder-kernels==0.4.2 175 | SQLAlchemy==1.3.1 176 | statsmodels==0.9.0 177 | sympy==1.3 178 | tables==3.5.1 179 | tblib==1.3.2 180 | terminado==0.8.1 181 | testpath==0.4.2 182 | toolz==0.9.0 183 | tornado==6.0.2 184 | tqdm==4.31.1 185 | traitlets==4.3.2 186 | tushare==1.2.35 187 | unicodecsv==0.14.1 188 | urllib3==1.24.1 189 | wcwidth==0.1.7 190 | webencodings==0.5.1 191 | Werkzeug==0.14.1 192 | widgetsnbextension==3.4.2 193 | wrapt==1.11.1 194 | wurlitzer==1.0.2 195 | xlrd==1.2.0 196 | XlsxWriter==1.1.5 197 | xlwings==0.15.4 198 | xlwt==1.3.0 199 | zict==0.1.4 200 | zipp==0.3.3 201 | --------------------------------------------------------------------------------