C# (江湖小新)

编程入门 行业动态 更新时间:2024-10-07 00:27:01

C# (江湖<a href=https://www.elefans.com/category/jswz/34/1764144.html style=小新)"/>

C# (江湖小新)

效果

可转债分析器用c# 再写一次,其原理与之前python写的基本一样,只是因为程序语言不同,所以写法上可能不太相同。本文就不再介绍分析中的这些数据的含义,有还不了解的同学可以在公众号中查看我之前用python写的可转债分析器 Python—写个可转债分析器  

 

本次重写主要解决了以下问题:

  • 用c#编写,图形化界面可以很简单的就做出来

  • 因集思录网站更新很多接口有变动,之前的接口地址不能用了,本次重新采用最新的接口访问

  • 系统兼容方面,没有python那么挑剔,比如说 pthon编写的用win7 32位系统编写的程序只能在别人win7 32位电脑上运行;c# 相比而言就简单多了,基本上win7或win10都可以运行

程序逻辑及代码

主窗体的设计:

  • 一个label,显示提示方案

  • 一个TextBox 输入框,用来输入 可转债代码

  • 一个Button按钮,点击用来获取数据并按规则进行数据分析

Btton 按钮逻辑如下:

  • 获取页面录入的可转债代码

  • 请求集思录可转债列表,并从中筛选出 用户输入的可转债记录

  • 单独再请求可转债详情接口,获取列表中没有的记录

  • 在详情接口需要单独去中登公司的官网查询 股票质押率

  • 计算按当前价格买入的各种收益率

  • 最后将计算后的结果输出到页面上

private void button1_Click(object sender, EventArgs e)
{// 获取页面录入的可转债代码string bondId = this.textBox1.Text;if (string.IsNullOrEmpty(bondId)){return;}// 从转债列表中筛选出当前输入的转债JObject jo = GetBondObjByList(bondId);if(jo == null){return;}//获取转债详情JObject bondDetail = GetBondDetailDict(bondId, jo);// 计算收益率CalcRate(bondDetail);//输出到页面PrintData(bondDetail);
}

查询可转债列表

private JObject GetBondObjByList(string bondId)
{string resp = HttpHelper.doGet("/");// 解析数据JObject jo = (JObject)JsonConvert.DeserializeObject(resp);if (jo["code"].ToString() != "200" || string.IsNullOrEmpty(jo["data"].ToString())){return null;}JArray dataArray = (JArray)JsonConvert.DeserializeObject(jo["data"].ToString());for (int i = 0; i < dataArray.Count; i++){JObject j = JObject.Parse(dataArray[i].ToString());string bond_id = j["bond_id"].ToString();if (string.Equals(bond_id, bondId)){return j;}}return null;
}

查询可转债详情


private JObject GetBondDetailDict(string bondId, JObject bondDict)
{//获取转债详情string bondDetail = HttpHelper.doGet("/" + bondId);// 解析网页内容HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();doc.LoadHtml(bondDetail);// 转股率string cvt_rt = doc.GetElementbyId("cvt_rt").InnerText;bondDict.Add("cvt_rt", cvt_rt);// 行业HtmlNode htmlNode = doc.GetElementbyId("tc_data");string industry = htmlNode.SelectSingleNode(".//div[@class='stock_indu']").SelectSingleNode(".//a").InnerText;bondDict.Add("indusity", industry);// 利息string cpn_desc = doc.GetElementbyId("cpn_desc").InnerText;bondDict.Add("rate", cpn_desc);// 到期赎回价string redeem_price = doc.GetElementbyId("redeem_price").InnerText;bondDict.Add("redeem_price", redeem_price);// 回售价string put_price = doc.GetElementbyId("put_price").InnerText;bondDict.Add("put_price", put_price);// 担保HtmlNode node1 = doc.GetElementbyId("guarantor").ParentNode;HtmlNode node = node1.SelectNodes("/html[1]/body[1]/div[4]/div[2]/div[1]/div[1]/table[3]/tr[1]/td[2]")[0];string guarantor = node.InnerText;bondDict.Add("guarantor", guarantor);// 查询股东质押率string pledge = GetPledge(bondDict["stock_id"].ToString());bondDict.Add("pledge", pledge);return bondDict;
}

查询股东质押率

private string GetPledge(string stock_cd)
{// 每周五才会出最新数据,保守直接取6天前的数据DateTime dt=DateTime.Now;string queryDate= dt.AddDays(-6).ToString("yyyy.MM.dd");string resultHtml = HttpHelper.doPost("",String.Format("queryDate={0}&secCde={1}",queryDate, stock_cd));string pledge = "";try{// 解析网页内容HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();doc.LoadHtml(resultHtml);HtmlNode node = doc.DocumentNode;HtmlNode stockNode = node.SelectSingleNode("/html[1]/body[1]/div[2]/table[1]/tr[2]/td[8]");pledge = stockNode.InnerText + "%";}catch(Exception ex){Console.WriteLine(ex);}return pledge;
}

计算各种收益率

private JObject CalcRate(JObject data)
{Regex regex = new Regex(@"\d.\d");//计算收益率List<double> newRateList = new List<double>();string[] rateList = data["rate"].ToString().Split('%');foreach(string rate in rateList){MatchCollection matchCollection = regex.Matches(rate);if(matchCollection.Count > 0){string tmp = matchCollection[0].Value;newRateList.Add(Double.Parse(tmp));}}// 剩余年限为空,说明已经登记强赎了,不再关注下面的到期与回售价值if (string.IsNullOrEmpty(data["year_left"].ToString())){data["maturity"] = "-";data["priceDq"] = "-";data["priceDqYear"] = "-";data["backPrice"] = "-";data["priceHs"] = "-";data["priceHsYear"] = "-";return data;}// 到期价值=到期赎回价+ 除最后一年外,所有未付利息之和*80%double maturity = CalcMaturity(newRateList, Double.Parse(data["year_left"].ToString()), Double.Parse(data["redeem_price"].ToString()));data["maturity"] = maturity;// 到期收益率double price = Double.Parse(data["price"].ToString());double priceDq = Math.Round((maturity - price) / price, 2) * 100;data["priceDq"] = priceDq + "%";// 到期年化收益率double priceDqYear = Math.Round(priceDq / Double.Parse(data["year_left"].ToString()), 2);data["priceDqYear"] = priceDqYear + "%";// 回售价= 100+ 除最后两年,所有未付利息之和*80% (由于大部分转债都是最后两年开始回售,此处利息按第四年算)double priceBack = 100 + newRateList[3];double backPrice = CalcBack(newRateList, Double.Parse(data["year_left"].ToString()), priceBack);data["backPrice"] = backPrice + "";// 回售收益率double priceHs = Math.Round((backPrice - price) / price * 100, 2);data["priceHs"] = priceHs + "%";// 回售年化收益率double priceHsYear = priceHs;double leftYear = Double.Parse(data["year_left"].ToString()) - 2;if (leftYear > 0)priceHsYear = Math.Round(priceHs / leftYear, 2);data["priceHsYear"] = priceHsYear + "%";return data;
}private double CalcMaturity(List<double> newRateList, double yearLeft, double redeemPrice)
{double rateTotal = 0D;if (yearLeft > 1)// 大于1年,按两年利息算,最赎回价+ 倒数第二年的利息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%的税double result = redeemPrice + rateTotal * 0.8;return Math.Round(result,2);
}private double CalcBack(List<double> newRateList, double yearLeft, double priceBack)
{double leftYear = yearLeft - 2;double rateTotal = 0D;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%的税double result = priceBack + rateTotal * 0.8;return Math.Round(result,2);
}

最后将结果输出到页面


private void PrintData(JObject data)
{// 先清空列表this.listView1.Clear();this.listView1.Columns.Add("描述", 200, HorizontalAlignment.Center);this.listView1.Columns.Add("内容",600, HorizontalAlignment.Center);AddItemToListView("转债代码", data["bond_id"].ToString());AddItemToListView("转债名称", data["bond_nm"].ToString());AddItemToListView("是否登记强赎", string.IsNullOrEmpty(data["redeem_icon"].ToString()) ? "否" : data["ref_yield_info"].ToString());AddItemToListView("现价", data["price"].ToString());AddItemToListView("评级", data["rating_cd"].ToString());AddItemToListView("PB(下调转股价空间)", data["pb"].ToString() + "  (PB越大说明下修转股价的空间越大)");AddItemToListView("已转股比例", data["cvt_rt"].ToString() + "  (已转股的比率太多了的话,建议不要买了,公司提升股价的愿望较弱)");AddItemToListView("剩余年限", data["year_left"].ToString());AddItemToListView("到期价值", data["maturity"].ToString() + "  (按当前情况买入,持有到期来估算,加上持有中的利息,已扣除利息税,持有超过1年按2年利息计算)");AddItemToListView("到期收益率", data["priceDq"].ToString());AddItemToListView("到期年化收益率", data["priceDqYear"].ToString());AddItemToListView("回售价值", data["backPrice"].ToString() + "  (按当前情况买入,持有到倒数第二年计算,加上持有中的利息,已扣除利息税,持有超过1年按2年利息计算)");AddItemToListView("回售收益率", data["priceHs"].ToString());AddItemToListView("回售年化收益率", data["priceHsYear"].ToString());AddItemToListView("有无回售条款", string.IsNullOrEmpty(data["put_price"].ToString())?"无":"有" );AddItemToListView("有无担保", data["guarantor"].ToString());AddItemToListView("转债占比", data["convert_amt_ratio"].ToString() + "(表示当前剩余可转债占当前流通市值的比值)");AddItemToListView("股东质押比例", data["pledge"].ToString() + "  (此值越高,说明公司越缺钱,公司提高股价或者下修转股价的概率越大)");AddItemToListView("行业", data["indusity"].ToString());AddItemToListView("溢价率", data["premium_rt"].ToString() + "%");
}

Http请求工具类

internal class HttpHelper
{public static string doPost(string Url, string jsonParas){string strURL = Url;//创建一个HTTP请求  HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strURL);//Post请求方式  request.Method = "POST";//内容类型request.ContentType = "application/x-www-form-urlencoded";//设置参数,并进行URL编码 string paraUrlCoded = jsonParas;//System.Web.HttpUtility.UrlEncode(jsonParas);   byte[] payload;//将Json字符串转化为字节  payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);//设置请求的ContentLength   request.ContentLength = payload.Length;//发送请求,获得请求流 Stream writer;try{writer = request.GetRequestStream();//获取用于写入请求数据的Stream对象}catch (Exception ex){throw ex;}//将请求参数写入流writer.Write(payload, 0, payload.Length);writer.Close();//关闭请求流HttpWebResponse response = null;Stream s = null;StreamReader sRead = null;string postContent = null;try{//获得响应流response = (HttpWebResponse)request.GetResponse();s = response.GetResponseStream();sRead = new StreamReader(s);postContent = sRead.ReadToEnd();}catch (WebException ex){response = ex.Response as HttpWebResponse;}finally{if (sRead != null){sRead.Close();}if (s != null){s.Close();}if (response != null){response.Close();}}return postContent;//返回Json数据}public static string doGet(string url){//创建HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);//设置请求方法httpWebRequest.Method = "GET";httpWebRequest.Headers.Add("Cookie", "xxx");httpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36";//发送请求HttpWebResponse response = null;Stream s = null;StreamReader sRead = null;string postContent = null;try{//获得响应流response = (HttpWebResponse)httpWebRequest.GetResponse();s = response.GetResponseStream();sRead = new StreamReader(s);postContent = sRead.ReadToEnd();}catch (WebException ex){response = ex.Response as HttpWebResponse;}finally{if (sRead != null){sRead.Close();}if (s != null){s.Close();}if (response != null){response.Close();}}return postContent;//返回Json数据}}

以上就是可转债分析器的源码啦,大家感兴趣的也可以自己照着这个写写,里面的功能还可以再完善下,比如说: 可能有的人买入的价格与当前的价格有很大的差异,想分析一下按自己买入的价格来计算收益情况,这个也是可以做的,之前在Python里面做过了,逻辑一样,本次就不弄了,感兴趣的同学自己可以弄弄,如果写的过程中发现了问题也可以私信我

更多**好看的内容**和**好玩的案例**请关注**我的微信公众号: 程序猿知秋** 

更多推荐

C# (江湖小新)

本文发布于:2024-02-27 23:17:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1766889.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:小新   江湖

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!