業(yè)務(wù)需求分析
- 根據(jù)輸入的可轉(zhuǎn)債代碼和 價(jià)格(可選) ,分析單個(gè)可轉(zhuǎn)債主要信息
- 分析的主要字段是:
- 基本信息: 代碼、名稱、現(xiàn)價(jià)、剩余年限、行業(yè)、溢價(jià)率
- 已轉(zhuǎn)股比例: 此比例過(guò)高的話,大股東提升股價(jià)或下修轉(zhuǎn)股價(jià)的動(dòng)力就弱
- 到期價(jià)值: 贖回價(jià)+持有期未付利息之和*80%, 扣除了20%的稅
- 到期收益率: 到期價(jià)值/當(dāng)前轉(zhuǎn)債價(jià)格-100%
- 到期年化收益率: 到期收益率/剩余年限
- 回售價(jià)值: [回售價(jià)+當(dāng)期的利息(按第四年算)] +持有到第四年所有未付利息之和*80%
- 回售收益率: 回售價(jià)值/當(dāng)前轉(zhuǎn)債價(jià)格-100%
- 回售年化收益率: 回售收益率/ 當(dāng)前持有到第四年的年限(如果小于1,則直接取回售收益率)
- 股東質(zhì)押比例: 此值越高,代表公司越缺錢(qián),將債主轉(zhuǎn)成股東的動(dòng)力越大
- 評(píng)級(jí): 評(píng)級(jí)越高,違約的風(fēng)險(xiǎn)越低
- PB: 市值/凈資產(chǎn), PB越大,說(shuō)明下修轉(zhuǎn)股價(jià)的空間越大
- 發(fā)行規(guī)模: 此值越大說(shuō)明盤(pán)子越大
- 有無(wú)回售條款: 個(gè)別大公司,可能沒(méi)有,盡量買有回售的
- 有無(wú)擔(dān)保: 有的話可減少違約風(fēng)險(xiǎn)
- 轉(zhuǎn)債占比:當(dāng)前剩余的可轉(zhuǎn)債占公司當(dāng)前流通市值的比值
- 是否登記強(qiáng)贖 :如果登記了強(qiáng)贖,買之前應(yīng)仔細(xì)看強(qiáng)贖日期
- 關(guān)于轉(zhuǎn)債利息部分,大部分轉(zhuǎn)債都是一年一付,且是按轉(zhuǎn)債發(fā)行日期開(kāi)始計(jì)算,與持有人持有時(shí)間無(wú)關(guān),所以此處計(jì)算利息時(shí),認(rèn)為超過(guò)1年,則按兩年利息計(jì)算
程序分析
程序依賴
-
提供數(shù)據(jù)的網(wǎng)站(集思錄)、中登公司
-
**第三方庫(kù)依賴:requests、bs4、prettytable
**
程序邏輯分析
- 抓取所有可轉(zhuǎn)債列表,通過(guò)輸入的轉(zhuǎn)債代碼過(guò)濾出具體轉(zhuǎn)債
- 根據(jù)轉(zhuǎn)債代碼,找到當(dāng)前轉(zhuǎn)債的 行業(yè)、已轉(zhuǎn)股比例、擔(dān)保情況、利息等信息
- 在中登官網(wǎng)獲取該公司的質(zhì)押比例
- 計(jì)算到期價(jià)值、到期收益率、到期年化收益率、回售價(jià)值、回售收益率、回售年化收益率
- 格式化輸出所有關(guān)鍵字段信息
程序重要代碼
請(qǐng)求可轉(zhuǎn)債列表
def get_request(url):
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36"
}
try:
resp = requests.get(url, headers=header)
resp.encoding = "utf-8"
if resp.status_code == 200:
return resp.text
return None
except Exception as e:
print("http 請(qǐng)求失敗!!,", e)
return None
def get_bonds_list(url):
'''獲取可轉(zhuǎn)債列表'''
resp = get_request(url)
resp_json = json.loads(resp)
datas = resp_json["rows"]
if datas is None:
return None
return datas
查詢可轉(zhuǎn)債詳細(xì)信息
def get_bonds_detail(datas, bondCode):
if datas == None or bondCode == None:
print("請(qǐng)求參數(shù)為空,請(qǐng)檢查程序!!")
return None
result = None;
for cell in datas:
data=cell["cell"]
bond_id = data["bond_id"]
if bond_id == bondCode:
result = data
break
else:
print("沒(méi)有查詢到需要找的可轉(zhuǎn)債,請(qǐng)重新開(kāi)始??!")
print("*"*50)
return None
bondId = result["bond_id"]
# 查詢債券詳細(xì)信息
content = get_request("https://www.jisilu.cn/data/convert_bond_detail/%s" % bondId)
if not content:
print("查詢單個(gè)轉(zhuǎn)債信息失敗,bondId: %s" % bondId)
return None
# 解析行業(yè),已轉(zhuǎn)股比例等信息
soup = BeautifulSoup(content, "html.parser")
cvtRt = soup.find(id="cvt_rt").text
if cvtRt is None:
cvtRt = "-"
result["cvt_rt"] = cvtRt
indusity = soup.find(class_="jisilu_nav").select("a")[1].text
if indusity is None:
indusity = "-"
result["indusity"] = indusity
# 利息
rate = soup.find(id="cpn_desc").text
if rate is None:
rate = "-"
result["rate"] = rate
# 到期贖回價(jià)
redeem_price = soup.find(id="redeem_price").text
if redeem_price is None:
redeem_price = "-"
result["redeem_price"] = redeem_price
# 回售價(jià)
put_price = soup.find(id="put_price").text
if put_price is None:
put_price = "-"
result["put_price"] = put_price
# 擔(dān)保
guarantor = soup.find(id="guarantor").text
if guarantor is None:
guarantor = "-"
result["guarantor"] = guarantor
# 轉(zhuǎn)債占流通市值占比
convert_amt_ratio = soup.find(id="convert_amt_ratio").text
if convert_amt_ratio is None:
convert_amt_ratio = "-"
result["convert_amt_ratio"] = convert_amt_ratio
# 查詢股東質(zhì)押率
pledge = get_pledge(result["stock_cd"])
result["pledge"] = pledge
return result
通過(guò)中登公司管網(wǎng) 查詢股東質(zhì)押比例(質(zhì)押比例每周最后一個(gè)交易日才更新,當(dāng)前如果不是周六的話,就往前推6天,取上一周的)
def get_pledge(stock_cd):
'''查詢股東質(zhì)押比例,暫時(shí)發(fā)現(xiàn)周日好像無(wú)法查詢'''
# queryData = "2021.01.02"113035
queryData = time.strftime("%Y.%m.%d", time.localtime())
today = datetime.datetime.today().weekday() - 1
if today!=6:
today = datetime.date.today()- datetime.timedelta(days=6)
queryData=today.strftime("%Y.%m.%d")
content = get_request("http://www.chinaclear.cn/cms-rank/queryPledgeProportion?queryDate=%s&secCde=%s" % (
queryData, stock_cd))
soup = BeautifulSoup(content, "html.parser")
frTmp = soup.find(class_="Stock Stock2")
tdList = frTmp.find_all("td")
pledge = tdList[-1].text
if pledge is None:
pledge = "-"
else:
pledge = pledge + "%"
return pledge
計(jì)算投資價(jià)值及收益率
def calc_rate(data):
'''計(jì)算收益率'''
# 過(guò)濾利息
newRateList = []
rateList = data["rate"].split("%")
# 將每年的利息過(guò)濾出來(lái)
for r in rateList:
newR = re.findall(r"\\d.\\d", r)
if len(newR) > 0:
newRateList.append(float(newR[0]))
# 到期價(jià)值=到期贖回價(jià)+ 除最后一年外,所有未付利息之和*80%
maturity = calc_maturity(newRateList, data["year_left"], data["redeem_price"])
data["maturity"] = maturity
# 到期收益率
price = float(data["price"])
priceDq = format((maturity - price)/price*100, ".2f")
data["priceDq"] = priceDq + "%"
# 到期年化收益率
priceDqYear = format(float(priceDq) / float(data["year_left"]), ".2f")
data["priceDqYear"] = priceDqYear + "%"
# 回售價(jià)= 100+ 除最后兩年,所有未付利息之和*80% (由于大部分轉(zhuǎn)債都是最后兩年開(kāi)始回售,此處利息按第四年算)
priceBack = 100 + newRateList[3]
backPrice = calc_back(newRateList, data["year_left"], priceBack)
data["backPrice"] = backPrice
# 回售收益率
priceHs = format((backPrice - price)/price*100, ".2f")
data["priceHs"] = priceHs + "%"
# 回售年化收益率
priceHsYear = priceHs
leftYear = float(data["year_left"]) - 2
if leftYear > 0:
priceHsYear = format(float(priceHs) / leftYear, ".2f")
data["priceHsYear"] = priceHsYear + "%"
return data
根據(jù)利息計(jì)算價(jià)值
def calc_back(newRateList, yearLeft, priceBack):
yearLeft = float(yearLeft)
leftYear = yearLeft - 2
rateTotal = float(0)
if leftYear >= 1:
rateTotal += newRateList[3]
if leftYear >= 2:
rateTotal += newRateList[2]
if leftYear >= 3:
rateTotal += newRateList[1]
if leftYear >= 4:
rateTotal += newRateList[0]
# 扣除20%的稅
result = priceBack + rateTotal * 0.8
return result
def calc_maturity(newRateList, yearLeft, redeemPrice):
yearLeft = float(yearLeft)
rateTotal = 0
if yearLeft > 1:
# 大于1年,按兩年利息算,最贖回價(jià)+ 倒數(shù)第二年的利息
rateTotal += newRateList[4]
if yearLeft > 2:
rateTotal += newRateList[3]
if yearLeft > 3:
rateTotal += newRateList[2]
if yearLeft > 4:
rateTotal += newRateList[1]
if yearLeft > 5:
rateTotal += newRateList[0]
# 扣除20%的稅
result = float(redeemPrice) + rateTotal * 0.8
return result
最終結(jié)果打印
def print_data(data):
table=PrettyTable(header=False)
table.add_row(["轉(zhuǎn)債代碼",data["bond_id"]])
table.add_row(["轉(zhuǎn)債名稱",data["bond_nm"]])
table.add_row(["現(xiàn)價(jià)",data["price"]])
table.add_row(["評(píng)級(jí)",data["rating_cd"]])
table.add_row(["PB(下調(diào)轉(zhuǎn)股價(jià)空間)",str(data["pb"])+"(PB越大說(shuō)明下修轉(zhuǎn)股價(jià)的空間越大)"])
table.add_row(["已轉(zhuǎn)股比例",str(data["cvt_rt"])+"(已轉(zhuǎn)股的比率太多了的話,建議不要買了,公司提升股價(jià)的愿望較弱)"])
table.add_row(["剩余年限",data["year_left"]])
table.add_row(["到期價(jià)值",str(data["maturity"])+"(按當(dāng)前情況買入,持有到期來(lái)估算,加上持有中的利息,已扣除利息稅,持有超過(guò)1年按2年利息計(jì)算)"])
table.add_row(["到期收益率",data["priceDq"]])
table.add_row(["到期年化收益率",data["priceDqYear"]])
table.add_row(["回售價(jià)值",str(data["backPrice"])+"(按當(dāng)前情況買入,持有到倒數(shù)第二年計(jì)算,加上持有中的利息,已扣除利息稅,持有超過(guò)1年按2年利息計(jì)算)"])
table.add_row(["回售收益率",data["priceHs"]])
table.add_row(["回售年化收益率",data["priceHsYear"]])
table.add_row(["有無(wú)回售條款","無(wú)(無(wú)回售條款,最好不要買)" if data["put_price"]=="-" else "有"])
table.add_row(["有無(wú)擔(dān)保",data["guarantor"]])
table.add_row(["轉(zhuǎn)債占比",str(data["convert_amt_ratio"])+"(表示當(dāng)前剩余可轉(zhuǎn)債占當(dāng)前流通市值的比值)"])
table.add_row(["股東質(zhì)押比例",str(data["pledge"])+"(此值越高,說(shuō)明公司越缺錢(qián),公司提高股價(jià)或者下修轉(zhuǎn)股價(jià)的概率越大)"])
table.add_row(["行業(yè)",data["indusity"]])
table.add_row(["溢價(jià)率",str(data["premium_rt"])+"%"])
table.add_row(["是否登記強(qiáng)贖","否" if data["force_redeem"]==None else data["force_redeem"].replace("\\r\\n",",")])
print(table)
主方法調(diào)用
while True:
print("請(qǐng)輸入要分析的可轉(zhuǎn)債代碼與價(jià)格,中間用逗號(hào)分隔(如不輸入價(jià)格,默認(rèn)按當(dāng)前價(jià)),輸入q退出!!")
input_str=input("請(qǐng)輸入:")
if input_str==None or input_str.strip()==None or len(input_str)==0:
print("輸入為空,需要重新輸入")
continue
if input_str=="q":
break
input_list=input_str.split(",")
input_code=input_list[0].strip()
input_price=input_list[1].strip() if len(input_list)>1 else None
# 獲取可轉(zhuǎn)債列表
datas=tools.get_bonds_list("https://www.jisilu.cn/data/cbnew/cb_list/?___jsl=LST___t=1609766310721")
# 查詢轉(zhuǎn)債詳細(xì)信息,及組裝行業(yè),已轉(zhuǎn)股比率等信息
data=tools.get_bonds_detail(datas,input_code)
if data==None:
continue
# 計(jì)算收益率
if input_price != None:
data["price"]=input_price
data=tools.calc_rate(data)
# 輸出當(dāng)前轉(zhuǎn)債的信息
tools.print_data(data)
使用案例
127007 ** 湖廣轉(zhuǎn)債分析**
- 評(píng)級(jí):AA+ ,評(píng)級(jí)比較高,表示違約的概率小
- PB:0.63, PB是 市值/凈資產(chǎn),這個(gè)值越小,說(shuō)明公司下調(diào)轉(zhuǎn)股價(jià)的空間就越小,小于1,基本上不會(huì)下調(diào)轉(zhuǎn)股價(jià)了
- 已轉(zhuǎn)股比例:29.71% , 說(shuō)明之前漲到了 130以上了,已經(jīng)轉(zhuǎn)了一部分股票了,這個(gè)比例還不算高,說(shuō)明還有一大部分沒(méi)轉(zhuǎn)股
- 到期價(jià)值:111.44, 根據(jù)年限及利息,從現(xiàn)在拿著,一直等到到期贖回,每張相當(dāng)于 111.44元
- 到期收益率:11.38%, 以當(dāng)前的價(jià)格買入,持有到期的收益率
- 到期年化收益率:3.27%, 用到期收益率除以剩余年限,這個(gè)收益率比貨幣基金高點(diǎn),比債券基金少點(diǎn)
- 回售價(jià)值:102.7, 表示從現(xiàn)在開(kāi)始持有到第四年,加上利息,如果回售的話,每張大概是102.7元,收益率是 2.56%, 年化收益率是 1.79%,價(jià)值跟貨幣基金差不多
- 股東質(zhì)押比例:7.77% , 不是很高,說(shuō)明公司暫時(shí)不是很缺錢(qián),相對(duì)而言,轉(zhuǎn)股的動(dòng)力會(huì)比較弱
- **行業(yè): 有線電視網(wǎng)絡(luò) ** , 這是傳媒行業(yè),根據(jù)之前統(tǒng)計(jì)的已退市可轉(zhuǎn)債情況來(lái)看,這個(gè)行業(yè) 觸發(fā)強(qiáng)贖的概率還是比較高的
**總結(jié)下: **湖廣轉(zhuǎn)債,違約概率很低,最差的情況,以當(dāng)前價(jià)格買的話,最后收益略高于貨幣基金。 其所處行業(yè)還不錯(cuò),但公司暫時(shí)不是很缺錢(qián),暫時(shí)基本上不能通過(guò)下調(diào)轉(zhuǎn)股價(jià),來(lái)增加觸發(fā)強(qiáng)贖概率(說(shuō)明短期內(nèi),除非市場(chǎng)環(huán)境影響,公司自己主動(dòng)采取措施提升股價(jià)的希望很小)。 但是投資者如果長(zhǎng)期持有的話,是不會(huì)虧本的,在剩余的3.5年中,還是有不小的概率觸發(fā)強(qiáng)贖的。 整體評(píng)價(jià)一般。
**注: 以上分析,都是分析在最差的情況下,能有什么樣的收益率,投資可轉(zhuǎn)債想要好收益率,當(dāng)然是在強(qiáng)贖的情況下。 用安道全的話說(shuō),每只可轉(zhuǎn)債都應(yīng)該強(qiáng)贖,且概率都很大。 但這兩年發(fā)行的可轉(zhuǎn)債很多,質(zhì)量也都參差不齊,未來(lái)是否有轉(zhuǎn)債會(huì)違約,誰(shuí)也說(shuō)不準(zhǔn),但相信只要在 到期價(jià)值以內(nèi)購(gòu)買,AA級(jí)以上的債卷,長(zhǎng)期持有,收益率想來(lái)是不會(huì)太差的,風(fēng)險(xiǎn)也小。 巴菲特: 投資的第一條原則是 不要虧損, 第二條原則是, 參照第一條 ...
**
-
分析器
+關(guān)注
關(guān)注
0文章
93瀏覽量
12727 -
python
+關(guān)注
關(guān)注
56文章
4827瀏覽量
86695
發(fā)布評(píng)論請(qǐng)先 登錄
偏振分析器
CCS中性能分析器profile的使用?
請(qǐng)問(wèn)python-樹(shù)莓派如何通過(guò)按鍵控制步進(jìn)電機(jī)正反轉(zhuǎn)?
一個(gè)高效的語(yǔ)法分析器生成工具
轉(zhuǎn)換到TimeQuest時(shí)序分析器教程(電子書(shū))
一種實(shí)用的脈沖幅度分析器
網(wǎng)絡(luò)分析器,網(wǎng)絡(luò)分析器原理是什么?
協(xié)議分析器在WLAN中的應(yīng)用
靜態(tài)代碼分析器
Py-spy:用于Python 程序性能監(jiān)控、分析器

py-spy:用于Python程序的性能監(jiān)控、分析器

評(píng)論