私募机构版适当性问卷:用Python实现风险评分与合格投资者校验 简介作为机构投资者参与私募基金投资前的必备合规环节这份风险调查问卷机构版旨在系统评估机构的财务实力、投资目标与风险承受能力协助金融机构履行适当性义务。问卷涵盖基本信息、净资产规模、年营业收入、合格投资者确认以及投资目的等核心项目并附有风险评估评分标准便于实操中快速划分风险等级推荐匹配的私募基金产品。压缩包内含1个docx格式文档文件大小约15KB内容为可直接编辑的问卷模板适用于私募基金管理人、银行私行、财富管理机构等展业场景。已有68人学习使用说明该模板在行业中具有一定关注度。借助这份问卷机构能够如实确认自身风险偏好与财务门槛金融机构也可在合规前提下降低错配风险提升适当性管理效率。1. 机构版私募问卷不是表单是一套可计算的适当性规则拿到这份《私募基金投资者风险调查问卷机构版》时不少人会把它当成填完归档的 Word 模板。但真正做过适当性管理系统的工程师都清楚机构版和个人版完全是两套逻辑个人版的核心是 KYC 打分机构版的核心是合格投资者校验加风险承受力评级两道门槛缺一不可。净资产不低于 1000 万是硬性准入条件风险等级决定机构最终能买 R 几的产品——这两件事如果靠人工 Excel 处理出错只是时间问题。这里把问卷拆成评分规则、校验逻辑和自动再评估触发条件给出能直接落地的 Python 实现。读完后你能把任何一份同类问卷快速结构化到系统里而不是继续让它躺在 Word 文档中。2. 问卷评分标准拆解机构版四级结构与权重分配2.1 机构版和个人版评估维度的本质差异个人版问卷关注年龄、收入、投资经验、可投资资产、风险偏好最终输出 C1-C5 风险等级。机构版问卷多了两个决定性维度机构性质与财务合规性。换句话说个人版先评级后匹配产品机构版是先验资后评级。问卷开头的净资产不低于 1000 万元不是一道打分题而是一道一票否决题——这直接改变了系统的数据模型不能把题目统一放进一个 score 字段里。问卷题目布局也做了分层基本信息与投资目的是第一层财务指标是第二层投资经验与决策流程是第三层风险偏好与流动性需求是第四层。每一层在系统中的角色不同基本层用于留痕财务层用于合格投资者校验后两层才实际进入风险评分。解析问卷时不能按顺序遍历题目编号要按题目编号映射到业务字段# 问卷章节 → 业务字段映射解析时按 section 分组落库 SECTION_FIELDS { basic_identity: {inst_type, legal_rep, contact, cert_type}, financial_indicator: {net_assets, annual_revenue}, invest_experience: {fund_exp, decision_maker}, risk_attitude: {loss_tolerance, target_return, liquidity}, }这套映射的价值在于问卷版本演进时只需要改配置。比如 2025 年版问卷把年营业收入从财务层挪到基本信息层字段集合不变落库逻辑也不用动变化的只是解析配置。实际项目中问卷模板经常微调把解析逻辑和业务逻辑分开是维护成本最低的做法。2.2 百分制评分标准与四个打分维度的分值表从问卷后附的评分标准来看采用的是百分制、四维度加权财务实力 40 分、投资经验 25 分、风险偏好 25 分、流动性需求 10 分。财务实力维度里净资产规模占 30 分、年营业收入占 10 分投资经验维度里私募基金投资年限占 15 分、投资决策机制占 10 分风险偏好维度里可承受最大损失占 15 分、预期收益目标占 10 分流动性需求为单题满分 10 分。评分标准里分值映射以四级选项为主每道题四个选项按保守到激进的顺序排列分值如下。这套映射是依据问卷选项顺序还原的各家机构落地时可以按自己的评分标准微调题目模块选项 A选项 B选项 C选项 D满分净资产规模010203030年营业收入0361010私募投资年限05101515投资决策机制0361010可承受最大损失05101515预期收益目标0361010流动性需求0361010这里要特别注意选项 A 得分 0的语义它不是没作答而是该维度最低分。未作答和选 A 在系统里必须区分开未作答走异常流程选 A 正常参与计算。之前在实际项目里见过把两者都记 0 分的实现结果问卷只填一半也能算出等级这在适当性审查里是直接暴露的合规缺陷。顺带提一下权重调整的问题。如果公司内部风险政策变化需要把投资经验维度从 25 分上调到 30 分同时压缩财务实力占比映射表的分值不是简单的整体缩放而是每个选项分值的重新分配。改动前先跑一遍历史样本做回测确认调整后各等级分布没有剧烈偏移再上线新版本评分标准。2.3 得分到风险等级的阈值映射百分制得分按阈值映射到五档风险等级对应关系参考《证券期货投资者适当性管理办法》的框架总分 0-30 为 C1 保守型31-50 为 C2 稳健型51-70 为 C3 平衡型71-85 为 C4 积极型86-100 为 C5 激进型。总分区间风险等级可购买产品范围0-30C1 保守型R131-50C2 稳健型R1-R251-70C3 平衡型R1-R371-85C4 积极型R1-R486-100C5 激进型R1-R5绝大多数私募基金属于 R5 级产品。按适当性规则只有 C5 机构可以直接申购C4 机构坚持购买必须补充风险揭示确认并由机构书面确认愿意承担超出风险承受能力的后果。评分引擎只负责算分最终是否允许交易是评分等级 特别确认记录两个条件共同决定的结果这个组合判断要在交易链路里做不能依赖前端展示。3. 用 Python 把问卷落成可执行的风险评分引擎3.1 定义机构资料模型与评分映射表先把问卷题目结构化。最直接的做法是用 dataclass 定义机构资料模型每个字段对应问卷中的一个答案选项。字段值保留问卷自身的字母编号而不是直接存储分值这样评分标准调整时只改映射表不需要迁移历史数据。from dataclasses import dataclass, asdict dataclass class InstitutionProfile: inst_type: str # 机构性质: A-国有企事业单位 B-非上市民营企业 C-外资企业 D-上市公司 net_assets: str # 净资产: A-500万以下 B-500万-2000万 C-2000万-1亿 D-1亿以上 annual_revenue: str # 年营业收入四级选项 fund_exp: str # 私募基金投资年限 decision_maker: str # 投资决策机制 loss_tolerance: str # 可承受最大损失 target_return: str # 预期收益目标 liquidity: str # 流动性需求实际对接数据库时这些字段就是问卷表的结构化列。问卷通过 OCR 或人工录入转成 JSON 后直接反序列化到这个对象。评分映射表单独写成常量保持与评估逻辑分离后续任何评分标准的调整都不需要动函数本体SCORING_MATRIX { net_assets: {A: 0, B: 10, C: 20, D: 30}, annual_revenue: {A: 0, B: 3, C: 6, D: 10}, fund_exp: {A: 0, B: 5, C: 10, D: 15}, decision_maker: {A: 0, B: 3, C: 6, D: 10}, loss_tolerance: {A: 0, B: 5, C: 10, D: 15}, target_return: {A: 0, B: 3, C: 6, D: 10}, liquidity: {A: 0, B: 3, C: 6, D: 10}, }映射表是评分标准在代码里的唯一载体。将来评分标准从 100 分制改成 120 分制或者新增一个资产负债率维度只需改这张表和阈值配置评估函数完全不需要变。3.2 评分计算与等级判定函数评分函数遍历映射表对每个维度取机构选择对应的分值累加同时记录分值明细。映射表里没有的答案统一记 0 分但在明细里标记 INVALID供上层合规校验识别。RISK_LEVELS [ (30, C1-保守型), (50, C2-稳健型), (70, C3-平衡型), (85, C4-积极型), (100, C5-激进型), ] def evaluate(profile: InstitutionProfile) - dict: 计算机构风险承受力得分与等级 total 0 details {} invalid [] for key, score_map in SCORING_MATRIX.items(): answer getattr(profile, key, E) # 缺省视为无效答案 if answer not in score_map: invalid.append(key) details[key] {answer: answer, score: 0, status: INVALID} continue score score_map[answer] details[key] {answer: answer, score: score, status: OK} total score level UNRATED for threshold, name in RISK_LEVELS: if total threshold: level name break return { total_score: total, level: level, details: details, invalid_fields: invalid, passed: len(invalid) 0, }逻辑说明getattr(profile, key, E)用缺省值 E 兜底防止某个字段漏填导致 KeyErrorRISK_LEVELS 按阈值升序排列遍历时第一次满足 total ≤ threshold 就返回对应等级86-100 分自然落到 C5invalid 列表记录所有无效答案评分函数本身不拒绝任何输入判定权交给上层校验逻辑。提示某个维度得 0 分有两种可能——选了选项 A最低档或者没作答。details 里的 status 必须能把这两种情况分开评分结论页只允许展示 OK 状态下的得分INVALID 状态一律拦截。实际跑数据时如果发现某机构得分异常优先检查原始问卷里答案字母是否被 OCR 识别错误比如把 B 识别成 8、把 D 识别成 O。这类脏数据进不到评分逻辑里因为答案不在映射表中会被 invalid_fields 拦下来但拦截的代价是工单滞留。所以解析问卷时要对答案字段做白名单校验只接受 A/B/C/D 四个字母从源头过滤。3.3 结构化输出与版本归档评分结果建议直接序列化成 JSON 存入适当性管理系统作为留痕证据的一部分。展示端再把 details 渲染成问卷样式的表格或者生成 PDF 附件归档。import json def build_record(profile: InstitutionProfile) - str: result evaluate(profile) record { profile: asdict(profile), evaluation: result, evaluated_at: 2025-01-15 10:30:00, operator: systemfund_company, version: survey_inst_2024_v3, } return json.dumps(record, ensure_asciiFalse, indent2)version 字段是关键。适当性监管要求评分标准和问卷版本可追溯同一机构在不同年份做的问卷版本不同评分标准也可能不同。归档必须带版本号否则审计时无法解释为什么同一机构前后风险等级发生变化。evaluated_at 建议取数据库时间戳而不是应用服务器本地时间避免大批量操作时时间精度不一致。4. 合格投资者校验边界一票否决与异常数据拦截4.1 净资产门槛的硬校验实现合格投资者校验必须先于评分执行。机构净资产不低于 1000 万是法定门槛。问卷里净资产题目选 A500 万以下直接判不通过选 B500 万-2000 万属于边界区间不能直接放行要补充净资产审计报告或财务报表确认实际净资产不低于 1000 万选 C 或 D 默认通过留待审计抽查。def check_qualified(profile: InstitutionProfile, verified_net_assets: float | None None) - dict: 合格投资者校验verified_net_assets 为审计确认值万元 q profile.net_assets if q A: return {pass: False, reason: 净资产低于500万未达1000万门槛} if q B: if verified_net_assets is None: return {pass: PENDING, reason: 净资产区间含混需补充审计报告确认是否≥1000万} if verified_net_assets 1000: return {pass: True, reason: f经审计确认净资产{verified_net_assets}万元} return {pass: False, reason: 审计确认净资产未达1000万门槛} return {pass: True, reason: 净资产区间明确高于门槛}PENDING 状态是这套校验里容易被忽略的设计。实际项目里如果只做 pass/fail 两态选 B 的机构会被一刀切拒绝或放行前者误伤合格机构、后者埋合规隐患。三态设计配合人工审核工单是适当性管理系统里比较稳妥的取舍。从排错角度看如果机构反馈我们明明满足了条件却被拒优先查 verified_net_assets 参数有没有从人工审核模块传进来。这个参数是独立于问卷之外的确认值很多实现在问卷校验时忘了带上它导致所有选 B 的机构都被 PENDING 卡住形成大面积工单积压。4.2 机构性质与财务数据的交叉验证机构性质对净资产、营业收入选项有明显约束。比如选 D上市公司但净资产选 B500 万-2000 万基本不可能A 股上市公司净资产绝大多数远超这个区间选 A国有企事业单位但年收入选最低档也需要警惕。这类矛盾不一定代表机构弄虚作假但必须人工核实不能直接进评分流程。机构性质净资产约束校验动作上市公司必须 ≥ C 档与公开财报交叉核对不一致退回国有企事业单位不做硬约束确认净资产选项与审计报告一致外资企业不做硬约束确认净资产口径为境内法人主体非上市民营企业不做硬约束抽检财务报表外资企业这里有个容易踩坑的点境外母公司的净资产不能算进境内法人机构的净资产问卷填的是境内法人主体自身的数据。系统字段必须明确是境内法人净资产还是合并口径净资产解析问卷时在元数据里标注口径避免后续审计时产生争议。4.3 综合判定优先级与失效降级处理把合格投资者校验和评分结果放到一起做综合判定。前面评分函数的 invalid_fields 在这里派上用场只要有一个维度没有有效答案评分结果就不能作为适当性依据系统进入待完善状态而不是给默认低分。def decide_eligibility(profile: InstitutionProfile, verified_net_assets: float | None None) - dict: qual check_qualified(profile, verified_net_assets) eval_result evaluate(profile) if qual[pass] is False: return {decision: REJECT_HARD, detail: qual} if qual[pass] PENDING: return {decision: REJECT_MANUAL_REVIEW, detail: qual} if not eval_result[passed]: return {decision: REJECT_INCOMPLETE, detail: {invalid: eval_result[invalid_fields]}} return {decision: ALLOW, level: eval_result[level], product_max_risk: R5 if eval_result[level] C5 else R4}判定优先级是合格投资者硬性拒绝 边界待人工复核 问卷完整性 风险等级。这个顺序不能反反了就会出现净资产不达标但风险等级是 C5 的机构被放行到申购环节。问卷有效期建议在系统里配置为一年到期前 30 天自动生成再评估任务机构发生重大变更净资产大幅下降、经营范围变更、法定代表人变更时立即触发重新评估而不是等问卷自然到期。5. 评分引擎接入适当性管理流程的几个落地技巧先讲触发时机。制度上要求了解客户信息发生重大变化时重新评估但重大变化的标准要翻译成运营人员能执行的规则。我习惯在机构资料表上加一个 risk_review_triggers 字段存 JSON 规则数组[ {event: net_assets_decline_30pct, action: immediate_reassess}, {event: questionnaire_expire_30d, action: pending_review}, {event: legal_rep_change, action: reassess} ]运营系统消费这些规则生成待办工单技术侧不用每次改代码。第二个技巧是评分标准做成配置而不是写死在代码里。前面 SCORING_MATRIX 已经和评估逻辑分离生产环境更灵活的存法是把映射表放数据库或独立配置表版本号与问卷模板版本关联。评分标准修改后历史评估记录保留旧版本得分明细新评估使用新版本审计对照时结构清晰。第三个技巧是留痕字段不要省。监管人员现场检查时通常要求调取任意一笔申购对应的适当性全链路问卷原文件、评分明细、风险等级、产品风险等级、特别确认函、复核人意见。我在归档表里固定放 audit_trail 字段用 JSON 存 questionnaire_file_hash、scoring_version、evaluator、review_operator 和时间戳查询时一条 SQL 就能拼出完整链路。最后提醒一个容易忽视的点评分引擎输出的风险等级与产品匹配关系要在交易系统里做硬校验而不是只在营销端做提示。申购接口调用时实时查询该机构当前风险等级与产品风险等级不匹配直接拒绝并返回错误码错误码对应到适当性规则条款。这样即使前端绕过页面后端交易链路也能堵住。本文还有配套的精品资源点击获取