siat 3.1.23__py3-none-any.whl → 3.2.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/capm_beta2.py +41 -19
- siat/markowitz2-20240620.py +2614 -0
- siat/markowitz2.py +52 -4
- siat/risk_adjusted_return2.py +45 -6
- siat/sector_china.py +17 -9
- siat/security_price2.py +12 -1
- siat/security_prices.py +38 -17
- siat/security_trend2-20240620.py +493 -0
- siat/security_trend2.py +17 -11
- siat/stock.py +76 -22
- siat/stock_technical-20240620.py +2736 -0
- siat/stock_technical.py +207 -52
- siat/valuation_china.py +7 -5
- {siat-3.1.23.dist-info → siat-3.2.1.dist-info}/METADATA +1 -1
- {siat-3.1.23.dist-info → siat-3.2.1.dist-info}/RECORD +17 -14
- {siat-3.1.23.dist-info → siat-3.2.1.dist-info}/WHEEL +0 -0
- {siat-3.1.23.dist-info → siat-3.2.1.dist-info}/top_level.txt +0 -0
siat/markowitz2.py
CHANGED
@@ -252,6 +252,23 @@ if __name__=='__main__':
|
|
252
252
|
printout=True
|
253
253
|
graph=False
|
254
254
|
|
255
|
+
#测试3
|
256
|
+
Market={'Market':('China','000300.SS','锂电池1号')}
|
257
|
+
Stocks={'300750.SZ':0.4,#宁德时代
|
258
|
+
'002594.SZ':0.3,#比亚迪
|
259
|
+
'300014.SZ':0.2,#亿纬锂能
|
260
|
+
'300207.SZ':0.1,#欣旺达
|
261
|
+
}
|
262
|
+
portfolio=dict(Market,**Stocks)
|
263
|
+
|
264
|
+
indicator='Adj Close'
|
265
|
+
adjust='qfq'; source='auto'; ticker_type='bond'
|
266
|
+
thedate='2024-6-19'
|
267
|
+
pastyears=2
|
268
|
+
printout=True
|
269
|
+
graph=False
|
270
|
+
|
271
|
+
|
255
272
|
pf_info=portfolio_build(portfolio,thedate,pastyears,printout,graph)
|
256
273
|
|
257
274
|
"""
|
@@ -260,12 +277,30 @@ def portfolio_cumret(portfolio,thedate,pastyears=1, \
|
|
260
277
|
printout=True,graph=True):
|
261
278
|
"""
|
262
279
|
def portfolio_build(portfolio,thedate='default',pastyears=1, \
|
280
|
+
indicator='Adj Close', \
|
281
|
+
adjust='qfq',source='auto',ticker_type='auto', \
|
263
282
|
printout=True,graph=False):
|
264
283
|
"""
|
265
284
|
功能:收集投资组合成份股数据,绘制收益率趋势图,并与等权和期间内交易额加权策略组合比较
|
266
285
|
注意:此处无需RF,待到优化策略时再指定
|
267
286
|
printout=True控制获取股价时是否逐个显示
|
287
|
+
|
288
|
+
特别注意:若ticker_type='fund'可能导致无法处理股票的复权价!
|
289
|
+
若要指定特定的证券为债券,则需要使用列表逐一指定证券的类型(股票,债券,基金)
|
268
290
|
"""
|
291
|
+
#判断复权标志
|
292
|
+
indicator_list=['Close','Adj Close']
|
293
|
+
if indicator not in indicator_list:
|
294
|
+
print(" Warning(portfolio_build): invalid indicator",indicator)
|
295
|
+
print(" Supported indicator:",indicator_list)
|
296
|
+
indicator='Adj Close'
|
297
|
+
|
298
|
+
adjust_list=['','qfq','hfq']
|
299
|
+
if adjust not in adjust_list:
|
300
|
+
print(" Warning(portfolio_build): invalid indicator",adjust)
|
301
|
+
print(" Supported adjust:",adjust_list)
|
302
|
+
adjust='qfq'
|
303
|
+
|
269
304
|
import datetime
|
270
305
|
stoday = datetime.date.today()
|
271
306
|
if thedate=='default':
|
@@ -329,18 +364,23 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
|
|
329
364
|
|
330
365
|
# 抓取投资组合股价
|
331
366
|
#prices=get_prices(tickerlist,start,thedate)
|
332
|
-
|
367
|
+
#判断是否赚取复权价
|
368
|
+
if indicator == 'Adj Close' and adjust == '':
|
369
|
+
adjust='qfq'
|
370
|
+
if indicator == 'Close' and adjust != '':
|
371
|
+
indicator = 'Adj Close'
|
372
|
+
|
333
373
|
if printout:
|
334
374
|
#prices=get_prices_simple(tickerlist,start,thedate) #有待改造?
|
335
375
|
#债券优先
|
336
376
|
prices,found=get_price_mticker(tickerlist,start,thedate, \
|
337
|
-
adjust=
|
377
|
+
adjust=adjust,source=source,ticker_type=ticker_type,fill=False)
|
338
378
|
else:
|
339
379
|
with HiddenPrints():
|
340
380
|
#prices=get_prices_simple(tickerlist,start,thedate) #有待改造?
|
341
381
|
prices,found=get_price_mticker(tickerlist,start,thedate, \
|
342
|
-
adjust=
|
343
|
-
|
382
|
+
adjust=adjust,source=source,ticker_type=ticker_type,fill=False)
|
383
|
+
|
344
384
|
if found == 'Found':
|
345
385
|
ntickers=len(list(prices['Close']))
|
346
386
|
nrecords=len(prices)
|
@@ -360,6 +400,14 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
|
|
360
400
|
print(" #Error(portfolio_build): retrieved empty prices for",pname)
|
361
401
|
return None
|
362
402
|
#..........................................................................
|
403
|
+
#判断是否使用复权价:若是,使用Adj Close直接覆盖Close。方法最简单,且兼容后续处理!
|
404
|
+
if (indicator =='Adj Close') or (adjust !=''):
|
405
|
+
prices_collist=list(prices)
|
406
|
+
for pc in prices_collist:
|
407
|
+
pc1=pc[0]; pc2=pc[1]
|
408
|
+
if pc1=='Close':
|
409
|
+
pc_adj=('Adj Close',pc2)
|
410
|
+
prices[pc]=prices[pc_adj]
|
363
411
|
|
364
412
|
# 取各个成份股的收盘价
|
365
413
|
aclose=prices['Close']
|
siat/risk_adjusted_return2.py
CHANGED
@@ -81,11 +81,18 @@ def get_rolling_sharpe_sortino(ticker,start,end,rar_name="sharpe", \
|
|
81
81
|
|
82
82
|
start1=date_adjust(start,adjust=-dateahead)
|
83
83
|
|
84
|
+
#判断复权价
|
85
|
+
if ('adj' in ret_type_lower):
|
86
|
+
adjust='qfq'
|
87
|
+
else:
|
88
|
+
adjust=''
|
89
|
+
|
84
90
|
#抓取股价
|
85
91
|
#pricedf=get_price(ticker,start1,end,source=source)
|
86
92
|
#pricedf=get_price_security(ticker,start1,end,source=source)
|
87
|
-
pricedf,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1, \
|
88
|
-
|
93
|
+
pricedf,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end, \
|
94
|
+
adjust=adjust, \
|
95
|
+
source=source,ticker_type=ticker_type)
|
89
96
|
|
90
97
|
if found !='Found':
|
91
98
|
print(" #Error(get_rolling_sharpe_sortino): no records found for",ticker)
|
@@ -115,6 +122,12 @@ def get_rolling_sharpe_sortino(ticker,start,end,rar_name="sharpe", \
|
|
115
122
|
#开始日期富余一段时间,有助于绘图时显示出期望的开始日期
|
116
123
|
startpd=pd.to_datetime(date_adjust(start,adjust=-7))
|
117
124
|
endpd=pd.to_datetime(end)
|
125
|
+
|
126
|
+
rardf4['index_tmp']=rardf4.index
|
127
|
+
rardf4['index_tmp']=rardf4['index_tmp'].apply(lambda x: pd.to_datetime(x))
|
128
|
+
rardf4.set_index(['index_tmp'],inplace=True)
|
129
|
+
#rardf4.drop(['index_tmp'],inplace=True)
|
130
|
+
|
118
131
|
rardf5=rardf4[(rardf4.index >=startpd) & (rardf4.index <=endpd)]
|
119
132
|
|
120
133
|
#确定风险字段名
|
@@ -169,11 +182,19 @@ def get_expanding_sharpe_sortino(ticker,start,end,rar_name="sharpe", \
|
|
169
182
|
dateahead=7
|
170
183
|
start1=date_adjust(start,adjust=-dateahead)
|
171
184
|
|
185
|
+
#判断复权价
|
186
|
+
ret_type=ret_type.title()
|
187
|
+
if ('Adj' in ret_type):
|
188
|
+
adjust='qfq'
|
189
|
+
else:
|
190
|
+
adjust=''
|
191
|
+
|
172
192
|
#抓取股价
|
173
193
|
#pricedf=get_price(ticker,start1,end,source=source)
|
174
194
|
#pricedf=get_price_security(ticker,start1,end,source=source)
|
175
|
-
pricedf,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1, \
|
176
|
-
|
195
|
+
pricedf,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end, \
|
196
|
+
adjust=adjust, \
|
197
|
+
source=source,ticker_type=ticker_type)
|
177
198
|
|
178
199
|
#计算收益率和收益率标准差
|
179
200
|
rardf2=calc_expanding_return(pricedf,start)
|
@@ -285,8 +306,17 @@ def get_rolling_treynor_alpha(ticker,start,end,rar_name="alpha", \
|
|
285
306
|
#计算CAPM需要的日期提前量
|
286
307
|
start2=date_adjust(start1,adjust=-regression_period-7*2)
|
287
308
|
|
309
|
+
#判断复权价
|
310
|
+
ret_type=ret_type.title()
|
311
|
+
if ('Adj' in ret_type):
|
312
|
+
adjust='qfq'
|
313
|
+
else:
|
314
|
+
adjust=''
|
315
|
+
|
288
316
|
#CAPM回归,计算贝塔系数
|
289
|
-
reg_result,dretdf3=regression_capm(ticker,start2,end,
|
317
|
+
reg_result,dretdf3=regression_capm(ticker,start2,end, \
|
318
|
+
adjust=adjust, \
|
319
|
+
RF=RF, \
|
290
320
|
regtrddays=regtrddays,mktidx=mktidx, \
|
291
321
|
source=source,ticker_type=ticker_type)
|
292
322
|
|
@@ -371,8 +401,17 @@ def get_expanding_treynor_alpha(ticker,start,end,rar_name="alpha", \
|
|
371
401
|
#计算CAPM需要的日期提前量
|
372
402
|
start2=date_adjust(start1,adjust=-regression_period-7*2)
|
373
403
|
|
404
|
+
#判断复权价
|
405
|
+
ret_type=ret_type.title()
|
406
|
+
if ('Adj' in ret_type):
|
407
|
+
adjust='qfq'
|
408
|
+
else:
|
409
|
+
adjust=''
|
410
|
+
|
374
411
|
#CAPM回归,计算贝塔系数
|
375
|
-
reg_result,dretdf3=regression_capm(ticker,start2,end,
|
412
|
+
reg_result,dretdf3=regression_capm(ticker,start2,end, \
|
413
|
+
adjust=adjust, \
|
414
|
+
RF=RF, \
|
376
415
|
regtrddays=regtrddays,mktidx=mktidx, \
|
377
416
|
source=source,ticker_type=ticker_type)
|
378
417
|
|
siat/sector_china.py
CHANGED
@@ -1161,7 +1161,7 @@ if __name__=='__main__':
|
|
1161
1161
|
period="day"
|
1162
1162
|
industry_list='all'
|
1163
1163
|
|
1164
|
-
def get_industry_sw(itype='1',period="day",industry_list='all'):
|
1164
|
+
def get_industry_sw(itype='1',period="day",industry_list='all',max_sleep=8):
|
1165
1165
|
"""
|
1166
1166
|
功能:遍历某类申万指数,下载数据
|
1167
1167
|
itype: F表征指数,n=1/2/3行业指数,S风格指数,B大类风格,C金创类
|
@@ -1174,7 +1174,7 @@ def get_industry_sw(itype='1',period="day",industry_list='all'):
|
|
1174
1174
|
if not (itype in typelist):
|
1175
1175
|
print(" #Error(get_industry_sw): unsupported industry category",itype)
|
1176
1176
|
print(" Supported industry category",typelist)
|
1177
|
-
print(" F: Featured, n-Level n
|
1177
|
+
print(" F: Featured, n-Level n industry, S-Styled, B- Big Styled, C- Financial Innovation, A-All (more time))")
|
1178
1178
|
return None
|
1179
1179
|
|
1180
1180
|
#获得指数代码
|
@@ -1192,10 +1192,10 @@ def get_industry_sw(itype='1',period="day",industry_list='all'):
|
|
1192
1192
|
#循环获取指标
|
1193
1193
|
import pandas as pd
|
1194
1194
|
import akshare as ak
|
1195
|
-
import datetime
|
1195
|
+
import datetime; import random; import time
|
1196
1196
|
df=pd.DataFrame()
|
1197
1197
|
|
1198
|
-
print("
|
1198
|
+
print(" Start searching industry data, it takes time, please wait ...")
|
1199
1199
|
num=len(ilist)
|
1200
1200
|
if num <= 10:
|
1201
1201
|
steps=5
|
@@ -1205,7 +1205,7 @@ def get_industry_sw(itype='1',period="day",industry_list='all'):
|
|
1205
1205
|
total=len(ilist)
|
1206
1206
|
fail_list=[]
|
1207
1207
|
for i in ilist:
|
1208
|
-
|
1208
|
+
print_progress_percent2(i,ilist,steps=5,leading_blanks=4)
|
1209
1209
|
#print(" Retrieving information for industry",i)
|
1210
1210
|
|
1211
1211
|
#抓取指数价格
|
@@ -1235,7 +1235,11 @@ def get_industry_sw(itype='1',period="day",industry_list='all'):
|
|
1235
1235
|
df=df._append(dft2)
|
1236
1236
|
|
1237
1237
|
current=ilist.index(i)
|
1238
|
-
print_progress_percent(current,total,steps=steps,leading_blanks=2)
|
1238
|
+
#print_progress_percent(current,total,steps=steps,leading_blanks=2)
|
1239
|
+
|
1240
|
+
#生成随机数睡眠,试图防止被反爬虫,不知是否管用!
|
1241
|
+
random_int=random.randint(1,max_sleep)
|
1242
|
+
time.sleep(random_int)
|
1239
1243
|
|
1240
1244
|
#num=list(set(list(df['ticker'])))
|
1241
1245
|
if len(fail_list)==0:
|
@@ -1266,7 +1270,7 @@ if __name__=='__main__':
|
|
1266
1270
|
industry_list=['850831.SW','801785.SW','801737.SW','801194.SW',
|
1267
1271
|
'801784.SW','801783.SW','801782.SW']
|
1268
1272
|
|
1269
|
-
def get_industry_sw2(industry_list,period="day"):
|
1273
|
+
def get_industry_sw2(industry_list,period="day",max_sleep=8):
|
1270
1274
|
"""
|
1271
1275
|
功能:遍历指定的申万指数列表,下载数据
|
1272
1276
|
period="day"; choice of {"day", "week", "month"}
|
@@ -1280,10 +1284,10 @@ def get_industry_sw2(industry_list,period="day"):
|
|
1280
1284
|
#循环获取指标
|
1281
1285
|
import pandas as pd
|
1282
1286
|
import akshare as ak
|
1283
|
-
import datetime
|
1287
|
+
import datetime; import random; import time
|
1284
1288
|
df=pd.DataFrame()
|
1285
1289
|
|
1286
|
-
print("Searching industry information, please wait ...")
|
1290
|
+
print(" Searching industry information, it takes time, please wait ...")
|
1287
1291
|
ilist=industry_list
|
1288
1292
|
num=len(ilist)
|
1289
1293
|
if num <= 10:
|
@@ -1323,6 +1327,10 @@ def get_industry_sw2(industry_list,period="day"):
|
|
1323
1327
|
|
1324
1328
|
current=ilist.index(i)
|
1325
1329
|
print_progress_percent(current,total,steps=steps,leading_blanks=2)
|
1330
|
+
|
1331
|
+
#生成随机数睡眠,试图防止被反爬虫,不知是否管用!
|
1332
|
+
random_int=random.randint(1,max_sleep)
|
1333
|
+
time.sleep(random_int)
|
1326
1334
|
|
1327
1335
|
#num=list(set(list(df['ticker'])))
|
1328
1336
|
if len(fail_list) > 0:
|
siat/security_price2.py
CHANGED
@@ -89,7 +89,7 @@ def get_price_1ticker(ticker,fromdate,todate, \
|
|
89
89
|
#检查复权选项合理性
|
90
90
|
ak_fq_list=['','qfq','hfq','qfq-factor','hfq-factor']
|
91
91
|
if adjust not in ak_fq_list:
|
92
|
-
adjust=''
|
92
|
+
adjust='qfq'
|
93
93
|
|
94
94
|
#变换ticker为内部格式(yahoo格式)
|
95
95
|
ticker1=ticker1_cvt2yahoo(ticker)
|
@@ -231,6 +231,17 @@ if __name__=='__main__':
|
|
231
231
|
source='auto'
|
232
232
|
fill=True
|
233
233
|
|
234
|
+
#测试复权价
|
235
|
+
ticker=['300750.SZ','300014.SZ']
|
236
|
+
fromdate="2023-4-20"
|
237
|
+
todate="2023-4-30"
|
238
|
+
ticker_type='fund'
|
239
|
+
|
240
|
+
adjust='qfq'
|
241
|
+
source='auto'
|
242
|
+
fill=False
|
243
|
+
|
244
|
+
|
234
245
|
prices,found=get_price_mticker(ticker,fromdate,todate,adjust,source,ticker_type,fill)
|
235
246
|
|
236
247
|
def get_price_mticker(ticker,fromdate,todate, \
|
siat/security_prices.py
CHANGED
@@ -766,7 +766,11 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
|
|
766
766
|
if ticker_type in ['auto','stock'] and suffix not in ['SW']:
|
767
767
|
try:
|
768
768
|
#仅用于股票的历史行情数据(考虑复权)
|
769
|
-
|
769
|
+
dffqno=ak.stock_zh_a_daily(ticker2,start1,end1,adjust='')
|
770
|
+
dffq=ak.stock_zh_a_daily(ticker2,start1,end1,adjust=adjust)
|
771
|
+
dffq.rename(columns={'close':'Adj Close'},inplace=True)
|
772
|
+
|
773
|
+
df=pd.merge(dffqno,dffq[['date','Adj Close']],on=['date'])
|
770
774
|
df['Date']=df['date']
|
771
775
|
except:
|
772
776
|
df=None
|
@@ -901,7 +905,6 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
|
|
901
905
|
#设置新的索引
|
902
906
|
df.set_index(['Date'],inplace=True)
|
903
907
|
df.rename(columns={'open':'Open','high':'High','low':'Low','close':'Close','volume':'Volume'},inplace=True)
|
904
|
-
df['Adj Close']=df['Close']
|
905
908
|
|
906
909
|
try:
|
907
910
|
df1=df[df.index >= start]
|
@@ -956,7 +959,15 @@ def get_price_ak_us(symbol, fromdate, todate, adjust=""):
|
|
956
959
|
import akshare as ak
|
957
960
|
#print(" Searching info in Sina for",symbol,"... ...")
|
958
961
|
try:
|
959
|
-
|
962
|
+
if adjust=='':
|
963
|
+
df=ak.stock_us_daily(symbol=symbol,adjust=adjust)
|
964
|
+
else:
|
965
|
+
dffqno=ak.stock_us_daily(symbol=symbol,adjust='')
|
966
|
+
dffq=ak.stock_us_daily(symbol=symbol,adjust='qfq')
|
967
|
+
dffq.rename(columns={'close':'Adj Close'},inplace=True)
|
968
|
+
|
969
|
+
df=pd.merge(dffqno,dffq[['date','Adj Close']],on=['date'])
|
970
|
+
|
960
971
|
except:
|
961
972
|
#print(" #Error(get_price_ak_us): no info found for",symbol)
|
962
973
|
return None
|
@@ -982,7 +993,8 @@ def get_price_ak_us(symbol, fromdate, todate, adjust=""):
|
|
982
993
|
|
983
994
|
df2.rename(columns={'open':'Open','high':'High','low':'Low','close':'Close','volume':'Volume'},inplace=True)
|
984
995
|
df2['ticker']=symbol
|
985
|
-
|
996
|
+
if 'Adj Close' not in list(df2):
|
997
|
+
df2['Adj Close']=df2['Close']
|
986
998
|
df2['source']='新浪'
|
987
999
|
df2['footnote']=adjust
|
988
1000
|
|
@@ -1000,14 +1012,21 @@ if __name__=='__main__':
|
|
1000
1012
|
if __name__=='__main__':
|
1001
1013
|
symbol='0700.HK'
|
1002
1014
|
symbol='0700.hk'
|
1015
|
+
|
1003
1016
|
symbol='00700.HK'
|
1004
|
-
fromdate='
|
1005
|
-
todate='
|
1017
|
+
fromdate='2014-5-1'
|
1018
|
+
todate ='2014-5-31'
|
1019
|
+
adjust="qfq"
|
1020
|
+
|
1021
|
+
tx=get_price_ak_hk(symbol='00700.HK',fromdate='2014-5-1',todate='2014-5-30',adjust="qfq")
|
1006
1022
|
|
1007
|
-
def get_price_ak_hk(symbol,
|
1023
|
+
def get_price_ak_hk(symbol,fromdate,todate,adjust=""):
|
1008
1024
|
"""
|
1009
1025
|
抓取单个港股股价,不能处理股指,股指无.HK后缀
|
1010
1026
|
"""
|
1027
|
+
DEBUG=False
|
1028
|
+
if DEBUG:
|
1029
|
+
print("Start searching HK stock prices for",symbol,"...")
|
1011
1030
|
|
1012
1031
|
#检查日期期间
|
1013
1032
|
result,start,end=check_period(fromdate,todate)
|
@@ -1027,19 +1046,20 @@ def get_price_ak_hk(symbol, fromdate, todate, adjust=""):
|
|
1027
1046
|
symbol3=symbol2
|
1028
1047
|
|
1029
1048
|
try:
|
1030
|
-
|
1049
|
+
if adjust == '':
|
1050
|
+
df=ak.stock_hk_daily(symbol=symbol3, adjust=adjust)
|
1051
|
+
else:
|
1052
|
+
dffqno=ak.stock_hk_daily(symbol=symbol3, adjust='')
|
1053
|
+
dffq =ak.stock_hk_daily(symbol=symbol3,adjust='qfq')
|
1054
|
+
dffq.rename(columns={'close':'Adj Close'},inplace=True)
|
1055
|
+
|
1056
|
+
df=pd.merge(dffqno,dffq[['date','Adj Close']],on=['date'])
|
1031
1057
|
except:
|
1032
1058
|
print(" #Error(get_price_ak_hk): no info found for",symbol)
|
1033
1059
|
return None
|
1034
1060
|
|
1035
|
-
|
1036
|
-
|
1037
|
-
import datetime as dt
|
1038
|
-
try:
|
1039
|
-
df['Date']=df['Date'].dt.tz_localize(None)
|
1040
|
-
except:
|
1041
|
-
import pandas as pd
|
1042
|
-
df['Date']=pd.to_datetime(df['date'])
|
1061
|
+
#去掉可能出现的时区信息
|
1062
|
+
df['Date']=pd.to_datetime(df['date'])
|
1043
1063
|
#设置新的索引
|
1044
1064
|
df.set_index(['Date'],inplace=True)
|
1045
1065
|
|
@@ -1056,7 +1076,8 @@ def get_price_ak_hk(symbol, fromdate, todate, adjust=""):
|
|
1056
1076
|
|
1057
1077
|
df2.rename(columns={'open':'Open','high':'High','low':'Low','close':'Close','volume':'Volume'},inplace=True)
|
1058
1078
|
df2['ticker']=symbol
|
1059
|
-
|
1079
|
+
if 'Adj Close' not in list(df2):
|
1080
|
+
df2['Adj Close']=df2['Close']
|
1060
1081
|
df2['source']='新浪'
|
1061
1082
|
|
1062
1083
|
ptname=ticker_name(symbol,'stock')
|