Appearance
常见使用场景的教程
交易流水相关教程
录入流水的通用示例
当您要使用接下来介绍的方式导入流水时,您需要注意
- 您需要将您在其他系统获得的流水转化为 rqamsc 所要求的字典格式,具体数据结构可参考 交易流水对象
- 在构建交易流水时一个关键的字段是 transaction_type(交易类型, 如 'buy', 'sell', 'cash_in' 等),不同系统获得的流水该值差异可能巨大,您需要将其转化为 rqams 规定的标准值,具体可参考交易类型
- 所有流水会被标记为 openapi 来源的流水,该类流水的特性可以参考 交易流水来源
以下是一个导入流水的完整过程的示例代码
python
import datetime
import rqamsc
from rqamsc import TransactionType
def demo():
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
trades = [
# 第一条流水
{
'transaction_type': 'buy', # 交易类型,字段值可在文档【交易类型】中参考
'account': '范例产品交易账号中文名', # 交易账户名称,不提供则默认第一个产品账户
'datetime': datetime.datetime(2024, 5, 7, 10, 4, 25),
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'quantity': 1, # 分红、付息等现金类交易则不需要提供
'price': 10, # 分红、付息等现金类交易则不需要提供
'settlement_amount': 0, # 买卖等类型可以不提供该字段,但分红、付息、出入金等(可参考文档【给产品导入交易流水】中介绍)必须设置该字段作为交易金额
'commission': 0.1, # 交易佣金, 不提供默认为0
'tax': 0, # 交易税, 不提供默认为0
'other_fees': 0, # 其他费用, 不提供默认为0
'exchange_rate': 1, # 汇率, 不提供默认为1
'remarks': '这是当天第一笔交易', # 备注, 可不提供
'foreign_id': '可指定一个在交易系统范围内唯一的id', # 外部id, 可不提供, 具体功能可参考文档【交易流水来源】中介绍
'asset_unit_id': None # 资产单元id, 如果是资产单元下的流水需要指定该字段,不指定则默认该流水是产品层流水
},
# 第二条流水
{
'transaction_type': 'sell', # 交易类型
'datetime': datetime.datetime(2024, 5, 7, 11, 4, 25),
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'quantity': 1,
'price': 100,
'commission': 0.1
},
# 第三条流水
{
'transaction_type': 'cash_in', # 入金
'datetime': datetime.datetime(2024, 5, 7, 14, 4, 25),
'order_book_id': 'CNY',
'symbol': 'CNY',
'settlement_amount': 1000000, # 入金的金额
'foreign_id': '123321954783203'
},
# 第四条流水
{
'transaction_type': 'dividend_payment', # 现金分红
'account': '一个不存在的账号',
'datetime': datetime.datetime(2024, 5, 7, 8, 0, 0),
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'settlement_amount': 1, # 分红的金额
},
# 第五条流水
{
'transaction_type': 'interest_payment', # 利息支出
'datetime': datetime.datetime(2024, 5, 7, 16, 0, 0),
'order_book_id': 'CNY',
'symbol': 'CNY',
'settlement_amount': 50, # 利息支出金额
'remarks': '银行借款利息支出'
}
# ... 可增加更多流水
]
# 调用导入流水api,使用result变量接收返回结果并打印输出,可使用chunk_size参数指定每批上传的流水数量,默认1000
result = rqamsc.insert_product_trades('一个范例产品', trades, chunk_size=500)
print(result)
if __name__ == '__main__':
demo()
# [
# 本批次流水的导入结果
# 第一条流水导入结果: modify表示覆盖了相同foreign_id的流水
# {'id': '66aca9b916822a16d8143b58', 'action': 'modify'},
# 第二条流水导入结果: insert表示增加成功
# {'id': '66acae1c6d4a6ec991079160', 'action': 'insert'},
# {'id': '66acae1c6d4a6ec991079161', 'action': 'insert'},
# 第四条流水导入失败
# {'err': '该产品中没有该交易账户名: 一个不存在的账号'}
# ... 该结果列表和上传流水的顺序一致,即 chunk_start + 列表下标 = 该流水在上传数据序列中的位置
# ]录入股票交易流水
更多交易类型(如两融业务)可以参考 交易类型 字段的枚举值
python
import datetime
import rqamsc
from rqamsc import TransactionType
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
trades = [
# 第一条:最简单的股票买入,只提供必须字段
{
'transaction_type': TransactionType.buy, # 买入
'datetime': datetime.datetime(2024, 5, 7, 9, 30, 0),
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'quantity': 1000, # 买入1000股
'price': 12.50 # 每股12.50元
},
# 第二条:或许你可以提供更详细的字段
{
'transaction_type': TransactionType.sell, # 卖出
'datetime': datetime.datetime(2024, 5, 8, 14, 30, 0),
'account': '范例产品交易账号中文名', # 交易账户名称,不提供则默认第一个产品账户
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'quantity': 500,
'price': 13.20,
'commission': 6.60, # 佣金
'tax': 0, # 交易税, 不提供默认为0
'other_fees': 0.5, # 其他费用
'remarks': '部分止盈', # 备注信息
'foreign_id': 'SELL_001_20240508' # 外部系统ID,可不提供, 用于去重
},
# 第三条:分红收入流水 - 股票分红
{
'transaction_type': TransactionType.dividend_payment, # 红利入账
'datetime': datetime.datetime(2024, 5, 15, 9, 0, 0),
'order_book_id': '000001.XSHE', # 股票分红
'symbol': '平安银行',
'settlement_amount': 12500, # 分红金额12,500元
},
# 第四条:分红税支付流水
{
'transaction_type': TransactionType.dividend_tax_payment, # 红利税支付
'datetime': datetime.datetime(2024, 5, 15, 9, 1, 0),
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'settlement_amount': 1250, # 红利税10%
},
# 第五条:送股流水
{
'transaction_type': TransactionType.bonus_share, # 红股
'datetime': datetime.datetime(2024, 5, 16, 9, 0, 0),
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'quantity': 250, # (十送五)
},
]
result = rqamsc.insert_product_trades_v2('我的产品', trades)
print(result)
# id 字段的值表示导入后流水的id, insert表示流水是新增
# [
# {'id': '697b1c896d9670c3ac85592c', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac85592d', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac85592e', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac85592f', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac855930', 'action': 'insert'},
# ]录入期货交易流水
期货交易与股票类似,但需要注意合约代码的格式:
python
import datetime
import rqamsc
from rqamsc import TransactionType
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
trades = [
# 第一条:最简单的期货开仓,只提供必须字段
{
'transaction_type': TransactionType.buy_open, # 开多仓
'datetime': datetime.datetime(2024, 5, 7, 10, 15, 0),
'order_book_id': 'IF2406', # 沪深300期货主力合约
'symbol': 'IF2406',
'quantity': 2, # 开仓2手
'price': 3250.0 # 每点3250元
},
# 第二条:或许你可以提供更详细的字段
{
'transaction_type': 'sell_close', # 平多仓
'datetime': datetime.datetime(2024, 5, 8, 11, 30, 0),
'account': '范例产品交易账号中文名', # 交易账户名称,不提供则默认第一个产品账户
'order_book_id': 'IF2406',
'symbol': 'IF2406',
'quantity': 1, # 平仓1手
'price': 3280.0, # 盈利平仓
'commission': 15.0, # 期货手续费
'remarks': '部分止盈平仓',
'foreign_id': 'FUT_SELL_001' # 外部系统ID
}
]
result = rqamsc.insert_product_trades_v2('期货产品', trades)
print(result)
# [
# {'id': '697b1c896d9670c3ac85592c', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac85592d', 'action': 'insert'},
# ]录入现金类流水示例
这个示例展示如何导入现金类流水,包括入金、利息收入和利息支出等。
python
import datetime
import rqamsc
from rqamsc import TransactionType
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
trades = [
# 入金流水
{
'transaction_type': 'cash_in', # 入金
'datetime': datetime.datetime(2024, 5, 7, 9, 0, 0),
'order_book_id': 'CNY', # 人民币
'symbol': 'CNY',
'settlement_amount': 1000000 # 入金100万元
},
# 银行存款利息收入
{
'transaction_type': TransactionType.interest_income, # 利息收入
'datetime': datetime.datetime(2024, 5, 8, 16, 0, 0),
'order_book_id': 'CNY',
'symbol': 'CNY',
'settlement_amount': 850, # 利息收入850元
},
# 借款利息支出
{
'transaction_type': TransactionType.interest_payment, # 利息支出
'datetime': datetime.datetime(2024, 5, 10, 16, 0, 0),
'order_book_id': 'CNY',
'symbol': 'CNY',
'settlement_amount': 2500, # 利息支出2500元
},
]
result = rqamsc.insert_product_trades_v2('我的产品', trades)
print(result)
# [
# {'id': '697b1c896d9670c3ac85592c', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac85592d', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac85592e', 'action': 'insert'},
# ]录入回购交易流水示例
这个示例展示如何导入回购相关流水,包括正回购、逆回购以及到期购回等操作。
python
import datetime
import rqamsc
from rqamsc import TransactionType
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
trades = [
# 逆回购操作 - 资金出借
{
'transaction_type': TransactionType.reverse_repo, # 逆回购
'datetime': datetime.datetime(2024, 5, 7, 10, 30, 0),
'order_book_id': '131810.XSHE', # 深市1天逆回购
'symbol': 'R-001',
'quantity': 10, # 10手,即100万元
'price': 2.5, # 年化利率 2.5%
},
# 逆回购到期购回 - 资金收回
{
'transaction_type': TransactionType.reverse_repo_repurchase, # 逆回购购回
'datetime': datetime.datetime(2024, 5, 8, 16, 0, 0),
'order_book_id': '131810.XSHE',
'symbol': 'R-001',
'quantity': 10,
'price': 2.5,
'settlement_amount': 1000068.49, # 本金+利息
},
# 正回购操作 - 质押融资
{
'transaction_type': TransactionType.repo, # 正回购
'datetime': datetime.datetime(2024, 5, 10, 14, 0, 0),
'order_book_id': '204001.XSHG', # 沪市1天回购
'symbol': 'GC001',
'quantity': 5, # 5手,即50万元
'price': 3.2, # 年化利率 3.2%
},
# 正回购到期购回 - 还款付息
{
'transaction_type': TransactionType.repo_repurchase, # 正回购购回
'datetime': datetime.datetime(2024, 5, 11, 16, 0, 0),
'order_book_id': '204001.XSHG',
'symbol': 'GC001',
'quantity': 5,
'price': 3.2,
'settlement_amount': 500044.44, # 本金+利息
}
]
result = rqamsc.insert_product_trades_v2('我的产品', trades)
print(result)
# [
# {'id': '697b1c896d9670c3ac85592c', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac85592d', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac85592e', 'action': 'insert'},
# {'id': '697b1c896d9670c3ac85592f', 'action': 'insert'},
# ]录入带有foreign_id字段的流水
这个示例展示如何使用 foreign_id 字段来避免重复导入和实现流水覆盖更新功能。
python
import datetime
import rqamsc
from rqamsc import TransactionType
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
# 第一次导入 - 初始流水
trades_initial = [
{
'transaction_type': TransactionType.buy,
'datetime': datetime.datetime(2024, 5, 7, 9, 30, 0),
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'quantity': 1000,
'price': 12.50,
'commission': 6.25,
'remarks': '初始买入',
'foreign_id': 'ORDER_001_20240507' # 外部系统唯一ID
}
]
print("=== 第一次导入 ===")
result1 = rqamsc.insert_product_trades('我的产品', trades_initial)
print(result1)
# [{'id': '697b1c896d9670c3ac85592c', 'action': 'insert'}]
# 第二次导入 - 使用相同foreign_id但修改了数据(比如更正佣金费率)
trades_corrected = [
{
'transaction_type': TransactionType.buy,
'datetime': datetime.datetime(2024, 5, 7, 9, 30, 0),
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'quantity': 1000,
'price': 12.50,
'commission': 12.50, # 修正后的佣金
'remarks': '已修正佣金费率',
'foreign_id': 'ORDER_001_20240507' # 相同的外部ID
}
]
print("\n=== 第二次导入(覆盖) ===")
result2 = rqamsc.insert_product_trades_v2('我的产品', trades_corrected)
print(result2)
# action为'modify',说明覆盖了原有记录
# [
# {'id': 'xxx', 'action': 'modify'}
# ]
#
# foreign_id的最佳实践:
# 1. 使用业务系统中的唯一标识符作为foreign_id
# 2. 重新导入相同foreign_id的流水会覆盖原流水
# 3. 不提供foreign_id的流水会始终新增,不会覆盖录入每日的结算流水文件单
使用下述方式导入流水时,您通常每日收盘后都会收到当日的流水结算文件,您需要注意
- 不同券商的交易文件格式非常不同,甚至同一券商不同时期的格式也可能发生较大变化,您需要确保RQAMS中该产品下交易账户的交易通道类型为您实际使用的券商类型。(若您所用券商我们还未支持,请联系我们)
- 使用此方式导入的流水称为日终结算流水,该流水类型特点可参考 交易流水来源
python
import datetime
import rqamsc
from rqamsc import TransactionType
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
product_name = '一个产品'
product = rqamsc.get_product(product_name)
print(product)
# Product(
# ...
# accounts=[
# {'name': '一个产品的账号名称', 'is_custodian': False, 'account_number': 'xxx', 'broker': 'ricequant'}
# ]
# ...
# )
account_name = product.accounts[0]['name']
file_path = r'path/to/your/trades_file.xlsx'
print(rqamsc.upload_product_settlement_trade_file(product_name, account_name, file_path))
# effect_count 表示识别并成功导入的流水数量为 58 条
# err_msg 为报错信息,表示文件中第二行的合约没有正确被识别
# confirmation_id 表示凭证id
# {
# 'path/to/your/trades_file.xlsx':
# {
# 'effect_count': 58,
# 'err_msg': [{ "line_num": 2, "msg": "无法识别资产:资产分类信息获取失败" }],
# 'confirmation_id': '697b3055c9087bc930ed8868'
# }
# }估值表相关教程
录入估值表文件
使用该方式时您需要确保您的产品会收到托管的估值表,通常市面上大部分估值表RQAMS已经可以适配识别。(若您收到的估值表格式无法识别,请联系我们) 以下代码展示了如何将本地的估值表文件导入产品
python
import rqamsc
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
print(
rqamsc.upload_valuation_reports(
'一个有估值表的产品',
[
r'your/valuation_report/path/file1.xlsx',
r'your/valuation_report/path/file2.xlsx',
],
)
)
# 返回一个列表,列表中元素包含的关键信息如下:
# file: 文件地址
# err_msg: 导入失败时的错误信息
# effect_count:导入成功的数量, 0表示未导入,1表示成功
# valuation_report_id:导入成功后估值表的id
# confirmation_id: 凭证id
# [
# {
# 'err_msg': [],
# 'confirmation_id': '69805115af070387af13290b',
# 'effect_count': 1,
# 'valuation_report_id': '69805115409221935ecbe4c4',
# 'date': '2020-11-02',
# 'is_modified': False,
# 'file': 'your/valuation_report/path/file1.xlsx',
# },
# {
# 'err_msg': ['该产品在2020-11-03已存在估值表'],
# 'file': 'your/valuation_report/path/file2.xlsx',
# }
# ]录入自己构建的字典格式估值表
通过 dict、json 格式的估值表数据导入产品,该方式需要您对RQAMS的头寸需要的信息有相当程度的了解, 并将您在其他渠道获取的头寸转化为RQAMS要求的估值表数据格式。 在满足上述条件后,通常在以下情况更推荐您这种导入方式:
- 您的估值表格式在RQAMS中还未适配,因此无法导入,而您此时需要将估值表导入RQAMS
- 您的估值来源并不是传统估值表,您需要将组合的截面头寸导入RQAMS
以下代码展示了如何构建估值表中的关键信息及调用api导入
python
import rqamsc
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
# 产品于2024-09-03日的估值信息
valuation_report = {
'date': '2024-09-03', # 持仓单日期
'total_equity': 2004.00, # 净资产
'units': 2000, # 份额
'unit_net_value': 1.002, # 单位累计净值
'acc_unit_net_value': 1.002, # 单位累计净值
'positions': [
# 第一条持仓
{
'order_book_id': 'CNY',
'symbol': '活期存款',
'asset_class': 'current_deposit',
'direction': 'long',
'market_value': 1000.00,
},
# 第二条持仓
{
'order_book_id': '000001.XSHE',
'symbol': '平安银行',
'asset_class': 'stock',
'direction': 'long',
'market_value': 1004.00, # 持仓市值
'quantity': 100.00, # 持仓数量
'cost_price': 10.00, # 单位成本
'cost': 1000.00, # 成本
'fair_value': 10.04, # 公允价格
},
# 第三条持仓
{
'order_book_id': '600519.XSHG',
'symbol': '贵州茅台',
'asset_class': 'stock',
'direction': 'short', # 空头
'market_value': -150000.00, # 持仓市值
'quantity': 100.00, # 持仓数量
'cost_price': 2000.00, # 单位成本
'cost': -200000.00, # 成本
'fair_value': 1500, # 公允价格
},
],
}
# 调用导入估值表api
result = rqamsc.insert_valuation_reports('要导入持仓单的产品id或名称', valuation_report)
print(result)
# 参考文件估值表的返回
# [
# {
# 'err_msg': [],
# 'confirmation_id': '6980675cabe35ad7c92cf357',
# 'effect_count': 1,
# 'valuation_report_id': '698060c6409221935eef4de2',
# 'date': '2024-09-03',
# 'is_modified': True,
# 'file': '产品名称_2024-09-03_api导入数据.csv',
# }
# ]Tips: 您需要注意的是:如果您使用估值表驱动产品的估值,在发生了申购、赎回、分红等事件后,RQAMS无法仅通过估值表倒推出准确的托管事件,为获取当日准确的收益率数据,您需要导入对应发生的托管事件,具体导入方式可以参考托管事件相关教程
托管事件相关教程
给产品录入申购赎回托管事件
需要将从其他渠道获取到的申赎事件按照 托管事件要求的格式 转换后再录入,示例如下
python
import rqamsc
from rqamsc import CustodianEvent
from rqamsc.definition import CustodianEventType
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
custodian_events = [
# 使用 CustodianEvent 构建的申购
CustodianEvent(
custodian_event_type=CustodianEventType.subscription_fund_received,
sr_open_date='2026-01-05', # 申购开放日
date='2026-01-06', # 申购到账日
unit_net_value=1.4, # 按什么净值申购
# unit_net_value=1, # 如果是产品的初始资金取1即可
# 也可以考虑直接取开放日当天单位净值
# unit_net_value=rqamsc.get_balance('一个产品', dt=20260105)['unit_net_value'],
amount=1000000,
),
# 使用 CustodianEvent 构建的赎回
CustodianEvent(
custodian_event_type=CustodianEventType.redemption_paid,
sr_open_date='2026-01-16', # 赎回开放日
date='2026-01-19', # 赎回出账日
unit_net_value=rqamsc.get_balance('一个产品', dt=20260116)['unit_net_value'],
amount=1000000,
),
# 使用字典构建的赎回
{
'custodian_event_type': CustodianEventType.redemption_paid,
'sr_open_date': '2026-01-15', # 赎回开放日
'date': '2026-01-19', # 赎回出账日
'unit_net_value': rqamsc.get_balance('一个产品', dt=20260116)['unit_net_value'],
'amount': 500000,
},
]
print(rqamsc.insert_custodian_events('一个产品', custodian_events))
# 数量为3表示三条都录入成功
# {'effect_count': 3}录入产品分红托管事件
示例如下
python
import datetime
import rqamsc
from rqamsc import CustodianEvent, CustodianEventType
rqamsc.init('username', 'password', uri="https://www.ricequant.com", ssl_verify=True)
rqamsc.choose_workspace('需要指定的工作空间')
custodian_events = [
# 使用 CustodianEvent 对象构建
CustodianEvent(
date=datetime.date(2020, 1, 1),
custodian_event_type=CustodianEventType.product_dividend_paid,
amount=1000000
),
# 使用字典构建
{
'date': '2021-01-05',
'custodian_event_type': 'product_dividend_paid',
'amount': 1000000
}
]
print(rqamsc.insert_custodian_events('一个产品', custodian_events))
# {'effect_count': 2}