买空/卖空支持(continue)

This commit is contained in:
fasiondog 2022-09-19 23:26:32 +08:00
parent a78e89e443
commit 3be3a880b3
6 changed files with 81 additions and 56 deletions

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2022 hikyuu.org
*
* Created on: 2022-09-18
* Author: fasiondog
*/
#pragma once
#include "hikyuu/DataType.h"
#include "hikyuu/Stock.h"
#if HKU_SUPPORT_SERIALIZATION
#include <boost/serialization/nvp.hpp>
#endif
namespace hku {
struct ContractRecord {
ContractRecord() = default;
ContractRecord(const Stock& stk, const Datetime& datetime, price_t price, double number,
double marginRatio)
: stock(stk), datetime(datetime), price(price), number(number), marginRatio(marginRatio) {}
Stock stock;
Datetime datetime; // 交易日期
price_t price; // 成交价格
double number; // 成交数量
double marginRatio; // 保证金比例
price_t profit; // 上次结算时盈亏
private:
#if HKU_SUPPORT_SERIALIZATION
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar& BOOST_SERIALIZATION_NVP(datetime);
ar& BOOST_SERIALIZATION_NVP(price);
ar& BOOST_SERIALIZATION_NVP(number);
ar& BOOST_SERIALIZATION_NVP(marginRatio);
}
#endif
};
} // namespace hku

View File

@ -10,24 +10,6 @@
namespace hku { namespace hku {
PositionRecord::PositionRecord(const Stock& stock, const Datetime& takeDatetime,
const Datetime& cleanDatetime, double number, price_t avgPrice,
price_t stoploss, price_t goalPrice, double totalNumber,
price_t totalMoney, price_t totalCost, price_t totalRisk,
price_t sellMoney)
: stock(stock),
takeDatetime(takeDatetime),
cleanDatetime(cleanDatetime),
number(number),
avgPrice(avgPrice),
stoploss(stoploss),
goalPrice(goalPrice),
totalNumber(totalNumber),
buyMoney(totalMoney),
totalCost(totalCost),
totalRisk(totalRisk),
sellMoney(sellMoney) {}
PositionRecord::PositionRecord(PositionRecord&& rv) PositionRecord::PositionRecord(PositionRecord&& rv)
: stock(rv.stock), : stock(rv.stock),
takeDatetime(rv.takeDatetime), takeDatetime(rv.takeDatetime),
@ -111,7 +93,7 @@ price_t PositionRecord::addTradeRecord(const TradeRecord& tr) {
totalNumber += tr.number; totalNumber += tr.number;
buyMoney = roundEx(tr.realPrice * tr.number * stock.unit() * tr.marginRatio + buyMoney, buyMoney = roundEx(tr.realPrice * tr.number * stock.unit() * tr.marginRatio + buyMoney,
stock.precision()); stock.precision());
contracts.emplace_back(tr.datetime, tr.realPrice, tr.number, tr.marginRatio); contracts.emplace_back(stock, tr.datetime, tr.realPrice, tr.number, tr.marginRatio);
} else { } else {
sellMoney = roundEx(sellMoney + tr.realPrice * tr.number * stock.unit(), stock.precision()); sellMoney = roundEx(sellMoney + tr.realPrice * tr.number * stock.unit(), stock.precision());
price_t frozen_cash = 0.0; price_t frozen_cash = 0.0;

View File

@ -10,6 +10,7 @@
#define POSITIONRECORD_H_ #define POSITIONRECORD_H_
#include "TradeRecord.h" #include "TradeRecord.h"
#include "ContractRecord.h"
#if HKU_SUPPORT_SERIALIZATION #if HKU_SUPPORT_SERIALIZATION
#include <boost/serialization/split_member.hpp> #include <boost/serialization/split_member.hpp>
@ -18,30 +19,6 @@
namespace hku { namespace hku {
struct ContractRecord {
ContractRecord() = default;
ContractRecord(const Datetime& datetime, price_t price, double number, double marginRatio)
: datetime(datetime), price(price), number(number), marginRatio(marginRatio) {}
Datetime datetime; // 交易日期
price_t price; // 成交价格
double number; // 成交数量
price_t marginRatio; // 保证金比例
private:
#if HKU_SUPPORT_SERIALIZATION
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar& BOOST_SERIALIZATION_NVP(datetime);
ar& BOOST_SERIALIZATION_NVP(price);
ar& BOOST_SERIALIZATION_NVP(number);
ar& BOOST_SERIALIZATION_NVP(marginRatio);
}
#endif
};
/** /**
* *
* @ingroup TradeManagerClass * @ingroup TradeManagerClass
@ -51,10 +28,6 @@ public:
PositionRecord() = default; PositionRecord() = default;
PositionRecord(const PositionRecord&) = default; PositionRecord(const PositionRecord&) = default;
PositionRecord(PositionRecord&& rv); PositionRecord(PositionRecord&& rv);
PositionRecord(const Stock& stock, const Datetime& takeDatetime, const Datetime& cleanDatetime,
double number, price_t avgPrice, price_t stoploss, price_t goalPrice,
double totalNumber, price_t buyMoney, price_t totalCost, price_t totalRisk,
price_t sellMoney);
PositionRecord& operator=(const PositionRecord&) = default; PositionRecord& operator=(const PositionRecord&) = default;
PositionRecord& operator=(PositionRecord&& rv); PositionRecord& operator=(PositionRecord&& rv);
@ -66,7 +39,7 @@ public:
price_t addTradeRecord(const TradeRecord& tr); price_t addTradeRecord(const TradeRecord& tr);
/** /**
* *
* @note * @note
*/ */
price_t getProfitOfPreDay(Datetime datetime); price_t getProfitOfPreDay(Datetime datetime);
@ -83,6 +56,7 @@ public:
price_t totalCost = 0.0; ///< 累计交易总成本 price_t totalCost = 0.0; ///< 累计交易总成本
price_t totalRisk = 0.0; ///< 累计交易风险 = 各次 (买入价格-止损)*买入数量, 不包含交易成本 price_t totalRisk = 0.0; ///< 累计交易风险 = 各次 (买入价格-止损)*买入数量, 不包含交易成本
price_t sellMoney = 0.0; ///< 累计卖出资金 price_t sellMoney = 0.0; ///< 累计卖出资金
// Datetime preSettleDate; ///< 上一次结算日期
bool isShort = false; bool isShort = false;
std::list<ContractRecord> contracts; std::list<ContractRecord> contracts;

View File

@ -353,7 +353,7 @@ TradeRecord TradeManager::buy(const Datetime& datetime, const Stock& stock, pric
// 账户资金精度及保证金比例 // 账户资金精度及保证金比例
int precision = getParam<int>("precision"); int precision = getParam<int>("precision");
double marginRatio = getMarginRatio(datetime, stock); auto marginRatio = getMarginRatio(datetime, stock);
CostRecord cost = getBuyCost(datetime, stock, realPrice, number); CostRecord cost = getBuyCost(datetime, stock, realPrice, number);
// 买入资产价值 // 买入资产价值
@ -748,6 +748,23 @@ void TradeManager::updateWithWeight(const Datetime& datetime) {
m_last_update_datetime = datetime; m_last_update_datetime = datetime;
} }
void TradeManager::_updateSettleByDay(const Datetime& datetime) {
HKU_IF_RETURN(m_contracts.empty(), void());
auto iter = m_contracts.begin();
// 假定同一账户操作的开闭市时间相同,从第一个证券获取闭市时间
if (m_market_close_time == Null<TimeDelta>()) {
m_market_close_time =
StockManager::instance().getMarketInfo(iter->stock.market()).closeTime2();
}
price_t profit = 0.0;
price_t need_maintain_money = 0.0;
for (; iter != m_contracts.end(); ++iter) {
}
}
void TradeManager::_saveAction(const TradeRecord& record) { void TradeManager::_saveAction(const TradeRecord& record) {
HKU_IF_RETURN(getParam<bool>("save_action") == false, void()); HKU_IF_RETURN(getParam<bool>("save_action") == false, void());
std::stringstream buf(std::stringstream::out); std::stringstream buf(std::stringstream::out);
@ -980,10 +997,9 @@ bool TradeManager::_add_buy_tr(const TradeRecord& tr) {
//更新当前持仓记录 //更新当前持仓记录
position_map_type::iterator pos_iter = m_position.find(tr.stock.id()); position_map_type::iterator pos_iter = m_position.find(tr.stock.id());
if (pos_iter == m_position.end()) { if (pos_iter == m_position.end()) {
m_position[tr.stock.id()] = PositionRecord( PositionRecord position;
tr.stock, tr.datetime, Null<Datetime>(), tr.number, tr.realPrice, tr.stoploss, position.addTradeRecord(tr);
tr.goalPrice, tr.number, money, tr.cost.total, m_position[tr.stock.id()] = position;
roundEx((tr.realPrice - tr.stoploss) * tr.number * tr.stock.unit(), precision), 0.0);
} else { } else {
PositionRecord& position = pos_iter->second; PositionRecord& position = pos_iter->second;
position.number += tr.number; position.number += tr.number;

View File

@ -15,6 +15,7 @@
#include "TradeRecord.h" #include "TradeRecord.h"
#include "PositionRecord.h" #include "PositionRecord.h"
#include "FundsRecord.h" #include "FundsRecord.h"
#include "ContractRecord.h"
#include "OrderBrokerBase.h" #include "OrderBrokerBase.h"
#include "crt/TC_Zero.h" #include "crt/TC_Zero.h"
@ -239,6 +240,9 @@ private:
//以脚本的形式保存交易动作,便于修正和校准 //以脚本的形式保存交易动作,便于修正和校准
void _saveAction(const TradeRecord&); void _saveAction(const TradeRecord&);
// 更新当前时刻前一结算日权益
void _updateSettleByDay(const Datetime& datetime);
bool _add_init_tr(const TradeRecord&); bool _add_init_tr(const TradeRecord&);
bool _add_buy_tr(const TradeRecord&); bool _add_buy_tr(const TradeRecord&);
bool _add_sell_tr(const TradeRecord&); bool _add_sell_tr(const TradeRecord&);
@ -264,6 +268,10 @@ private:
position_map_type m_position; //当前持仓交易对象的持仓记录 ["sh000001"-> ] position_map_type m_position; //当前持仓交易对象的持仓记录 ["sh000001"-> ]
PositionRecordList m_position_history; //持仓历史记录 PositionRecordList m_position_history; //持仓历史记录
TimeDelta m_market_close_time; // 缓存市场闭市时间
list<ContractRecord> m_contracts; // 记录当前持仓的合约
map<Datetime, FundsRecord> m_funds; // 记录每日结算资产
list<string> m_actions; //记录交易动作,便于修改或校准实盘时的交易 list<string> m_actions; //记录交易动作,便于修改或校准实盘时的交易
//================================================== //==================================================
@ -287,6 +295,7 @@ private:
ar& bs::make_nvp<PositionRecordList>("m_position", position); ar& bs::make_nvp<PositionRecordList>("m_position", position);
ar& BOOST_SERIALIZATION_NVP(m_position_history); ar& BOOST_SERIALIZATION_NVP(m_position_history);
ar& BOOST_SERIALIZATION_NVP(m_trade_list); ar& BOOST_SERIALIZATION_NVP(m_trade_list);
ar& BOOST_SERIALIZATION_NVP(m_contracts);
ar& BOOST_SERIALIZATION_NVP(m_actions); ar& BOOST_SERIALIZATION_NVP(m_actions);
} }
@ -309,6 +318,7 @@ private:
} }
ar& BOOST_SERIALIZATION_NVP(m_position_history); ar& BOOST_SERIALIZATION_NVP(m_position_history);
ar& BOOST_SERIALIZATION_NVP(m_trade_list); ar& BOOST_SERIALIZATION_NVP(m_trade_list);
ar& BOOST_SERIALIZATION_NVP(m_contracts);
ar& BOOST_SERIALIZATION_NVP(m_actions); ar& BOOST_SERIALIZATION_NVP(m_actions);
} }

View File

@ -19,9 +19,6 @@ using namespace hku;
void export_PositionRecord() { void export_PositionRecord() {
class_<PositionRecord>("PositionRecord", "持仓记录", init<>()) class_<PositionRecord>("PositionRecord", "持仓记录", init<>())
.def(init<const Stock&, const Datetime&, const Datetime&, double, price_t, price_t, price_t,
double, price_t, price_t, price_t, price_t>())
.def("__str__", &PositionRecord::toString) .def("__str__", &PositionRecord::toString)
.def("__repr__", &PositionRecord::toString) .def("__repr__", &PositionRecord::toString)