feat: support multiple manager when outputing high-score-fund

main
jackluson 2 years ago
parent 381073fc19
commit 72450f19dd

@ -0,0 +1,43 @@
'''
Desc:
File: /query.py
Project: crud
File Created: Wednesday, 21st September 2022 10:54:27 pm
Author: luxuemin2108@gmail.com
-----
Copyright (c) 2022 Camel Lu
'''
import sys
sys.path.append('./src')
from sqlalchemy.orm import Session
from sqlalchemy import and_
from models.fund import FundBase, FundQuarter
from models.manager import ManagerAssoc
from models.var import engine
session = Session(engine)
def query_high_score_funds(quarter_index):
words = ['%指数%', '%C', '%E', '%H%']
rule = and_(*[FundBase.fund_name.notlike(w) for w in words])
res = session.query(FundQuarter,ManagerAssoc,FundBase).where(FundQuarter.fund_code == ManagerAssoc.fund_code).where(FundQuarter.fund_code == FundBase.fund_code).filter(FundQuarter.quarter_index == quarter_index, \
FundQuarter.morning_star_rating_5 >= 3, # 5年评级大于等于3
FundQuarter.morning_star_rating_3 == 5, # 3年评级等于5
FundQuarter.stock_position_total >= 50, # 股票仓位大于50
FundQuarter.stock_position_ten <= 60, # 十大股票仓位小于60
FundQuarter.risk_assessment_sharpby > 1, # 夏普比例大于1
FundQuarter.risk_rating_2 > 1, # 2年风险评级大于1
FundQuarter.risk_rating_3 > 1, # 3年风险评级大于1
FundQuarter.risk_rating_5 > 1, # 5年风险评级大于1
# ManagerAssoc.manager_start_date < last_year_date, # 至少任职该基金一年
FundQuarter.total_asset < 100, # 总规模资金小于100亿
).filter(rule).all()
return res
if __name__ == '__main__':
quarter_index = '2022-Q2'
fund_list = query_high_score_funds(quarter_index)
# print("fund_list",fund_list)

@ -7,36 +7,73 @@ Author: luxuemin2108@gmail.com
-----
Copyright (c) 2021 Camel Lu
'''
from datetime import timedelta, date
from utils.index import get_last_quarter_str, update_xlsx_file_with_insert
from sql_model.fund_query import FundQuery
from pprint import pprint
from crud.query import query_high_score_funds
import pandas as pd
def output_high_score_funds(each_query=None, quarter_index=None):
def output_high_score_funds(quarter_index=None):
"""
输出高分基金
"""
if each_query == None:
each_query = FundQuery()
if quarter_index == None:
quarter_index = get_last_quarter_str()
print("quarter_index", quarter_index)
high_score_funds = each_query.select_high_score_funds(
quarter_index=quarter_index)
columns_bk = ['代码', '名称', '季度', '总资产', '现任基金经理管理起始时间', '投资风格', '三月最大回撤', '六月最大回撤', '夏普比率', '阿尔法系数', '贝塔系数',
'R平方', '标准差', '风险系数', '两年风险评级', '三年风险评级', '五年风险评级', '五年晨星评级', '三年晨星评级', '股票仓位', '十大持股仓位']
fund_list = query_high_score_funds(quarter_index)
funds_map = {}
for fund in fund_list:
fund_code = fund[0].fund_code
exist_fund = funds_map.get(fund_code)
if exist_fund:
exist_fund.append(fund)
funds_map[fund_code] = exist_fund
else:
funds_map[fund_code] = [fund]
high_score_funds = []
delta = timedelta(days=1 * 365)
date_now = date.today()
for fund_code, funds in funds_map.items():
fund_info = []
is_meet_manager_start_date = False
is_super_one = False
for fund_item in funds:
if is_meet_manager_start_date == False and date_now - delta > fund_item[1].manager_start_date:
is_meet_manager_start_date = True
if is_super_one == True:
fund_info[3] = fund_info[3] + ",\n" + fund_item[1].manager.name
manager_start_date = fund_item[1].manager_start_date.strftime('%Y-%m-%d')
fund_info[4] = fund_info[4] + ",\n" + manager_start_date
else:
is_super_one = True
fund_info.append(fund_item[0].fund_code)
fund_info.append(fund_item[0].fund.fund_name)
fund_info.append(fund_item[0].investname_style)
fund_info.append(fund_item[1].manager.name)
manager_start_date = fund_item[1].manager_start_date.strftime('%Y-%m-%d')
fund_info.append(manager_start_date)
fund_info.append(fund_item[0].fund.found_date)
fund_info.append(fund_item[0].morning_star_rating_3)
fund_info.append(fund_item[0].morning_star_rating_5)
fund_info.append(fund_item[0].risk_assessment_sharpby)
fund_info.append(fund_item[0].stock_position_total)
fund_info.append(fund_item[0].stock_position_ten)
fund_info.append(fund_item[0].risk_rating_2)
fund_info.append(fund_item[0].risk_rating_3)
fund_info.append(fund_item[0].risk_rating_5)
fund_info.append(fund_item[0].risk_statistics_alpha)
fund_info.append(fund_item[0].risk_statistics_beta)
fund_info.append(fund_item[0].risk_assessment_standard_deviation)
fund_info.append(fund_item[0].total_asset)
fund_info.append(fund_item[0].quarter_index)
if is_meet_manager_start_date:
high_score_funds.append(fund_info)
columns = ['代码', '名称', '投资风格', '基金经理', '现任经理管理起始时间', '成立时间', '三年晨星评级', '五年晨星评级', '夏普比率', '股票仓位', '十大持股仓位',
'两年风险评级', '三年风险评级', '五年风险评级', '阿尔法系数', '贝塔系数', '标准差', '总资产', '数据更新时间']
df_high_score_funds = pd.DataFrame(high_score_funds, columns=columns)
# pprint(df_high_score_funds)
path = './outcome/数据整理/funds/high-score-funds.xlsx'
update_xlsx_file_with_insert(path, df_high_score_funds, quarter_index)
if __name__ == '__main__':
each_query = FundQuery()
output_high_score_funds(each_query)
output_high_score_funds()

@ -9,16 +9,27 @@ Copyright (c) 2022 Camel Lu
'''
import sys
sys.path.append('./src')
from sqlalchemy.orm import relationship
from sqlalchemy import Table
from models.var import prefix, ORM_Base, engine
fund_table_base = prefix + 'base'
fund_base_tablename = prefix + 'base'
fund_quarter_tablename = prefix + 'quarter'
fund_table = Table(fund_table_base, ORM_Base.metadata, autoload=True, autoload_with=engine)
fund_base_table = Table(fund_base_tablename, ORM_Base.metadata, autoload=True, autoload_with=engine)
fund_quarter_table = Table(fund_quarter_tablename, ORM_Base.metadata, autoload=True, autoload_with=engine)
class Fund(ORM_Base):
__table__ = fund_table
class FundBase(ORM_Base):
__table__ = fund_base_table
def __repr__(self):
return f"Fund Base(id={self.id!r}, name={self.fund_code!r}, manager_id={self.fund_name!r})"
class FundQuarter(ORM_Base):
__table__ = fund_quarter_table
fund = relationship('FundBase', backref='fund_quarter')
def __repr__(self):
return f"Fund {fund_quarter_tablename}(id={self.id!r}, name={self.fund_code!r})"

@ -105,46 +105,6 @@ class FundQuery(BaseQuery):
sql, [self.quarter_date, self.quarter_index, page_start, page_limit]) # 执行sql语句
return self.cursor.fetchall() # 获取查询的所有记录
def select_high_score_funds(self, *, quarter_index=None):
"""获取高分基金池
Args:
quarter_index (string, optional): 查询季度. Defaults to None.
Returns:
[]tuple: 高分基金池
"""
last_year_time = time.localtime(time.time() - 365 * 24 * 3600)
last_year_date = time.strftime('%Y-%m-%d', last_year_time)
if quarter_index == None:
quarter_index = self.quarter_index
sql = "SELECT a.fund_code, b.fund_name, a.investname_style, c.name, a.manager_start_date, b.found_date, a.morning_star_rating_3, \
a.morning_star_rating_5, a.risk_assessment_sharpby, a.stock_position_total, a.stock_position_ten,\
a.risk_rating_2, a.risk_rating_3, a.risk_rating_5,\
a.risk_statistics_alpha, a.risk_statistics_beta, a.risk_assessment_standard_deviation,\
a.total_asset, a.quarter_index FROM fund_morning_quarter as a \
LEFT JOIN fund_morning_base AS b ON a.fund_code = b.fund_code \
LEFT JOIN fund_morning_manager AS c ON c.manager_id = a.manager_id \
WHERE b.fund_name NOT LIKE '%%C' AND b.fund_name NOT LIKE '%%E' AND b.fund_name NOT LIKE '%%H%%' AND b.fund_name NOT LIKE '%%指数%%' \
AND a.quarter_index = %s AND a.total_asset < 100 AND \
a.morning_star_rating_5 >= 3 AND a.morning_star_rating_3 = 5 AND a.stock_position_total >= 50 AND a.stock_position_ten <= 60 \
AND a.risk_assessment_sharpby > 1 AND a.risk_rating_2 > 1 AND a.risk_rating_3 > 1 AND a.risk_rating_5 > 1 AND a.manager_start_date < %s \
ORDER BY a.risk_assessment_sharpby DESC, a.risk_statistics_alpha DESC;"
sql_bk = "SELECT a.fund_code, b.fund_name, a.quarter_index, a.total_asset , a.manager_start_date, \
a.investname_style, a.three_month_retracement, a.june_month_retracement, a.risk_assessment_sharpby,\
a.risk_statistics_alpha, a.risk_statistics_beta, a.risk_statistics_r_square, a.risk_assessment_standard_deviation,\
a.risk_assessment_risk_coefficient, a.risk_rating_2, a.risk_rating_3, a.risk_rating_5, a.morning_star_rating_5,\
a.morning_star_rating_3, a.stock_position_total, a.stock_position_ten FROM fund_morning_quarter as a \
LEFT JOIN fund_morning_base AS b ON a.fund_code = b.fund_code \
WHERE b.fund_name NOT LIKE '%%C' AND b.fund_name NOT LIKE '%%H' AND b.fund_name NOT LIKE '%%E' AND a.quarter_index = %s AND \
a.morning_star_rating_5 >= 3 AND a.morning_star_rating_3 = 5 AND a.stock_position_total >= 50 AND a.stock_position_ten <= 60 \
AND a.risk_assessment_sharpby >1 AND a.risk_rating_2 > 1 AND a.risk_rating_3 > 1 AND a.risk_rating_5 > 1 AND a.manager_start_date < %s \
ORDER BY a.risk_assessment_sharpby DESC, a.risk_rating_5 DESC;"
self.cursor.execute(sql, [quarter_index, last_year_date]) # 执行sql语句
results = self.cursor.fetchall() # 获取查询的所有记录
return results
def select_certain_condition_funds(self, *, quarter_index=None, morning_star_rating_5=None, morning_star_rating_3=None, manager_start_date=None, stock_position_total=None, stock_position_ten=None, **rest_dicts):
print("rest_dicts", rest_dicts)
if quarter_index == None:

@ -254,13 +254,16 @@ def update_xlsx_file_with_insert(path, df_data, sheet_name, index = 0):
if os.path.exists(path):
writer = pd.ExcelWriter(path, engine='openpyxl')
workbook = load_workbook(path)
if sheet_name in workbook.sheetnames:
del workbook[sheet_name]
writer.book = workbook
df_data.to_excel(
writer, sheet_name=sheet_name)
workbook = writer.book
writer.sheets = {ws.title:ws for ws in workbook.worksheets}
del workbook[sheet_name]
# workbook.remove(sheet_name)
del workbook[sheet_name]
workbook._add_sheet(writer.sheets.get(sheet_name), index)
writer.book = workbook

Loading…
Cancel
Save