Merge remote-tracking branch 'origin/hotfix/zs_v1.3_1016' into feature/zs_v1.3.3

This commit is contained in:
gongpei
2025-10-30 10:19:52 +08:00
21 changed files with 792 additions and 67 deletions
@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YieldChain.Security;
using YLErp.DBModels.Base;
namespace YLErp.DBModels
{
/// <summary>
/// 债券期间付息表
/// </summary>
[Table("bond_payment_info")]
public class BondPayment
{
public long id { get; set; }
/// <summary>
/// 加密主键
/// </summary>
[NotMapped]
public string EncryptId
{
get { return DataProtect.Encrypt(id.ToString()); }
}
/// <summary>
/// 债券代码
/// </summary>
[Column("inner_code")]
public int inner_code { get; set; }
[Column("underlying_code")]
public string underlyingCode { get; set; }
/// <summary>
/// 债券代码
/// </summary>
[DisplayName("债券代码")]
[NotMapped]
public string security_id { get; set; }
/// <summary>
/// 债券名称
/// </summary>
[DisplayName("债券名称")]
[NotMapped]
public string symbol { get; set; }
/// <summary>
/// 利息税率(%)
/// </summary>
[DisplayName("利息税率(%)")]
[Column("interest_tax_rate")]
public decimal? coupon_rate { get; set; }
/// <summary>
/// 现金流发放日
/// </summary>
[DisplayName("理论付息(兑付)日")]
[Column("pay_date_PL")]
public DateTime? payment_date_pl { get; set; }
/// <summary>
/// 现金流发放日
/// </summary>
[DisplayName("实际付息(兑付)日")]
[Column("pay_date_act")]
public DateTime? payment_date { get; set; }
/// <summary>
/// 每张兑付利息额
/// </summary>
[DisplayName("每张兑付利息额")]
[Column("paying_interest")]
public decimal? payment_interest { get; set; }
/// <summary>
/// 每张兑付本金额
/// </summary>
[DisplayName("每张兑付本金额")]
[Column("paying_principal")]
public decimal? payment_parvalue { get; set; }
/// <summary>
/// 每张兑付本息额
/// </summary>
[DisplayName("每张兑付本息额")]
[Column("paying_price")]
public decimal? paying_price { get; set; }
/// <summary>
/// 渠道来源
/// </summary>
[Column("info_source")]
public string channel_source { get; set; }
/// <summary>
/// 聚源JSID
/// </summary>
public long jsid { get; set; }
/// <summary>
/// 发布时间
/// </summary>
[Column("insert_time")]
public DateTime create_time { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[DisplayName("更新时间")]
[Column("update_time")]
public DateTime update_time { get; set; }
}
}
@@ -183,5 +183,8 @@ namespace YLErp.DBModels
/// 支付日
/// </summary>
public DateTime? PayDate { get; set; }
[NotMapped]
public DateTime? TradeStartDate { get; set; }
}
}
@@ -317,6 +317,18 @@ namespace YLErp.DBModels
public string UnderlyingPinYin { get; set; }
/// <summary>
/// 聚源内部id
/// </summary>
public long? InnerCode { get; set; }
/// <summary>
/// 债券增值税
/// </summary>
[Column("value_added_tax")]
[DisplayName("增值税率")]
public decimal? ValueAddedTax { get; set; }
public override string ToString()
{
return $"{UnderlyingCode}--{UnderlyingName}--{id}--{UnderlyingInstrumentType}";
+23 -21
View File
@@ -510,7 +510,7 @@ namespace YLErp.BLL.Eod
&& t.TradeType == "收益互换").ToList();
//OTC持仓交易
var tradeIdList = tradeList.Select(t => t.id).ToList();
var positions = db.swap_position.Where(x => tradeIdList.Contains(x.SwapTradeId) && !x.IsInitial && x.PosiQuantity > 0&&!x.Invalid).ToList();
var positions = db.swap_position.Where(x => tradeIdList.Contains(x.SwapTradeId) && !x.IsInitial && x.PosiQuantity > 0 && !x.Invalid).ToList();
var swapFlows = db.swap_flow.Where(x => x.DataState == (int)SwapFlowDateStateEnum.).ToList();
using var bondDb = new BondOmsDBContext();
var clientPositions = bondDb.client_position.AsEnumerable();
@@ -533,18 +533,18 @@ namespace YLErp.BLL.Eod
td,
p
};
var positionGroup = query.AsEnumerable().GroupBy(x => new { x.p.UnderlyingCode, x.td.ClientId,x.p.PosiDirection});
var positionGroup = query.AsEnumerable().GroupBy(x => new { x.p.UnderlyingCode, x.td.ClientId, x.p.PosiDirection });
var dealSwapFlowIds = new List<long>();
SwapTradeAutoService swapTradeAutoService = new SwapTradeAutoService(optUser);
var datenow = DateTime.Now;
foreach (var pair in positionGroup)
{
var client = DataCacheProvider.GetClientDataSource().GetData(pair.Key.ClientId);
if (client == null||string.IsNullOrEmpty(pair.Key.UnderlyingCode))
if (client == null || string.IsNullOrEmpty(pair.Key.UnderlyingCode))
{
continue;
}
var clientPosition = clientPositions.FirstOrDefault(x => x.client_id == pair.Key.ClientId && x.security_id == pair.Key.UnderlyingCode&&x.direction== pair.Key.PosiDirection);
var clientPosition = clientPositions.FirstOrDefault(x => x.client_id == pair.Key.ClientId && x.security_id == pair.Key.UnderlyingCode && x.direction == pair.Key.PosiDirection);
var trades = pair.Select(s => s.td).ToList();
var tradeIds = trades.Select(x => x.id);
var positionGroupItems = positions.Where(x => tradeIds.Contains(x.SwapTradeId) && x.UnderlyingCode == pair.Key.UnderlyingCode && x.PosiDirection == pair.Key.PosiDirection);
@@ -563,15 +563,17 @@ namespace YLErp.BLL.Eod
var multiplier = ConsGlobal.InstrumentType.IsBond(lastPosi.UnderlyingInstrumentType) ? ConsGlobal.bondShowPriceMultiple : 1;
// 计算加权平均价格(区分债券和非债券)
var weightedPrice = posiQty==0?0: positionGroupItems
.Sum(s => {
var weightedPrice = posiQty == 0 ? 0 : positionGroupItems
.Sum(s =>
{
decimal price = ConsGlobal.InstrumentType.IsBond(lastPosi.UnderlyingInstrumentType)
? s.PosiGrossPrice * ConsGlobal.bondShowPriceMultiple
: s.PosiGrossPrice;
return s.PosiQuantity * price;
}) / posiQty;
var weightedNetPrice = posiQty==0?0: positionGroupItems
.Sum(s => {
var weightedNetPrice = posiQty == 0 ? 0 : positionGroupItems
.Sum(s =>
{
decimal price = ConsGlobal.InstrumentType.IsBond(lastPosi.UnderlyingInstrumentType)
? s.PosiNetPrice * ConsGlobal.bondShowPriceMultiple
: s.PosiNetPrice;
@@ -584,7 +586,7 @@ namespace YLErp.BLL.Eod
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(pair.Key.UnderlyingCode);
clientPosition = CreateClientPosition(clientPosition, pair.Key.ClientId, pair.Key.UnderlyingCode, netPrice, price, posiQty / 10000, comminsions, positionType == PositionTypeFlag.Long ? 0 : 1, lastPosi.ContractSize, pair.Key.PosiDirection);
clientPosition.position_notional_principal = totalNotional;
if (pair.Key.PosiDirection==(int)SwapDirectionEnum.)
if (pair.Key.PosiDirection == (int)SwapDirectionEnum.)
{
var flowMerges = MergeSwapFlow(newSwapFlows, multiplier);
dealSwapFlowIds.AddRange(newSwapFlows.Select(s => s.id));
@@ -596,7 +598,7 @@ namespace YLErp.BLL.Eod
clientPosition.update_user = 0;
SetClientPositionPrice(clientPosition);
clientPosition.swap_market_value = clientPosition.full_price_now * clientPosition.position_qty * (clientPosition.side == 0 ? 1 : -1);
clientPosition.position_profit_loss = (clientPosition.full_price_now - clientPosition.deal_full_price_avg) * clientPosition.position_qty * (clientPosition.side == 0 ? 1 : -1) - clientPosition.commission;
clientPosition.position_profit_loss = (clientPosition.full_price_now - clientPosition.deal_full_price_avg) * 0.01m * (clientPosition.position_qty * 10000) * (clientPosition.side == 0 ? 1 : -1) - clientPosition.commission;
clientPosition.position_profit_loss = Math.Round(clientPosition.position_profit_loss ?? 0, 2, MidpointRounding.AwayFromZero);
clientPosition.today_profit_loss = clientPosition.swap_market_value - lastPv;
if (clientPosition.deal_full_price_avg > 0 && enableCalcBongd)//发kafka 获取成交收益率
@@ -629,7 +631,7 @@ namespace YLErp.BLL.Eod
continue;
}
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(swapFlowGroup.Key.UnderlyingCode);
var multiplier = um!=null&& um.IsBond() ? ConsGlobal.bondShowPriceMultiple : 1;
var multiplier = um != null && um.IsBond() ? ConsGlobal.bondShowPriceMultiple : 1;
var flowMerges = MergeSwapFlow(swapFlowGroup.ToList(), multiplier);
var flowMergeMax = flowMerges.OrderByDescending(s => s.TradingQty).First();
var flowMergeMin = flowMerges.FirstOrDefault(x => x.BsType != flowMergeMax.BsType);
@@ -665,7 +667,7 @@ namespace YLErp.BLL.Eod
bondDb.SaveChanges();
}
}
sql = $"{nameof(ClientPosition.create_time)}<'{datenow.AddSeconds(-1):yyyy-MM-dd HH:mm:ss}' or {nameof(ClientPosition.position_qty)}=0";
sql = $"{nameof(ClientPosition.create_time)}<'{datenow.AddSeconds(-1):yyyy-MM-dd HH:mm:ss}' or {nameof(ClientPosition.position_qty)}=0";
bondDb.BulkDelete<ClientPosition>(sql);
bondDb.SaveChanges();
#endregion
@@ -741,10 +743,10 @@ namespace YLErp.BLL.Eod
private static void BondCalcApi(ClientPosition clientPosition)
{
var resp = BondCalcHepler.BondCalc(clientPosition.security_id, clientPosition.deal_full_price_avg ?? 0, "DP");
if (resp!=null)
if (resp != null)
{
clientPosition.deal_yield_avg = resp.ytm* ConsGlobal.bondPriceMultiple;
_yLCache.StringSetWithNoPrefix<CalBondResult>("TRS-BondFullPrice:" + clientPosition.security_id, resp,TimeSpan.FromHours(1));
clientPosition.deal_yield_avg = resp.ytm * ConsGlobal.bondPriceMultiple;
_yLCache.StringSetWithNoPrefix<CalBondResult>("TRS-BondFullPrice:" + clientPosition.security_id, resp, TimeSpan.FromHours(1));
}
}
/// <summary>
@@ -759,7 +761,7 @@ namespace YLErp.BLL.Eod
/// <param name="comminsion"></param>
/// <param name="side"></param>
/// <returns></returns>
private static ClientPosition CreateClientPosition(ClientPosition clientPosition, int clientId, string underlyingCode, decimal price, decimal fullPrice, decimal qty, decimal comminsion, int side,decimal contractsize,int direction)
private static ClientPosition CreateClientPosition(ClientPosition clientPosition, int clientId, string underlyingCode, decimal price, decimal fullPrice, decimal qty, decimal comminsion, int side, decimal contractsize, int direction)
{
var underlyingName = DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingCode)?.UnderlyingName;
var client = DataCacheProvider.GetClientDataSource().GetData(clientId);
@@ -781,7 +783,7 @@ namespace YLErp.BLL.Eod
clientPosition.side = side;
clientPosition.create_time = DateTime.Now;
clientPosition.client_user_id = 0;
clientPosition.position_notional_principal = fullPrice* qty * 10000 * contractsize * ConsGlobal.bondPriceMultiple;
clientPosition.position_notional_principal = fullPrice * qty * 10000 * contractsize * ConsGlobal.bondPriceMultiple;
clientPosition.direction = direction;
return clientPosition;
}
@@ -865,7 +867,7 @@ namespace YLErp.BLL.Eod
clientPosition.deal_full_price_avg = priceResult.Item1;
}
clientPosition.commission = flowMerges.Sum(s => s.TradingFee);
clientPosition.position_qty = Math.Abs(allPosiQty/10000);
clientPosition.position_qty = Math.Abs(allPosiQty / 10000);
clientPosition.position_notional_principal = Math.Abs(allPosiQty) * clientPosition.deal_full_price_avg * ConsGlobal.bondPriceMultiple;
if (allPosiQty < 0)
{
@@ -881,7 +883,7 @@ namespace YLErp.BLL.Eod
return (clientPosition.deal_full_price_avg ?? 0, clientPosition.deal_price_avg ?? 0);
}
var sameAmount = flowMergeSame.TradingAmountAvg * flowMergeSame.TradingQty;
var sameNetAmount = (flowMergeSame.TradingAmountNetAvg??0) * flowMergeSame.TradingQty;
var sameNetAmount = (flowMergeSame.TradingAmountNetAvg ?? 0) * flowMergeSame.TradingQty;
var totalQty = (clientPosition.position_qty ?? 0) + flowMergeSame.TradingQty;
if (totalQty == 0)
{
@@ -1052,7 +1054,7 @@ namespace YLErp.BLL.Eod
//根据TradeId,VolType,ValueDate更新已经存在的数据
var tradeids = resultRisks.Select(t => t.TradeId).ToList();
var tradeRisks = db.realtime_trade_risk.Where(x => tradeids.Contains(x.TradeId) && x.VolType == volType && x.ValueDate == valueDate).ToList();
var delTradeRisks= db.realtime_trade_risk.Where(x => !tradeids.Contains(x.TradeId) && x.VolType == volType && x.ValueDate == valueDate).ToList();
var delTradeRisks = db.realtime_trade_risk.Where(x => !tradeids.Contains(x.TradeId) && x.VolType == volType && x.ValueDate == valueDate).ToList();
db.realtime_trade_risk.RemoveRange(delTradeRisks);
for (var i = 0; i < tradeRisks.Count; i++)
{
@@ -2388,7 +2390,7 @@ namespace YLErp.BLL.Eod
public static ClientBalanceForTrsResponse GetClientBalance(int clientId)
{
if (_yLCache!=null)
if (_yLCache != null)
{
return _yLCache.StringGet<ClientBalanceForTrsResponse>("ClientBalance:" + clientId);
}
+2
View File
@@ -406,5 +406,7 @@ namespace YLErp.BLL
public DbSet<client_margin_config> clientMarginConfig { get; set; }
public DbSet<client_margin_detail> clientMarginDetail { get; set; }
public DbSet<trade_contract_oa_result> tradeContractOaResult { get; set; }
public DbSet<BondPayment> bondPayment { get; set; }
}
}
@@ -0,0 +1,167 @@
using BaseOUDAL;
using DocumentFormat.OpenXml.Bibliography;
using ExcelDataReader.Log;
using YLErp.DBModels;
using YLErp.Helpers;
namespace YLErp.Modules.EodModule
{
/// <summary>
/// 债券期间付息服务
/// </summary>
public class BondPaymentService : YLBaseService
{
private static IYcLogger Log = LogFactory.GetLogger(nameof(BondPaymentService));
public BondPaymentService(OptUserInfo userInfo) : base(userInfo)
{
}
public SearchListResult<BondPaymentDto> SearchList(BondPaymentReq req)
{
var valueDtStart = req.ValueDateStart.Year > 2000 ? req.ValueDateStart : DateTime.Today.AddYears(-1);
var valueDtEnd = req.ValueDateEnd.Year > 2000 ? req.ValueDateEnd.AddDays(1) : DateTime.Today.AddYears(1);
var predicatUn = PredicateBuilder.Create<underlying_manager>(d => d.LaunchState == "1");
var predicatEoc = PredicateBuilder.Create<BondPayment>(source => source.payment_date >= valueDtStart && source.payment_date < valueDtEnd);
if (!string.IsNullOrEmpty(req.DataSource))
{
predicatEoc = predicatEoc.And(d => d.channel_source.Contains(req.DataSource));
}
if (!string.IsNullOrEmpty(req.MarketName))
{
predicatUn = predicatUn.And(d => d.MarketName == req.MarketName);
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
predicatEoc = predicatEoc.And(d => d.underlyingCode.Contains(req.UnderlyingCode));
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "payment_date";
req.sord = "desc";
}
var queryUn = DbContext.underlying_manager.Where(predicatUn).Select(n => new { n.id, n.MarketName, n.UnderlyingCode, n.UnderlyingName, n.UnderlyingInstrumentType, n.InnerCode });
var query = from un in queryUn
join source in DbContext.bondPayment.Where(predicatEoc) on un.UnderlyingCode equals source.underlyingCode
select new BondPaymentDto
{
id = source.id,
channel_source = source.channel_source,
MarketName = un.MarketName,
security_id = un.UnderlyingCode,
symbol = un.UnderlyingName,
coupon_rate = source.coupon_rate,
payment_date = source.payment_date,
payment_interest = source.payment_interest,
payment_parvalue = source.payment_parvalue,
create_time = source.create_time,
update_time = source.update_time
};
var result = query.ToSearchList(req);
return result;
}
public BondPayment SaveBondPayment(BondPayment req)
{
if (req is null)
{
throw new ArgumentNullException(nameof(req));
}
BondPayment dbmodel;
if (req.id == 0)
{
DbContext.bondPayment.Add(dbmodel = req);
}
else
{
dbmodel = DbContext.bondPayment.Find(req.id);
if (dbmodel == null)
{
throw new ServiceException("数据不存在");
}
UpdateChanges(dbmodel, req);
}
dbmodel.update_time = DateTime.Now;
DbContext.SaveChanges();
return dbmodel;
}
/// <summary>
/// 获取某债券的期间付息情况集合
/// </summary>
/// <param name="underylingCode"></param>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <returns></returns>
public List<BondPayment> GetBondPayments(string underlyingCode, DateTime startDate, DateTime endDate)
{
var result = DbContext.bondPayment.Where(x => x.underlyingCode == underlyingCode && x.payment_date > startDate && x.payment_date <= endDate).AsNoTracking().ToList();
return result;
}
public List<BondPayment> GetTargetDatePayments(string underlyingCode, DateTime targetDate)
{
var startDate = targetDate.Date;
var endDate = startDate.AddDays(1);
return DbContext.bondPayment.AsNoTracking().Where(x => x.underlyingCode == underlyingCode && x.payment_date >= startDate && x.payment_date < endDate).ToList();
}
/// <summary>
/// 计算某债券某段时间的期间付息
/// </summary>
/// <param name="underylingCode">债券代码</param>
/// <param name="startDate">计息开始日</param>
/// <param name="endDate">计息结束日</param>
/// <param name="qty">持仓数量</param>
/// <param name="longRatio">多空方向</param>
/// <param name="payDirection">收支方向</param>
/// <returns></returns>
public decimal CalcPayment(string underlyingCode, DateTime startDate, DateTime endDate, decimal qty, decimal longRatio, decimal payDirection)
{
var payments = GetBondPayments(underlyingCode, startDate, endDate);
return CalcPayment(payments, qty, longRatio, payDirection);
}
/// <summary>
/// 计算某债券期间付息
/// </summary>
/// <param name="payments">期间付息集合</param>
/// <param name="qty">持仓数量</param>
/// <param name="longRatio">多空方向</param>
/// <param name="payDirection">收支方向</param>
/// <returns></returns>
public decimal CalcPayment(List<BondPayment> payments, decimal qty, decimal longRatio, decimal payDirection)
{
var interest = payments.Sum(s => s.payment_interest ?? 0);
return interest * qty * 0.01m * longRatio * payDirection;
}
}
/// <summary>
///
/// </summary>
public class BondPaymentReq : BaseSearchReq
{
/// <summary>
/// 数据来源
/// </summary>
public string DataSource { get; set; }
/// <summary>
/// 标的代码
/// </summary>
public string UnderlyingCode { get; set; }
public DateTime ValueDateStart { get; set; }
public DateTime ValueDateEnd { get; set; }
// 市场
public string MarketName { get; set; }
}
public class BondPaymentDto : BondPayment
{
public string MarketName { get; set; }
}
}
@@ -205,7 +205,7 @@ namespace YLErp.Modules.ReportModule.SettlementReportModule
Directory.CreateDirectory(targetPath);
}
var clientName = report.client.Name;
var fileName = report.ReportFrom == DateTime.MinValue ? $"估值表_{report.ReportEnd:yyyyMMdd}_{clientName}" : $"估值表_{report.ReportFrom:yyyyMMdd}_{report.ReportEnd:yyyyMMdd}_{clientName}";
var fileName = report.ReportFrom == DateTime.MinValue ? $"浙商证券_估值表_{report.ReportEnd:yyyyMMdd}_{clientName}" : $"浙商证券_估值表_{report.ReportFrom:yyyyMMdd}_{report.ReportEnd:yyyyMMdd}_{clientName}";
var targetFileName = Path.Combine(targetPath, $"{fileName}.xlsx");
var excelDeclareModel = new ExcelDeclareModel()
+48 -13
View File
@@ -9,6 +9,7 @@ using OfficeOpenXml.Drawing.Controls;
using Org.BouncyCastle.Asn1.Ocsp;
using Qdp.Pricing.Base.Implementations;
using Qdp.Pricing.Core.Modules;
using Qdp.Pricing.Library.Base.Utilities;
using System.Linq.Expressions;
using YLErp.BLL;
using YLErp.BLL.Eod;
@@ -71,6 +72,7 @@ namespace YLErp.Modules.SwapModule
}
else
{
unwindData.TradeStartDate = td.StartDate;
unwindData.CloseType = commodity ? 1 : 2;
unwindData.StartDate = td.TradeDate.Value;
if (preDealDate.HasValue)
@@ -400,7 +402,7 @@ namespace YLErp.Modules.SwapModule
}
else if (position.InterestMode == (int)InterestModeEnum.)
{
_closePosiNotionalValue = _posiNotionalValue * closePrecent;
_closePosiNotionalValue = _posiNotionalValue * closePrecent;
_posiNotionalValue = _posiNotionalValue;
}
else if (position.InterestMode == (int)InterestModeEnum. || position.InterestMode == (int)InterestModeEnum.)
@@ -433,7 +435,7 @@ namespace YLErp.Modules.SwapModule
position.FloatRate = Convert.ToDecimal(floatRate);
positionClone.FloatRate = position.FloatRate;
}
else if(!swap)
else if (!swap)
{
throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{rateDate:yyyy年MM月dd日}的价格");
}
@@ -769,7 +771,7 @@ namespace YLErp.Modules.SwapModule
DealFloatPosition(unwindData);
var flowList = new List<swap_flow_event>(unwindData.FlowEvents);
var eventId = SaveSwapDeal(unwindData, (int)SwapEventTypeEnum., clientCashId, "系统操作_平仓");
if (unwindData.CloseMethod == (int)CloseMethodEnum.|| unwindData.ClosePercent==1)
if (unwindData.CloseMethod == (int)CloseMethodEnum. || unwindData.ClosePercent == 1)
{
td.TradeStatus = "已平仓";
td.trade_extend = DbContext.trade_extend.FirstOrDefault(x => x.TradeId == td.id);
@@ -812,7 +814,7 @@ namespace YLErp.Modules.SwapModule
/// <param name="td"></param>
/// <param name="unwindPrice"></param>
/// <param name="unwindPriceFee"></param>
public void AuotoSwapUnwind(int tradeid, decimal unwindPrice, decimal unwindPriceFee, decimal unwindNetFee, decimal unwindNet, DateTime valueDate, decimal unwindQty,decimal closeFee)
public void AuotoSwapUnwind(int tradeid, decimal unwindPrice, decimal unwindPriceFee, decimal unwindNetFee, decimal unwindNet, DateTime valueDate, decimal unwindQty, decimal closeFee)
{
unwindPriceFee = decimal.Parse(unwindPriceFee.ToString("F10"));
var td = DbContext.trade.Find(tradeid);
@@ -850,7 +852,7 @@ namespace YLErp.Modules.SwapModule
unwindData.CloseMethod = unwindQty == unwindData.PositionQty ? (int)CloseMethodEnum. : (int)CloseMethodEnum.;
unwindData.ClosePercent = unwindData.PositionQty == 0 ? 0 : unwindPercent;
unwindData.CloseNotionalValue = position == null ? 0 : unwindQty * position.PosiGrossPrice * position.ContractSize;
unwindData.CloseNotionalValue = unwindPercent >= 1? unwindData.PosiNotionalValue: Math.Round(unwindData.CloseNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
unwindData.CloseNotionalValue = unwindPercent >= 1 ? unwindData.PosiNotionalValue : Math.Round(unwindData.CloseNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
unwindData.CloseQty = unwindQty;
if (position != null)
{
@@ -881,12 +883,13 @@ namespace YLErp.Modules.SwapModule
floatEvent.TradingFeePending = Math.Round(floatEvent.TradingFeePending, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
floatEvent.TradingFee = closeFee;
floatEvent.MarkClosePnl = (unwindPrice - position.PosiGrossPrice) * unwindQty * floatRatio * longRatio;
floatEvent.MarkClosePnl = Math.Round(floatEvent.MarkClosePnl + ((floatEvent.TradingFeePending+ closeFee) * floatRatio * -1), ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
floatEvent.MarkClosePnl = Math.Round(floatEvent.MarkClosePnl + ((floatEvent.TradingFeePending + closeFee) * floatRatio * -1) + floatEvent.DividendIn, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
floatEvent.TradingAmount = unwindPrice * floatEvent.Quantity * floatEvent.ContractSize;
floatEvent.TradingAmount = Math.Round(floatEvent.TradingAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
floatEvent.OptLog = "流水自动";
floatEvent.OptLog = "流水自动";
floatEvent.ClientId = td.ClientId;
floatEvent.SetOpt(UserInfo);
EnrichDividendIn(floatEvent, unwindQty, td);
}
unwindData.FlowEvents.Add(floatEvent);
var interestPositions = GetUnwindInterests(unwindData.ValueDate, unwindData.UnwindDate.Value, td.id, unwindPercent, (int)SwapEventTypeEnum.);
@@ -896,14 +899,46 @@ namespace YLErp.Modules.SwapModule
});
foreach (var item in interestPositions)
{
item.TdInterestAmount=Math.Round(item.TdInterestAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
item.InterestAmount=Math.Round(item.InterestAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
item.TdInterestAmount = Math.Round(item.TdInterestAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
item.InterestAmount = Math.Round(item.InterestAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
item.InterestClosePnL = Math.Round(item.InterestClosePnL, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
}
unwindData.FlowEvents.AddRange(interestPositions);
CalcCloseAmount(unwindData);
DealUnwind(unwindData, td);
}
private void EnrichDividendIn(swap_flow_event flowEvent, decimal unwindQty, trade td)
{
if (flowEvent.UnwindDate == null)
{
throw new ArgumentNullException("平仓日期缺失");
}
var date = flowEvent.EventDate;
BondPaymentService servie = new BondPaymentService(UserInfo);
var payments = servie.GetBondPayments(flowEvent.UnderlyingCode, td.StartDate.Value, date);
int shortRatio = flowEvent.PositionType == (int)PositionTypeFlag.Long ? 1 : -1;
int directionRatio = flowEvent.PayDirection == (int)SwapDirectionEnum. ? 1 : -1;
// + 付息日>上日日终且小于等于平仓日期的分红数据
var dividendIn = servie.CalcPayment(payments, unwindQty, shortRatio, directionRatio);
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(flowEvent.UnderlyingCode);
decimal tax = um.ValueAddedTax ?? 0;
dividendIn = dividendIn / (1 + tax) * (1 - tax);
flowEvent.DividendIn = Math.Round(dividendIn, 2, MidpointRounding.AwayFromZero);
}
public decimal GetUnderlyingTax(string code)
{
var data = DataCacheProvider.GetUnderlyingDataSource().GetData(code);
if (data == null)
{
return 0;
}
return data.ValueAddedTax ?? 0;
}
/// <summary>
/// 衡泰新增平仓事件
/// </summary>
@@ -1051,7 +1086,7 @@ namespace YLErp.Modules.SwapModule
return interests;
}
private void DealUnwind(UnwindData unwindData, trade td, string actionMsg = "系统操作_自动平仓")
private void DealUnwind(UnwindData unwindData, trade td, string actionMsg = "系统操作_自动平仓")
{
int clientCashId = AddClientCashInCashOut(td, Convert.ToDouble(-unwindData.SwapRealizedPnL), ClientCashInCashOut._平仓费, unwindData.ValueDate);
if (unwindData.SwapMarginAmount != 0)
@@ -1082,7 +1117,7 @@ namespace YLErp.Modules.SwapModule
td.TradeAmount -= Convert.ToDouble(unwindData.CloseQty);
td.Notional = td.TradeAmount;
td.OptDate = DateTime.Now;
td.OptId= UserId;
td.OptId = UserId;
td.OptName = UserName;
DbContext.SaveChanges();
}
@@ -1362,7 +1397,7 @@ namespace YLErp.Modules.SwapModule
decimal shortRatio = item.PositionType == (int)PositionTypeFlag.Long ? -1m : 1m;
item.TradingAmountFeeAvg = item.TradingAmountAvg + item.TradingFeePending / unwindData.CloseQty * shortRatio;
item.TradingAmountNetFeeAvg = item.TradingAmountNetAvg + item.TradingFeePending / unwindData.CloseQty * shortRatio;
item.TradingAmount= item.TradingAmountAvg * unwindData.CloseQty;
item.TradingAmount = item.TradingAmountAvg * unwindData.CloseQty;
}
}
}
@@ -1378,7 +1413,7 @@ namespace YLErp.Modules.SwapModule
if (!string.IsNullOrEmpty(position.UnderlyingCode))
{
position.PosiQuantity -= unwindData.CloseQty;
position.PosiNotionalValue = unwindData.PosiNotionalValue- unwindData.CloseNotionalValue;
position.PosiNotionalValue = unwindData.PosiNotionalValue - unwindData.CloseNotionalValue;
position.PosiTradingFee -= position.PosiTradingFee * unwindData.ClosePercent;
position.PosiTradingFeePending -= position.PosiTradingFeePending * unwindData.ClosePercent;
}
@@ -137,7 +137,7 @@ namespace YLErp.Modules.SwapModule
}
var flowEvents = new List<swap_flow_event>();
Expression<Func<swap_flow_event, bool>> eventExpression = x => x.SwapTradeId == td.id && x.DataState == (int)SwapFlowDateStateEnum.;
eventExpression = eventExpression.And(x => x.EventDate == settleDate );
eventExpression = eventExpression.And(x => x.EventDate == settleDate);
//if (settleDate == td.TradeDate)
//{
// eventExpression = eventExpression.And(x => x.EventDate == settleDate);
@@ -443,7 +443,7 @@ namespace YLErp.Modules.SwapModule
decimal allPosiNotionalValue = 0;
decimal longNotionalValue = realPositions.Where(s => s.PositionType == (int)PositionTypeFlag.Long).Sum(s => s.PosiNotionalValue);//剩余多头名义本金规模
decimal shortNotionalValue = realPositions.Where(s => s.PositionType == (int)PositionTypeFlag.Short).Sum(s => s.PosiNotionalValue);//剩余空头名义本金规模
foreach (var eventGroup in eventQuery.GroupBy(g => g.PositionId))//持仓标的腿合成持仓
{
var eventList = eventGroup.ToList();
@@ -562,7 +562,7 @@ namespace YLErp.Modules.SwapModule
unwindData.CloseNotionalValue = tdCloseNotionalValue;
swapEvent.EventData = JsonHelper.Serialize(unwindData);
DbContext.SaveChanges();
SaveEodSwap(td, tradeDate,preSettleDate);
SaveEodSwap(td, tradeDate, preSettleDate);
DbContext.SaveChanges();
trans?.Commit();
}
@@ -717,7 +717,7 @@ namespace YLErp.Modules.SwapModule
var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNotional, posiShortNational, posiNotionalValue, closePercent, (int)SwapEventTypeEnum., false, true, grossPrice, orginPv, true);
decimal InterestAmount = interests.Sum(x => x.InterestAmount);
decimal TdInterestAmount = interests.Sum(x => x.TdInterestAmount);
newEodPayPosition.ValueDate = valueDate;
newEodPayPosition.PositionId = position.id;
UpdateDbOption(newEodPayPosition);
@@ -750,7 +750,7 @@ namespace YLErp.Modules.SwapModule
newEodPayPosition.InterestFeeSum = eodPayPosition.InterestFeeSum + newEodPayPosition.TdInterestFee - newEodPayPosition.TdCloseInterestFee;
newEodPayPosition.InterestProfitSum = newEodPayPosition.InterestIncomeSum + newEodPayPosition.InterestFeeSum;
//持仓价值
newEodPayPosition.SwapPositionValue = newEodPayPosition.InterestProfitSum + newEodPayPosition.PosiProfitSum;
newEodPayPosition.SwapPositionValue = newEodPayPosition.InterestProfitSum + newEodPayPosition.PosiProfitSum;
//累计已实现
newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio;
@@ -824,7 +824,7 @@ namespace YLErp.Modules.SwapModule
preEodPositions.Add(eodPayPosition);
var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNotional, posiShortNational, closeNational, 1, eventType, false, true, grossPrice, orginPv, true);
decimal TdInterestAmount = interests.Sum(x => x.TdInterestAmount);
newEodPayPosition.ValueDate = valueDate;
newEodPayPosition.PositionId = position.id;
UpdateDbOption(newEodPayPosition);
@@ -970,7 +970,7 @@ namespace YLErp.Modules.SwapModule
}
var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNational, posiShortNational, posiNotionalValue, closePercent, 0, false, needPrice, grossPrice, orginPv);
UpdateDbOption(newEodPayPosition);
newEodPayPosition.PosiStatus = 0;
newEodPayPosition.Invalid = false;
newEodPayPosition.ValueDate = valueDate;
@@ -1137,11 +1137,21 @@ namespace YLErp.Modules.SwapModule
{
return curretEod;
}
var dealDate = curretEod.ValueDate;
var dealDate = curretEod.ValueDate;
int shortRatio = eod.PositionType == (int)PositionTypeFlag.Long ? 1 : -1;
int directionRatio = eod.PosiDirection == (int)SwapDirectionEnum. ? 1 : -1;
curretEod.PosiStatus = curretEod.PosiQuantity == 0 ? 1 : 0;
var price = UnderlyingCodePrice(eod.UnderlyingCode, dealDate, out decimal vobp);
decimal tax = um.ValueAddedTax ?? 0;
BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
if (valueDate > td.StartDate.Value && curretEod.PosiQuantity > 0)
{
decimal payment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, eod.ValueDate, valueDate, curretEod.PosiQuantity, shortRatio, directionRatio);
// 考虑增值税
curretEod.TdPosiDividend = payment / (1 + tax) * (1 - tax);
}
curretEod.PosiDividendSum = eod.PosiQuantity > 0 ? (eod.PosiDividendSum + curretEod.TdPosiDividend) : 0;
curretEod.PosiQuantity = eod.PosiQuantity;
if (curretEod.PosiStatus == 1)
{
curretEod.PosiNotionalValue = 0;
@@ -1149,12 +1159,13 @@ namespace YLErp.Modules.SwapModule
curretEod.UnderlyingPrice = price;
curretEod.UnderlyingMarketValue = curretEod.UnderlyingPrice * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio;
curretEod.PosiMtmPnL = (curretEod.UnderlyingPrice - curretEod.PosiGrossPrice) * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio * directionRatio;
curretEod.TdPosiDividend = 0;
curretEod.PosiDividendSum = eod.PosiDividendSum + curretEod.TdPosiDividend;
curretEod.PosiProfitSum = curretEod.PosiMtmPnL + curretEod.PosiDividendSum+ curretEod.PosiFeePending;
//curretEod.TdPosiDividend = 0;
//curretEod.PosiDividendSum = eod.PosiDividendSum + curretEod.TdPosiDividend;
curretEod.PosiProfitSum = curretEod.PosiMtmPnL + curretEod.PosiDividendSum + curretEod.PosiFeePending;
curretEod.TdCloseFee = 0;
curretEod.TdCloseQty = 0;
curretEod.TdCloseMtmPnl = 0;
// 需要计算平仓盈亏分红
curretEod.TdCloseDividend = 0;
curretEod.RealizedMtmPnL = eod.RealizedMtmPnL + curretEod.TdCloseMtmPnl;
curretEod.RealizedDividend = eod.RealizedDividend + curretEod.TdCloseDividend;
@@ -1197,6 +1208,7 @@ namespace YLErp.Modules.SwapModule
if (curretEod == null)
{
curretEod = eod.Clone();
curretEod.TdPosiDividend = 0;
curretEod.id = 0;
curretEod.ValueDate = valueDate;
}
@@ -1206,7 +1218,7 @@ namespace YLErp.Modules.SwapModule
{
return curretEod;
}
var dealDate = curretEod.ValueDate;
var dealDate = curretEod.ValueDate;
int shortRatio = eod.PositionType == (int)PositionTypeFlag.Long ? 1 : -1;
int directionRatio = eod.PosiDirection == (int)SwapDirectionEnum. ? 1 : -1;
var price = UnderlyingCodePrice(eod.UnderlyingCode, dealDate, out decimal vobp);
@@ -1214,13 +1226,28 @@ namespace YLErp.Modules.SwapModule
curretEod.UnderlyingPrice = price;
curretEod.UnderlyingMarketValue = curretEod.UnderlyingPrice * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio;
curretEod.PosiMtmPnL = (curretEod.UnderlyingPrice - curretEod.PosiGrossPrice) * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio * directionRatio;
curretEod.PosiDividendSum = eod.PosiDividendSum + curretEod.TdPosiDividend;
curretEod.PosiProfitSum = curretEod.PosiMtmPnL + curretEod.PosiDividendSum + curretEod.PosiFeePending;
curretEod.TdPosiDividend = 0;
if (valueDate > td.StartDate.Value && (curretEod.PosiQuantity > 0))
{
decimal tax = um.ValueAddedTax ?? 0;
BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
decimal payment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, eod.ValueDate, valueDate, curretEod.PosiQuantity, shortRatio, directionRatio);
// 考虑增值税
curretEod.TdPosiDividend = payment / (1 + tax) * (1 - tax);
}
curretEod.RealizedMtmPnL = eod.RealizedMtmPnL + curretEod.TdCloseMtmPnl;
curretEod.RealizedDividend = eod.RealizedDividend + curretEod.TdCloseDividend;
curretEod.RealizedFee = eod.RealizedFee + curretEod.TdCloseFee;
curretEod.RealizedPnl = eod.RealizedPnl + curretEod.TdCloseMtmPnl;
curretEod.PosiStatus = curretEod.PosiQuantity == 0 ? 1 : 0;
var closeQty = unwindEvents.Where(x => x.EventType == (int)SwapFlowEventTypeEnum.).ToList().Sum(s => s.Quantity);
// 当日浮动端平仓盈亏·分红 = 平仓数量/昨天剩余平仓数量 * 昨日浮动端待实现收益·分红
curretEod.TdCloseDividend = unwindEvents.Sum(e => e.DividendIn);
curretEod.RealizedDividend = curretEod.RealizedDividend + curretEod.TdCloseDividend;
// 浮动端待实现收益·分红 = 昨日 + 当日浮动端分红 - 当日浮动端平仓盈亏·分红
curretEod.PosiDividendSum = eod.PosiDividendSum + curretEod.TdPosiDividend - curretEod.TdCloseDividend;
curretEod.PosiProfitSum = curretEod.PosiMtmPnL + curretEod.PosiDividendSum + curretEod.PosiFeePending;
if (curretEod.PosiStatus == 1)
{
curretEod.PosiNotionalValue = 0;
@@ -1295,13 +1322,13 @@ namespace YLErp.Modules.SwapModule
curretEod.PosiNetFeePrice = Math.Round(curretEod.PosiNetFeePrice ?? 0, 10, MidpointRounding.AwayFromZero);
}
curretEod.PosiNotionalValue = curretEod.PosiGrossPrice * curretEod.PosiQuantity * curretEod.ContractSize;
curretEod.PosiNotionalValue= Math.Round(curretEod.PosiNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
curretEod.PosiNotionalValue = Math.Round(curretEod.PosiNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
curretEod.TdPosiDividend = unwindEvents.Sum(x => x.DividendIn) * directionRatio;
curretEod.TdCloseFee = unwindFlowEvents.Sum(x => x.TradingFee+x.TradingFeePending);
curretEod.TdCloseFee = unwindFlowEvents.Sum(x => x.TradingFee + x.TradingFeePending);
curretEod.TdCloseQty = unwindQty;
curretEod.TdCloseMtmPnl = unwindEvents.Sum(x => x.MarkClosePnl);
}
if (curretEod.PosiQuantity==0)
if (curretEod.PosiQuantity == 0)
{
curretEod.PosiFeePending = 0;
}
@@ -1322,7 +1349,7 @@ namespace YLErp.Modules.SwapModule
{
return curretEod;
}
var dealDate = settleDate;
var dealDate = settleDate;
curretEod.ValueDate = settleDate;
curretEod.PosiStartDate = position.PosiStartDate;
curretEod.PosiMatuirityDate = td.ExerciseDate.Value;
@@ -1432,11 +1459,11 @@ namespace YLErp.Modules.SwapModule
/// </summary>
/// <param name="td">互换交易</param>
/// <param name="settleDate">收盘日</param>
private void SaveEodSwap(trade td, DateTime settleDate,DateTime preSettleDate)
private void SaveEodSwap(trade td, DateTime settleDate, DateTime preSettleDate)
{
var eod_Swaps = DbContext.eod_swap.Where(x => x.SwapTradeId == td.id && x.ValueDate >= preSettleDate && x.ValueDate<= settleDate).ToList();
var eod_Swap = eod_Swaps.FirstOrDefault(x => x.ValueDate == settleDate);
var preEodSwap= eod_Swaps.FirstOrDefault(x => x.ValueDate == preSettleDate);
var eod_Swaps = DbContext.eod_swap.Where(x => x.SwapTradeId == td.id && x.ValueDate >= preSettleDate && x.ValueDate <= settleDate).ToList();
var eod_Swap = eod_Swaps.FirstOrDefault(x => x.ValueDate == settleDate);
var preEodSwap = eod_Swaps.FirstOrDefault(x => x.ValueDate == preSettleDate);
if (eod_Swap == null)
{
eod_Swap = new eod_swap();
@@ -1894,14 +1921,14 @@ namespace YLErp.Modules.SwapModule
{
eventDate = QdpCalendarHelper.GetNonHoliday(eventDate.AddDays(tradeExtend.ExtendObj.SettlementRules));
}
item.DayCount = (eventDate - item.position.PosiStartDate).Days+1;
item.DayCount = (eventDate - item.position.PosiStartDate).Days + 1;
//item.position.PosiProfitSum += item.position.VTradingFee-item.position.PosiFeePending;
SetClientEodPosition(item.position);
//item.position.PosiProfitSum += item.TradingFee;
var posiProfitSum= item.position.PosiProfitSum;
var posiProfitSum = item.position.PosiProfitSum;
//item.position.PosiProfitSum 不需要加交易费用
item.position.PosiProfitSum = item.position.PosiProfitSum - item.position.PosiFeePending-item.position.PosiDividendSum;
item.NetSettmentAmount = item.position.PosiProfitSum+ item.position.PosiDividendSum+ item.position.PosiFeePending;
item.position.PosiProfitSum = item.position.PosiProfitSum - item.position.PosiFeePending - item.position.PosiDividendSum;
item.NetSettmentAmount = item.position.PosiProfitSum + item.position.PosiDividendSum + item.position.PosiFeePending;
item.PeriodAmount = item.position.PosiDividendSum;
var margins = positions.Where(x => x.SwapTradeId == item.position.SwapTradeId);
var interests = eodPositions.Where(x => x.SwapTradeId == item.position.SwapTradeId && x.ValueDate == item.position.ValueDate);
@@ -1909,14 +1936,14 @@ namespace YLErp.Modules.SwapModule
var eodInterests = interests.Where(x => !marginTypes.Contains(x.InterestMode));
var floatRateInterest = eodInterests.Where(x => !string.IsNullOrEmpty(x.FloatRateUnderlyingCode)).FirstOrDefault();
item.position.FloatRateUnderlyingCode = floatRateInterest?.FloatRateUnderlyingCode;
item.position.FloatRate= floatRateInterest?.FloatRate??0;
item.position.FloatRate = floatRateInterest?.FloatRate ?? 0;
item.OpenMarginAmount = margins.Sum(s => s.InterestPrincipalFix * (s.InterestDirection == (int)SwapDirectionEnum. ? 1 : -1));
item.OpenMarginRate = margins.Sum(s => s.InterestRateDefault * (s.InterestDirection == (int)SwapDirectionEnum. ? 1 : -1));
item.MarginInterestAmount = eodMargins.Sum(s => s.InterestIncomeSum * (s.InterestDirection == (int)SwapDirectionEnum. ? 1 : -1));
item.InterestAmount = eodInterests.Sum(s => s.InterestIncomeSum * (s.InterestDirection == (int)SwapDirectionEnum. ? -1 : 1));
item.InterestRate = eodInterests.Sum(s => s.InterestRateDefault);
item.NetSettmentAmount += item.InterestAmount + item.MarginInterestAmount + eodMargins.Sum(s => s.InterestPrincipalFix * (s.InterestDirection == (int)SwapDirectionEnum. ? 1 : -1));
item.NetSettmentAmount = Math.Round(item.NetSettmentAmount, ConsGlobal.MoneyRound,MidpointRounding.AwayFromZero);
item.NetSettmentAmount = Math.Round(item.NetSettmentAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
if (item.position.PosiNotionalValue != 0 && item.position.PosiNetPrice != 0)
{
item.FloatRateAbs = item.position.PosiNotionalValue == 0 ? 0 : item.InterestAmount / item.position.PosiNotionalValue;
@@ -1962,7 +1989,7 @@ namespace YLErp.Modules.SwapModule
return;
}
}
/// <summary>
/// 获取客户互换持仓信息
/// </summary>
@@ -1987,7 +2014,7 @@ namespace YLErp.Modules.SwapModule
foreach (var item in eodSwaps)
{
var tradeOrigin = trades.First(x => x.id == item.SwapTradeId);
var realizedPnL = item.RealizedMtmPnL + item.RealizedInterest;
var realizedPnL = item.RealizedMtmPnL + item.RealizedInterest;
var tdExtend = tradeExtends.First(x => x.TradeId == item.SwapTradeId);
eod_position model = new eod_position()
{
+2
View File
@@ -53,6 +53,8 @@
<FunctionSub Name="每日估值报告邮件发送" Title="每日估值报告邮件发送" Type="Operate" Note="是否有每日估值报告权限" ></FunctionSub>
<FunctionSub Name="日终价格查看" Type="Operate" Title="日终价格查看"></FunctionSub>
<FunctionSub Name="日终价格修改" Type="Operate" Title="日终价格修改"></FunctionSub>
<FunctionSub Name="债券付息数据查看" Type="Operate" Title="债券付息数据查看"></FunctionSub>
<FunctionSub Name="债券付息数据修改" Type="Operate" Title="债券付息数据修改"></FunctionSub>
<FunctionSub Name="交易确认书" Title="交易确认书"></FunctionSub>
<FunctionSub Name="交易确认书生成" Title="交易确认书生成" Type="Operate" Note="是否有交易确认书生成权限" ></FunctionSub>
<FunctionSub Name="交易确认书邮件发送" Title="交易确认书邮件发送" Type="Operate" Note="是否有交易确认书邮件发送权限" ></FunctionSub>
+2
View File
@@ -605,6 +605,8 @@ namespace YLErp.Web
public bool _日终价格查看 => HasRight("结算管理-日终价格查看");
public bool _债券付息数据查看 => HasRight("结算管理-债券付息数据查看");
public bool _日终价格修改 => HasRight("结算管理-日终价格修改");
public bool _结算汇率查看 => HasRight("结算管理-结算汇率查看");
@@ -0,0 +1,94 @@
using Org.BouncyCastle.Ocsp;
using YLErp.DBModels;
using YLErp.Modules.EodModule;
namespace YLErp.Web.Controllers
{
public class BondPaymentController : BaseController
{
readonly IViewRenderService _viewRenderer;
public BondPaymentController(IViewRenderService viewRenderer)
{
_viewRenderer = viewRenderer;
}
[MyAuthorize("结算管理-债券付息数据查看")]
public ActionResult BondPaymentList()
{
return View();
}
[HttpPost]
public JsonResult BondPaymentQuery(BondPaymentReq req)
{
var sList = new BondPaymentService(CurUser).SearchList(req);
return Json(sList);
}
public ActionResult BondPaymentView(string enid)
{
var intid = DecryptLong(enid);
var r = yldb.bondPayment.Find(intid);
var um = yldb.underlying_manager.FirstOrDefault(x => x.UnderlyingCode == r.underlyingCode);
r.symbol = um?.UnderlyingName;
r.security_id = um?.UnderlyingCode;
return View(r);
}
public ActionResult BondPaymentEdit(string enid)
{
if (string.IsNullOrEmpty(enid) || enid == "0")
{
return View(new BondPayment());
}
var intid = DecryptLong(enid);
var dbmodel = yldb.bondPayment.Find(intid);
if (dbmodel == null)
{
return ShowError("找不到数据");
}
var um = yldb.underlying_manager.FirstOrDefault(x => x.UnderlyingCode == dbmodel.security_id);
dbmodel.symbol = um?.UnderlyingName;
return View(dbmodel);
}
public JsonResult BondPaymentEditJson(BondPayment req)
{
if (!string.IsNullOrEmpty(req.EncryptId))
{
req.id = DecryptLong(req.EncryptId);
}
var r = new BondPaymentService(CurUser).SaveBondPayment(req);
return JsonSuccess("更新成功", r);
}
[HttpPost]
public JsonResult DeletBondPayment(string id)
{
var intid = DecryptLong(id);
var r = yldb.bondPayment.Find(intid);
if (r == null)
{
return JsonError("找不到债券期间付息信息");
}
yldb.bondPayment.Remove(r);
yldb.SaveChanges();
return JsonSuccess("删除成功");
}
/// <summary>
/// 获取某债券期间付息
/// </summary>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <param name="underlyingCode"></param>
/// <returns></returns>
public JsonResult GetBondPayMentInterest(DateTime startDate, DateTime endDate, string underlyingCode)
{
var payments = new BondPaymentService(CurUser).GetBondPayments(underlyingCode, startDate, endDate);
decimal interest = payments.Sum(s => s.payment_interest ?? 0) * 0.01m;
return JsonSuccess("", interest);
}
}
}
@@ -0,0 +1,57 @@
@model BondPayment
@{
ViewBag.Title = "债券期间付息 | 编辑";
Layout = "~/Views/Shared/_InfoLayout.cshtml";
}
@section JS
{
<script type="text/javascript">
$(function () {
$(".datepicker").datepicker({ changeMonth: true, changeYear: true, showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true });
$(".form-group").addClass("col-md-6");
});
function checkSubmitData() {
var pass = $('#form1').valid();
return pass;
}
function saveeod_bond_price() {
if (!checkSubmitData()) return false;
var data = $("#form1").serialize();
main.post("/BondPayment/BondPaymentEditJson", data).done(function (res) {
window.location.href = "/BondPayment/BondPaymentView?enid=" + res.obj.EncryptId;
main.parentReloadData();
});
}
</script>
}
<form class="yc-panel" id="form1" method="post" onsubmit="return false;">
@Html.HiddenFor(model => model.id)
@Html.HiddenFor(model => model.jsid)
@Html.HiddenFor(model => model.coupon_rate)
@Html.HiddenFor(model => model.payment_parvalue)
@Html.HiddenFor(model => model.paying_price)
@Html.HiddenFor(model => model.channel_source)
<h4>债券期间付息修改</h4>
<div style="margin-top:20px;">
<div class='form-group col-md-6'>
<label class='formlabel'>债券名称</label>
<input class='text-box' type='text' value='@(Model.symbol)' readonly=readonly />
</div>
<div class='form-group col-md-6'>
<label class='formlabel'>债券代码</label>
<input class='text-box' type='text' value='@(Model.security_id)' readonly=readonly />
</div>
@Html.MyDateFor(model => model.payment_date)
@Html.MyTextFor(model => model.payment_interest)
</div>
<div style="padding:10px;padding-left:130px;">
<button class="btn btn-primary" type="button" onclick="saveeod_bond_price();">保存</button>
<button class="btn btn-primary" type="button" onclick="layer.closeMe();">关闭</button>
</div>
</form>
@@ -0,0 +1,43 @@
@{
var DataSources = new List<string> { "聚源", "人工" };
ViewBag.Title = "债券期间付息管理";
Layout = "~/Views/Shared/_InfoLayout.cshtml";
}
@section CSS {
<style>
.container {
width: 100%;
}
@@media (min-width: 1400px) {
.container {
max-width: 1400px;
}
}
.card-import-result .close {
display: none;
}
</style>
}
@section JS {
<script>
var curdate = "@valuedateBLL.ValueDate.ToString("yyyy-MM-dd")";
</script>
<script src="~/Scripts/app/bondPayment/bondpaymentList.js?v=@(HtmlUtil.JsVersion)"></script>
}
<div style="display:none;width:350px;" id="errormessage"></div>
<div class="searchdiv">
@Html.SearchDateRange("ValueDate", "支付日期")
@Html.MyAceDropdownInput2("DataSource", "数据来源", GlobalData.GetSelectItems(DataSources))
@Html.MyAceDropdownInput2("MarketName", "市场", MarketController.GetAllmarketName())
@Html.ShortInput("UnderlyingCode", "标的代码")
@MyControls.SearchBtn()
@MyControls.Btn("导出", "downloadExcel()")
</div>
@Html.Raw(JqGridSimple.OutTable())
@@ -0,0 +1,46 @@
@model BondPayment
@{
ViewBag.Title = "债券期间付息|查看";
Layout = "~/Views/Shared/_InfoLayout.cshtml";
}
@section JS {
<script type="text/javascript">
function deletBondPayment(id) {
if (confirm("确定删除吗?")) {
$.ajax({
type: "Post",
url: "/BondPayment/DeletBondPayment",
data: { id: id, d: new Date() },
success: function (data) {
alert(data.msg);
if (data.success == true) {
window.parent.location = window.parent.location;
window.close();
}
},
error: function (msg) {
alert("error:" + msg);
}
});
}
}
</script>
}
<div class="toolbarDiv">
@if (CurUser.结算管理_日终价格修改)
{
@MyControls.Btn("修改", "window.location.href=('/BondPayment/BondPaymentEdit/?enid=" + Model.EncryptId + "');")
}
@MyControls.Btn("关闭", "layer.closeMe();")
</div>
<div class="yc-panel">
<table class="table table-bordered">
<tr>@Html.MyDisplayFor(m => m.payment_date, Utilities.ShowValidDatetime(Model.payment_date))</tr>
<tr>@Html.MyDisplayFor(m => m.security_id)</tr>
<tr>@Html.MyDisplayFor(m => m.symbol)</tr>
<tr>@Html.MyDisplayFor(m => m.payment_interest)</tr>
<tr>@Html.MyDisplayFor(m => m.update_time, Utilities.ShowValidDatetime(Model.update_time))</tr>
</table>
</div>
@@ -122,6 +122,11 @@
{
<a class="btn btn-link" href="/eodPrice/eodPriceList" target="_blank">日终价格管理</a>
}
@if (CurUser.结算管理_债券付息数据查看)
{
<a class="btn btn-link" href="/BondPayment/BondPaymentList" target="_blank">债券付息数据</a>
}
@if (CurUser.结算管理_结算汇率查看)
{
<a class="btn btn-link" href="/eod_currency_rate/eod_currency_rateList" target="_blank">结算汇率设置</a>
@@ -308,6 +308,10 @@
<label class='formlabel'>描述</label>
<input id='Desc' class='text-box' type='text' value='@(underlying.UnderlyingDesc)' name='Desc' />
</div>
<div class='form-group col-6'>
<label class='formlabel'>增值税率</label>
<input id='ValueAddedTax' class='text-box' type='number' value='@(underlying.ValueAddedTax)' name='ValueAddedTax' />
</div>
</div>
<div class="Stock" style="padding-left:130px;">
@@ -170,6 +170,11 @@
@Html.MyDisplayFor(m => m.Price)
</tr>
}
<tr>
<th class="tdRight">增值税率</th>
<td>@(Model.ValueAddedTax.OtcFormatPercent())</td>
</tr>
</tbody>
</table>
</div>
+7 -1
View File
@@ -208,9 +208,15 @@
</ItemGroup>
<ItemGroup>
<None Include="Views\EodFile\Index.cshtml" />
<None Include="Views\BondPayment\BondPaymentEdit.cshtml" />
<None Include="Views\BondPayment\BondPaymentList.cshtml" />
<None Include="Views\BondPayment\BondPaymentView.cshtml" />
<None Include="Views\EodFile\Index.cshtml" />
<None Include="Views\EtradingRule\EtradingRuleEdit.cshtml" />
<None Include="Views\EtradingRule\Index.cshtml" />
<None Include="wwwroot\Scripts\app\bondPayment\bondpaymentList.js" />
</ItemGroup>
<ItemGroup>
@@ -0,0 +1,89 @@
$(function () {
$("#DateToValueDate").val(curdate)
$("#DateFromValueDate").val(curdate)
var PostData = { ValueDateEnd: curdate, ValueDateStart: curdate };
$(".datepicker").datepicker({ changeMonth: true, changeYear: true, showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true });
var grid = jQuery('#listGrid').jqGrid({
url: '/BondPayment/BondPaymentQuery',
datatype: 'json',
height: 'auto',
width: '100%',
autowidth: false,
shrinkToFit: false,
viewrecords: true,
jsonReader: { repeatitems: false },
cmTemplate: { align: 'center', width: 120 },
mtype: 'POST',
postData: PostData,
colModel: colModelGrid,
pager: jQuery('#pagerGrid'),
pagerpos: 'left',
rowNum: 20,
rowList: [20, 30, 50, 200, 10000],
footerrow: false
});
function keyEnter(event) {
try {
var e = event ? event : (window.event ? window.event : null);
(e.keyCode == 13) && SearchClick(true);
} catch (e) { }
}
document.onkeydown = keyEnter;
});
var colModelGrid = [{
name: '', label: '操作', index: '', width: 120, formatter: showToolName
}, {
name: 'payment_date', label: '支付日期', index: 'payment_date', width: 120, formatter: 'date'
}, {
name: 'MarketName', label: '市场', index: 'MarketName', width: 200
}, {
name: 'security_id', label: '债券代码', index: 'security_id', width: 150
}, {
name: 'symbol', label: '债券名称', index: 'symbol', width: 200
}, {
name: 'payment_interest', label: '支付利息', index: 'payment_interest', width: 100
},
{
name: 'update_time', label: '更新时间', index: 'update_time', width: 160, formatter: 'datetime'
}, {
name: 'channel_source', label: '数据来源', index: 'channel_source', sortable: false, width: 120
}];
function showToolName(cellValue, options, rowObject) {
return "<input type=\"button\" class=\"wentiEdit\" title='查看债券期间付息' onclick=\"startView('{0}')\" value=\"{1}\" />".template(rowObject.EncryptId, "查看");
}
function startView(id) {
var srcurl = "/BondPayment/BondPaymentView/?enid=" + id;
main.open("查看债券期间付息", srcurl, { area: ['800px', '600px'] });
}
function SearchClick(isSearchclick) {
var listGrid = $('#listGrid');
listGrid.appendPostData({ UnderlyingCode: $("#UnderlyingCode").val() });
listGrid.appendPostData({ MarketName: $("#MarketName").val() });
listGrid.appendPostData({ ValueDateStart: $("#DateFromValueDate").val() });
listGrid.appendPostData({ ValueDateEnd: $("#DateToValueDate").val() });
listGrid.appendPostData({ DataSource: $("#DataSource").val() });
if (isSearchclick) {
//点击搜索时默认第一页
listGrid.jqGrid('setGridParam', { page: 1 });
}
listGrid.trigger('reloadGrid');
}
function reloadData() {
SearchClick(false);
}
function downloadExcel() {
var dateTemp = new Date().Format("yyyyMMdd");
var fileName = "债券期间付息" + dateTemp;
var formatters = _.map(['市场', '债券代码', '债券名称', '支付利息']
, x => new Object({ colName: x, formatter: "text" }));
formatters.push(_.map(['支付日期', '更新时间']
, x => new Object({ colName: x, formatter: "datetime" })));
main.toExcel("listGrid", fileName, "xls", null, "操作", formatters)
}
@@ -51,6 +51,7 @@ const vue = new Vue({
});
this.ratio = this.floatPosition.PayDirection == 1 ? -1 : 1;
this.shortRatio = this.floatPosition.PositionType == 1 ? 1 : -1;
this.TradeStartDate = model.TradeStartDate;
},
IsBond(instType) {
return tradeHelper.IsBond(instType);
@@ -262,6 +263,20 @@ const vue = new Vue({
});
thisObj.calcCloseAmount();
thisObj.dataFormat();
thisObj.getDivindIn();
});
},
getDivindIn() {
var thisObj = this;
let ratio = this.floatPosition.PositionType == 1 ? 1 : -1;
let floatRatio = this.floatPosition.PayDirection == 1 ? 1 : -1;
var postData = { startDate: thisObj.TradeStartDate, endDate: thisObj.deal.UnwindDate, underlyingCode: thisObj.floatPosition.UnderlyingCode }
main.post("/BondPayment/GetBondPayMentInterest", postData, { async: false }).done(function (resp) {
thisObj.floatPosition.DividendIn = parseFloat(thisObj.deal.CloseQty) * resp.obj * ratio * floatRatio;
var posiQty = parseFloat(thisObj.floatPosition.Quantity) - parseFloat(thisObj.deal.CloseQty);
thisObj.floatPosition.DividendPending = posiQty * resp.obj * ratio * floatRatio;
thisObj.calcFloatClosePnl();
thisObj.dataFormat();
});
},
closeTrade() {//平仓