组合

持仓、容量、暴露以及组合模型输入。

面向任务的示例参见使用指南。以下签名由与本站点其余内容同一提交的公共头文件生成。

class portfolio_inputs

组合领域工作流使用的独立可选输入表。

每个提供的帧由本对象持有;materialize() 返回另一份独立副本。只返回已提供的字段,分别位于 returns、positions、transactions 与 benchmark_returns 之下。提供的空帧会被保留。

公共函数

inline portfolio_inputs(std::optional<dataframe> returns = std::nullopt, std::optional<dataframe> positions = std::nullopt, std::optional<dataframe> transactions = std::nullopt, std::optional<dataframe> benchmark_returns = std::nullopt)

由可选输入帧构造容器。

参数:
  • returns -- Optional return frame stored under returns.

  • positions -- Optional position frame stored under positions.

  • transactions -- Optional transaction frame stored under transactions.

  • benchmark_returns -- Optional benchmark frame stored under benchmark_returns.

inline std::map<std::string, dataframe> materialize() const

返回每张已提供输入表的独立副本。

仅为已提供的字段添加键;提供的空帧会被保留。重复调用会产生彼此独立的帧。

返回:

Map from input name to an owned copy of the frame.

struct capacity_assessment

assess_liquidity() 的值语义结果。

公共成员

dataframe liquidation_days

各非现金资产的清仓所需天数,索引为滚动成交量预热之后的持仓日期。

std::vector<ticker_liquidity> ticker_maximums

各标的的最大清仓天数与配置百分比,按标的排序。

std::vector<transaction_liquidity> low_liquidity_transactions

扫描窗口内各标的的最大 K 线消耗百分比,按标的排序。

struct capacity_config

控制 assess_liquidity() 的参数。

公共成员

double max_bar_consumption = 0.2

每日假定可成交的单根 K 线金额占比上限;必须落在 (0, 1]。

double capital_base = 1'000'000.0

用于缩放持仓配置的货币金额资本;必须为正。

std::size_t mean_volume_window = 5U

滚动平均成交额所用的前置 K 线数量;必须不小于 1。

std::optional<std::size_t> last_n_days

可选的末尾天数扫描上限;设置时必须不小于 1。

struct daily_txn_bar

一条按标的/日期聚合的交易 K 线。

公共成员

timestamp date

交易日期。

std::string symbol

成交标的。

double amount

当日交易金额的绝对值之和。

double price

该日期的 K 线价格。

double volume

该日期的 K 线股份成交量。

struct exposure_bundle

共享同一索引的多头、空头、总敞口与净敞口帧。

公共成员

dataframe long_exposure

多头暴露值;单位由产生它的接口决定。

dataframe short_exposure

空头暴露值;符号与单位由产生它的接口决定。

dataframe gross_exposure

总暴露值;单位由产生它的接口决定。

dataframe net_exposure

净暴露(多头减空头);未填充该值的接口为空。

struct long_short_aggregate

针对全部、多头与空头完整交易的逐统计量结果。

公共成员

std::vector<std::string> statistic_names

统计量名称,按输入顺序排列。

std::vector<double> all_trades

全部完整交易的统计量值。

std::vector<double> long_trades

多头完整交易的统计量值;不存在时为 NaN。

std::vector<double> short_trades

空头完整交易的统计量值;不存在时为 NaN。

struct position_record

一条堆叠形式的持仓观测。

公共成员

timestamp date

持仓时间戳。

std::string symbol

持仓列名。

double value

持仓值;可能为 NaN。

struct ranked_position

由 get_top_long_short_abs() 排序的标的与值配对。

公共成员

std::string symbol

持仓列名。

double value

该列各行上的极值。

struct round_trip_stat_table

带行列标签的矩形统计表。

公共成员

std::vector<std::string> row_labels

数值行的标签。

std::vector<std::string> column_labels

数值列的标签。

std::vector<std::vector<double>> values

行优先存储的统计量值。

struct round_trip_statistic

agg_all_long_short() 应用的命名统计量。

公共成员

std::string name

输出统计量名称。

std::function<double(std::span<const double>)> compute

可调用统计量;聚合之前必须设置。

struct round_trip_stats

完整交易表与各标的的收益统计。

前四个表按该顺序包含非空的 All trades、short 与 long 分组的行。

公共成员

round_trip_stat_table pnl

盈亏统计。

round_trip_stat_table summary

交易笔数与胜率。

round_trip_stat_table duration

以天计的持仓时长统计,以及每日与每月交易数。

round_trip_stat_table returns

完整交易收益统计。

std::vector<std::string> symbol_labels

标的,按升序排列。

std::vector<std::string> symbol_stat_labels

八项逐标的收益统计量的固定标签。

std::vector<std::vector<double>> symbol_values

每个标的统计量一行,symbol_labels 中每个标的对应一个值。

struct round_trip_transaction

用于构造完整交易输入与平仓交易的交易记录。

公共成员

timestamp date = 0

UTC 纳秒时间戳。

std::string symbol

成交标的。

double amount = 0.0

带符号数量。

double price = 0.0

单位成交价。

struct sector_assignment

get_sector_exposures() 使用的标的到行业指派。

公共成员

std::string symbol

持仓列名。

std::string sector

输出行业列名。

struct sector_definition

暴露分桶的数值标识与输出标签。

公共成员

double id

分桶数值标识;行业暴露将其与面板单元格比较。

std::string name

输出列标签。

struct ticker_liquidity

各标的的最大清仓时间。

公共成员

std::string symbol

持仓列名。

double days_to_liquidate

扫描中的最大天数;无则为 NaN。

double position_allocation_pct

该日期的持仓配置百分比(100 * fraction)。

struct top_positions

排序后的多头、空头与绝对持仓列表。

公共成员

std::vector<ranked_position> long_positions

最大的正向列极值,按降序排列。

std::vector<ranked_position> short_positions

最负的列极值,按升序排列。

std::vector<ranked_position> absolute_positions

绝对值最大的列极值,按降序排列。

struct trade_record

流动性辅助函数使用的一笔交易。

公共成员

timestamp date

交易时间戳;K 线辅助函数按精确值匹配。

std::string symbol

成交标的。

double amount

带符号数量;使用其绝对值。

struct transaction_liquidity

各标的最差的交易 K 线消耗。

公共成员

std::string symbol

成交标的。

timestamp date

消耗量最大的日期。

double max_percent_bar_consumed

成交量占该 K 线成交量的百分比。

enum class fincore::turnover_denominator

get_turnover() 使用的除数约定。

取值:

enumerator actual_gross_book

上一行与当前行总规模(不含现金)的平均值;第一行使用当前总规模的一半。

enumerator portfolio_value

所有数值持仓列(含现金)的行和。

std::vector<round_trip_transaction> fincore::add_closing_transactions(const dataframe &positions, std::span<const round_trip_transaction> transactions)

为每个仍未平掉的持仓追加一笔平仓交易。

各标的的净金额由交易记录计算。对于持仓中绝对净金额不小于 1e-6 的每个非现金 double 列,在最后一个持仓时间戳加一秒处追加一笔平仓交易。其金额为净金额的相反数,其价格为最终持仓值除以净金额。随后从合并结果中移除金额为零的交易。

参数:
  • positions -- Frame with at least one row and a double cash column; its other double columns are treated as positions.

  • transactions -- Existing transactions, preserved in input order.

抛出:

input_error -- If positions is empty or has no double cash column.

返回:

Input transactions followed by generated closing transactions, with zero-amount entries removed.

dataframe fincore::adjust_returns_for_slippage(const dataframe &returns, const dataframe &positions, const dataframe &transactions, double slippage_bps, std::string_view returns_column_name = returns_column, std::string_view amount_column_name = transaction_amount_column, std::string_view price_column_name = transaction_price_column)

按成交名义金额调整每日收益率以计入滑点。

对收益率、持仓与交易日期并集排序后的每个 UTC 日进行处理。同时具有收益率与组合价值的日期提供 pnl = return * portfolio_value;从该损益中扣除 成交名义金额 * slippage_bps / 10000 的成本,并按调整后与原始损益之比重新缩放当日收益率。没有可用收益率/损益配对的日子以及损益为零的日子得到 0.0。

参数:
  • returns -- Frame with a double returns_column_name column whose UTC days are strictly increasing and unique.

  • positions -- Wide position frame whose double columns are summed per row to obtain portfolio value; its UTC days must be strictly increasing and unique.

  • transactions -- Transaction frame consumed by get_txn_vol().

  • slippage_bps -- Slippage in basis points of traded notional.

  • returns_column_name -- Input and output return column name.

  • amount_column_name -- Signed-quantity column in transactions.

  • price_column_name -- Execution-price column in transactions.

抛出:

input_error -- If a column is invalid, a return or position day is duplicated or out of order, or a required transaction column is invalid.

返回:

Frame indexed by the sorted union of UTC days with adjusted decimal returns under returns_column_name.

long_short_aggregate fincore::agg_all_long_short(const dataframe &round_trips, std::string_view column, std::span<const round_trip_statistic> statistics)

对全部、多头与空头完整交易应用调用方提供的统计量。

每个统计量先按行序作用于 column 的所有值,再作用于由必需的 long 布尔列选出的子集。子集为空的统计量在该子集上返回 NaN。

参数:
  • round_trips -- Frame containing a double value column and a bool long column.

  • column -- Value column to aggregate.

  • statistics -- Statistics to apply, in output order.

抛出:

input_error -- If column is not a valid double column, a column length differs from the frame index length, or a statistic has no callable compute.

返回:

Statistic names and per-statistic values for all, long and short trades.

dataframe fincore::apply_sector_mappings_to_round_trips(const dataframe &round_trips, const std::map<std::string, std::string> &sector_mappings)

复制完整交易并依据标的映射添加行业列。

输出保留输入索引、所有 double 列,以及除已有 sector 之外的所有字符串列;其他类型的列不会被复制。存在字符串类型的 symbol 列时,使用 sector_mappings 追加一个新的 sector 列;映射中不存在的标的得到空字符串。没有 symbol 列时不会添加行业列。

参数:
  • round_trips -- Round-trip frame to copy.

  • sector_mappings -- Symbol-to-sector mapping.

返回:

Copied frame with the mapped sector column when possible.

dataframe fincore::apply_slippage_penalty(const dataframe &returns, const dataframe &transactions_with_bar_data, double simulate_starting_capital, double backtest_starting_capital, double impact = 0.1, std::string_view returns_column_name = returns_column, std::string_view amount_column_name = transaction_amount_column, std::string_view price_column_name = transaction_price_column, std::string_view volume_column_name = transaction_bar_volume_column)

对每日收益率应用二次市场冲击惩罚。

交易按 simulate_starting_capital / backtest_starting_capital 从回测资本缩放为模拟资本。对每笔交易,shares = |scaled amount|,dollars = price * shares,惩罚为 (shares / volume)^2 * impact * dollars;惩罚按 UTC 日汇总。收益日复合为财富,每日惩罚除以模拟组合价值后从当日收益中扣除。

参数:
  • returns -- Frame with a double returns_column_name column whose UTC days are strictly increasing and unique.

  • transactions_with_bar_data -- Frame with double amount, price and volume columns of matching lengths.

  • simulate_starting_capital -- Starting capital of the simulation.

  • backtest_starting_capital -- Starting capital of the backtest; must be nonzero.

  • impact -- Quadratic impact coefficient.

  • returns_column_name -- Input and output return column name.

  • amount_column_name -- Signed-quantity column.

  • price_column_name -- Execution-price column.

  • volume_column_name -- Bar share-volume column.

抛出:

input_error -- If backtest_starting_capital is zero, a column name is empty or duplicated, a required column is absent or not double, its length differs from the frame index length, or return days are duplicated or out of order.

返回:

Frame indexed by UTC return days with adjusted decimal returns under returns_column_name.

capacity_assessment fincore::assess_liquidity(const dataframe &positions, std::span<const trade_record> transactions, const dataframe &prices, const dataframe &volumes, const capacity_config &config = {})

评估持仓与交易流动性。

使用同一份已校验配置组合 days_to_liquidate_positions()、get_max_days_to_liquidate_by_ticker() 与 get_low_liquidity_transactions()。

参数:
  • positions -- Wide position frame with a double column per asset; a cash column is excluded when present.

  • transactions -- Trades used for the low-liquidity scan.

  • prices -- Bar price frame with the same index as positions and a double column per position asset.

  • volumes -- Bar share-volume frame with the same index as positions and a double column per position asset.

  • config -- Liquidity parameters, validated before any computation.

抛出:

input_error -- If config is invalid, an input index differs, a transaction amount is non-finite, a trade date is absent from the price index, or a position double column is malformed. The price and volume frames must also provide a double column for every position asset.

返回:

Value-owned liquidation frame and per-symbol liquidity records.

exposure_bundle fincore::compute_cap_exposures(const dataframe &positions, const dataframe &caps, std::string_view cash_column_name = cash_column)

返回市值分桶的暴露比例。

分桶使用市值面板单位下的闭区间:Micro 覆盖 50M-300M,Small 300M-2B,Mid 2B-10B,Large 10B-200B,Mega 为 200B 及以上。低于 50M 的值不匹配任何分桶,落在共享边界上的值可同时匹配相邻分桶。暴露比例的计算方式与 compute_sector_exposures() 相同。

参数:
  • positions -- Wide position frame.

  • caps -- Wide market-cap panel with the same index as positions and a double column for every non-cash asset.

  • cash_column_name -- Name of the cash column excluded when present.

抛出:

input_error -- If the frames do not share an identical index, cash_column_name is empty, no double position column exists, or a position column length differs from the index length.

返回:

Bundle of long, short, gross and net exposure frames with Micro, Small, Mid, Large and Mega columns.

exposure_bundle fincore::compute_sector_exposures(const dataframe &positions, const dataframe &sectors, std::span<const sector_definition> definitions, std::string_view cash_column_name = cash_column)

返回行业的多头、空头、总暴露与净暴露比例。

通过将 sectors 的每个单元格与 sector_definition::id 比较来把资产匹配到定义。对每一行,结果包报告该行业占非现金持仓的多头总额、空头总额(以负比例表示)与总敞口总额的比例;净暴露为多头减空头。没有匹配持仓的行业贡献为零。

参数:
  • positions -- Wide position frame.

  • sectors -- Wide sector-id panel with the same index as positions and a double column for every non-cash asset.

  • definitions -- Sector identifiers and output column names.

  • cash_column_name -- Name of the cash column excluded when present.

抛出:

input_error -- If the frames do not share an identical index, cash_column_name is empty, no double position column exists, or a position column length differs from the index length.

返回:

Bundle of long, short, gross and net exposure frames with one column per definition.

dataframe fincore::compute_style_factor_exposures(const dataframe &positions, const dataframe &risk_factors, std::string_view cash_column_name = cash_column)

返回各时间戳的加权风格因子暴露。

对每一行,暴露为非现金资产列上的 sum(position * factor) / sum(|position|)。NaN 持仓完全跳过;NaN 因子对分子贡献为零,但其持仓仍计入分母。分母为零或结果非有限时得到 0.0。

参数:
  • positions -- Wide position frame.

  • risk_factors -- Wide factor panel with the same index as positions and a double column for every non-cash position asset.

  • cash_column_name -- Name of the cash column excluded when present.

抛出:

input_error -- If the frames do not share an identical index, cash_column_name is empty, no double position column exists, or a position column length differs from the index length.

返回:

Frame with an exposure double column aligned to the positions index.

exposure_bundle fincore::compute_volume_exposures(const dataframe &shares_held, const dataframe &volumes, double percentile = 0.5)

返回持仓与成交量的暴露百分比。

对每一行以及共有的股份/成交量列计算 shares / volume。正股份计入多头集合,负股份以正幅值计入空头集合,绝对比例计入总敞口集合。报告值为各集合在 percentile 处线性插值分位数的 100 倍;集合为空时为 0.0。只有共有列参与分位数计算;任一股份列中的非零股份值都要求存在有限且为正 matching volume。

参数:
  • shares_held -- Wide share-count frame.

  • volumes -- Wide share-volume frame with the same index as shares_held.

  • percentile -- Quantile in [0, 1] applied within each row.

抛出:

input_error -- If the frames do not share an identical index, percentile is outside [0, 1], or a nonzero share value has no finite positive matching volume.

返回:

Bundle whose long_exposure, short_exposure and gross_exposure frames hold an exposure column; net_exposure is empty.

std::vector<daily_txn_bar> fincore::daily_txns_with_bar_data(std::span<const trade_record> transactions, const dataframe &prices, const dataframe &volumes)

返回与价格和成交量面板连接的按日聚合交易 K 线。

交易按精确的 (symbol, date) 以绝对金额汇总;日期不做归一化。每个交易日期都必须存在于价格索引中,且每个成交标的都必须同时具有价格列与成交量列。结果先按标的、再按日期排序。

参数:
  • transactions -- Trade records.

  • prices -- Bar price panel.

  • volumes -- Bar share-volume panel with the same index as prices.

抛出:

input_error -- If an amount is not finite, a trade date is absent from the price index, a traded symbol lacks a price or volume column, or the price and volume indices differ.

返回:

One bar per symbol/day with absolute amount, price and volume.

dataframe fincore::days_to_liquidate_positions(const dataframe &positions, const dataframe &prices, const dataframe &volumes, double max_bar_consumption = 0.2, double capital_base = 1000000.0, std::size_t mean_volume_window = 5U, std::string_view cash_column_name = cash_column)

返回清仓各持仓资产所需的天数。

持仓配置使用所有 double 列的行和。日成交额为前置 mean_volume_window 根 K 线上 price * volume 的均值,因此窗口内的前若干行属于预热并被省略。每个值为 allocation * capital_base / (max_bar_consumption * 平均成交额);平均成交额为 NaN 或零时该行返回 NaN。指定的现金列存在时被排除,但并非必需。

参数:
  • positions -- Wide position frame with a double column per asset.

  • prices -- Bar price frame with the same index as positions and a double column for every non-cash asset.

  • volumes -- Bar share-volume frame with the same index as positions and a double column for every non-cash asset.

  • max_bar_consumption -- Maximum fraction of a bar's dollar volume per day; must be in (0, 1].

  • capital_base -- Capital in currency units used to scale positions; must be positive.

  • mean_volume_window -- Number of preceding bars in the dollar-volume mean; must be at least 1.

  • cash_column_name -- Cash column excluded from the output.

抛出:

input_error -- If a numeric parameter is out of range, the frames do not share the same index, a position double column is malformed, or cash_column_name is empty or contains an embedded NUL.

返回:

Frame indexed by position dates after warm-up with one days column per non-cash asset; empty when there are no complete windows.

dataframe fincore::extract_round_trips(const dataframe &transactions, std::chrono::nanoseconds max_delta = default_round_trip_max_delta, std::string_view symbol_column_name = transaction_symbol_column, std::string_view amount_column_name = transaction_amount_column, std::string_view price_column_name = transaction_price_column)

从交易行中提取先进先出完整交易。

先按 groupby_consecutive_transactions() 的方式合并交易。每个块以先进先出方式与反向的未平仓批次匹配;一个块既可能平掉已有批次,也可能留下新的剩余持仓。价格为负的块会被跳过。输出索引为从 0 开始递增的完整交易序号。

输出列为 pnl、open_dt、close_dt、long、rt_returns、symbol 与 duration(以时间戳存储的经过纳秒数)。由卖出平仓的完整交易其 long 为 true;rt_returns 为 pnl 除以匹配的开仓名义金额,该名义金额为零时取 0。

参数:
  • transactions -- Frame with a string symbol column and double amount and price columns.

  • max_delta -- Maximum allowed gap when consolidating transactions.

  • symbol_column_name -- String symbol column.

  • amount_column_name -- Double signed-quantity column.

  • price_column_name -- Double execution-price column.

抛出:

input_error -- If a field name or required column is invalid, or an elapsed duration cannot be represented as a timestamp.

返回:

Round-trip frame with a sequential index and the documented columns.

round_trip_stats fincore::gen_round_trip_stats(const dataframe &round_trips, std::string_view pnl_column_name = round_trip_pnl_column, std::string_view returns_column_name = round_trip_return_column, std::string_view long_column_name = round_trip_long_column, std::string_view symbol_column_name = transaction_symbol_column, std::string_view open_column_name = round_trip_open_datetime_column, std::string_view close_column_name = round_trip_close_datetime_column)

计算完整交易业绩表与逐标的统计。

持仓时长按 close - open 以天计算。每个表按该顺序包含非空的 All trades、short 与 long 分组的行,列标签为固定英文。逐标的值使用 symbol_stat_labels 列出的统计量,每个标的一列。空帧产生默认构造的空统计。

参数:
  • round_trips -- Frame containing the required pnl, return, long, symbol, open and close columns.

  • pnl_column_name -- Double profit/loss column.

  • returns_column_name -- Double round-trip return column.

  • long_column_name -- Bool long/short flag column.

  • symbol_column_name -- String symbol column.

  • open_column_name -- Timestamp opening column.

  • close_column_name -- Timestamp closing column.

抛出:

input_error -- If a column name contains an embedded NUL, a required double column is invalid, or a required column length differs from the frame index length.

返回:

Round-trip statistic tables and per-symbol statistics.

std::pair<std::vector<double>, std::vector<double>> fincore::get_long_short_notional(const dataframe &positions, std::string_view cash_column_name = cash_column)

返回各时间戳的多头与空头名义金额。

每一行把正的非现金持仓值累加到第一个向量,把负值的绝对值累加到第二个向量。跳过 NaN 单元格。指定的现金列存在时被排除,但并非必需。

参数:
  • positions -- Wide position frame.

  • cash_column_name -- Name of the cash column to exclude.

抛出:

input_error -- If cash_column_name is empty or contains an embedded NUL, no double column exists, or a double column length differs from the index length.

返回:

Pair of long and short vectors, each aligned to the positions index.

dataframe fincore::get_long_short_pos(const dataframe &positions, std::string_view cash_column_name = cash_column)

返回各时间戳的多头与空头持仓总额。

正的非现金持仓值累加为多头,负值以正幅值累加为空头。跳过 NaN 单元格。指定的现金列存在时被排除,但并非必需。

参数:
  • positions -- Wide position frame.

  • cash_column_name -- Name of the cash column to exclude.

抛出:

input_error -- If cash_column_name is empty, no double column exists, or a double column length differs from the index length.

返回:

Frame with long and short double columns aligned to the positions index.

std::vector<transaction_liquidity> fincore::get_low_liquidity_transactions(std::span<const trade_record> transactions, const dataframe &prices, const dataframe &volumes, std::optional<std::size_t> last_n_days = std::nullopt)

返回近期交易中各标的最差的 K 线消耗。

交易按精确的 (symbol, date) 以绝对金额汇总。设置 last_n_days 时,仅扫描严格晚于 newest - last_n_days 天的日期,其中 newest 为最新交易日期。对每个标的保留 amount / volume * 100 最大的日期,结果按标的排序。

参数:
  • transactions -- Trade records.

  • prices -- Price panel whose index defines valid trade dates.

  • volumes -- Bar share-volume panel with the same index as prices and a volume column for every scanned symbol.

  • last_n_days -- Optional number of trailing days to scan.

抛出:

input_error -- If an amount is not finite, a trade date is absent from the price index, or the price and volume indices differ.

返回:

One record per symbol with a scanned trade; empty when there are no transactions.

std::vector<ticker_liquidity> fincore::get_max_days_to_liquidate_by_ticker(const dataframe &positions, const dataframe &prices, const dataframe &volumes, double max_bar_consumption = 0.2, double capital_base = 1000000.0, std::size_t mean_volume_window = 5U, std::optional<std::size_t> last_n_days = std::nullopt, std::string_view cash_column_name = cash_column)

返回各持仓标的的最大清仓时间。

使用给定参数调用 days_to_liquidate_positions()。设置 last_n_days 时,只考虑不早于 newest - last_n_days 天的指标行。每条记录报告最大天数值,以及该日期以百分比表示的持仓配置(100 * fraction)。没有有效值的标的其字段保持 NaN。结果按标的排序。

参数:
  • positions -- Wide position frame with a double column per asset.

  • prices -- Bar price frame with the same index as positions and a double column for every non-cash asset.

  • volumes -- Bar share-volume frame with the same index as positions and a double column for every non-cash asset.

  • max_bar_consumption -- Maximum fraction of a bar's dollar volume per day; must be in (0, 1].

  • capital_base -- Capital in currency units used to scale positions; must be positive.

  • mean_volume_window -- Number of preceding bars in the dollar-volume mean; must be at least 1.

  • last_n_days -- Optional number of trailing days to scan.

  • cash_column_name -- Cash column excluded from the output.

抛出:

input_error -- If days_to_liquidate_positions() rejects a parameter, an index, or a position column.

返回:

One record per non-cash asset, sorted by symbol.

dataframe fincore::get_max_median_position_concentration(const dataframe &positions, std::string_view cash_column_name = cash_column)

返回按行的多头与空头持仓集中度度量。

配置比例按 get_percent_alloc() 的方式在所有 double 列上计算。对每一行,max_long 为最大的正非现金配置,median_long 为正配置的中位数,median_short 为负配置的中位数,max_short 为最负的配置。没有配置的一侧返回 NaN。

参数:
  • positions -- Wide position frame with a required double cash column.

  • cash_column_name -- Name of the cash column excluded from the measures.

抛出:

input_error -- If the cash name is empty, the cash column is absent or not double, no double column exists, or a double column length differs from the index length.

返回:

Frame with max_long, median_long, median_short and max_short columns.

dataframe fincore::get_percent_alloc(const dataframe &positions)

将每个数值持仓列返回为其行和的比例。

输出具有相同索引,并按输入顺序为每个输入 double 列生成一个 double 列。NaN 单元格不计入行和在输出中仍为 NaN;行和为零时返回 NaN。取值为比例而非百分比。

参数:

positions -- Wide position frame with at least one double column whose values match the frame index length.

抛出:

input_error -- If no double column exists or a double column length differs from the index length.

返回:

Frame of row-wise position fractions.

dataframe fincore::get_sector_exposures(const dataframe &positions, std::span<const sector_assignment> assignments, std::string_view cash_column_name = cash_column)

通过汇总指派的持仓返回原始行业暴露。

按 assignments 中命名的每个行业生成一列,按行业的字典序排列,随后是从持仓复制的现金列。只有标的名称对应已有非现金 double 列的指派才参与;未指派的资产被忽略。取值为原始持仓之和,而不是比例。

参数:
  • positions -- Wide position frame with a required double cash column.

  • assignments -- Symbol-to-sector assignments.

  • cash_column_name -- Name of the cash column copied to the output.

抛出:

input_error -- If cash_column_name is empty, no double position column exists, or a double column length differs from the index length.

返回:

Frame indexed like positions with one column per sector plus cash.

top_positions fincore::get_top_long_short_abs(const dataframe &positions, std::size_t top = 10U, std::string_view cash_column_name = cash_column)

返回按标的排序的最大多头、空头与绝对持仓。

每个非现金 double 列在其最大值为正时计入多头列表,其最小值为负时计入空头列表,其绝对值最大者计入绝对值列表。列表按值排序(多头与绝对值降序,空头升序)并截断为前 top 项。忽略 NaN 行;没有合格值的标的被省略。

参数:
  • positions -- Wide position frame.

  • top -- Maximum number of entries in each returned list.

  • cash_column_name -- Name of the cash column to exclude.

抛出:

input_error -- If cash_column_name is empty or contains an embedded NUL, no double column exists, or a double column length differs from the index length.

返回:

Ranked long, short and absolute position lists.

dataframe fincore::get_turnover(const dataframe &positions, const dataframe &transactions, turnover_denominator denominator = turnover_denominator::actual_gross_book, std::string_view cash_column_name = cash_column, std::string_view amount_column_name = transaction_amount_column, std::string_view price_column_name = transaction_price_column)

使用选定分母返回每日换手率。

输出索引为持仓日与交易日并集的排序结果,两者都归一化到 UTC 零点。交易名义金额来自 get_txn_vol(),持仓日期必须严格递增且唯一。actual_gross_book 除以上一行与当前行总规模(不含现金)的平均值,第一行使用当前总规模的一半。portfolio_value 除以所有 double 持仓列(含现金)的行和。非有限的比例返回 0.0,且取值为比例而非百分比。

参数:
  • positions -- Wide position frame with at least one double column.

  • transactions -- Transaction frame consumed by get_txn_vol().

  • denominator -- Denominator convention.

  • cash_column_name -- Cash column excluded from actual_gross_book; unused by portfolio_value.

  • amount_column_name -- Signed-quantity column in transactions.

  • price_column_name -- Execution-price column in transactions.

抛出:

input_error -- If the denominator value is unknown, a column name is invalid, the cash column is missing or not double for actual_gross_book, position days are duplicated or out of order, or a required transaction column is invalid.

返回:

Frame indexed by UTC day with a turnover double column.

dataframe fincore::get_txn_vol(const dataframe &transactions, std::string_view amount_column_name = transaction_amount_column, std::string_view price_column_name = transaction_price_column)

返回每日交易名义金额与股份总量。

行按 UTC 日历日分组,归一化到零点并升序排序。txn_volume 汇总 |amount| * price,txn_shares 汇总 |amount|;计算结果为 NaN 的贡献被跳过,无穷值得到保留。

参数:
  • transactions -- Frame with double amount and price columns.

  • amount_column_name -- Signed-quantity column.

  • price_column_name -- Execution-price column.

抛出:

input_error -- If a column name is empty or duplicated, a required column is absent or not double, or its length differs from the frame index length.

返回:

Frame indexed by UTC day with txn_volume and txn_shares double columns.

dataframe fincore::gross_lev(const dataframe &positions, std::string_view cash_column_name = cash_column)

返回各时间戳的总杠杆。

总杠杆为非现金持仓值绝对值之和除以所有 double 列(含现金)的行和。跳过 NaN 单元格;分母为零或比例非有限时返回 NaN。

参数:
  • positions -- Wide position frame with a required double cash column.

  • cash_column_name -- Name of the cash column excluded from the numerator.

抛出:

input_error -- If the cash name is empty, the cash column is absent or not double, no double column exists, or a double column length differs from the index length.

返回:

Frame with a gross_lev double column.

dataframe fincore::groupby_consecutive_transactions(const dataframe &transactions, std::chrono::nanoseconds max_delta = default_round_trip_max_delta, std::string_view symbol_column_name = transaction_symbol_column, std::string_view amount_column_name = transaction_amount_column, std::string_view price_column_name = transaction_price_column)

将连续同向交易分组成价格/金额块。

行按标的、时间戳与原始位置排序,随后对同一标的相邻且金额同为正或同为非正的行进行合并,直到与前一行的间隔超过 max_delta 为止。块的金额为其金额之和,其价格为金额加权平均价,其时间戳为首行的时间戳。max_delta 为负时禁用合并。

参数:
  • transactions -- Frame with a string symbol column and double amount and price columns.

  • max_delta -- Maximum allowed gap between merged transactions.

  • symbol_column_name -- String symbol column.

  • amount_column_name -- Double signed-quantity column.

  • price_column_name -- Double execution-price column.

抛出:

input_error -- If a field name is empty or duplicated, a required column is absent or of the wrong type, or a column length differs from the frame index length.

返回:

Frame indexed by each block's first timestamp with amount, symbol and price columns under the supplied names.

dataframe fincore::make_transaction_frame(std::span<const portfolio_transaction> transactions)

由已校验的交易构造带所有权的交易帧。

每个输入都用 map_transaction() 校验。帧索引保存交易日期;列为字符串 symbol 以及 double 的 amount 与 price 列。保留输入顺序与重复日期。

参数:

transactions -- Transactions to convert.

抛出:

fincore_error -- If any transaction fails validation.

返回:

Frame with symbol, amount and price columns indexed by date.

portfolio_transaction fincore::map_transaction(const portfolio_transaction &transaction)

校验组合交易并返回其副本。

有效交易须具有非空 symbol 以及有限的 amount 与 price;其他字段原样复制。

参数:

transaction -- Transaction to validate.

抛出:

fincore_error -- If the symbol is empty or the amount or price is not finite.

返回:

Copy of transaction.

std::vector<position_record> fincore::stack_positions(const dataframe &positions, bool pos_in_dollars = true, std::string_view cash_column_name = cash_column)

以长表形式返回持仓,每行每个非现金列一条记录。

记录先按输入行顺序、再按输入列顺序排列。保留 NaN 值,指定的现金列存在时被排除。pos_in_dollars 标志为接口兼容性而接受,但本实现不据此转换数值。

参数:
  • positions -- Wide position frame.

  • pos_in_dollars -- Retained for API compatibility; values pass through unchanged.

  • cash_column_name -- Name of the cash column to exclude.

抛出:

input_error -- If cash_column_name is empty or contains an embedded NUL, no double column exists, or a double column length differs from the index length.

返回:

Stacked position records.

constexpr std::string_view fincore::cash_column = {"cash"}

宽表持仓帧中现金列的默认名称。

constexpr std::chrono::nanoseconds fincore::default_round_trip_max_delta{std::chrono::hours{8}}

合并为同一块的相邻交易之间允许的最大间隔(8 小时)。

constexpr std::string_view fincore::round_trip_close_datetime_column = {"close_dt"}

完整交易的平仓时间戳列。

constexpr std::string_view fincore::round_trip_duration_column = {"duration"}

完整交易的经过纳序列,以时间戳存储。

constexpr std::string_view fincore::round_trip_long_column = {"long"}

完整交易的多头/空头标志列。

constexpr std::string_view fincore::round_trip_open_datetime_column = {"open_dt"}

完整交易的开仓时间戳列。

constexpr std::string_view fincore::round_trip_pnl_column = {"pnl"}

完整交易的盈亏列。

constexpr std::string_view fincore::round_trip_return_column = {"rt_returns"}

完整交易的收益列。

constexpr std::string_view fincore::transaction_amount_column = {"amount"}

交易帧中带符号数量列的默认名称。

constexpr std::string_view fincore::transaction_bar_volume_column = {"volume"}

apply_slippage_penalty() 使用的默认 K 线股份成交量列。

constexpr std::string_view fincore::transaction_price_column = {"price"}

交易帧中成交价的默认列。

constexpr std::string_view fincore::transaction_symbol_column = {"symbol"}

交易帧与完整交易帧中 symbol 列的默认名称。