-
Notifications
You must be signed in to change notification settings - Fork 724
资金管理
本文档详细介绍了Hikyuu量化交易框架中的资金管理模块,重点阐述了其决定每笔交易投入资金量的核心功能。文档深入分析了MoneyManagerBase基类的设计与实现,并详细说明了MM_FixedPercent(固定比例)、MM_FixedRisk(固定风险)、MM_FixedCount(固定手数)和MM_WilliamsFixedRisk(威廉姆斯固定风险)等策略的计算逻辑和风险管理理念。通过代码示例展示了如何在策略中配置不同的资金管理器,并阐述了其对整体投资组合风险和收益的影响。
资金管理模块位于hikyuu_cpp/hikyuu/trade_sys/moneymanager/目录下,采用C++实现,并通过Python包装器提供接口。该模块遵循清晰的分层结构,将接口定义、具体实现和构建工具分离。
graph TD
A[资金管理模块] --> B[crt/]
A --> C[imp/]
A --> D[MoneyManagerBase.h/cpp]
A --> E[build_in.h]
B --> F[MM_FixedPercent.h]
B --> G[MM_FixedRisk.h]
B --> H[MM_FixedCount.h]
B --> I[MM_WilliamsFixedRisk.h]
C --> J[FixedPercentMoneyManager.cpp/h]
C --> K[FixedRiskMoneyManager.cpp/h]
C --> L[FixedCountMoneyManager.cpp/h]
C --> M[WilliamsFixedRiskMoneyManager.cpp/h]
D --> N[核心基类]
E --> O[创建函数]
Diagram sources
- MoneyManagerBase.h
- crt/MM_FixedPercent.h
- imp/FixedPercentMoneyManager.cpp
Section sources
- MoneyManagerBase.h
- crt/MM_FixedPercent.h
- imp/FixedPercentMoneyManager.cpp
资金管理模块的核心组件包括MoneyManagerBase基类和多个具体的资金管理策略实现。MoneyManagerBase定义了所有资金管理器必须遵循的接口和公共行为,而具体的策略类则继承自该基类并实现特定的资金计算逻辑。这些组件共同协作,根据预设的风险管理规则动态计算每笔交易的头寸规模。
Section sources
- MoneyManagerBase.h
- MoneyManagerBase.cpp
资金管理模块采用面向对象的设计模式,以MoneyManagerBase为抽象基类,通过继承机制实现多种具体的资金管理策略。该架构的核心是_getBuyNumber纯虚函数,所有子类必须重写此方法来定义其独特的头寸计算公式。资金管理器在运行时被集成到交易系统中,当产生买入信号时,系统会调用资金管理器的getBuyNumber方法,该方法在进行一系列检查(如现金充足性、最小交易单位等)后,调用子类实现的_getBuyNumber来获取最终的交易数量。
classDiagram
class MoneyManagerBase {
+string name()
+void name(string)
+void setTM(TradeManagerPtr)
+TradeManagerPtr getTM()
+void setQuery(KQuery)
+const KQuery& getQuery()
+MoneyManagerPtr clone()
+void buyNotify(TradeRecord)
+void sellNotify(TradeRecord)
+double getSellNumber(Datetime, Stock, price_t, price_t, SystemPart)
+double getSellShortNumber(Datetime, Stock, price_t, price_t, SystemPart)
+double getBuyShortNumber(Datetime, Stock, price_t, price_t, SystemPart)
+double getBuyNumber(Datetime, Stock, price_t, price_t, SystemPart)
+size_t currentBuyCount(Stock)
+size_t currentSellCount(Stock)
+virtual double _getBuyNumber(Datetime, Stock, price_t, price_t, SystemPart) = 0
+virtual double _getSellNumber(Datetime, Stock, price_t, price_t, SystemPart)
+virtual double _getSellShortNumber(Datetime, Stock, price_t, price_t, SystemPart)
+virtual double _getBuyShortNumber(Datetime, Stock, price_t, price_t, SystemPart)
+virtual void _reset()
+virtual MoneyManagerPtr _clone() = 0
-string m_name
-KQuery m_query
-TradeManagerPtr m_tm
-unordered_map<Stock, pair<size_t, size_t>> m_buy_sell_counts
}
class FixedPercentMoneyManager {
+FixedPercentMoneyManager()
+~FixedPercentMoneyManager()
+void _checkParam(string)
+double _getBuyNumber(Datetime, Stock, price_t, price_t, SystemPart)
+MoneyManagerPtr _clone()
}
class FixedRiskMoneyManager {
+FixedRiskMoneyManager()
+~FixedRiskMoneyManager()
+void _checkParam(string)
+double _getBuyNumber(Datetime, Stock, price_t, price_t, SystemPart)
+MoneyManagerPtr _clone()
}
class FixedCountMoneyManager {
+FixedCountMoneyManager()
+~FixedCountMoneyManager()
+void _checkParam(string)
+double _getBuyNumber(Datetime, Stock, price_t, price_t, SystemPart)
+double _getSellShortNumber(Datetime, Stock, price_t, price_t, SystemPart)
+MoneyManagerPtr _clone()
}
class WilliamsFixedRiskMoneyManager {
+WilliamsFixedRiskMoneyManager()
+~WilliamsFixedRiskMoneyManager()
+void _checkParam(string)
+double _getBuyNumber(Datetime, Stock, price_t, price_t, SystemPart)
+MoneyManagerPtr _clone()
}
MoneyManagerBase <|-- FixedPercentMoneyManager
MoneyManagerBase <|-- FixedRiskMoneyManager
MoneyManagerBase <|-- FixedCountMoneyManager
MoneyManagerBase <|-- WilliamsFixedRiskMoneyManager
MoneyManagerBase --> TradeManager : "使用"
MoneyManagerBase --> KQuery : "使用"
Diagram sources
- MoneyManagerBase.h
- FixedPercentMoneyManager.h
- FixedRiskMoneyManager.h
- FixedCountMoneyManager.h
- WilliamsFixedRiskMoneyManager.h
本节将深入分析资金管理模块中的各个关键组件,包括基类和具体的策略实现。
MoneyManagerBase是所有资金管理策略的抽象基类,它定义了资金管理器的核心接口和公共功能。该类继承自enable_shared_from_this,便于在需要时安全地获取自身的shared_ptr。它通过PARAMETER_SUPPORT_WITH_CHECK宏支持参数化配置,并提供了setParam和getParam等方法来管理策略参数。
基类的核心功能是getBuyNumber方法,它是一个非虚的公共接口,负责处理所有资金管理器共有的逻辑,如检查交易账户(m_tm)的有效性、验证风险值的合法性、确保交易数量不小于最小交易单位(minTradeNumber)、以及根据可用现金调整最终的交易数量。在进行这些通用检查后,getBuyNumber会调用一个名为_getBuyNumber的纯虚函数,该函数的具体实现由子类提供,用于计算理论上的头寸规模。
此外,基类还提供了setTM和setQuery方法来设置关联的交易账户和查询条件,以及clone方法用于创建资金管理器的副本,这对于在回测中保持策略状态的独立性至关重要。
Section sources
- MoneyManagerBase.h
- MoneyManagerBase.cpp
MM_FixedPercent策略,也称为百分比风险模型,是一种经典的风险管理方法,其核心理念是将每笔交易的风险控制在总资产的固定百分比内。
该策略的计算公式为:买入数量 = (账户现金 × 风险百分比p) / 交易风险(risk)。
- 账户现金:指在交易时刻,交易账户中可用于投资的现金余额。
- 风险百分比(p):一个由用户配置的参数,表示愿意为单笔交易承担的风险占总资产的比例,例如0.02代表2%。
- 交易风险(risk):指每股股票的潜在最大损失,通常由交易系统根据止损点计算得出。
该策略的实现类为FixedPercentMoneyManager,其_getBuyNumber方法直接应用了上述公式。通过将风险与总资产挂钩,该策略实现了仓位的动态调整:当账户盈利时,可投入的资金增加,从而可能买入更多股票;当账户亏损时,可投入的资金减少,自动降低了仓位,体现了“让利润奔跑,截断亏损”的原则。
flowchart TD
Start([开始]) --> ValidateInput["验证参数 p > 0 且 p <= 1"]
ValidateInput --> CalculateCash["获取账户现金"]
CalculateCash --> CalculateRisk["获取每股交易风险"]
CalculateRisk --> CalculateFormula["计算: (现金 * p) / 风险"]
CalculateFormula --> ApplyMinTrade["调整为最小交易单位的整数倍"]
ApplyMinTrade --> CheckCash["检查现金是否充足"]
CheckCash --> |充足| ReturnResult["返回计算结果"]
CheckCash --> |不足| ReduceNum["减少交易数量直至现金足够"]
ReduceNum --> ReturnResult
ReturnResult --> End([结束])
Diagram sources
- MM_FixedPercent.h
- FixedPercentMoneyManager.cpp
Section sources
- MM_FixedPercent.h
- FixedPercentMoneyManager.cpp
MM_FixedRisk策略是一种更为直接的风险控制方法,它为每笔交易设定一个固定的、绝对的金额作为最大可承受的损失。
该策略的计算公式为:买入数量 = 固定风险金额 / 每股交易风险。
- 固定风险金额:一个由用户预先设定的固定数值,例如1000元,表示无论账户总资产是多少,单笔交易的最大亏损额都限制在这个数值。
-
每股交易风险:与
MM_FixedPercent相同,指每股股票的潜在最大损失。
该策略的实现类为FixedRiskMoneyManager。其_getBuyNumber方法的逻辑非常简洁,直接将固定的risk参数除以每股风险。这种策略的优势在于风险敞口非常明确和一致,便于投资者进行心理预期和压力测试。然而,它不考虑账户的当前规模,可能导致在账户资金较少时仓位过重,或在资金较多时仓位过轻。
flowchart TD
Start([开始]) --> ValidateInput["验证参数 risk > 0"]
ValidateInput --> GetFixedRisk["获取固定风险金额"]
GetFixedRisk --> GetRiskPerShare["获取每股交易风险"]
GetRiskPerShare --> CalculateNum["计算: 固定风险 / 每股风险"]
CalculateNum --> ApplyMinTrade["调整为最小交易单位的整数倍"]
ApplyMinTrade --> CheckCash["检查现金是否充足"]
CheckCash --> |充足| ReturnResult["返回计算结果"]
CheckCash --> |不足| ReduceNum["减少交易数量直至现金足够"]
ReduceNum --> ReturnResult
ReturnResult --> End([结束])
Diagram sources
- MM_FixedRisk.h
- FixedRiskMoneyManager.cpp
Section sources
- MM_FixedRisk.h
- FixedRiskMoneyManager.cpp
MM_FixedCount策略是一种最简单的资金管理方法,它不进行任何风险计算,而是为每次买入操作指定一个固定的交易数量。
该策略的计算逻辑为:买入数量 = 用户设定的固定数量n。
- 固定数量(n):一个由用户配置的数值,表示每次买入时交易的股票数量。
该策略的实现类为FixedCountMoneyManager。其_getBuyNumber方法直接返回参数n。此策略主要用于策略回测的基准比较,因为它忽略了资金和风险因素,假设资金是无限充足的。在实际交易中,这种策略风险极高,因为它可能导致在账户资金不足时无法执行交易,或在市场波动剧烈时造成不成比例的巨大亏损。
flowchart TD
Start([开始]) --> GetFixedCount["获取固定交易数量 n"]
GetFixedCount --> ApplyMinTrade["调整为最小交易单位的整数倍"]
ApplyMinTrade --> CheckCash["检查现金是否充足"]
CheckCash --> |充足| ReturnResult["返回固定数量 n"]
CheckCash --> |不足| ReduceNum["减少交易数量直至现金足够"]
ReduceNum --> ReturnResult
ReturnResult --> End([结束])
Diagram sources
- MM_FixedCount.h
- FixedCountMoneyManager.cpp
Section sources
- MM_FixedCount.h
- FixedCountMoneyManager.cpp
MM_WilliamsFixedRisk策略结合了MM_FixedPercent和MM_FixedRisk的特点,它使用一个固定的最大损失金额,但这个金额是根据账户现金和一个风险百分比动态计算得出的。
该策略的计算公式为:买入数量 = (账户现金 × 风险百分比p) / 最大损失(max_loss)。
- 账户现金:交易时刻的账户现金余额。
- 风险百分比(p):用户配置的风险比例。
- 最大损失(max_loss):一个固定的金额,代表单笔交易允许的最大亏损额。
该策略的实现类为WilliamsFixedRiskMoneyManager。其_getBuyNumber方法首先计算出一个动态的“固定风险”值(即现金 * p),然后用这个值除以预设的max_loss来得到交易数量。这实际上意味着,策略试图将风险控制在max_loss,但可用的“风险预算”是现金 * p。这种设计提供了一种更精细的风险控制方式,既保证了单笔交易的最大亏损额是固定的,又确保了风险预算与账户规模成正比。
flowchart TD
Start([开始]) --> ValidateInput["验证参数 p > 0 且 max_loss > 0"]
ValidateInput --> CalculateCash["获取账户现金"]
CalculateCash --> CalculateDynamicRisk["计算动态风险: 现金 * p"]
CalculateDynamicRisk --> CalculateNum["计算: 动态风险 / max_loss"]
CalculateNum --> ApplyMinTrade["调整为最小交易单位的整数倍"]
ApplyMinTrade --> CheckCash["检查现金是否充足"]
CheckCash --> |充足| ReturnResult["返回计算结果"]
CheckCash --> |不足| ReduceNum["减少交易数量直至现金足够"]
ReduceNum --> ReturnResult
ReturnResult --> End([结束])
Diagram sources
- MM_WilliamsFixedRisk.h
- WilliamsFixedRiskMoneyManager.cpp
Section sources
- MM_WilliamsFixedRisk.h
- WilliamsFixedRiskMoneyManager.cpp
资金管理模块的依赖关系清晰,主要依赖于框架内的其他核心组件。
graph LR
A[资金管理器] --> B[TradeManager]
A --> C[KQuery]
A --> D[Parameter]
A --> E[SystemPart]
B --> F[交易记录]
B --> G[资金记录]
C --> H[K线数据]
D --> I[参数管理]
E --> J[系统组件]
style A fill:#f9f,stroke:#333
style B fill:#bbf,stroke:#333
style C fill:#bbf,stroke:#333
style D fill:#bbf,stroke:#333
style E fill:#bbf,stroke:#333
Diagram sources
- MoneyManagerBase.h
- MoneyManagerBase.cpp
Section sources
- MoneyManagerBase.h
- MoneyManagerBase.cpp
资金管理模块的性能主要体现在其计算效率和内存使用上。由于其核心计算(如乘除法)非常简单,且不涉及复杂的循环或递归,因此计算开销极低,对整体回测或实盘交易系统的性能影响可以忽略不计。内存方面,每个资金管理器实例只维护少量的成员变量(如名称、参数、交易账户指针等),内存占用很小。其性能瓶颈通常不在于算法本身,而在于与TradeManager交互时获取账户状态(如现金余额)的效率,但这属于TradeManager模块的优化范畴。
在使用资金管理模块时,可能会遇到以下常见问题:
-
交易数量为0:这通常是因为计算出的理论交易数量小于交易品种的最小交易单位(如A股的100股)。请检查
minTradeNumber参数,并确保资金管理器计算出的数量是其整数倍。 -
现金不足:当
auto-checkin参数为false(默认)时,如果计算出的交易所需资金超过账户现金,系统会自动减少交易数量直至现金足够,甚至可能将数量减至0。若希望强制交易,可将auto-checkin设为true,系统会自动向账户存入所需资金。 -
参数验证失败:如果传入了非法参数(如
MM_FixedPercent的p大于1或小于0),程序会通过HKU_ASSERT断言失败。请确保所有参数都在有效范围内。 -
交易账户为空:如果
MoneyManagerBase中的m_tm指针为空,调用getBuyNumber等方法会返回0并记录错误。请确保在使用资金管理器前已通过setTM方法正确设置了交易账户。
Section sources
- MoneyManagerBase.cpp
- FixedPercentMoneyManager.cpp
Hikyuu的资金管理模块提供了一个强大且灵活的框架,用于控制交易风险和决定头寸规模。通过MoneyManagerBase基类和多种具体策略的实现,用户可以根据自己的风险偏好选择合适的资金管理方法。MM_FixedPercent适合追求风险与收益动态平衡的投资者,MM_FixedRisk适合风险厌恶型且追求一致性的投资者,MM_FixedCount主要用作测试基准,而MM_WilliamsFixedRisk则提供了一种结合两者优点的混合策略。正确配置和使用资金管理器,对于构建稳健、可持续的交易系统至关重要。
from hikyuu import *
# 创建一个交易系统
sys = SYS()
# 配置不同的资金管理器
# 1. 固定比例 (2%风险)
mm_fixed_percent = MM_FixedPercent(0.02)
# 2. 固定风险 (每笔交易1000元)
mm_fixed_risk = MM_FixedRisk(1000.0)
# 3. 固定手数 (每次100股)
mm_fixed_count = MM_FixedCount(100)
# 4. 威廉姆斯固定风险 (风险比例10%,最大损失2000元)
mm_williams = MM_WilliamsFixedRisk(0.1, 2000.0)
# 将资金管理器添加到交易系统中
sys.set_mm(mm_fixed_percent) # 或其他策略
# ... 继续配置信号、止损等组件此示例展示了如何在Python中创建和配置不同的资金管理器,并将其集成到交易系统中。选择合适的策略并调整参数,可以显著影响投资组合的整体风险和收益特征。
Section sources
- MoneyManager.py