第一次玩这个策略,实测了一个便宜股筛选的策略,半年调仓一次,选择 0< PE< 10,0< PE<1.5,股息率 > 3% 排名前列的股票。中间浪费了一些手续费,收益率还是符合要求,但是发现终究还是要看天吃饭呀~
import pandas as pd
from jqdata import *
from datetime import date, timedelta
import math
# 获取所有股票当天 / 近期的 PE, PB, ROE
q = query(
valuation.code,
valuation.pe_ratio,
valuation.pb_ratio
)
df = get_fundamentals(q)
df = df[df["pe_ratio"] > 0]
df = df[df["pe_ratio"] < 10]
df = df[df["pb_ratio"] > 0]
df = df[df["pb_ratio"] < 1.5]
def DividendRatio(security_list,end_date,count=1):
'''查询股息率(日更新)
输入:股票池,截止日期,获取数量
输出:panel结构,单位:1'''
trade_days = get_trade_days(end_date=end_date,count = count)
security_list.sort()
secu_list = [x[:6] for x in security_list]
code_df = jy.run_query(query(
jy.SecuMain.InnerCode,jy.SecuMain.SecuCode,
# jy.SecuMain.ChiName,jy.SecuMain.CompanyCode
).filter(
jy.SecuMain.SecuCode.in_(secu_list),jy.SecuMain.SecuCategory==1).order_by(jy.SecuMain.SecuCode))
code_df['code'] = security_list
df = jy.run_query(query(
# jy.LC_DIndicesForValuation #得到整表
jy.LC_DIndicesForValuation.InnerCode,
jy.LC_DIndicesForValuation.TradingDay,
jy.LC_DIndicesForValuation.DividendRatio,
).filter(jy.LC_DIndicesForValuation.InnerCode.in_(code_df.InnerCode),
jy.LC_DIndicesForValuation.TradingDay.in_(trade_days)
))
f_df = df.merge(code_df,on='InnerCode').set_index(['TradingDay','code']).drop(['InnerCode','SecuCode'],axis=1)
panel = f_df.to_panel()
return panel
df = df.sort_values(["code"], ascending=[True])
yesterday = date.today() - timedelta(1)
dividend_ratio_panel = DividendRatio(df.code.tolist(), yesterday.strftime("%Y-%m-%d"))
dividend_ratio = dividend_ratio_panel.major_xs(yesterday.strftime("%Y-%m-%d"))["DividendRatio"].tolist()
/opt/conda/lib/python3.5/site-packages/sqlalchemy/dialects/mysql/base.py:1936: SAWarning: MariaDB (10, 2, 6) before 10.2.9 has known issues regarding CHECK constraints, which impact handling of NULL values with SQLAlchemy's boolean datatype (MDEV-13596). An additional issue prevents proper migrations of columns with CHECK constraints (MDEV-11114). Please upgrade to MariaDB 10.2.9 or greater, or use the MariaDB 10.1 series, to avoid these issues. "series, to avoid these issues." % (mdb_version, )) /opt/conda/lib/python3.5/site-packages/ipykernel_launcher.py:23: DeprecationWarning: Panel is deprecated and will be removed in a future version. The recommended way to represent these types of 3-dimensional data are with a MultiIndex on a DataFrame, via the Panel.to_frame() method Alternatively, you can use the xarray package http://xarray.pydata.org/en/stable/. Pandas provides a `.to_xarray()` method to help automate this conversion.
df["dividend_ratio"] = dividend_ratio
df = df.dropna()
df = df[df["dividend_ratio"] > 0.03]
industry_df = finance.run_query(
query(
finance.STK_COMPANY_INFO.code,
finance.STK_COMPANY_INFO.industry_id
).filter(
finance.STK_COMPANY_INFO.code.in_(df["code"].tolist())
)
)
df["industry_id"] = industry_df["industry_id"].tolist()
df_sorted = df.sort_values(["pe_ratio", "pb_ratio", "dividend_ratio"], ascending=[True, True, False])
def get_industry_id(code):
df = finance.run_query(
query(
finance.STK_COMPANY_INFO.industry_id
).filter(
finance.STK_COMPANY_INFO.code == code
)
)
return df["industry_id"][0]
def get_six_stocks(sorted_stock_list, max_stock):
stock_list_info = []
stock_list = []
occur_dict = {}
for loc in range(sorted_stock_list.shape[0]):
field = get_industry_id(sorted_stock_list.iloc[loc]["code"])
if field in occur_dict:
if occur_dict[field] >= max_stock * 0.3:
continue
else:
occur_dict[field] += 1
stock_list_info.append(sorted_stock_list.iloc[loc])
stock_list.append(sorted_stock_list.iloc[loc]["code"])
else:
stock_list_info.append(sorted_stock_list.iloc[loc])
stock_list.append(sorted_stock_list.iloc[loc]["code"])
occur_dict[field] = 1
if len(stock_list) >= max_stock:
break
return stock_list_info, stock_list
stock_list_info, stock_list = get_six_stocks(df_sorted, 10)
stock_list
['000016.XSHE', '600708.XSHG', '600240.XSHG', '000785.XSHE', '000825.XSHE', '000055.XSHE', '000488.XSHE', '600383.XSHG', '600808.XSHG', '002680.XSHE']
# 将 sum_price 中的钱平均分到这些股票上面
def buy_stock(stock_list, sum_price):
# 获取 stock_list 中股票的当日价格
price_dict = history(1, unit='1d', field='avg', security_list=stock_list, df=False, skip_paused=False, fq='pre')
for stock in price_dict.keys():
price_dict[stock] = price_dict[stock][0]
# 将 sum_price 平均分配到这些股票上
sum_price_dict = {}
per_price = sum_price / len(price_dict)
for stock in price_dict.keys():
sum_price_dict[stock] = math.floor(per_price / price_dict[stock] / 100)
sum_value = 0
for stock in sum_price_dict.keys():
sum_value += sum_price_dict[stock] * price_dict[stock]*100
res_value = sum_price - sum_value
return price_dict, sum_price_dict, res_value
(datetime.strptime("2018-09-12", "%Y-%m-%d").date()- timedelta(1)).strftime("%Y-%m-%d")
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-27-a0c3148a8241> in <module>() ----> 1 (datetime.strptime("2018-09-12", "%Y-%m-%d").date()- timedelta(1)).strftime("%Y-%m-%d") AttributeError: module 'datetime' has no attribute 'strptime'
dividend_ratio_panel.major_xs(dividend_ratio_panel.major_axis[0])
DividendRatio | |
---|---|
code | |
000001.XSHE | 0.012546 |
000006.XSHE | 0.035842 |
000016.XSHE | 0.047368 |
000030.XSHE | 0.039463 |
000031.XSHE | 0.011702 |
000036.XSHE | 0.114679 |
000040.XSHE | 0.004004 |
000042.XSHE | 0.015129 |
000043.XSHE | 0.016103 |
000046.XSHE | 0.029240 |
000055.XSHE | 0.038128 |
000059.XSHE | NaN |
000069.XSHE | 0.053476 |
000402.XSHE | 0.048387 |
000415.XSHE | 0.015625 |
000488.XSHE | 0.057614 |
000501.XSHE | 0.008155 |
000537.XSHE | 0.018732 |
000552.XSHE | 0.038462 |
000553.XSHE | 0.006300 |
000581.XSHE | 0.068926 |
000587.XSHE | NaN |
000625.XSHE | 0.074210 |
000631.XSHE | 0.109541 |
000656.XSHE | 0.046468 |
000667.XSHE | 0.011682 |
000671.XSHE | 0.009843 |
000683.XSHE | 0.008177 |
000708.XSHE | 0.032609 |
000718.XSHE | 0.035461 |
... | ... |
601166.XSHG | 0.041854 |
601169.XSHG | 0.045486 |
601186.XSHG | 0.016886 |
601222.XSHG | 0.009685 |
601229.XSHG | 0.030525 |
601288.XSHG | 0.043430 |
601328.XSHG | 0.049497 |
601390.XSHG | 0.015087 |
601398.XSHG | 0.044022 |
601577.XSHG | NaN |
601588.XSHG | 0.044534 |
601599.XSHG | 0.038732 |
601633.XSHG | 0.027869 |
601636.XSHG | 0.080950 |
601666.XSHG | NaN |
601668.XSHG | 0.029704 |
601678.XSHG | 0.039265 |
601699.XSHG | 0.036055 |
601800.XSHG | 0.019383 |
601818.XSHG | 0.045939 |
601828.XSHG | 0.032190 |
601838.XSHG | 0.033533 |
601900.XSHG | 0.029767 |
601939.XSHG | 0.041810 |
601988.XSHG | 0.048619 |
601997.XSHG | 0.029281 |
601998.XSHG | 0.045313 |
603035.XSHG | 0.019696 |
603518.XSHG | 0.011889 |
603766.XSHG | 0.104216 |
194 rows × 1 columns
df["pe_ratio_rank"] = df["pe_ratio"].rank(ascending=0,method='max')
df.sort_values(["pe_ratio_rank"])
code | pe_ratio | pb_ratio | dividend_ratio | industry_id | pe_ratio_rank | |
---|---|---|---|---|---|---|
2618 | 600611.XSHG | 9.9587 | 1.0058 | 0.032432 | G54 | 1.0 |
143 | 000552.XSHE | 9.7008 | 0.8392 | 0.038462 | B06 | 2.0 |
2673 | 600676.XSHG | 9.6030 | 0.8089 | 0.031320 | G54 | 3.0 |
3024 | 601567.XSHG | 9.5901 | 1.1056 | 0.051370 | C40 | 4.0 |
2226 | 600133.XSHG | 9.5514 | 0.9095 | 0.037281 | E48 | 5.0 |
2629 | 600622.XSHG | 9.2769 | 0.9909 | 0.033866 | K70 | 6.0 |
2426 | 600368.XSHG | 9.2709 | 1.0333 | 0.035727 | G54 | 7.0 |
2807 | 600820.XSHG | 9.2249 | 0.9210 | 0.032550 | E48 | 8.0 |
2366 | 600297.XSHG | 9.1467 | 1.0280 | 0.033482 | F52 | 9.0 |
3440 | 603766.XSHG | 9.1353 | 1.3392 | 0.104216 | C37 | 10.0 |
2952 | 601088.XSHG | 9.1030 | 1.3714 | 0.045500 | B06 | 11.0 |
2342 | 600269.XSHG | 9.0497 | 0.6414 | 0.044271 | G54 | 12.0 |
554 | 002091.XSHE | 8.9780 | 1.0402 | 0.041754 | F51 | 13.0 |
256 | 000708.XSHE | 8.9647 | 0.9965 | 0.032609 | C31 | 14.0 |
216 | 000656.XSHE | 8.8436 | 1.4560 | 0.046468 | K70 | 15.0 |
2431 | 600373.XSHG | 8.8012 | 1.0625 | 0.041494 | R85 | 16.0 |
2142 | 600035.XSHG | 8.7846 | 0.8127 | 0.045367 | G54 | 17.0 |
3029 | 601599.XSHG | 8.7359 | 0.9911 | 0.038732 | C17 | 18.0 |
856 | 002394.XSHE | 8.6363 | 1.0396 | 0.079365 | C17 | 19.0 |
2988 | 601216.XSHG | 8.5331 | 1.4853 | 0.070370 | C26 | 20.0 |
465 | 002002.XSHE | 8.5007 | 1.3164 | 0.036365 | C26 | 21.0 |
2932 | 601006.XSHG | 8.4271 | 1.1652 | 0.059569 | G53 | 22.0 |
2738 | 600743.XSHG | 8.3743 | 0.6763 | 0.048544 | K70 | 23.0 |
2902 | 600970.XSHG | 8.3212 | 1.2409 | 0.030039 | E48 | 24.0 |
2917 | 600987.XSHG | 8.3060 | 1.3539 | 0.034696 | C17 | 25.0 |
2575 | 600565.XSHG | 8.2019 | 0.8504 | 0.035391 | K70 | 26.0 |
2147 | 600048.XSHG | 8.1683 | 1.2856 | 0.035235 | K70 | 27.0 |
2715 | 600720.XSHG | 8.1554 | 0.9302 | 0.035938 | C30 | 28.0 |
565 | 002102.XSHE | 8.1498 | 0.7802 | 0.030289 | C27 | 29.0 |
2651 | 600649.XSHG | 8.1240 | 0.7039 | 0.049801 | K70 | 30.0 |
... | ... | ... | ... | ... | ... | ... |
3064 | 601818.XSHG | 6.3281 | 0.7967 | 0.045939 | J66 | 69.0 |
163 | 000581.XSHE | 6.2945 | 1.2637 | 0.068926 | C36 | 70.0 |
2449 | 600393.XSHG | 6.2107 | 0.8896 | 0.069307 | K70 | 71.0 |
2614 | 600606.XSHG | 6.2080 | 1.0711 | 0.043103 | K70 | 72.0 |
265 | 000718.XSHE | 6.1517 | 1.0429 | 0.035461 | K70 | 73.0 |
404 | 000926.XSHE | 6.1378 | 0.5635 | 0.032720 | K70 | 74.0 |
3099 | 601988.XSHG | 5.9936 | 0.7748 | 0.048619 | J66 | 75.0 |
3003 | 601328.XSHG | 5.9498 | 0.7355 | 0.049497 | J66 | 76.0 |
2935 | 601009.XSHG | 5.8820 | 1.0499 | 0.047196 | J66 | 77.0 |
381 | 000898.XSHE | 5.8328 | 0.8222 | 0.039523 | C31 | 78.0 |
2165 | 600068.XSHG | 5.8231 | 1.1424 | 0.043226 | E48 | 79.0 |
2351 | 600279.XSHG | 5.5936 | 0.7469 | 0.054545 | G55 | 80.0 |
2410 | 600350.XSHG | 5.5874 | 0.7485 | 0.040639 | G54 | 81.0 |
2391 | 600325.XSHG | 5.5034 | 1.0846 | 0.048240 | K70 | 82.0 |
2975 | 601166.XSHG | 5.4446 | 0.7883 | 0.041854 | J66 | 83.0 |
53 | 000069.XSHE | 5.1578 | 0.8957 | 0.053476 | K70 | 84.0 |
2749 | 600755.XSHG | 5.1164 | 1.0063 | 0.031397 | F51 | 85.0 |
1141 | 002680.XSHE | 5.0208 | 0.8758 | 0.122699 | C27 | 86.0 |
609 | 002146.XSHE | 4.9925 | 1.1959 | 0.057851 | K70 | 87.0 |
2577 | 600567.XSHG | 4.9160 | 1.1822 | 0.042625 | C22 | 88.0 |
2433 | 600376.XSHG | 4.8543 | 0.7787 | 0.093023 | K70 | 89.0 |
2796 | 600808.XSHG | 4.6497 | 1.1492 | 0.039192 | C31 | 90.0 |
2440 | 600383.XSHG | 4.5508 | 0.9644 | 0.065031 | K70 | 91.0 |
99 | 000488.XSHE | 4.3320 | 0.9892 | 0.057614 | C22 | 92.0 |
42 | 000055.XSHE | 4.2154 | 1.4189 | 0.038128 | C33 | 93.0 |
338 | 000825.XSHE | 4.0956 | 1.0213 | 0.050311 | C31 | 94.0 |
306 | 000785.XSHE | 3.9868 | 1.3978 | 0.030349 | F52 | 95.0 |
2319 | 600240.XSHG | 3.9346 | 0.5852 | 0.031847 | K70 | 96.0 |
2704 | 600708.XSHG | 2.9080 | 0.6737 | 0.046762 | K70 | 97.0 |
12 | 000016.XSHE | 1.5341 | 1.0370 | 0.047368 | C39 | 98.0 |
98 rows × 6 columns
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程