molinchz 发表于 2021-12-9 09:38:30

python可转债问题救助

# -*- coding:utf-8 -*-
import requests
import re
import time
import csv
import pandas as pd
from concurrent.futures import ThreadPoolExecutor
from multiprocessing import Pool
today = time.strftime("%Y-%m-%d", time.localtime())

class ConvertibleBond(object):
    def __init__(self, datas):
      # 转债代码
      self.bond_id = datas['bond_id']
      # 转债名称
      self.bond_nm = datas['bond_nm']
      # 正股代码
      self.stock_id = datas['stock_id']
      # 正股名称
      self.stock_nm = datas['stock_nm']
      #
      self.btype = datas['btype']
      # 转股价
      self.convert_price = datas['convert_price']
      #
      self.convert_price_valid_from = datas['convert_price_valid_from']
      self.convert_dt = datas['convert_dt']
      # 到期时间
      self.maturity_dt = datas['maturity_dt']
      # 正股价
      self.sprice = datas['sprice']
      # 现价
      self.price = datas['price']
      # 到期税前收益率
      self.ytm_rt = datas['ytm_rt']
      # 剩余年限
      self.year_left = datas['year_left']
      # 双低
      self.dblow = datas['dblow']
      # 强赎触发价
      self.force_redeem_price = datas['force_redeem_price']
      # 回售触发价
      self.put_convert_price = datas['put_convert_price']
      # 溢价率
      self.premium_rt = datas['premium_rt']
      # 到期税后收益
      self.ytm_rt_tax = datas['ytm_rt_tax']
      # 剩余规模
      self.orig_iss_amt = datas['orig_iss_amt']
      # 建仓线
      self.build = None
      # 加仓线
      self.plus = None
      # 重仓线
      self.Multiple = None
      # 评级
      self.rating_cd = datas['rating_cd']
      # 操作
      self.cz = None
      # 基准
      self.jz_rate = None
      self.sh_price = None
      self.dq_price = None
      self.sum_lixi = 0
    # 从集思录获取可转债的详情页面里面的可转债到期价值
    def getdarse(self):
      darse_url = 'https://www.jisilu.cn/data/convert_bond_detail/' + str(self.bond_id)
      darse_resp = requests.get(darse_url)
      html = darse_resp.content.decode('utf-8')
      lixi = re.findall(r'''
            <td.+?cpn_desc".+?>(.+?)</td>
            ''', html, re.VERBOSE)
      try:
            lixi = re.findall('.+?(\d+\.\d+).*?', lixi)

            for i in range(len(lixi) - 1):
                self.sum_lixi = self.sum_lixi + float(lixi)
            self.sh_price = float(re.findall('<td.+?redeem_price.+?\n(.+?)</td>', html).strip())
            self.dq_price = self.sh_price + self.sum_lixi * 0.8
            self.build = float(self.dq_price) - (float(self.year_left) * 2.5)
            self.plus = float(self.dq_price) - (float(self.year_left) * 4)
            self.Multiple = float(self.dq_price) - (float(self.year_left) * 6)
            self.jz_rate = (self.build - float(self.price)) / float(self.price)
      except:
            pass
      try:
            if float(self.price) <= self.build:
                self.cz = '建仓'
                if float(self.price) <= self.plus:
                  self.cz = '加仓'
                  if float(self.price) <= self.Multiple:
                        self.cz = '重仓'
      except:
            pass
def get_data():
    ua = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    headers = {'User_Agent': ua}
    url = 'https://www.jisilu.cn/data/cbnew/cb_list/?___jsl=LST___t=1620267814804'
    #最的简单的header字段,防止部分网址反爬虫机制
    # response = requests.get(url, headers=headers)
    data = response.json()
    rows = data['rows']
    return rows
# 最后根据筛选好的目录写入csv文件
def wirte_csv(cbs, name):
    f = open(f'{name}.csv', 'w', encoding='utf-8', newline='')
    csv_writer = csv.writer(f)
    csv_writer.writerow(["代 码", "转债名称", "现 价", "正股名称", "正股价格", "建仓线", "加仓线", "重仓线", "溢价率", "评级",
                         "回售触发价", "强赎触发价", "剩余年限", "双低", "操作"])
    for cb in cbs:
      csv_writer.writerow([cb.bond_id, cb.bond_nm, cb.price, cb.stock_nm, cb.sprice, cb.build, cb.plus, cb.Multiple,
                           cb.premium_rt, cb.rating_cd, cb.put_convert_price, cb.force_redeem_price, cb.year_left,
                           cb.dblow, cb.cz])
    f.close()
def wirte_xls(cbs):
    data_list = []
    for cb in cbs:
      data =
      data_list.append(data)
    df = pd.DataFrame(data_list)    #以数组方式写入
    df.columns = ["代 码", "转债名称", "现 价", "正股名称", "正股价格", "建仓线", "加仓线", "重仓线", "溢价率", "评级", "回售触发价", "强赎触发价", "剩余年限", "双低", "操作"]
    # print(df)
    df[["代 码", "现 价", "正股价格", "建仓线", "加仓线", "重仓线", "强赎触发价", "剩余年限", "双低"]] = df[
      ["代 码", "现 价", "正股价格", "建仓线", "加仓线", "重仓线", "强赎触发价", "剩余年限", "双低"]].astype(float)
    #,dtype = {"代 码' : float,"现 价' : float,"正股价格" : float,"建仓线": float, "加仓线": float, "重仓线": float, "溢价率": float, "回售触发价": float, "强赎触发价": float, "剩余年限": float}
    #df.apply(pd.to_numeric, errors='ignore')
    #df = df.infer_objects()
    df.to_excel('./筛选可转债.xlsx', sheet_name=today, index=False)
    print("=====================================已全部导出!=====================================")
def data(datas):
    data = datas['cell']
    cb = ConvertibleBond(data)
    cb.getdarse()
    opt = ['AAA', 'AA+', 'AA']
    #if cb.build != None and cb.rating_cd in opt and float(cb.price) <= 110 and float(cb.year_left) < 5.5 and float(cb.dblow) < 125:
    if cb.build != None and float(cb.price) <= 200:
      return cb

if __name__ == "__main__":
    start = time.time()
    cbs = []
    bs = []
    t = ThreadPoolExecutor(max_workers=10)
    # gedat = get_data()
    # print(gedat)
    for datas in t.map(data, get_data()):
      tmp = datas
      print(tmp)
      if datas != None:
            cbs.append(datas)

    # 根据到期收益率筛选前50名可转债
    print(list(cbs))
    cbs.sort(key=lambda x: x.jz_rate, reverse=True)
    cbs1 = cbs[:50]
    # 根据溢价率筛选前30名可转债
    cbs1.sort(key=lambda x: float(x.premium_rt[:-1]) * 0.01, reverse=False)
    cbs2 = cbs1[:30]
    cbs2.sort(key=lambda x: float(x.price), reverse=False)
    # print(cbs2)
    wirte_xls(cbs2)
    # wirte_csv(cbs2)
    # print("爬取完成")
    end = time.time()
    print(end - start)


代码 如上,运行到这里for datas in t.map(data, get_data()):   结果 是空,不知是怎么回事,调试数据 是有的,条件也用最简单的,但输出 <__main__.ConvertibleBond object at 0x000000000B374FD0>
<__main__.ConvertibleBond object at 0x000000000B3AA9D0>   ,还有一个问题是,我想单步调试多线程,但发现 进不了def data(datas):这个里面,求调试的方法?谢谢

molinchz 发表于 2021-12-9 15:04:03

那位大佬帮忙解一下{:5_109:}

JetMei 发表于 2021-12-27 19:34:45

本帖最后由 JetMei 于 2021-12-27 19:36 编辑

我是为了弄可转债,开始自学的Python

puianger 发表于 2021-12-27 20:17:51

我也是,我已经写出来了。

puianger 发表于 2021-12-27 20:18:34

加我微信交流一下,pulistie
页: [1]
查看完整版本: python可转债问题救助