siat 2.14.2__py3-none-any.whl → 3.0.1__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/common.py CHANGED
@@ -16,11 +16,11 @@ SIAT:Security Investment Analysis Tool
16
16
  #==============================================================================
17
17
  #关闭所有警告
18
18
  import warnings; warnings.filterwarnings('ignore')
19
-
20
- #==============================================================================
21
- SUFFIX_LIST_CN=['SS','SZ','BJ','NQ']
22
19
  import pandas as pd
23
20
  #==============================================================================
21
+ SUFFIX_LIST_CN=['SS','SZ','BJ','SW','SH']
22
+ SUFFIX_LIST_HK=['HK']
23
+ #==============================================================================
24
24
  #设置全局语言环境
25
25
  import pickle
26
26
 
@@ -239,19 +239,26 @@ def check_period(fromdate, todate):
239
239
  try:
240
240
  start=pd.to_datetime(fromdate)
241
241
  except:
242
- print("*** #Error(check_period), invalid date:",fromdate)
242
+ print(" #Error(check_period), invalid date:",fromdate)
243
+ return None, None, None
244
+
245
+ #开始日期不能晚于今日
246
+ import datetime
247
+ todaydt = pd.to_datetime(datetime.date.today())
248
+ if start > todaydt:
249
+ print(" #Error(check_period), invalid start date:",fromdate)
243
250
  return None, None, None
244
251
 
245
252
  #测试结束日期的合理性
246
253
  try:
247
254
  end=pd.to_datetime(todate)
248
255
  except:
249
- print(" #Error(check_period): invalid date:",todate)
256
+ print(" #Error(check_period): invalid date:",todate)
250
257
  return None, None, None
251
258
 
252
259
  #测试日期期间的合理性
253
260
  if start > end:
254
- print(" #Error(check_period): invalid period: from",fromdate,"to",todate)
261
+ print(" #Error(check_period): invalid period: from",fromdate,"to",todate)
255
262
  return None, None, None
256
263
 
257
264
  return True, start, end
@@ -417,6 +424,8 @@ def date_adjust2(basedate,adjust_year=0,adjust_month=0,adjust_day=0, \
417
424
  #==============================================================================
418
425
  if __name__ =="__main__":
419
426
  portfolio={'Market':('US','^GSPC'),'EDU':0.4,'TAL':0.3,'TEDU':0.2}
427
+
428
+ portfolio={'Market':('China','000001.SS','股债基组合'),'600519.SS':50,'sh010504':150,'sh010504':300}
420
429
 
421
430
  def decompose_portfolio(portfolio):
422
431
  """
@@ -426,7 +435,7 @@ def decompose_portfolio(portfolio):
426
435
  输出:市场,市场指数,股票代码列表和份额列表
427
436
  """
428
437
  #从字典中提取信息
429
- keylist=list(portfolio.keys())
438
+ keylist=list(portfolio.keys()) #注意:字典中相同的键会被合并为一个
430
439
  scope=portfolio[keylist[0]][0]
431
440
  mktidx=portfolio[keylist[0]][1]
432
441
 
@@ -1468,7 +1477,7 @@ if __name__=='__main__':
1468
1477
  _,_,tickerlist,sharelist=decompose_portfolio(portfolio)
1469
1478
  leading_blanks=2
1470
1479
 
1471
- def print_tickerlist_sharelist(tickerlist,sharelist,leading_blanks=2):
1480
+ def print_tickerlist_sharelist(tickerlist,sharelist,leading_blanks=2,ticker_type='auto'):
1472
1481
  """
1473
1482
  功能:纵向打印投资组合的成分股和持股比例
1474
1483
  输入:
@@ -1494,12 +1503,16 @@ def print_tickerlist_sharelist(tickerlist,sharelist,leading_blanks=2):
1494
1503
  sharelist_array = np.array(sharelist)
1495
1504
  total_shares=sharelist_array.sum()
1496
1505
  weights=sharelist_array/total_shares
1506
+
1507
+ #预处理ticker_type
1508
+ ticker_type_list=ticker_type_preprocess_mticker_mixed(tickerlist,ticker_type)
1497
1509
 
1498
1510
  import pandas as pd
1499
1511
  df=pd.DataFrame(columns=['证券代码','证券名称','持仓比例'])
1500
1512
  for t in tickerlist:
1501
1513
  pos=tickerlist.index(t)
1502
- tname=codetranslate(t)
1514
+ tt=ticker_type_list[pos]
1515
+ tname=ticker_name(t,tt)
1503
1516
  tweight=weights[pos]
1504
1517
 
1505
1518
  row=pd.Series({'证券代码':t,'证券名称':tname,'持仓比例':tweight})
@@ -2841,12 +2854,66 @@ def fix_package(file='stooq.py',package='pandas_datareader'):
2841
2854
  print(" Please RESTART your Python kernel before continue to use siat")
2842
2855
 
2843
2856
  return
2857
+
2858
+ #==============================================================================
2859
+ if __name__=='__main__':
2860
+ file='stock_info.pickle'
2861
+ package='siat'
2862
+ developer=False
2863
+
2864
+ file_position()
2865
+
2866
+ def file_position(file='stock_info.pickle',package='siat',mode='read'):
2867
+ """
2868
+ 功能:给定文件名file,返回其路径
2869
+ 注意:执行本程序可能需要系统管理员权限,可以系统管理员权限启动Jupyter或Spyder
2870
+
2871
+ 改进:建立一个Excel文件,记录需要修复的文件和包,例如:
2872
+ file package
2873
+ stooq.py pandas_datareader
2874
+ bond_zh_sina.py akshare
2875
+
2876
+ """
2877
+ #判断操作系统
2878
+ import sys; czxt=sys.platform
2879
+ if czxt in ['win32','win64']:
2880
+ os='windows'
2881
+ elif czxt in ['darwin']: #MacOSX
2882
+ os='mac'
2883
+ elif czxt in ['linux']: #linux
2884
+ os='linux'
2885
+ else:
2886
+ os='windows'
2887
+
2888
+ #目标地址
2889
+ cmdstr1='import '+package
2890
+ exec(cmdstr1) #无返回值地执行字符串代码
2891
+ #import pandas_datareader
2892
+ #objpath=pandas_datareader.__path__[0]
2893
+ cmdstr2=package+'.__path__[0]'
2894
+ objpath=eval(cmdstr2) #有返回值地执行字符串代码
2844
2895
 
2896
+ if os == 'windows':
2897
+ objpath1=objpath.replace("\\",'/')
2898
+ objfile=objpath1+'/'+file
2899
+ else:
2900
+ objpath1=objpath
2901
+ objfile=objpath1+'/'+file
2902
+
2903
+ if mode=='read':
2904
+ with open(objfile,'rb') as test:
2905
+ df = pickle.load(test)
2906
+ return df
2907
+ else:
2908
+ return objfile
2909
+ #==============================================================================
2910
+
2911
+
2845
2912
  #==============================================================================
2846
2913
  #==============================================================================
2847
2914
 
2848
- def df_preprocess(dfs,measure,axhline_label,x_label,y_label,lang='Chinese', \
2849
- preprocess='scaling',scaling_option='start'):
2915
+ def df_preprocess(dfs,measure,axhline_label,x_label,y_label, \
2916
+ preprocess='scaling',scaling_option='change%'):
2850
2917
  """
2851
2918
  功能:对于dfs中的数据进行预处理变换,以便克服数量级压制现象更好地展现多条曲线的趋势
2852
2919
  """
@@ -2862,9 +2929,6 @@ def df_preprocess(dfs,measure,axhline_label,x_label,y_label,lang='Chinese', \
2862
2929
  meanlist=[]
2863
2930
  for c in collist:
2864
2931
 
2865
- # 去掉缺失值
2866
- #dfs2[c].dropna(inplace=True)
2867
-
2868
2932
  if preprocess1 == 'standardize': #标准化
2869
2933
  cmean=dfs2[c].mean()
2870
2934
  cstd=dfs2[c].std()
@@ -2889,16 +2953,12 @@ def df_preprocess(dfs,measure,axhline_label,x_label,y_label,lang='Chinese', \
2889
2953
  return None
2890
2954
  if scaling_option == 'mean':
2891
2955
  cmean=dfs2[c].mean() #使用均值
2892
- if lang == 'English':
2893
- scalingOptionText='mean value'
2894
- else:
2895
- scalingOptionText='均值'
2956
+ scalingOptionText=text_lang('均值','mean value')
2957
+
2896
2958
  if scaling_option == 'min':
2897
2959
  cmean=dfs2[c].min() #使用最小值
2898
- if lang == 'English':
2899
- scalingOptionText='min value'
2900
- else:
2901
- scalingOptionText='最小值'
2960
+ scalingOptionText=text_lang('最小值','min value')
2961
+
2902
2962
  #if scaling_option == 'start':
2903
2963
  if scaling_option in ['start','percentage','change%']:
2904
2964
  # 从头寻找第一个非空数值
@@ -2909,11 +2969,13 @@ def df_preprocess(dfs,measure,axhline_label,x_label,y_label,lang='Chinese', \
2909
2969
  else:
2910
2970
  cmean=dfs2[c][n] #使用第一个非空值
2911
2971
  break
2912
-
2913
- if lang == 'English':
2914
- scalingOptionText='starting value'
2972
+
2973
+ if scaling_option in ['start']:
2974
+ scalingOptionText=text_lang('起点值','starting value')
2975
+ elif scaling_option in ['percentage']:
2976
+ scalingOptionText=text_lang('百分比','percentage')
2915
2977
  else:
2916
- scalingOptionText='起点值'
2978
+ scalingOptionText=text_lang('变化率%','change%')
2917
2979
 
2918
2980
  meanlist=meanlist+[cmean]
2919
2981
 
@@ -2949,6 +3011,7 @@ def df_preprocess(dfs,measure,axhline_label,x_label,y_label,lang='Chinese', \
2949
3011
  dfs2[c]=dfs2[c].apply(lambda x: (x/cfactor-1)*100)
2950
3012
 
2951
3013
  #设置中英文的脚注和纵轴标记
3014
+ lang=check_language()
2952
3015
  if lang == 'English':
2953
3016
  if preprocess1 == 'standardize':
2954
3017
  std_notes="Note: for ease of comparison, data are standardized "
@@ -3203,48 +3266,21 @@ def start_end_preprocess(start,end='today'):
3203
3266
  # 检查日期:开始日期
3204
3267
  start=start.lower()
3205
3268
 
3206
- """
3207
- if start in ['default','mrm','l1m']: # 默认近一个月
3208
- fromdate=date_adjust(todate,adjust=-31-7) #多几天有利于绘图坐标标示
3209
- elif start in ['l2m']: # 近2个月
3210
- fromdate=date_adjust(todate,adjust=-31*2-14)
3211
- elif start in ['mrq','l3m']: # 近三个月
3212
- fromdate=date_adjust(todate,adjust=-31*3-16)
3213
- elif start in ['l6m','mrh']: # 近6个月
3214
- fromdate=date_adjust(todate,adjust=-31*6-16)
3215
- elif start in ['mry','l12m']: # 近一年
3216
- fromdate=date_adjust(todate,adjust=-366-16)
3217
- elif start in ['l2y']: # 近两年以来
3218
- fromdate=date_adjust(todate,adjust=-366*2-15)
3219
- elif start in ['l3y']: # 近三年以来
3220
- fromdate=date_adjust(todate,adjust=-366*3-14)
3221
- elif start in ['l5y']: # 近五年以来
3222
- fromdate=date_adjust(todate,adjust=-366*5-13)
3223
- elif start in ['l8y']: # 近八年以来
3224
- fromdate=date_adjust(todate,adjust=-366*8-11)
3225
- elif start in ['l10y']: # 近十年以来
3226
- fromdate=date_adjust(todate,adjust=-366*10-9)
3227
- elif start in ['l20y']: # 近20年以来
3228
- fromdate=date_adjust(todate,adjust=-366*20-1)
3229
- elif start in ['l30y']: # 近30年以来
3230
- fromdate=date_adjust(todate,adjust=-366*30)
3231
- elif start in ['ytd']: # 今年以来
3232
- fromdate=str(todaydt.year-1)+'-12-1'
3233
- else:
3234
- validdate,fromdate=check_date2(start)
3235
- if not validdate:
3236
- print(" #Warning(security_trend): invalid date for",start,"/b, reset to MRM")
3237
- fromdate=date_adjust(todate,adjust=-31-16)
3238
- """
3239
3269
  if start in ['default','mrm','l1m']: # 默认近一个月
3240
3270
  fromdate=date_adjust2(todate,adjust_month=-1,adjust_day=-1) #有利于绘图横坐标日期标示
3271
+ elif start in ['mrw','l1w']: # 近1个周
3272
+ fromdate=date_adjust2(todate,adjust_month=0,adjust_day=-7-1)
3273
+ elif start in ['lhm','l2w']: # 近2个周
3274
+ fromdate=date_adjust2(todate,adjust_month=0,adjust_day=-7*2-1)
3275
+ elif start in ['l3w']: # 近3个周
3276
+ fromdate=date_adjust2(todate,adjust_month=0,adjust_day=-7*3-1)
3241
3277
  elif start in ['l2m']: # 近2个月
3242
3278
  fromdate=date_adjust2(todate,adjust_month=-2,adjust_day=-1)
3243
3279
  elif start in ['mrq','l3m']: # 近三个月
3244
3280
  fromdate=date_adjust2(todate,adjust_month=-3,adjust_day=-1)
3245
3281
  elif start in ['l6m','mrh']: # 近6个月
3246
3282
  fromdate=date_adjust2(todate,adjust_month=-6,adjust_day=-1)
3247
- elif start in ['mry','l12m']: # 近一年
3283
+ elif start in ['mry','l12m','l1y']: # 近一年
3248
3284
  fromdate=date_adjust2(todate,adjust_year=-1,to_prev_month_end=True)
3249
3285
  elif start in ['l2y']: # 近两年以来
3250
3286
  fromdate=date_adjust2(todate,adjust_year=-2,to_prev_month_end=True)
@@ -3275,6 +3311,337 @@ def start_end_preprocess(start,end='today'):
3275
3311
 
3276
3312
  return fromdate,todate
3277
3313
 
3314
+ #==============================================================================
3315
+ if __name__=='__main__':
3316
+ text_cn="这是中文"
3317
+ text_en="This is in English"
3318
+
3319
+ set_language('English')
3320
+ set_language('Chinese')
3321
+
3322
+ text_lang(text_cn, text_en)
3323
+
3324
+ def text_lang(text_cn, text_en):
3325
+ """
3326
+ 功能:检测当前语言环境,若为中文返回text_cn,否则返回text_cn
3327
+ """
3328
+ lang=check_language()
3329
+
3330
+ if lang == 'Chinese':
3331
+ result=text_cn
3332
+ else:
3333
+ result=text_en
3334
+
3335
+ return result
3336
+
3337
+ #==============================================================================
3338
+ if __name__=='__main__':
3339
+ df,_=get_price_1ticker('sh010504',fromdate='2024-1-1',todate='2024-4-6',fill=False)
3340
+
3341
+ def df_have_data(df):
3342
+ """
3343
+ 功能:判断df内是否有数据
3344
+ 返回:有数据-Found,df存在但无数据-Empty,其余-None
3345
+ """
3346
+ found=None
3347
+ if df is None:
3348
+ found='None'
3349
+ elif len(df)==0:
3350
+ found='Empty'
3351
+ else:
3352
+ found='Found'
3353
+
3354
+ return found
3355
+
3356
+ #==============================================================================
3357
+ if __name__=='__main__':
3358
+ df,_=get_price_1ticker('sz149976',fromdate='2024-1-1',todate='2024-4-6',fill=False)
3359
+ colname='Close'
3360
+ extend_business_date=False
3361
+
3362
+ df4=df_fill_extend(df,colname='Close',extend_business_date=False)
3363
+
3364
+ def df_fill_extend(df,colname='Close',extend_business_date=False):
3365
+ """
3366
+ 功能:对df进行填充
3367
+ colname:基于此判断是否为空,默认为'Close'
3368
+ extend_business_date:False=仅对df现有值进行填充,
3369
+ True=对于现有开始结束日期之间的所有非周末日期进行扩展后填充
3370
+ """
3371
+ import numpy as np
3372
+
3373
+ df1=df.copy()
3374
+ #仅对现有数据中的缺失值进行填充
3375
+ if not extend_business_date:
3376
+ df1['filled']=df1[colname].apply(lambda x: True if np.isnan(x) else False)
3377
+ df4=df1.ffill(axis=0) #从开始向尾部填充
3378
+ #df5=df4.bfill(axis=0) #从尾部向开始填充,容易对后续的分析结果造成误导,慎用!
3379
+ else:
3380
+ fromdate=df1.head(1).index[0].strftime('%Y-%m-%d')
3381
+ todate=df1.tail(1).index[0].strftime('%Y-%m-%d')
3382
+
3383
+ df2dt=pd.bdate_range(start=fromdate,end=todate)
3384
+ df2dt=pd.to_datetime(df2dt)
3385
+ df2=pd.DataFrame(index=df2dt)
3386
+ df3=pd.merge(df2,df1,how='outer',left_index=True,right_index=True)
3387
+
3388
+ df3['filled']=df3[colname].apply(lambda x: True if np.isnan(x) else False)
3389
+ df4=df3.ffill(axis=0) #从开始向尾部填充
3390
+ #df5=df4.bfill(axis=0) #从尾部向开始填充
3391
+
3392
+ return df4
3393
+
3394
+ #==============================================================================
3395
+ if __name__=='__main__':
3396
+ url="https://finance.yahoo.com"
3397
+ url="https://finance.sina.com.cn"
3398
+
3399
+ test_website(url)
3400
+
3401
+ def test_website(url):
3402
+ """
3403
+ 功能:测试一个网址是否可访问
3404
+ """
3405
+ import requests
3406
+ try:
3407
+ response = requests.get(url)
3408
+ if response.status_code == 200:
3409
+ #print(f"{url} is accessible.")
3410
+ return True
3411
+ else:
3412
+ #print(f"{url} is not accessible. Status code: {response.status_code}")
3413
+ return False
3414
+ except requests.exceptions.RequestException:
3415
+ #print(f"{url} is not accessible. Network error occurred.")
3416
+ return False
3417
+
3418
+ if __name__=='__main__':
3419
+ test_yahoo_finance()
3420
+
3421
+ def test_yahoo_finance():
3422
+ url="https://finance.yahoo.com"
3423
+ return test_website(url)
3424
+
3425
+ #==============================================================================
3426
+ if __name__=='__main__':
3427
+ check_os()
3428
+
3429
+ def check_os():
3430
+ """
3431
+ 功能:检测操作系统的类型
3432
+ """
3433
+ import platform
3434
+ system = platform.system()
3435
+ if system == "Windows":
3436
+ return "Windows"
3437
+ elif system == "Linux":
3438
+ return "Linux"
3439
+ elif system == "Darwin":
3440
+ return "Mac OSX"
3441
+ else:
3442
+ return "Unknown OS"
3443
+
3444
+ #==============================================================================
3445
+ if __name__=='__main__':
3446
+ check_python_version()
3447
+
3448
+ def check_python_version():
3449
+ """
3450
+ 功能:检测Python的版本号
3451
+ """
3452
+ import sys
3453
+ python_version = sys.version_info
3454
+ ver=f"{python_version.major}.{python_version.minor}.{python_version.micro}"
3455
+ return ver
3456
+
3457
+ #==============================================================================
3458
+ if __name__=='__main__':
3459
+ ticker='AAPL'
3460
+ fromdate='2011-1-1'
3461
+ todate='2020-12-31'
3462
+ retry_count=3
3463
+ pause=1
3464
+
3465
+ ticker='ABCD'
3466
+
3467
+ ticker=['AAPL','MSFT']
3468
+ ticker=['AAPL','MSFT','ABCD']
3469
+
3470
+ ticker=['600011.SS']
3471
+ fromdate='2020-1-1'
3472
+ todate='2020-6-30'
3473
+
3474
+ def upper_ticker(ticker):
3475
+ """
3476
+ 功能:改成大写,字符串或列表
3477
+ """
3478
+ if isinstance(ticker,str):
3479
+ return ticker.upper()
3480
+ elif isinstance(ticker,list):
3481
+ tlist=[]
3482
+ for t in ticker:
3483
+ try:
3484
+ tupper=t.upper()
3485
+ except:
3486
+ tupper=t
3487
+ tlist=tlist+[tupper]
3488
+ return tlist
3489
+
3490
+
3491
+ #==============================================================================
3492
+ if __name__=='__main__':
3493
+ ticker='600519.SS'
3494
+ ticker=['600519.SS','000858.SZ']
3495
+ ticker=['600519.SS','000858.SZ',pf]
3496
+
3497
+ ticker_type='auto'
3498
+ ticker_type='bond'
3499
+ ticker_type=['auto','bond']
3500
+ ticker_type=['xyz','bond']
3501
+
3502
+ ticker_type_preprocess_1str(ticker,ticker_type)
3503
+
3504
+ def ticker_type_preprocess_1str(ticker,ticker_type='auto'):
3505
+ """
3506
+ 功能:根据ticker情况(单个原生证券)处理ticker_type,使之与ticker对应
3507
+ """
3508
+ if isinstance(ticker,str):
3509
+ if isinstance(ticker_type,str):
3510
+ ticker_type9=ticker_type
3511
+ if isinstance(ticker_type,list):
3512
+ if len(ticker_type) >= 1:
3513
+ ticker_type9=ticker_type[0]
3514
+ else:
3515
+ ticker_type9='auto'
3516
+ else:
3517
+ ticker_type9=ticker_type
3518
+
3519
+ if ticker_type9 not in ['auto','stock','fund','bond']:
3520
+ ticker_type9='auto'
3521
+
3522
+ return ticker_type9
3523
+
3524
+ if __name__=='__main__':
3525
+ pf={'Market':('China','000001.SS','股债基组合'),'600519.SS':50,'sh018003':150,'sh010504':300}
3526
+ ticker=['600519.SS','000858.SZ','000002.SZ']
3527
+ ticker=['600519.SS','000858.SZ',pf]
3528
+
3529
+ ticker_type='auto'
3530
+ ticker_type='bond'
3531
+ ticker_type=['auto','bond']
3532
+ ticker_type=['xyz','bond']
3533
+
3534
+ ticker_type_preprocess_mstr(ticker,ticker_type)
3535
+
3536
+ def ticker_type_preprocess_mstr(ticker,ticker_type='auto'):
3537
+ """
3538
+ 功能:根据ticker情况(多个原生证券)处理ticker_type,使之与ticker对应
3539
+ """
3540
+ if isinstance(ticker,list):
3541
+ if isinstance(ticker_type,str):
3542
+ ticker_type8=[ticker_type]*len(ticker)
3543
+
3544
+ if isinstance(ticker_type,list):
3545
+ if len(ticker) > len(ticker_type):
3546
+ ticker_type8=ticker_type+[ticker_type[-1]]*(len(ticker)-len(ticker_type))
3547
+ else:
3548
+ ticker_type8=ticker_type
3549
+
3550
+ ticker_type9=[]
3551
+ for tt in ticker_type8:
3552
+ if tt not in ['auto','stock','fund','bond']:
3553
+ tt='auto'
3554
+ ticker_type9=ticker_type9+[tt]
3555
+
3556
+ else:
3557
+ ticker_type9=ticker_type
3558
+
3559
+ return ticker_type9
3560
+
3561
+ if __name__=='__main__':
3562
+ ticker={'Market':('China','000001.SS','股债基组合'),'600519.SS':50,'sh018003':150,'sh010504':300}
3563
+
3564
+ ticker_type='auto'
3565
+ ticker_type='bond'
3566
+ ticker_type=['auto','bond']
3567
+ ticker_type=['xyz','bond']
3568
+
3569
+ ticker_type_preprocess_1portfolio(ticker,ticker_type)
3570
+
3571
+ def ticker_type_preprocess_1portfolio(ticker,ticker_type='auto'):
3572
+ """
3573
+ 功能:根据ticker情况(单个投资组合)处理ticker_type,使之与ticker对应
3574
+ """
3575
+ if isinstance(ticker,dict):
3576
+ _,_,tickerlist,_=decompose_portfolio(ticker)
3577
+ if len(tickerlist)==1:
3578
+ ticker_type9=ticker_type_preprocess_1str(tickerlist[0],ticker_type)
3579
+ else:
3580
+ ticker_type9=ticker_type_preprocess_mstr(tickerlist,ticker_type)
3581
+ else:
3582
+ ticker_type9=ticker_type
3583
+
3584
+ return ticker_type9
3585
+
3586
+ if __name__=='__main__':
3587
+ pf={'Market':('China','000001.SS','股债基组合'),'600519.SS':50,'sh018003':150,'sh010504':300}
3588
+ ticker='600519.SS'
3589
+ ticker=['600519.SS','000858.SZ','000002.SZ']
3590
+ ticker={'Market':('China','000001.SS','股债基组合'),'600519.SS':50,'sh018003':150,'sh010504':300}
3591
+
3592
+ ticker=['600519.SS','000858.SZ',pf]
3593
+
3594
+ ticker_type='auto'
3595
+ ticker_type='bond'
3596
+ ticker_type=['auto','bond']
3597
+ ticker_type=['xyz','bond']
3598
+
3599
+ ticker_type_preprocess_mticker_mixed(ticker,ticker_type)
3600
+
3601
+ def ticker_type_preprocess_mticker_mixed(ticker,ticker_type='auto'):
3602
+ """
3603
+ 功能:根据ticker(可为列表,列表中可含有投资组合)情况处理ticker_type,使之与ticker对应
3604
+ """
3605
+ #单个证券,非投资组合
3606
+ if isinstance(ticker,str):
3607
+ ticker_type9=ticker_type_preprocess_1str(ticker,ticker_type)
3608
+ return ticker_type9
3609
+
3610
+ #单个证券,投资组合
3611
+ if isinstance(ticker,dict):
3612
+ ticker_type9=ticker_type_preprocess_1portfolio(ticker,ticker_type)
3613
+ return ticker_type9
3614
+
3615
+ #混合列表
3616
+ if isinstance(ticker,list):
3617
+ if isinstance(ticker_type,str):
3618
+ ticker_type8=[ticker_type]*len(ticker)
3619
+ if isinstance(ticker_type,list):
3620
+ if len(ticker) > len(ticker_type):
3621
+ ticker_type8=ticker_type+[ticker_type[-1]]*(len(ticker)-len(ticker_type))
3622
+ else:
3623
+ ticker_type8=ticker_type
3624
+
3625
+ ticker_type9=[]
3626
+ for t in ticker:
3627
+ pos=ticker.index(t)
3628
+ tt8=ticker_type8[pos]
3629
+ tt9=tt8
3630
+
3631
+ if isinstance(t,str):
3632
+ tt9=ticker_type_preprocess_1str(t,tt8)
3633
+
3634
+ if isinstance(t,dict):
3635
+ tt9=ticker_type_preprocess_1portfolio(t,tt8)
3636
+
3637
+ ticker_type9=ticker_type9+[tt9]
3638
+ else:
3639
+ ticker_type9=ticker_type
3640
+
3641
+ return ticker_type9
3642
+
3643
+
3644
+ #==============================================================================
3278
3645
  #==============================================================================
3279
3646
  #==============================================================================
3280
3647