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.
@@ -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
- 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')
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
- 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')
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
- 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')")
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
@@ -120,3 +120,6 @@ from siat.stock_technical import *
120
120
  # 2FA: Google Authenticator
121
121
  from siat.google_authenticator import *
122
122
 
123
+ # 提问记录
124
+ from siat.luchy_draw import *
125
+
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=[14], \
192
- MOM_day=10,MOM_madays=[10], \
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
- AD_day=26,AD_madays=[5,20], \
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=[3,5]
2624
- MOM_day=10; MOM_madays=[5,20]
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
- AD_day=26; AD_madays=[5,20]
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=[5,10], \
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
- #资金流:3日作为信号,5日作为确认信号
2707
- MFI_day=14,MFI_madays=[3,5], \
2708
- MOM_day=10,MOM_madays=[5,20], \
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
- AD_day=26,AD_madays=[5,20], \
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='dotted', \
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
- AD_day=AD_day,AD_madays=AD_madays, \
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=' '+l.upper(),
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=":",c=color_list[pos],linewidth=2)
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='grey',lw=2)
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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.2.25
3
+ Version: 3.2.31
4
4
  Summary: Securities Investment Analysis Tools (siat)
5
5
  Home-page: https://pypi.org/project/siat/
6
6
  Author: Prof. WANG Dehong, International Business School, Beijing Foreign Studies University
@@ -1,5 +1,6 @@
1
- siat/__init__.py,sha256=gP5uajXnJesnH5SL0ZPwq_Qhv59AG1bs4qwZv26Fo2Y,2894
2
- siat/allin.py,sha256=f1VWxZLvPLR57ilk9GOziZMWjyAYOYLXbvQI4z38r50,2708
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=DYSewOV9kRTusA3PX37BVbLQuo3qAeJML_qmEljXcAc,131491
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.25.dist-info/METADATA,sha256=rrntA_Rsj1bjBtLPjAssepn-I-IYK1cxL7eAMMHDgmU,7234
140
- siat-3.2.25.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
141
- siat-3.2.25.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
142
- siat-3.2.25.dist-info/RECORD,,
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