siat 3.2.25__py3-none-any.whl → 3.2.31__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siat/__init__ -20240701.py +65 -0
- siat/__init__.py +18 -32
- siat/allin.py +3 -0
- siat/luchy_draw.py +369 -0
- siat/stock_technical.py +37 -30
- {siat-3.2.25.dist-info → siat-3.2.31.dist-info}/METADATA +1 -1
- {siat-3.2.25.dist-info → siat-3.2.31.dist-info}/RECORD +9 -7
- {siat-3.2.25.dist-info → siat-3.2.31.dist-info}/WHEEL +0 -0
- {siat-3.2.25.dist-info → siat-3.2.31.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
功能:一次性引入SIAT的所有模块
|
4
|
+
作者:王德宏,北京外国语大学国际商学院
|
5
|
+
版权:2021-2024(C) 仅限教学使用,商业使用需要授权
|
6
|
+
联络:wdehong2000@163.com
|
7
|
+
"""
|
8
|
+
|
9
|
+
#==============================================================================
|
10
|
+
#屏蔽所有警告性信息
|
11
|
+
import warnings; warnings.filterwarnings('ignore')
|
12
|
+
#==============================================================================
|
13
|
+
from siat.allin import *
|
14
|
+
#==============================================================================
|
15
|
+
#同一命令行多个输出,主要用于Jupyter Notebook
|
16
|
+
from IPython.core.interactiveshell import InteractiveShell
|
17
|
+
InteractiveShell.ast_node_interactivity='all'
|
18
|
+
#==============================================================================
|
19
|
+
# 检查是否存在新版本
|
20
|
+
try:
|
21
|
+
import pkg_resources
|
22
|
+
current_version=pkg_resources.get_distribution("siat").version
|
23
|
+
current_list=current_version.split('.')
|
24
|
+
print("Successfully imported siat version",current_version)
|
25
|
+
|
26
|
+
import luddite
|
27
|
+
latest_version=luddite.get_version_pypi("siat")
|
28
|
+
latest_list=latest_version.split('.')
|
29
|
+
|
30
|
+
newest=True
|
31
|
+
for i in range(3):
|
32
|
+
#print(i)
|
33
|
+
if int(current_list[i]) < int(latest_list[i]):
|
34
|
+
newest=False
|
35
|
+
|
36
|
+
"""
|
37
|
+
if not newest:
|
38
|
+
print("The latest version of siat is",latest_version,'\n')
|
39
|
+
print("*** If you expect to upgrade siat in Anaconda Prompt, use the instruction below:")
|
40
|
+
print(" pip install siat --upgrade")
|
41
|
+
print("*** If you expect to upgrade in Jupyter, add a \'!\' right before the instruction above",'\n')
|
42
|
+
|
43
|
+
print("*** If you encounter incompatible plug-in, try to uninstall siat first and reinstall it:")
|
44
|
+
print(" pip uninstall siat")
|
45
|
+
print(" pip install siat",'\n')
|
46
|
+
|
47
|
+
print("*** If you have a slow internet connection, use an option trailing the instruction above:")
|
48
|
+
print(" -i https://mirrors.aliyun.com/pypi/simple/",'\n')
|
49
|
+
|
50
|
+
print("If you have done any of the above, restart the Python (eg. restarting the kernel)")
|
51
|
+
print("Provided you still need additional help, please contact wdehong2000@163.com")
|
52
|
+
"""
|
53
|
+
if not newest:
|
54
|
+
#print("The latest version of siat is",latest_version,'\n')
|
55
|
+
print("Now there is a newer version of siat",latest_version,'\n')
|
56
|
+
print("*** How to upgrade siat?")
|
57
|
+
print("Upgrade directly from official source? use command: upgrade_siat()")
|
58
|
+
print("Upgrade from Tsinghua? use command: upgrade_siat(alternative='tsinghua')")
|
59
|
+
print("Upgrade from Alibaba? use command: upgrade_siat(alternative='alibaba')")
|
60
|
+
|
61
|
+
except:
|
62
|
+
pass
|
63
|
+
|
64
|
+
|
65
|
+
#==============================================================================
|
siat/__init__.py
CHANGED
@@ -17,46 +17,32 @@ from IPython.core.interactiveshell import InteractiveShell
|
|
17
17
|
InteractiveShell.ast_node_interactivity='all'
|
18
18
|
#==============================================================================
|
19
19
|
# 检查是否存在新版本
|
20
|
+
check_newer_version=False
|
21
|
+
|
20
22
|
try:
|
21
23
|
import pkg_resources
|
22
24
|
current_version=pkg_resources.get_distribution("siat").version
|
23
25
|
current_list=current_version.split('.')
|
24
26
|
print("Successfully imported siat version",current_version)
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
newest=True
|
31
|
-
for i in range(3):
|
32
|
-
#print(i)
|
33
|
-
if int(current_list[i]) < int(latest_list[i]):
|
34
|
-
newest=False
|
35
|
-
|
36
|
-
"""
|
37
|
-
if not newest:
|
38
|
-
print("The latest version of siat is",latest_version,'\n')
|
39
|
-
print("*** If you expect to upgrade siat in Anaconda Prompt, use the instruction below:")
|
40
|
-
print(" pip install siat --upgrade")
|
41
|
-
print("*** If you expect to upgrade in Jupyter, add a \'!\' right before the instruction above",'\n')
|
28
|
+
if check_newer_version:
|
29
|
+
import luddite
|
30
|
+
latest_version=luddite.get_version_pypi("siat")
|
31
|
+
latest_list=latest_version.split('.')
|
42
32
|
|
43
|
-
|
44
|
-
|
45
|
-
|
33
|
+
newest=True
|
34
|
+
for i in range(3):
|
35
|
+
#print(i)
|
36
|
+
if int(current_list[i]) < int(latest_list[i]):
|
37
|
+
newest=False
|
46
38
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
#print("The latest version of siat is",latest_version,'\n')
|
55
|
-
print("Now there is a newer version of siat",latest_version,'\n')
|
56
|
-
print("*** How to upgrade siat?")
|
57
|
-
print("Upgrade directly from official source? use command: upgrade_siat()")
|
58
|
-
print("Upgrade from Tsinghua? use command: upgrade_siat(alternative='tsinghua')")
|
59
|
-
print("Upgrade from Alibaba? use command: upgrade_siat(alternative='alibaba')")
|
39
|
+
if not newest:
|
40
|
+
#print("The latest version of siat is",latest_version,'\n')
|
41
|
+
print("Now there is a newer version of siat",latest_version,'\n')
|
42
|
+
print("*** How to upgrade siat?")
|
43
|
+
print("Upgrade directly from official source? use command: upgrade_siat()")
|
44
|
+
print("Upgrade from Tsinghua? use command: upgrade_siat(alternative='tsinghua')")
|
45
|
+
print("Upgrade from Alibaba? use command: upgrade_siat(alternative='alibaba')")
|
60
46
|
|
61
47
|
except:
|
62
48
|
pass
|
siat/allin.py
CHANGED
siat/luchy_draw.py
ADDED
@@ -0,0 +1,369 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
"""
|
4
|
+
本模块功能:幸运抽奖,仅限课堂案例演示用
|
5
|
+
创建日期:2024年6月29日
|
6
|
+
最新修订日期:
|
7
|
+
作者:王德宏 (WANG Dehong, Peter)
|
8
|
+
作者单位:北京外国语大学国际商学院
|
9
|
+
用途限制:仅限研究与教学使用,不可商用!商用需要额外授权。
|
10
|
+
特别声明:作者不对使用本工具进行证券投资导致的任何损益负责!
|
11
|
+
"""
|
12
|
+
|
13
|
+
#==============================================================================
|
14
|
+
#关闭所有警告
|
15
|
+
import warnings; warnings.filterwarnings('ignore')
|
16
|
+
import warnings; warnings.filterwarnings('ignore')
|
17
|
+
|
18
|
+
import pandas as pd
|
19
|
+
import pickle
|
20
|
+
import random
|
21
|
+
import datetime
|
22
|
+
import time
|
23
|
+
import os
|
24
|
+
from IPython.display import display_html, HTML
|
25
|
+
|
26
|
+
#==============================================================================
|
27
|
+
|
28
|
+
def current_dir(printout=True):
|
29
|
+
"""
|
30
|
+
功能:找出当前路径
|
31
|
+
"""
|
32
|
+
|
33
|
+
current_path = os.getcwd()
|
34
|
+
|
35
|
+
if printout:
|
36
|
+
print(f"[当前工作路径] {current_path}")
|
37
|
+
|
38
|
+
return current_path
|
39
|
+
|
40
|
+
#==============================================================================
|
41
|
+
if __name__=='__main__':
|
42
|
+
file_path="S:\北外工作-24春\小学期-人大\学生名单\student_list.xlsx"
|
43
|
+
pickle_path="student_list.pkl"
|
44
|
+
|
45
|
+
existing(file_path)
|
46
|
+
existing(pickle_path)
|
47
|
+
|
48
|
+
|
49
|
+
def existing(file_path):
|
50
|
+
"""
|
51
|
+
功能:检查文件file_path是否存在,不带路径时检查当前目录
|
52
|
+
"""
|
53
|
+
# 检查文件是否存在
|
54
|
+
if os.path.exists(file_path):
|
55
|
+
if os.path.isfile(file_path):
|
56
|
+
return True
|
57
|
+
else:
|
58
|
+
return False
|
59
|
+
else:
|
60
|
+
return False
|
61
|
+
|
62
|
+
#==============================================================================
|
63
|
+
if __name__=='__main__':
|
64
|
+
text="A B C"
|
65
|
+
text_color='red'
|
66
|
+
text_size=12
|
67
|
+
delay=1
|
68
|
+
|
69
|
+
typewriter(text,text_color='red',text_size=12,delay=1)
|
70
|
+
|
71
|
+
def typewriter(text,text_color='blue',text_size=12,delay=3):
|
72
|
+
from IPython.display import display_html
|
73
|
+
|
74
|
+
time.sleep(delay)
|
75
|
+
|
76
|
+
text_html="<center><font size="+str(text_size)+" color="+text_color+">"+text
|
77
|
+
display_html(text_html, raw=True)
|
78
|
+
|
79
|
+
return
|
80
|
+
|
81
|
+
#==============================================================================
|
82
|
+
|
83
|
+
def pickle_write(df,pickle_path):
|
84
|
+
|
85
|
+
ok2go=True
|
86
|
+
|
87
|
+
prompt="File "+pickle_path+" already exists, overwrite it? [yes/no]"
|
88
|
+
file_exist=existing(pickle_path)
|
89
|
+
if file_exist:
|
90
|
+
yes=read_yes_no(prompt, default=None)
|
91
|
+
if not yes:
|
92
|
+
ok2go=False
|
93
|
+
|
94
|
+
if ok2go:
|
95
|
+
with open(pickle_path, 'wb') as pickle_file:
|
96
|
+
# 使用pickle模块的dump函数写入对象
|
97
|
+
pickle.dump(df,pickle_file)
|
98
|
+
|
99
|
+
return
|
100
|
+
|
101
|
+
if __name__=='__main__':
|
102
|
+
course="SICS RUC24"
|
103
|
+
file_path="S:\北外工作-24春\小学期-人大\学生名单\student_list.xlsx"
|
104
|
+
pickle_path="student_list.pkl"
|
105
|
+
skiprows=1
|
106
|
+
column='Name'
|
107
|
+
|
108
|
+
draw_limit=2
|
109
|
+
absent_limit=2
|
110
|
+
pass_limit=2
|
111
|
+
|
112
|
+
lucky_draw_header_create(course,file_path, \
|
113
|
+
skiprows=1,column='Name',draw_limit=2, \
|
114
|
+
absent_limit=2,pass_limit=2)
|
115
|
+
pickle_read(pickle_path=course+' header.pkl')
|
116
|
+
|
117
|
+
|
118
|
+
def lucky_draw_header_create(course,file_path, \
|
119
|
+
skiprows=1,column='Name',draw_limit=2, \
|
120
|
+
absent_limit=2,pass_limit=2):
|
121
|
+
|
122
|
+
pickle_path=course+" header.pkl"
|
123
|
+
|
124
|
+
header_dict={'course':course,'file_path':file_path,'pickle_path':pickle_path, \
|
125
|
+
'skiprows':skiprows,'column':column,'draw_limit':draw_limit, \
|
126
|
+
'absent_limit':absent_limit,'pass_limit':pass_limit}
|
127
|
+
|
128
|
+
pickle_write(header_dict,pickle_path)
|
129
|
+
|
130
|
+
return
|
131
|
+
|
132
|
+
def lucky_draw_header_modify(course,file_path="current", \
|
133
|
+
skiprows=="current",column=="current",draw_limit=="current", \
|
134
|
+
absent_limit=="current",pass_limit=="current"):
|
135
|
+
|
136
|
+
pickle_path=course+" header.pkl"
|
137
|
+
header_dict=pickle_read(pickle_path)
|
138
|
+
|
139
|
+
if file_path !='current':
|
140
|
+
header_dict['file_path']=file_path
|
141
|
+
else:
|
142
|
+
file_path=header_dict['file_path']
|
143
|
+
|
144
|
+
if skiprows !='current':
|
145
|
+
header_dict['skiprows']=skiprows
|
146
|
+
else:
|
147
|
+
skiprows=header_dict['skiprows']
|
148
|
+
|
149
|
+
if column !='current':
|
150
|
+
header_dict['column']=column
|
151
|
+
else:
|
152
|
+
column=header_dict['column']
|
153
|
+
|
154
|
+
if draw_limit !='current':
|
155
|
+
header_dict['draw_limit']=draw_limit
|
156
|
+
else:
|
157
|
+
draw_limit=header_dict['draw_limit']
|
158
|
+
|
159
|
+
if absent_limit !='current':
|
160
|
+
header_dict['absent_limit']=absent_limit
|
161
|
+
else:
|
162
|
+
absent_limit=header_dict['absent_limit']
|
163
|
+
|
164
|
+
if pass_limit !='current':
|
165
|
+
header_dict['pass_limit']=pass_limit
|
166
|
+
else:
|
167
|
+
pass_limit=header_dict['pass_limit']
|
168
|
+
|
169
|
+
header_dict={'course':course,'file_path':file_path,'pickle_path':pickle_path, \
|
170
|
+
'skiprows':skiprows,'column':column,'draw_limit':draw_limit, \
|
171
|
+
'absent_limit':absent_limit,'pass_limit':pass_limit}
|
172
|
+
|
173
|
+
pickle_write(header_dict,pickle_path)
|
174
|
+
|
175
|
+
return
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
lucky_draw_initialize(file_path,skiprows=1,column='Name',pickle_path="student_list.pkl")
|
181
|
+
|
182
|
+
def lucky_draw_initialize(file_path,skiprows=1,column='Name',pickle_path="student_list.pkl"):
|
183
|
+
"""
|
184
|
+
功能:读入带有指定路径的Excel文件file_path,跳过前skiprows行
|
185
|
+
Excel文件结构:抽奖名单字段为'Name',字段位于第2行
|
186
|
+
输出:存入pickle文件student_list.pkl
|
187
|
+
"""
|
188
|
+
|
189
|
+
df = pd.read_excel(file_path,skiprows=skiprows)
|
190
|
+
|
191
|
+
df1=df[[column]].copy()
|
192
|
+
|
193
|
+
todaydt = str(datetime.date.today())
|
194
|
+
df1['Date']=todaydt
|
195
|
+
df1['Lucky']=0
|
196
|
+
df1['Absent']=0
|
197
|
+
df1['Answer']=0
|
198
|
+
|
199
|
+
#排序
|
200
|
+
df1.sort_values(by=[column,'Date','Lucky','Absent','Answer'],inplace=True)
|
201
|
+
df1.reset_index(drop=True,inplace=True)
|
202
|
+
|
203
|
+
pickle_write(df1,pickle_path)
|
204
|
+
|
205
|
+
return
|
206
|
+
|
207
|
+
#==============================================================================
|
208
|
+
if __name__=='__main__':
|
209
|
+
pickle_path="student_list.pkl"
|
210
|
+
|
211
|
+
df=pickle_read(pickle_path)
|
212
|
+
|
213
|
+
def pickle_read(pickle_path="student_list.pkl"):
|
214
|
+
with open(pickle_path,'rb') as pickle_file:
|
215
|
+
df = pickle.load(pickle_file)
|
216
|
+
return df
|
217
|
+
|
218
|
+
#==============================================================================
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
|
223
|
+
#==============================================================================
|
224
|
+
if __name__=='__main__':
|
225
|
+
alist=["A","B","C","D"]
|
226
|
+
|
227
|
+
for i in range(4):
|
228
|
+
print(random_select(alist))
|
229
|
+
|
230
|
+
|
231
|
+
def random_select(alist):
|
232
|
+
return random.choice(alist)
|
233
|
+
|
234
|
+
#==============================================================================
|
235
|
+
|
236
|
+
if __name__=='__main__':
|
237
|
+
prompt="Is the lucky person here in class?"
|
238
|
+
|
239
|
+
read_yes_no(prompt)
|
240
|
+
|
241
|
+
|
242
|
+
def read_yes_no(prompt, default=None):
|
243
|
+
if default is None:
|
244
|
+
prompt += " [yes/no] "
|
245
|
+
else:
|
246
|
+
prompt += " [yes/no] (default: %s) " % ('yes' if default else 'no')
|
247
|
+
while True:
|
248
|
+
user_input = input(prompt).lower()
|
249
|
+
if user_input in ['', 'yes', 'y', 'true']:
|
250
|
+
return True
|
251
|
+
elif user_input in ['no', 'n', 'false']:
|
252
|
+
return False
|
253
|
+
elif user_input == '' and default is not None:
|
254
|
+
return default
|
255
|
+
else:
|
256
|
+
print("Please enter 'yes' or 'no' (or 'y'/'n').")
|
257
|
+
|
258
|
+
return
|
259
|
+
|
260
|
+
#==============================================================================
|
261
|
+
if __name__=='__main__':
|
262
|
+
draw_limit=2
|
263
|
+
absent_limit=2
|
264
|
+
column='Name'
|
265
|
+
pickle_path="student_list.pkl"
|
266
|
+
|
267
|
+
lucky_draw()
|
268
|
+
df=pickle_read(pickle_path)
|
269
|
+
|
270
|
+
|
271
|
+
def lucky_draw(draw_limit=2,absent_limit=2,column='Name',pickle_path="student_list.pkl"):
|
272
|
+
"""
|
273
|
+
draw_limit=2:整个课程每人最多2次抽签机会
|
274
|
+
absent_limit=2:整个课程每人最多缺席2次,超过就丧失抽签资格
|
275
|
+
"""
|
276
|
+
df=pickle_read(pickle_path)
|
277
|
+
|
278
|
+
alist=list(set(list(df[column])))
|
279
|
+
|
280
|
+
found=False
|
281
|
+
todaydt = str(datetime.date.today())
|
282
|
+
prompt="*** Is the lucky person here on site?"
|
283
|
+
prompt2="*** Do you expect to pass?"
|
284
|
+
|
285
|
+
while True:
|
286
|
+
while True:
|
287
|
+
aname=random_select(alist)
|
288
|
+
|
289
|
+
adf=df[df[column]==aname]
|
290
|
+
atimes=adf['Lucky'].sum()
|
291
|
+
aonsite=adf['Absent'].sum()
|
292
|
+
|
293
|
+
if atimes < draw_limit and aonsite <= absent_limit:
|
294
|
+
#检查今日是否被抽中过
|
295
|
+
drew_today=False
|
296
|
+
try:
|
297
|
+
adf_today=adf[adf['Date']==todaydt]
|
298
|
+
if len(adf_today) > 0:
|
299
|
+
if adf_today['Lucky'].sum() > 0 or adf_today['Absent'].sum() > 0:
|
300
|
+
drew_today=True
|
301
|
+
except: pass
|
302
|
+
|
303
|
+
if not drew_today:
|
304
|
+
found=True
|
305
|
+
break
|
306
|
+
else: continue
|
307
|
+
else:
|
308
|
+
continue
|
309
|
+
|
310
|
+
if not found:
|
311
|
+
print("Congratulations! all person has been lucky for",limit,"times")
|
312
|
+
else:
|
313
|
+
"""
|
314
|
+
print("\nThe lucky person is ",end='')
|
315
|
+
typewriter(aname,delay=1)
|
316
|
+
"""
|
317
|
+
typewriter(text=aname,text_color='blue',text_size=12,delay=1)
|
318
|
+
|
319
|
+
#print('')
|
320
|
+
onsite=read_yes_no(prompt)
|
321
|
+
#是否到场
|
322
|
+
if onsite: absent=0
|
323
|
+
else: absent=1
|
324
|
+
|
325
|
+
onpass=False; answer=0
|
326
|
+
if onsite:
|
327
|
+
onpass=read_yes_no(prompt2)
|
328
|
+
#是否pass
|
329
|
+
if onpass: answer=0
|
330
|
+
else: answer=1
|
331
|
+
|
332
|
+
#只要抽中,不论是否到场都记录
|
333
|
+
row=pd.Series({column:aname,'Date':todaydt,'Lucky':1,'Absent':absent,'Answer':answer})
|
334
|
+
try:
|
335
|
+
df=df.append(row,ignore_index=True)
|
336
|
+
except:
|
337
|
+
df=df._append(row,ignore_index=True)
|
338
|
+
|
339
|
+
if onsite and not onpass:
|
340
|
+
#到场且不pass,结束本轮抽签
|
341
|
+
break
|
342
|
+
else:
|
343
|
+
#未到场或pass,继续抽签
|
344
|
+
continue
|
345
|
+
|
346
|
+
df.sort_values(by=[column,'Date'],inplace=True)
|
347
|
+
pickle_write(df,pickle_path)
|
348
|
+
|
349
|
+
return
|
350
|
+
|
351
|
+
#==============================================================================
|
352
|
+
#==============================================================================
|
353
|
+
#==============================================================================
|
354
|
+
#==============================================================================
|
355
|
+
|
356
|
+
|
357
|
+
|
358
|
+
|
359
|
+
|
360
|
+
|
361
|
+
|
362
|
+
|
363
|
+
|
364
|
+
|
365
|
+
#==============================================================================#==============================================================================
|
366
|
+
#==============================================================================#==============================================================================
|
367
|
+
#==============================================================================#==============================================================================
|
368
|
+
|
369
|
+
#==============================================================================
|
siat/stock_technical.py
CHANGED
@@ -188,8 +188,10 @@ def calc_technical(df,start,end,technical='MACD', \
|
|
188
188
|
ROC_day=12,ROC_madays=[6], \
|
189
189
|
DMI_DIdays=[14],DMI_ADXdays=[6], \
|
190
190
|
|
191
|
-
MFI_day=14,MFI_madays=[
|
192
|
-
|
191
|
+
MFI_day=14,MFI_madays=[6], \
|
192
|
+
|
193
|
+
#提出选择12日或25日,移动均线为10日
|
194
|
+
MOM_day=12,MOM_madays=6, \
|
193
195
|
|
194
196
|
#需要显示SAR
|
195
197
|
SAR_day=4,SAR_madays=[5,20], \
|
@@ -201,7 +203,7 @@ def calc_technical(df,start,end,technical='MACD', \
|
|
201
203
|
TSF_day=14,TSF_madays=[5,20], \
|
202
204
|
|
203
205
|
#需要显示AD
|
204
|
-
|
206
|
+
AD_madays=[5], \
|
205
207
|
|
206
208
|
#不建议使用复权价,因为最高最低价和开盘价没有复权价!
|
207
209
|
indicator='Close', \
|
@@ -586,11 +588,11 @@ def calc_technical(df,start,end,technical='MACD', \
|
|
586
588
|
TRIX_madays=[TRIX_madays]
|
587
589
|
for d in TRIX_madays:
|
588
590
|
df['trix_ma'+str(d)] = talib.MA(df['trix'],timeperiod=d)
|
589
|
-
|
591
|
+
"""
|
590
592
|
if not more_details:
|
591
593
|
#不保留TRIX
|
592
594
|
df.drop(columns = ['trix'],inplace=True)
|
593
|
-
|
595
|
+
"""
|
594
596
|
#=========== DMA: 平均线差
|
595
597
|
"""
|
596
598
|
计算公式:
|
@@ -744,11 +746,11 @@ def calc_technical(df,start,end,technical='MACD', \
|
|
744
746
|
MFI_madays=[MFI_madays]
|
745
747
|
for d in MFI_madays:
|
746
748
|
df['mfi_ma'+str(d)] = df['mfi'].rolling(window=d).mean()
|
747
|
-
|
749
|
+
"""
|
748
750
|
if not more_details:
|
749
751
|
#不保留指标本身
|
750
752
|
df.drop(columns = ['mfi'],inplace=True)
|
751
|
-
|
753
|
+
"""
|
752
754
|
#=========== MOM:动量指标
|
753
755
|
"""
|
754
756
|
|
@@ -760,11 +762,11 @@ def calc_technical(df,start,end,technical='MACD', \
|
|
760
762
|
MOM_madays=[MOM_madays]
|
761
763
|
for d in MOM_madays:
|
762
764
|
df['mom_ma'+str(d)] = df['mom'].rolling(window=d).mean()
|
763
|
-
|
765
|
+
"""
|
764
766
|
if not more_details:
|
765
767
|
#不保留指标本身
|
766
768
|
df.drop(columns = ['mom'],inplace=True)
|
767
|
-
|
769
|
+
"""
|
768
770
|
#=========== BETA:贝塔系数
|
769
771
|
"""
|
770
772
|
动态贝塔系数?
|
@@ -805,18 +807,17 @@ def calc_technical(df,start,end,technical='MACD', \
|
|
805
807
|
"""
|
806
808
|
if technical=='AD':
|
807
809
|
|
808
|
-
#df['ad'] = talib.AD(df['High'],df['Low'],df[indicator],df['Volume'],timeperiod=AD_day)
|
809
810
|
df['ad'] = talib.AD(df['High'],df['Low'],df[indicator],df['Volume'])
|
810
811
|
|
811
812
|
if not isinstance(AD_madays,list):
|
812
813
|
AD_madays=[AD_madays]
|
813
814
|
for d in AD_madays:
|
814
815
|
df['ad_ma'+str(d)] = df['ad'].rolling(window=d).mean()
|
815
|
-
|
816
|
+
"""
|
816
817
|
if not more_details:
|
817
818
|
#不保留指标本身
|
818
819
|
df.drop(columns = ['ad'],inplace=True)
|
819
|
-
|
820
|
+
"""
|
820
821
|
|
821
822
|
|
822
823
|
#过滤日期===================================================================
|
@@ -2620,12 +2621,12 @@ if __name__ =="__main__":
|
|
2620
2621
|
WR_days=[10,6]
|
2621
2622
|
ROC_day=12; ROC_madays=6
|
2622
2623
|
DMI_DIdays=14; DMI_ADXdays=6
|
2623
|
-
MFI_day=14; MFI_madays=[
|
2624
|
-
MOM_day=
|
2624
|
+
MFI_day=14; MFI_madays=[6]
|
2625
|
+
MOM_day=12; MOM_madays=6
|
2625
2626
|
SAR_day=4; SAR_madays=[5,20]
|
2626
2627
|
BETA_day=5; BETA_madays=[5,20]
|
2627
2628
|
TSF_day=14; TSF_madays=[5,10]
|
2628
|
-
|
2629
|
+
AD_madays=[5]
|
2629
2630
|
|
2630
2631
|
|
2631
2632
|
ticker='002594.SZ';ticker_type='auto'
|
@@ -2691,7 +2692,7 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
2691
2692
|
|
2692
2693
|
DMA_fastperiod=10,DMA_slowperiod=50,DMA_madays=[10], \
|
2693
2694
|
|
2694
|
-
TRIX_day=12,TRIX_madays=[
|
2695
|
+
TRIX_day=12,TRIX_madays=[20], \
|
2695
2696
|
|
2696
2697
|
BIAS_days=[6,12,24], \
|
2697
2698
|
|
@@ -2703,9 +2704,10 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
2703
2704
|
|
2704
2705
|
DMI_DIdays=7,DMI_ADXdays=6, \
|
2705
2706
|
|
2706
|
-
#资金流:
|
2707
|
-
MFI_day=14,MFI_madays=[
|
2708
|
-
|
2707
|
+
#资金流:
|
2708
|
+
MFI_day=14,MFI_madays=[6], \
|
2709
|
+
|
2710
|
+
MOM_day=12,MOM_madays=6, \
|
2709
2711
|
|
2710
2712
|
#需要显示SAR
|
2711
2713
|
SAR_day=4,SAR_madays=[5,20], \
|
@@ -2717,7 +2719,7 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
2717
2719
|
TSF_day=14,TSF_madays=[5,10], \
|
2718
2720
|
|
2719
2721
|
#需要显示AD
|
2720
|
-
|
2722
|
+
AD_madays=[], \
|
2721
2723
|
|
2722
2724
|
#数据提前量,用于前置计算指标的移动平均值
|
2723
2725
|
ahead_days=30*8, \
|
@@ -2739,11 +2741,11 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
2739
2741
|
|
2740
2742
|
#价格线的绘图参数
|
2741
2743
|
#price_line_style=(0,(1,1)), \
|
2742
|
-
price_line_style=
|
2744
|
+
price_line_style=(0,(3,1,1,1,1,1)), \
|
2743
2745
|
price_line_color=['red','green'], \
|
2744
2746
|
price_line_width=1,price_line_marker='o', \
|
2745
2747
|
marker_sizes=[30,120,250], \
|
2746
|
-
|
2748
|
+
):
|
2747
2749
|
"""
|
2748
2750
|
功能:计算和绘制证券技术分析指标的简易图,仅供进一步探索使用,仅用于单个证券(股债基)
|
2749
2751
|
|
@@ -2867,7 +2869,7 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
2867
2869
|
TSF_day=TSF_day,TSF_madays=TSF_madays, \
|
2868
2870
|
|
2869
2871
|
#需要显示AD
|
2870
|
-
|
2872
|
+
AD_madays=AD_madays, \
|
2871
2873
|
|
2872
2874
|
indicator=indicator, \
|
2873
2875
|
more_details=more_details)
|
@@ -3007,6 +3009,9 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
3007
3009
|
ax3.set_facecolor('papayawhip')
|
3008
3010
|
|
3009
3011
|
color_list=['k','g','b','c','m','yellowgreen','tomato','lime','orange','deepskyblue']
|
3012
|
+
|
3013
|
+
if isinstance(attention_values,int):
|
3014
|
+
attention_values=[attention_values]
|
3010
3015
|
attention_draws=[False] * len(attention_values)
|
3011
3016
|
|
3012
3017
|
for l in tech_line_collist:
|
@@ -3037,7 +3042,7 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
3037
3042
|
xy=(x_end, y_end),
|
3038
3043
|
xytext=(x_end, y_end),color=last_line_color)
|
3039
3044
|
"""
|
3040
|
-
ax.annotate(text='
|
3045
|
+
ax.annotate(text=''+l.upper(),
|
3041
3046
|
xy=(x_end, y_end),
|
3042
3047
|
xytext=(x_end, y_end),color=last_line_color,fontsize=legend_txt_size)
|
3043
3048
|
|
@@ -3053,7 +3058,7 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
3053
3058
|
|
3054
3059
|
#如果需要绘制关注线,且尚未绘制过,则绘制
|
3055
3060
|
if line_al and not attention_draws[pos]:
|
3056
|
-
ax.axhline(y=attention_values[pos],ls=
|
3061
|
+
ax.axhline(y=attention_values[pos],ls='dotted',c=color_list[pos],linewidth=1)
|
3057
3062
|
|
3058
3063
|
attention_draws[pos]=True
|
3059
3064
|
|
@@ -3109,8 +3114,8 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
3109
3114
|
ax2.set_ylabel(ylabeltxt2,fontsize=ylabel_txt_size)
|
3110
3115
|
|
3111
3116
|
#细灰线先画出轮廓
|
3112
|
-
ax2.plot(df1.index,df1[indicator],label=
|
3113
|
-
linestyle=price_line_style,color='
|
3117
|
+
ax2.plot(df1.index,df1[indicator],label=ylabeltxt2, \
|
3118
|
+
linestyle=price_line_style,color='k',lw=2)
|
3114
3119
|
|
3115
3120
|
#不同颜色绘制涨跌价格线
|
3116
3121
|
first_time=True; second_time=False
|
@@ -3119,11 +3124,13 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
3119
3124
|
if df1seg['up_down'].values[0] >=0:
|
3120
3125
|
seg_color=price_line_color1
|
3121
3126
|
#labeltxt=ylabeltxt2+'(当日↑)'
|
3122
|
-
labeltxt=ylabeltxt2+'(当日阳线)'
|
3127
|
+
#labeltxt=ylabeltxt2+'(当日阳线)'
|
3128
|
+
labeltxt='当日↑'
|
3123
3129
|
else:
|
3124
3130
|
seg_color=price_line_color2
|
3125
3131
|
#labeltxt=ylabeltxt2+'(当日↓)'
|
3126
|
-
labeltxt=ylabeltxt2+'(当日阴线)'
|
3132
|
+
#labeltxt=ylabeltxt2+'(当日阴线)'
|
3133
|
+
labeltxt='当日↓'
|
3127
3134
|
|
3128
3135
|
if first_time:
|
3129
3136
|
first_time=False; second_time=True
|
@@ -3135,7 +3142,7 @@ def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
|
3135
3142
|
ax2.scatter(df1seg.index,df1seg[indicator], \
|
3136
3143
|
s=df1seg['marker_size'], \
|
3137
3144
|
label=labeltxt, \
|
3138
|
-
linestyle=':',color=seg_color,lw=price_line_width,marker=price_line_marker)
|
3145
|
+
linestyle=':',color=seg_color,lw=price_line_width,marker=price_line_marker,alpha=0.5)
|
3139
3146
|
|
3140
3147
|
ax2.legend(loc=loc2,fontsize=legend_txt_size)
|
3141
3148
|
|
@@ -1,5 +1,6 @@
|
|
1
|
-
siat/__init__.py,sha256=gP5uajXnJesnH5SL0ZPwq_Qhv59AG1bs4qwZv26Fo2Y,2894
|
2
|
-
siat/
|
1
|
+
siat/__init__ -20240701.py,sha256=gP5uajXnJesnH5SL0ZPwq_Qhv59AG1bs4qwZv26Fo2Y,2894
|
2
|
+
siat/__init__.py,sha256=NJn2HSa0cdet21YFoJs5nafHgrM3H3J3wdtFYi1KzfM,2065
|
3
|
+
siat/allin.py,sha256=f8mlMSQJUgx4mRVOJNlHH2SZP0jUyWaeDPT2V6AGfY8,2757
|
3
4
|
siat/alpha_vantage_test.py,sha256=tKr-vmuFH3CZAqwmISz6jzjPHzV1JJl3sPfZdz8aTfM,747
|
4
5
|
siat/assets_liquidity.py,sha256=o_UZdLs693uNWPEQB2OzxDH0mdWimOmq4qe_vx1pue0,28987
|
5
6
|
siat/assets_liquidity_test.py,sha256=UWk6HIUlizU7LQZ890fGx8LwU1jMMrIZswg8cFUJWZ8,1285
|
@@ -64,6 +65,7 @@ siat/grafix_test.py,sha256=kXvcpLgQNO7wd30g_bWljLj5UH7bIVI0_dUtXbfiKR0,3150
|
|
64
65
|
siat/holding_risk.py,sha256=G3wpaewAKF9CwEqRpr4khyuDu9SU2EGyQUHdk7cmHOA,30693
|
65
66
|
siat/holding_risk_test.py,sha256=FRlw_9wFG98BYcg_cSj95HX5WZ1TvkGaOUdXD7-V86s,474
|
66
67
|
siat/local_debug_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
|
68
|
+
siat/luchy_draw.py,sha256=d4Ga2KqbF0nBv4P6GQBSRe2vq3S55G2B0HtKuEJJzyo,11699
|
67
69
|
siat/market_china.py,sha256=hKoTLUyHuzsuG2L3_IuLx_utTKqS-__mZ63wrElh65U,45943
|
68
70
|
siat/markowitz.py,sha256=glHikhabFAF6Hb6df1pYfhkxid2IZXBYAVQng5wd9Wk,97526
|
69
71
|
siat/markowitz2-20240620.py,sha256=irZAPnjaatFsKQmFRMENP-cO6bEUl2narYtkU5NKTWI,108019
|
@@ -115,7 +117,7 @@ siat/stock_prices_kneighbors.py,sha256=WfZvo5EyeBsm-T37zDj7Sl9dPSRq5Bx4JxIJ9IUum
|
|
115
117
|
siat/stock_prices_linear.py,sha256=-OUKRr27L2aStQgJSlJOrJ4gay_G7P-m-7t7cU2Yoqk,13991
|
116
118
|
siat/stock_profile.py,sha256=B3eIwzEmiCqiCaxIlhfdEPsQBoW1PFOe1hkiY3mVF6Y,26038
|
117
119
|
siat/stock_technical-20240620.py,sha256=A4x18mZgYSA8SSiDz4u_O3gd5oVRgbI6JIiBfFY0tVw,116013
|
118
|
-
siat/stock_technical.py,sha256=
|
120
|
+
siat/stock_technical.py,sha256=GPedxbOSPTi8zthDMu69edFVLES2RSNor2a1y8Zo42w,131612
|
119
121
|
siat/stock_test.py,sha256=E9YJAvOw1VEGJSDI4IZuEjl0tGoisOIlN-g9UqA_IZE,19475
|
120
122
|
siat/stooq.py,sha256=dOc_S5HLrYg48YAKTCs1eX8UTJOOkPM8qLL2KupqlLY,2470
|
121
123
|
siat/temp.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
@@ -136,7 +138,7 @@ siat/valuation.py,sha256=NKfeZMdDJOW42oLVHob6eSVBXUqlN1OCnnzwyGAst8c,48855
|
|
136
138
|
siat/valuation_china.py,sha256=EkZQaVkoBjM0c4MCNbaX-bMnlG0e3FXeaWczZDnkptU,67784
|
137
139
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
138
140
|
siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
|
139
|
-
siat-3.2.
|
140
|
-
siat-3.2.
|
141
|
-
siat-3.2.
|
142
|
-
siat-3.2.
|
141
|
+
siat-3.2.31.dist-info/METADATA,sha256=acxPalewEFV2nyg0ZetnYmjlFyvjL5X9S4UCVjjcJss,7234
|
142
|
+
siat-3.2.31.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
143
|
+
siat-3.2.31.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
144
|
+
siat-3.2.31.dist-info/RECORD,,
|
File without changes
|
File without changes
|