qff.frame.portfolio 源代码

# coding :utf-8
#
# The MIT License (MIT)
#
# Copyright (c) 2016-2019 XuHaiJiang/QFF
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from qff.frame.context import context, RUN_TYPE
from qff.price.cache import get_current_data


[文档]class Portfolio: """ 股票账户 账户当前的资金,标的信息,即所有标的操作仓位的信息汇总。 ================== ============== ============================================================== 属性 类型 说明 ================== ============== ============================================================== starting_cash float 初始资金 available_cash float 可用资金, 可用来购买证券的资金 locked_cash float 冻结资金, 挂单锁住资金 total_assets float 账户总资产, 包括现金, 仓位(股票)的总价值, 可用来计算收益 positions_assets float 持仓资产价值 benchmark_assets float 基准市值 income float 账户累计收益 returns float 账户收益率 day_income float 当日盈亏金额 day_returns float 当日涨幅 positions Dict 当前仓位,key值为股票代码,value是 :class:`.Position` 对象 benchmark_returns float 基准收益率 ================== ============== ============================================================== """ def __init__(self, starting_cash): self.starting_cash = starting_cash # 初始资金 self.available_cash = starting_cash # 可用资金, 可用来购买证券的资金 self.locked_cash = 0 # 挂单锁住资金 self.positions = {} # key值为股票代码,value是Position对象 self.pre_total_assets = starting_cash # 上一个交易日的资产总值,用于计算当日收益。 self._snapshot_time = None self._total_assets = 0 self._position_assets = 0 def update(self): self._position_assets = sum([pst.valuation for pst in self.positions.values()]) self._total_assets = round(self.available_cash + self._position_assets + self.locked_cash, 2) self._snapshot_time = context.current_dt @property def positions_assets(self): """ 持仓资产市值 """ if context.current_dt != self._snapshot_time: self.update() return self._position_assets @property def total_assets(self): """ 账户当日总市值 包括现金, 仓位(股票)的总价值, 可用来计算收益 """ if context.current_dt != self._snapshot_time: self.update() return self._total_assets @property def benchmark_assets(self): """ 基准市值 """ if context.run_type == RUN_TYPE.BACK_TEST: b_assets = round(context.bm_data.loc[context.current_dt[0:10]].close / context.bm_start * self.starting_cash, 2) else: b_assets = round(get_current_data(context.benchmark, market='index').last_price / context.bm_start * self.starting_cash, 2) return b_assets @property def income(self): """ 账户累计收益 """ return round(self.total_assets - self.starting_cash , 2) @property def returns(self): """ 账户累计收益率 """ return round(self.total_assets / self.starting_cash - 1, 4) @property def benchmark_returns(self): """ 基准收益率 """ return round(self.benchmark_assets / self.starting_cash - 1, 4) @property def day_income(self): """ 账户当日盈亏 """ return round(self.total_assets - self.pre_total_assets, 2) @property def day_returns(self): """ 账户当日涨幅 """ return round(self.total_assets / self.pre_total_assets - 1, 4) @property def message(self): """ 账户当前资产信息快照 """ return { '日期': context.current_dt[:10], '现金资产': round(self.available_cash + self.locked_cash, 2), '持仓资产': self.positions_assets, '账户总资产': self.total_assets, '累计收益额': self.income, '累计收益率': self.returns, '当日盈亏金额': self.day_income, '当日涨幅': self.day_returns, '仓位': round(self.positions_assets / self.total_assets, 4), '基准总资产': self.benchmark_assets, '基准收益率': self.benchmark_returns, } @property def init_message(self): return { '日期': context.previous_date[:10], '现金资产': self.starting_cash, '持仓资产': 0, '账户总资产': self.starting_cash, '累计收益额': 0, '累计收益率': 0, '当日盈亏金额': 0, '当日涨幅': 0, '仓位': 0, '基准总资产': self.starting_cash, '基准收益率': 0, }
def get_portfolio(): """ 获取账户当前时刻信息 """ return context.portfolio.message, [pst.message for pst in context.portfolio.positions.values()]