Files
zszq-trs/YLErpDAL/Modules/SwapModule/SwapPushService.cs
T
2024-05-09 14:06:26 +08:00

1242 lines
61 KiB
C#

using BaseOUDAL;
using Confluent.Kafka;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.VariantTypes;
using Microsoft.Office.Interop.Excel;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using Qdp.Pricing.Library.Base.Utilities;
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using YLErp.Abstract;
using YLErp.DBModels;
using YLErp.DBModels.Enums;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Model.HengTaiModel;
using YLErp.Models;
using YLErp.Modules.AppModule;
using YLErp.Modules.ClientModule;
using YLErp.Modules.FinancialModule;
using YLErp.QdpModule;
using static YLErp.DBModels.ConsTrade;
namespace YLErp.Modules.SwapModule
{
public class SwapPushService : YLBaseService
{
// 互换交易kafkaTopic
private string reqInterestRateSwapInsert = string.Empty;
// 资产kafkaTopic
private string reqAssetSwapInsert = string.Empty;
// 预付金kafkaTopic
private string reqMarginInsert = string.Empty;
//平仓kafkaTopic
private string reqAcctSwapTerminate = string.Empty;
//交易对手方kafkaTopic
private string reqCounterPartyInfoInsert = string.Empty;
//交易对手方资金账户
private string reqCounterPartyCashAccoutInsert = string.Empty;
List<int> liveLogStates = new List<int>() { (int)SwapPushDataStateEnum.待推送 };
private IKafkaProduce kafkaProduceHelper;
public SwapPushService(OptUserInfo optUser) : base(optUser)
{
reqInterestRateSwapInsert = Environment.GetEnvironmentVariable("KafkaConfig_ReqInterestRateSwapInsertTopic");
reqAssetSwapInsert = Environment.GetEnvironmentVariable("KafkaConfig_ReqAssetSwapInsertTopic");
reqMarginInsert = Environment.GetEnvironmentVariable("KafkaConfig_ReqMarginInsertTopic");
reqAcctSwapTerminate = Environment.GetEnvironmentVariable("KafkaConfig_ReqAcctSwapTerminateTopic");
reqCounterPartyInfoInsert = Environment.GetEnvironmentVariable("KafkaConfig_ReqCounterPartyInfoInsertTopic");
reqCounterPartyCashAccoutInsert = Environment.GetEnvironmentVariable("KafkaConfig_ReqCounterPartyCashAccoutInsertTopic");
}
public void SetKafKaProduce(IKafkaProduce kafkaProduce)
{
kafkaProduceHelper = kafkaProduce;
}
/// <summary>
/// 推送交易
/// </summary>
public void PushTrade()
{
PushData(kafkaProduceHelper, reqInterestRateSwapInsert, SwapPushDataEnum.收益互换交易新增, "2042", PrepareTradeReq);
}
/// <summary>
/// 推送交易
/// </summary>
public void PushTradeUpdate()
{
PushData(kafkaProduceHelper, reqInterestRateSwapInsert, SwapPushDataEnum.收益互换交易修改, "3005", PrepareTradeReq);
PushPosition(kafkaProduceHelper, SwapPushDataEnum.互换资产交易修改, "3005");
PushMargin(kafkaProduceHelper, SwapPushDataEnum.预付金交易修改, "3005");
}
public void RePushLog(PushLog pushLog)
{
List<PushLog> pushLogs = new List<PushLog>() { pushLog };
var pushDataType = pushLog.data_type;
if (pushDataType == (int)SwapPushDataEnum.收益互换交易新增)
{
PushData(kafkaProduceHelper, reqInterestRateSwapInsert, pushLogs, "2042", PrepareTradeReq);
}
else if (pushDataType == (int)SwapPushDataEnum.收益互换交易修改)
{
PushData(kafkaProduceHelper, reqInterestRateSwapInsert, pushLogs, "3005", PrepareTradeReq);
}
else if (pushDataType == (int)SwapPushDataEnum.互换资产交易新增)
{
PushPositionData(kafkaProduceHelper, pushLogs, "2041");
}
else if (pushDataType == (int)SwapPushDataEnum.互换资产交易修改)
{
PushPositionData(kafkaProduceHelper, pushLogs, "3005");
}
else if (pushDataType == (int)SwapPushDataEnum.互换资产平仓)
{
PushUnwindPositionData(kafkaProduceHelper, pushLogs, true);
}
else if (pushDataType == (int)SwapPushDataEnum.预付金交易新增)
{
PushMarginData(kafkaProduceHelper, pushLogs, "2043");
}
else if (pushDataType == (int)SwapPushDataEnum.预付金交易修改)
{
PushMarginData(kafkaProduceHelper, pushLogs, "3005");
}
else if (pushDataType == (int)SwapPushDataEnum.互换预付金平仓)
{
PushUnwindMarginData(kafkaProduceHelper, pushLogs, true);
}
else if (pushDataType == (int)SwapPushDataEnum.客户创建 || pushDataType == (int)SwapPushDataEnum.客户修改)
{
PushClientData(kafkaProduceHelper, pushLogs);
}
else if (pushDataType == (int)SwapPushDataEnum.客户资金账户新增 || pushDataType == (int)SwapPushDataEnum.客户资金账户修改 || pushDataType == (int)SwapPushDataEnum.客户资金账户删除)
{
PushClientBannkData(kafkaProduceHelper, pushLogs);
}
else if (pushDataType == (int)SwapPushDataEnum.合约终止)
{
PushUnwindData(kafkaProduceHelper, pushLogs, "T");
}
else if (pushDataType == (int)SwapPushDataEnum.合约撤单)
{
PushRepealUnwind(kafkaProduceHelper, pushLogs);
}
//else if (pushDataType == (int)SwapPushDataEnum.客户入金新增)
//{
// PushRepealCash(kafkaProduceHelper, pushLogs);
//}
//else if (pushDataType == (int)SwapPushDataEnum.客户出金新增)
//{
// PushRepealCash(kafkaProduceHelper, pushLogs);
//}
}
/// <summary>
/// 交易对手方推送
/// </summary>
/// <param name="kafkaProduceHelper"></param>
public void PushClient()
{
var pushService = new PushLogService(UserInfo);
List<int> dataTypes = new List<int>() { (int)SwapPushDataEnum.客户创建, (int)SwapPushDataEnum.客户修改 };
var pushLogs = pushService.GetPushLogs(dataTypes, liveLogStates);
PushClientData(kafkaProduceHelper, pushLogs);
}
/// <summary>
/// 交易对手方银行卡信息推送
/// </summary>
public void PushClientBank()
{
var pushService = new PushLogService(UserInfo);
List<int> dataTypes = new List<int>() { (int)SwapPushDataEnum.客户资金账户修改, (int)SwapPushDataEnum.客户资金账户删除 };
var pushLogs = pushService.GetPushLogs(dataTypes, liveLogStates);
PushClientBannkData(kafkaProduceHelper, pushLogs);
}
/// <summary>
/// 推送客户资金记录
/// </summary>
public void PushClientCash()
{
//var pushService = new PushLogService(UserInfo);
//List<int> dataTypes = new List<int>() { (int)SwapPushDataEnum.客户入金新增, (int)SwapPushDataEnum.客户出金新增 };
//var pushLogs = pushService.GetPushLogs(dataTypes, liveLogStates);
//PushRepealCash(kafkaProduceHelper, pushLogs);
}
/// <summary>
/// 消费推送结果
/// </summary>
public void ConsumerTradeResp(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<ResponseBase>(msg);
var logid = Convert.ToInt64(result.HEADER.SERIAL_NO);
int resultState = (int)SwapPushDataStateEnum.推送失败;
if (result.HEADER.ERRCODE == "0" && result.RECORD.RESULT == "0")
{
resultState = (int)SwapPushDataStateEnum.推送成功;
}
var pushService = new PushLogService(UserInfo);
var pushLog = pushService.UpdateLogResp(logid, msg, resultState);
if (resultState == (int)SwapPushDataStateEnum.推送成功 && pushLog != null)
{
if (pushLog.data_type == (int)SwapPushDataEnum.收益互换交易新增)
{
var posiNumbers = DbContext.swap_position.Where(x => x.SwapTradeId == pushLog.data_id && x.IsInitial && !x.Invalid).Select(s => s.PosiNumber).ToList();
Expression<Func<PushLog, bool>> expression = n => n.data_type == (int)SwapPushDataEnum.互换资产交易新增 && posiNumbers.Contains(n.data_number);
Expression<Func<PushLog, bool>> expression2 = n => n.data_type == (int)SwapPushDataEnum.预付金交易新增 && posiNumbers.Contains(n.data_number);
var posiPushLogs = pushService.GetPushLogs(expression);
var marginPushLogs = pushService.GetPushLogs(expression2);
PushPositionData(kafkaProduceHelper, posiPushLogs, "2041");
PushMarginData(kafkaProduceHelper, marginPushLogs, "2043");
}
}
}
});
}
/// <summary>
/// 消费交易对手方推送结果
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerClientResp(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<ClientPushResp>(msg);
var logid = Convert.ToInt64(result.HEADER.SERIAL_NO);
int resultState = (int)SwapPushDataStateEnum.推送失败;
string irPartyId = string.Empty;
if (result.HEADER.ERRCODE == "0")
{
resultState = (int)SwapPushDataStateEnum.推送成功;
if (result.RECORD.PARSEINFO.Count > 0)
{
if (result.RECORD.PARSEINFO.Any(a => a.RESULT != "1"))
{
resultState = (int)SwapPushDataStateEnum.推送失败;
}
else
{
irPartyId = result.RECORD.PARSEINFO[0].XIR_PARTY_ID;
}
}
}
var pushService = new PushLogService(UserInfo);
var pushLog = pushService.UpdateLogResp(logid, msg, resultState);
if (resultState == (int)SwapPushDataStateEnum.推送成功)
{
new ClientSaveService(UserInfo).UpdateClientOutNumber(pushLog.data_number, irPartyId);
if (pushLog.data_type == (int)SwapPushDataEnum.客户创建)
{
Expression<Func<PushLog, bool>> expression = n => n.data_type == (int)SwapPushDataEnum.客户资金账户新增 && n.data_number == pushLog.data_number;
var pushLogs = pushService.GetPushLogs(expression);
PushClientData(kafkaProduceHelper, pushLogs);
}
}
}
});
}
/// <summary>
/// 消费交易对手方推送结果
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerClientBankResp(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<ClientPushResp>(msg);
var logid = Convert.ToInt64(result.HEADER.SERIAL_NO);
int resultState = (int)SwapPushDataStateEnum.推送失败;
if (result.HEADER.ERRCODE == "0")
{
resultState = (int)SwapPushDataStateEnum.推送成功;
if (result.RECORD.PARSEINFO.Count > 0)
{
if (result.RECORD.PARSEINFO.Any(a => a.RESULT != "1"))
{
resultState = (int)SwapPushDataStateEnum.推送失败;
}
}
}
new PushLogService(UserInfo).UpdateLogResp(logid, msg, resultState);
}
});
}
/// <summary>
/// 推送平仓
/// </summary>
/// <param name="kafkaProduceHelper"></param>
public void PushUnwind()
{
PushUnwindPosi(kafkaProduceHelper, SwapPushDataEnum.互换资产平仓, PushUnwindPositionData);
PushUnwindPosi(kafkaProduceHelper, SwapPushDataEnum.互换预付金平仓, PushUnwindMarginData);
PushUnwindData(kafkaProduceHelper, SwapPushDataEnum.合约终止, "T");
}
/// <summary>
/// 平仓或回退
/// </summary>
/// <param name="kafkaProduceHelper"></param>
/// <param name="swapPushDataEnum"></param>
/// <param name="operate"></param>
private void PushUnwindData(IKafkaProduce kafkaProduceHelper, SwapPushDataEnum swapPushDataEnum, string operate)
{
var pushService = new PushLogService(UserInfo);
List<int> dataTypes = new List<int>() { (int)swapPushDataEnum };
var pushLogs = pushService.GetPushLogs(dataTypes, liveLogStates);
PushUnwindData(kafkaProduceHelper, pushLogs, operate);
}
/// <summary>
/// 合约平仓推送
/// </summary>
/// <param name="kafkaProduceHelper"></param>
/// <param name="pushLogs"></param>
/// <param name="operate"></param>
private void PushUnwindData(IKafkaProduce kafkaProduceHelper, List<PushLog> pushLogs, string operate)
{
var pushService = new PushLogService(UserInfo);
var delPushIds = new List<long>();
foreach (var pushLog in pushLogs)
{
var swapEvent = DbContext.swap_event.FirstOrDefault(x => x.id == pushLog.data_id);
if (swapEvent == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
var trade = DbContext.trade.FirstOrDefault(x => x.id == swapEvent.SwapTradeId);
if (trade == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
if (trade.ValidState == ConsGlobal.InValid)
{
var number = trade.TradeNumber.Replace("XX","");
var tradePushs = pushService.GetPushLogs(x => x.data_number.StartsWith(number));
if (!tradePushs.Any(x => x.data_state == (int)SwapPushDataStateEnum.推送成功))//已经删除的交易没有推送成功的情况下全部删除记录
{
delPushIds.AddRange(tradePushs.Select(s => s.id));
pushService.DeleteLogs(delPushIds);
continue;
}
}
var req = new RequestBase<SwapUnwindReq>();
swapEvent.unwindData = JsonConvert.DeserializeObject<UnwindData>(swapEvent.EventData);
swapEvent.unwindData.FlowEvents = DbContext.swap_flow_event.Where(x => x.EventId == swapEvent.id).ToList();
req.RECORD = PrepareUnwindData(swapEvent);
if (req.RECORD == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
req.EXT_NO = trade.TradeNumber.Replace("XX", "");
req.SERIAL_NO = pushLog.id.ToString();
req.OPERATE = operate;
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(reqAcctSwapTerminate, data_req);
}
}
/// <summary>
/// 资产平仓推送
/// </summary>
/// <param name="kafkaProduceHelper"></param>
/// <param name="swapPushDataEnum"></param>
private void PushUnwindPosi(IKafkaProduce kafkaProduceHelper, SwapPushDataEnum swapPushDataEnum, Action<IKafkaProduce, List<PushLog>, bool> actionMethod)
{
var pushService = new PushLogService(UserInfo);
List<int> dataTypes = new List<int>() { (int)swapPushDataEnum };
var pushLogs = pushService.GetPushLogs(dataTypes, liveLogStates);
actionMethod(kafkaProduceHelper, pushLogs, true);
}
/// <summary>
/// 资产平仓推送
/// </summary>
/// <param name="kafkaProduceHelper"></param>
/// <param name="pushLogs"></param>
private void PushUnwindPositionData(IKafkaProduce kafkaProduceHelper, List<PushLog> pushLogs, bool unwind)
{
var pushService = new PushLogService(UserInfo);
var delPushIds = new List<long>();
foreach (var pushLog in pushLogs)
{
if (delPushIds.Contains(pushLog.id))
{
continue;
}
var flowEvent = DbContext.swap_flow_event.FirstOrDefault(x => x.id == pushLog.data_id);
if (flowEvent == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
var trade = DbContext.trade.FirstOrDefault(x => x.id == flowEvent.SwapTradeId);
if (trade == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
if (trade.ValidState == ConsGlobal.InValid)
{
var number = trade.TradeNumber.Replace("XX", "");
var tradePushs = pushService.GetPushLogs(x => x.data_number.StartsWith(number));
if (!tradePushs.Any(x => x.data_state == (int)SwapPushDataStateEnum.推送成功))//已经删除的交易没有推送成功的情况下全部删除记录
{
delPushIds.AddRange(tradePushs.Select(s => s.id));
pushService.DeleteLogs(delPushIds);
continue;
}
}
var client = DataCacheProvider.GetClientDataSource().GetData(trade.ClientId);
var req = new RequestBase<SwapPosiReq>();
req.RECORD = PrepareTradePosiUnwindReq(trade, flowEvent, pushLog.data_number);
if (req.RECORD == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
req.EXT_NO = pushLog.data_id.ToString();
req.SERIAL_NO = pushLog.id.ToString();
req.ACTION = "2041";
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(reqAssetSwapInsert, data_req);
}
}
/// <summary>
/// 预付金平仓推送
/// </summary>
/// <param name="kafkaProduceHelper"></param>
/// <param name="pushLogs"></param>
private void PushUnwindMarginData(IKafkaProduce kafkaProduceHelper, List<PushLog> pushLogs, bool unwind)
{
var pushService = new PushLogService(UserInfo);
foreach (var pushLog in pushLogs)
{
var flowEvent = DbContext.swap_flow_event.FirstOrDefault(x => x.id == pushLog.data_id);
if (flowEvent == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
var trade = DbContext.trade.FirstOrDefault(x => x.id == flowEvent.SwapTradeId);
var client = DataCacheProvider.GetClientDataSource().GetData(trade.ClientId);
var req = new RequestBase<SwapMarginReq>();
req.RECORD = PrepareTradeMarginUnwindReq(client, trade, flowEvent, unwind, pushLog.data_number);
if (req.RECORD == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
req.EXT_NO = pushLog.data_id.ToString();
req.SERIAL_NO = pushLog.id.ToString();
req.ACTION = "2043";
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(reqMarginInsert, data_req);
}
}
/// <summary>
/// 推送回退
/// </summary>
/// <param name="kafkaProduceHelper"></param>
public void PushRepealUnwind()
{
var pushService = new PushLogService(UserInfo);
List<int> dataTypes = new List<int>() { (int)SwapPushDataEnum.合约撤单 };
var pushLogs = pushService.GetPushLogs(dataTypes, liveLogStates);
PushRepealUnwind(kafkaProduceHelper, pushLogs);
}
private void PushRepealUnwind(IKafkaProduce kafkaProduceHelper, List<PushLog> pushLogs)
{
var pushService = new PushLogService(UserInfo);
foreach (var pushLog in pushLogs)
{
var trade = new trade();
if (pushLog.data_number.Contains("-"))
{
var position = DbContext.swap_position.FirstOrDefault(x => x.id == pushLog.data_id);
if (position == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
var hasInterest = DbContext.swap_position.Any(x => x.SwapTradeId == position.SwapTradeId && x.IsInitial && !x.Invalid && ConsTrade.InterestNotionalModels.Contains(x.InterestMode));
PushRepealUnwindData(kafkaProduceHelper, position, hasInterest, pushLog, position.PosiNumber, pushService);
}
else
{
trade = DbContext.trade.FirstOrDefault(x => x.id == pushLog.data_id);
if (trade == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
var positions = DbContext.swap_position.Where(x => x.SwapTradeId == trade.id && x.IsInitial).ToList();
var tradeNumber = trade.TradeNumber.Replace("XX", "CW");
var hasInterest = positions.Any(x => ConsTrade.InterestNotionalModels.Contains(x.InterestMode));
var posi = positions.Where(x => x.PosiDirection > 0).FirstOrDefault();
if (posi == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
PushRepealUnwindData(kafkaProduceHelper, posi, hasInterest, pushLog, tradeNumber, pushService);
}
}
}
private void PushRepealCash(IKafkaProduce kafkaProduceHelper, List<PushLog> pushLogs)
{
var consumerService = new SwapConsumerService(UserInfo);
consumerService.SetKafKaProduce(kafkaProduceHelper);
foreach (var pushLog in pushLogs)
{
//consumerService.PushCashToHT((int)pushLog.data_id,pushLog);
}
}
private void PushRepealUnwindData(IKafkaProduce kafkaProduceHelper, swap_position posi, bool hasInterest, PushLog pushLog, string tradeNumber, PushLogService pushService)
{
var req = new RequestBase<SwapUnwindReq>();
req.RECORD = PrepareRepealUnwindData(posi.id.ToString(), posi, hasInterest);
req.EXT_NO = tradeNumber;
req.SERIAL_NO = pushLog.id.ToString();
req.OPERATE = "D";
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(reqAcctSwapTerminate, data_req);
}
/// <summary>
/// 构建数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="kafkaProduceHelper"></param>
/// <param name="topic"></param>
/// <param name="swapPushDataEnum"></param>
/// <param name="funcMethod"></param>
private void PushData<T>(IKafkaProduce kafkaProduceHelper, string topic, SwapPushDataEnum swapPushDataEnum, string action, Func<SwapTradePushModel, T> funcMethod)
{
var pushService = new PushLogService(UserInfo);
List<int> dataTypes = new List<int>() { (int)swapPushDataEnum };
var pushLogs = pushService.GetPushLogs(dataTypes, liveLogStates);
var delPushIds = new List<long>();
foreach (var pushLog in pushLogs)
{
if (delPushIds.Contains(pushLog.id))
{
continue;
}
trade trade = DbContext.trade.FirstOrDefault(x => x.id == pushLog.data_id);
if (trade == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
if (trade.ValidState == ConsGlobal.InValid)
{
var number = trade.TradeNumber.Replace("XX", "");
var tradePushs = pushService.GetPushLogs(x => x.data_number.StartsWith(number));
if (!tradePushs.Any(x => x.data_state == (int)SwapPushDataStateEnum.推送成功))//已经删除的交易没有推送成功的情况下全部删除记录
{
delPushIds.AddRange(tradePushs.Select(s => s.id));
pushService.DeleteLogs(delPushIds);
continue;
}
}
var tradeExtend = DbContext.trade_extend.FirstOrDefault(x => x.TradeId == trade.id);
List<swap_position> positions = DbContext.swap_position.Where(x => x.SwapTradeId == trade.id && x.IsInitial && !x.Invalid).ToList();
var client = DataCacheProvider.GetClientDataSource().GetData(trade.ClientId);
SwapTradePushModel model = new SwapTradePushModel() { trade = trade, positions = positions, tradeExtend = tradeExtend, Client = client };
var req = new RequestBase<T>();
req.RECORD = funcMethod(model);
if (req.RECORD == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
req.EXT_NO = model.extNo;
req.SERIAL_NO = pushLog.id.ToString();
req.ACTION = action;
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(topic, data_req);
}
}
private void PushData<T>(IKafkaProduce kafkaProduceHelper, string topic, List<PushLog> pushLogs, string action, Func<SwapTradePushModel, T> funcMethod)
{
var pushService = new PushLogService(UserInfo);
foreach (var pushLog in pushLogs)
{
trade trade = DbContext.trade.FirstOrDefault(x => x.id == pushLog.data_id);
var tradeExtend = DbContext.trade_extend.FirstOrDefault(x => x.TradeId == trade.id);
List<swap_position> positions = positions = DbContext.swap_position.Where(x => x.SwapTradeId == trade.id && x.IsInitial && !x.Invalid).ToList();
var client = DataCacheProvider.GetClientDataSource().GetData(trade.ClientId);
SwapTradePushModel model = new SwapTradePushModel() { trade = trade, positions = positions, tradeExtend = tradeExtend, Client = client };
var req = new RequestBase<T>();
req.RECORD = funcMethod(model);
if (req.RECORD == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
req.EXT_NO = model.extNo;
req.SERIAL_NO = pushLog.id.ToString();
req.ACTION = action;
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(topic, data_req);
}
}
/// <summary>
/// 预付金推送
/// </summary>
/// <param name="kafkaProduceHelper"></param>
/// <param name="swapPushDataEnum"></param>
/// <param name="action"></param>
private void PushMargin(IKafkaProduce kafkaProduceHelper, SwapPushDataEnum swapPushDataEnum, string action)
{
var pushService = new PushLogService(UserInfo);
List<int> dataTypes = new List<int>() { (int)swapPushDataEnum };
var pushLogs = pushService.GetPushLogs(dataTypes, liveLogStates);
PushMarginData(kafkaProduceHelper, pushLogs, action);
}
/// <summary>
/// 预付金推送
/// </summary>
/// <param name="kafkaProduceHelper"></param>
/// <param name="pushLogs"></param>
/// <param name="action"></param>
private void PushMarginData(IKafkaProduce kafkaProduceHelper, List<PushLog> pushLogs, string action)
{
var pushService = new PushLogService(UserInfo);
foreach (var pushLog in pushLogs)
{
var position = DbContext.swap_position.FirstOrDefault(x => x.id == pushLog.data_id);
if (position == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
var trade = DbContext.trade.FirstOrDefault(x => x.id == position.SwapTradeId);
if (trade == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
var positions = new List<swap_position>() { position };
var client = DataCacheProvider.GetClientDataSource().GetData(trade.ClientId);
SwapTradePushModel model = new SwapTradePushModel() { trade = trade, positions = positions, Client = client };
var req = new RequestBase<SwapMarginReq>();
req.RECORD = PrepareTradeMarginReq(model);
if (req.RECORD == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
req.EXT_NO = position.PosiNumber;
req.SERIAL_NO = pushLog.id.ToString();
req.ACTION = action;
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(reqMarginInsert, data_req);
}
}
/// <summary>
/// 资产推送
/// </summary>
/// <param name="kafkaProduceHelper"></param>
/// <param name="swapPushDataEnum"></param>
/// <param name="action"></param>
private void PushPosition(IKafkaProduce kafkaProduceHelper, SwapPushDataEnum swapPushDataEnum, string action)
{
var pushService = new PushLogService(UserInfo);
List<int> dataTypes = new List<int>() { (int)swapPushDataEnum };
var pushLogs = pushService.GetPushLogs(dataTypes, liveLogStates);
PushPositionData(kafkaProduceHelper, pushLogs, action);
}
/// <summary>
/// 资产推送推送
/// </summary>
/// <param name="kafkaProduceHelper"></param>
/// <param name="pushLogs"></param>
/// <param name="action"></param>
private void PushPositionData(IKafkaProduce kafkaProduceHelper, List<PushLog> pushLogs, string action)
{
var pushService = new PushLogService(UserInfo);
foreach (var pushLog in pushLogs)
{
var position = DbContext.swap_position.FirstOrDefault(x => x.id == pushLog.data_id);
if (position == null)
{
var openQuery = from se in DbContext.swap_flow_event
join p in DbContext.swap_position on se.PositionId equals p.PositionId
where se.id == pushLog.data_id
select new { position = p, flowEvent = se };
var open = openQuery.FirstOrDefault();
if (open == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
position = open.position;
position.PosiQuantity = open.flowEvent.PositionQty ?? 0;
position.PosiNotionalValue = position.PosiQuantity * position.ContractSize;
}
var trade = DbContext.trade.FirstOrDefault(x => x.id == position.SwapTradeId);
if (trade == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
bool longShort = trade.StructureType == "多空组合";
var positions = new List<swap_position>() { position };
var client = DataCacheProvider.GetClientDataSource().GetData(trade.ClientId);
SwapTradePushModel model = new SwapTradePushModel() { trade = trade, positions = positions, Client = client };
var req = new RequestBase<SwapPosiReq>();
req.RECORD = PrepareTradePosiReq(model, longShort);
if (req.RECORD == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
req.EXT_NO = model.extNo;
req.SERIAL_NO = pushLog.id.ToString();
req.ACTION = action;
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(reqAssetSwapInsert, data_req);
}
}
/// <summary>
/// 平仓数据构造
/// </summary>
/// <param name="swapEvent"></param>
/// <returns></returns>
/// <summary>
/// 根据平仓详细事件构造数据
/// </summary>
/// <param name="flowEvent"></param>
/// <returns></returns>
private SwapUnwindReq PrepareUnwindData(swap_event swapEvent)
{
SwapUnwindReq swapUnwindReq = new SwapUnwindReq();
if (swapEvent == null)
{
return null;
}
var interestPositions = swapEvent.unwindData.FlowEvents.Where(x => x.InterestMode != (int)InterestModeEnum.初始预付金 && x.InterestMode != (int)InterestModeEnum.追加预付金).ToList();
var floatPositions = swapEvent.unwindData.FlowEvents.Where(x => x.PayDirection > 0).ToList();
var tradeinfFee = floatPositions.Sum(s => s.TradingFee + s.TradingFeePending);
var markClosePnl = floatPositions.Sum(s => s.MarkClosePnl);
swapUnwindReq.ACCTSWAP_TERMINATE.CUSTORDID = swapEvent.id.ToString();
swapUnwindReq.ACCTSWAP_TERMINATE.TERMINATE_TYPE = swapEvent.unwindData.CloseMethod == (int)CloseMethodEnum.全部平仓 ? "1" : "0";
swapUnwindReq.ACCTSWAP_TERMINATE.TERMINATE_COUNT = swapEvent.unwindData.CloseQty.OtcFormatMoney(false, 4);
var unwindDate = swapEvent.unwindData.UnwindDate.HasValue ? swapEvent.unwindData.UnwindDate.Value : swapEvent.unwindData.ValueDate;
var payDate = swapEvent.unwindData.PayDate.HasValue ? swapEvent.unwindData.PayDate.Value : swapEvent.unwindData.ValueDate;
var fixFee = interestPositions.Sum(s => s.InterestFee * (s.InterestDirection == (int)SwapDirectionEnum.支付 ? -1 : 1));
var gddAmount = interestPositions.Sum(s => s.InterestClosePnL) - fixFee;
swapUnwindReq.ACCTSWAP_TERMINATE.TERMINATE_DAY = unwindDate.ToString("yyyy-MM-dd");
swapUnwindReq.ACCTSWAP_TERMINATE.PAY_DAY = payDate.ToString("yyyy-MM-dd");
swapUnwindReq.ACCTSWAP_TERMINATE.ZCD_AMOUNT = (markClosePnl - tradeinfFee).OtcFormatMoney(false, 4);
swapUnwindReq.ACCTSWAP_TERMINATE.GDD_AMOUNT = gddAmount.OtcFormatMoney(false, 4);
swapUnwindReq.ACCTSWAP_TERMINATE.ORDSTATUS = "0";
swapUnwindReq.ACCTSWAP_TERMINATE.FIX_FEE = fixFee.OtcFormatMoney(false, 4);
swapUnwindReq.ACCTSWAP_TERMINATE.ASSET_FEE = tradeinfFee.OtcFormatMoney(false, 4);
return swapUnwindReq;
}
/// <summary>
/// 撤单数据构造
/// </summary>
/// <param name="trade"></param>
/// <param name="positions"></param>
/// <returns></returns>
private SwapUnwindReq PrepareRepealUnwindData(string dataId, swap_position posi, bool hasInterest)
{
decimal notionalValue = posi.PosiNotionalValue;
if (posi.PosiDirection == 0)
{
notionalValue = posi.InterestPrincipalFix;
}
SwapUnwindReq swapUnwindReq = new SwapUnwindReq();
swapUnwindReq.ACCTSWAP_TERMINATE.CUSTORDID = dataId;
swapUnwindReq.ACCTSWAP_TERMINATE.TERMINATE_TYPE = "1";
swapUnwindReq.ACCTSWAP_TERMINATE.TERMINATE_COUNT = posi.PosiQuantity.OtcFormatMoney(false, 4);
swapUnwindReq.ACCTSWAP_TERMINATE.TERMINATE_DAY = DateTime.Now.ToString("yyyy-MM-dd");
swapUnwindReq.ACCTSWAP_TERMINATE.ZCD_AMOUNT = notionalValue.OtcFormatMoney(false, 4);
swapUnwindReq.ACCTSWAP_TERMINATE.GDD_AMOUNT = "0";
swapUnwindReq.ACCTSWAP_TERMINATE.ORDSTATUS = "0";
if (hasInterest)
{
swapUnwindReq.ACCTSWAP_TERMINATE.GDD_AMOUNT = swapUnwindReq.ACCTSWAP_TERMINATE.ZCD_AMOUNT;
}
return swapUnwindReq;
}
/// <summary>
/// 交易请求数据组装
/// </summary>
/// <param name="td"></param>
/// <param name="positions"></param>
/// <returns></returns>
private SwapTradeReq PrepareTradeReq(SwapTradePushModel model)
{
var td = model.trade;
return PrepareTradeReqSingle(model);
}
/// <summary>
/// 非多空组合交易推送
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
private SwapTradeReq PrepareTradeReqSingle(SwapTradePushModel model)
{
var td = model.trade;
var tradeExtend = model.tradeExtend;
var positions = model.positions;
var client = model.Client;
SwapTradeReq swapTradeReq = new SwapTradeReq();
var floatRateInterest = positions.FirstOrDefault(x => !string.IsNullOrEmpty(x.FloatRateUnderlyingCode));
var interestList = positions.Where(x => ConsTrade.InterestModels.Contains(x.InterestMode)).ToList();
var marginList = positions.Where(x => x.InterestMode == (int)InterestModeEnum.初始预付金).ToList();
var marginAmount = marginList.Sum(s => s.InterestPrincipalFix * (s.InterestDirection == (int)SwapDirectionEnum.收取 ? 1 : -1));
var position = positions.FirstOrDefault(x => x.PosiDirection > 0 && x.IsInitial);
if (position == null)
{
return null;
}
var stockEqvNotional = position.PosiNotionalValue;
var marginRate = stockEqvNotional == 0 ? 0 : Math.Abs(marginAmount) / Convert.ToDecimal(stockEqvNotional);
if (interestList.Count == 0)
{
return null;
}
model.extNo = td.TradeNumber.Replace("XX", "");
var etradeAccount = new EtradeAccountService(UserInfo).GetEtradeAccount(td.AssetBookName);
#region BASEINFO
// swapTradeReq.BASEINFO.PARTY_ID = client?.Number;
swapTradeReq.BASEINFO.PARTY_NAME = td.ClientName;
swapTradeReq.BASEINFO.TRDTYPE = GetTradetype(positions);
swapTradeReq.BASEINFO.ORDDATE = td.TradeDate.Value.ToString("yyyy-MM-dd");
swapTradeReq.BASEINFO.GROUP_NAME = "TRS推送-"+ td.TradeDate.Value.ToString("yyyyMMdd");
swapTradeReq.BASEINFO.ORDSTATUS = "0";
swapTradeReq.BASEINFO.TRADER_ID = etradeAccount?.trader_account;
swapTradeReq.BASEINFO.SECU_INT = etradeAccount?.balance_account_trade;
#endregion
#region ACCTSWAP
swapTradeReq.ACCTSWAP.PRINCIPAL = stockEqvNotional.OtcFormatMoney(false, 4);
swapTradeReq.ACCTSWAP.PRINCIPAL_CNY = swapTradeReq.ACCTSWAP.PRINCIPAL;
swapTradeReq.ACCTSWAP.CURRENCY = "CNY";
swapTradeReq.ACCTSWAP.DILIVERY_CURRENCY = swapTradeReq.ACCTSWAP.CURRENCY;
swapTradeReq.ACCTSWAP.END_DAY = td.ExerciseDate.Value.ToString("yyyy-MM-dd");
//swapTradeReq.ACCTSWAP.CONTRACT_TYPE = "1";
swapTradeReq.ACCTSWAP.REGULAR_TYPE = "2";
swapTradeReq.ACCTSWAP.COUPON_TYPE = floatRateInterest != null ? "2" : "1";
swapTradeReq.ACCTSWAP.INTEREST_BASE = "0";
swapTradeReq.ACCTSWAP.PAYMENT_CALENDAR = new List<string>() { "CHINA_IB" };
swapTradeReq.ACCTSWAP.DAY_COUNTER = "Actual/365 (Fixed)";
swapTradeReq.ACCTSWAP.MARGIN_BEGIN_RATE = marginRate.OtcFormatMoney(false, 4);
swapTradeReq.ACCTSWAP.COUPON_RATE = position.PosiGrossPrice.OtcFormatMoney(false, 10);
swapTradeReq.ACCTSWAP.SETTLE_TYPE = "DIRECT";
if (td.StructureType == "定义文件型债券收益互换")
{
swapTradeReq.ACCTSWAP.SETTLE_TYPE = "CPAS";
}
var settleRules = 0;
if (floatRateInterest != null)
{
swapTradeReq.ACCTSWAP.IR_I_CODE = floatRateInterest.FloatRateUnderlyingCode;
swapTradeReq.ACCTSWAP.FLOAT_METHOD = floatRateInterest.InterestType == (int)InterestTypeEnum.单利 ? "0" : "2";
}
if (tradeExtend != null)
{
swapTradeReq.ACCTSWAP.FIXED_INTEREST_RULE = GetInterestRule(tradeExtend.ExtendObj.InterestCalcMode);
settleRules = tradeExtend.ExtendObj.SettlementRules;
}
swapTradeReq.ACCTSWAP.END_SETTLE_DATE = QdpCalendarHelper.GetNonHoliday(td.ExerciseDate.Value.AddDays(settleRules)).ToString("yyyy-MM-dd");
#endregion
#region ACCTSWAP.REGULAR_INFO
REGULAR_INFO rEGULAR_INFO = new REGULAR_INFO();
rEGULAR_INFO.FINAL_STUP_TYPE = "0";
rEGULAR_INFO.PAY_FREQ = "0D";//到期支付
rEGULAR_INFO.PAY_ADJUST = "0";
rEGULAR_INFO.PAY_OFFSET = "1D";
rEGULAR_INFO.RESET_FREQ = "7D";
rEGULAR_INFO.RESET_ADJUST = "4";
rEGULAR_INFO.INTEREST_OFFSET = "-1D";
rEGULAR_INFO.INTEREST_ADJUST = "2";
if (interestList.Count > 0)
{
var interest = interestList[0];
var observation = DbContext.trade_obervation.FirstOrDefault(x => x.PositionId == interest.PositionId);
if (observation != null)
{
rEGULAR_INFO.INTEREST_START_DAY = observation.ObservationStart.Value.ToString("yyyy-MM-dd");
rEGULAR_INFO.INTEREST_END_DAY = observation.IntervalList.OrderByDescending(o => o.Date).First().Date.ToString("yyyy-MM-dd");
}
else
{
rEGULAR_INFO.INTEREST_START_DAY = td.StartDate.Value.ToString("yyyy-MM-dd");
rEGULAR_INFO.INTEREST_END_DAY = td.ExerciseDate.Value.ToString("yyyy-MM-dd");
}
if (floatRateInterest != null)
{
rEGULAR_INFO.SPREAD = floatRateInterest.InterestRateDefault.ToString();
}
else
{
rEGULAR_INFO.RATE = interest.InterestRateDefault.ToString();
}
}
swapTradeReq.ACCTSWAP.REGULAR_INFO = rEGULAR_INFO;
#endregion
return swapTradeReq;
}
/// <summary>
/// 互换资产请求数据组装
/// </summary>
/// <param name="td"></param>
/// <param name="positions"></param>
/// <returns></returns>
private SwapPosiReq PrepareTradePosiReq(SwapTradePushModel model, bool longShort)
{
var client = model.Client;
model.extNo = "";
SwapPosiReq swapPosiReq = new SwapPosiReq();
var td = model.trade;
var position = model.positions.Where(x => x.PosiDirection > 0).FirstOrDefault();
if (position == null)
{
return null;
}
model.extNo = longShort ? position.PosiNumber + "-01" : position.PosiNumber;
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(position.UnderlyingCode);
if (underlying == null)
{
return null;
}
decimal price = Convert.ToDecimal(underlying.Price ?? 100);
var etradeAccount = new EtradeAccountService(UserInfo).GetEtradeAccount(td.AssetBookName);
swapPosiReq.BASEINFO.ORDDATE = td.TradeDate.Value.ToString("yyyy-MM-dd");
//swapPosiReq.BASEINFO.PARTY_ID = client?.Number;
swapPosiReq.BASEINFO.PARTY_NAME = td.ClientName;
swapPosiReq.BASEINFO.TRD_RELATED_NO = longShort ? position.PosiNumber : td.TradeNumber.Replace("XX", "");
swapPosiReq.BASEINFO.ORDSTATUS = "0";
swapPosiReq.BASEINFO.GROUP_NAME = "TRS推送-" + td.TradeDate.Value.ToString("yyyyMMdd");
swapPosiReq.BASEINFO.TRDTYPE = "10";
if ((position.PosiDirection == (int)SwapDirectionEnum.支付 && position.PositionType == (int)PositionTypeFlag.Long) || (position.PosiDirection == (int)SwapDirectionEnum.收取 && position.PositionType == (int)PositionTypeFlag.Short))
{
swapPosiReq.BASEINFO.TRDTYPE = "20";
}
// swapPosiReq.BASEINFO.SECU_INT = "TRS_YJC_ZC";
swapPosiReq.BASEINFO.TRADER_ID = etradeAccount?.trader_account;
swapPosiReq.BASEINFO.SECU_INT = etradeAccount?.balance_account_asset;
#region TRADEINFO
var underylingCode = position.UnderlyingCode.Split(".")[0];
swapPosiReq.TRADEINFO.TRD_FEE = "0";
swapPosiReq.TRADEINFO.SET_FEE = "0";
swapPosiReq.TRADEINFO.I_CODE = underylingCode;
swapPosiReq.TRADEINFO.MARKET = underlying.MarketCode;
swapPosiReq.TRADEINFO.A_TYPE = "SPT_BD";
swapPosiReq.TRADEINFO.PARVALUE = position.PosiQuantity.OtcFormatMoney(false, 4);
swapPosiReq.TRADEINFO.ORDPRICE = (price * position.PosiGrossPrice).OtcFormatMoney(false, 8);
swapPosiReq.TRADEINFO.ORDAMOUNT = (position.PosiQuantity * position.PosiGrossPrice).OtcFormatMoney(false, 4);
swapPosiReq.TRADEINFO.OCFLAG = "0";
swapPosiReq.TRADEINFO.SETDAYS = "1";
#endregion
return swapPosiReq;
}
private SwapPosiReq PrepareTradePosiUnwindReq(trade td, swap_flow_event flowEvent, string data_number)
{
SwapPosiReq swapPosiReq = new SwapPosiReq();
if (flowEvent == null)
{
return null;
}
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(flowEvent.UnderlyingCode);
if (underlying == null)
{
return null;
}
decimal price = Convert.ToDecimal(underlying.Price ?? 100);
var etradeAccount = new EtradeAccountService(UserInfo).GetEtradeAccount(td.AssetBookName);
swapPosiReq.BASEINFO.ORDDATE = flowEvent.UnwindDate.Value.ToString("yyyy-MM-dd");
var payDate = flowEvent.PayDate.HasValue ? flowEvent.PayDate.Value : flowEvent.UnwindDate.Value;
swapPosiReq.BASEINFO.SETDATE = payDate.ToString("yyyy-MM-dd");
//swapPosiReq.BASEINFO.PARTY_ID = client?.Number;
swapPosiReq.BASEINFO.PARTY_NAME = td.ClientName;
swapPosiReq.BASEINFO.TRD_RELATED_NO = td.TradeNumber.Replace("XX", "");
swapPosiReq.BASEINFO.ORDSTATUS = "0";
swapPosiReq.BASEINFO.GROUP_NAME = "TRS推送-" + flowEvent.UnwindDate.Value.ToString("yyyyMMdd");
swapPosiReq.BASEINFO.TRDTYPE = "20";
if ((flowEvent.PayDirection == (int)SwapDirectionEnum.支付 && flowEvent.PositionType == (int)PositionTypeFlag.Long) || (flowEvent.PayDirection == (int)SwapDirectionEnum.收取 && flowEvent.PositionType == (int)PositionTypeFlag.Short))
{
swapPosiReq.BASEINFO.TRDTYPE = "10";
}
// swapPosiReq.BASEINFO.SECU_INT = "TRS_YJC_ZC";
swapPosiReq.BASEINFO.TRADER_ID = etradeAccount?.trader_account;
swapPosiReq.BASEINFO.SECU_INT = etradeAccount?.balance_account_asset;
#region TRADEINFO
var underylingCode = flowEvent.UnderlyingCode.Split(".")[0];
swapPosiReq.TRADEINFO.TRD_FEE = "0";
swapPosiReq.TRADEINFO.SET_FEE = "0";
swapPosiReq.TRADEINFO.I_CODE = underylingCode;
swapPosiReq.TRADEINFO.MARKET = underlying.MarketCode;
swapPosiReq.TRADEINFO.A_TYPE = "SPT_BD";
swapPosiReq.TRADEINFO.PARVALUE = flowEvent.Quantity.OtcFormatMoney(false, 4);
swapPosiReq.TRADEINFO.ORDPRICE = (price * flowEvent.TradingAmountAvg).OtcFormatMoney(false, 8);
swapPosiReq.TRADEINFO.ORDAMOUNT = (flowEvent.Quantity * flowEvent.TradingAmountAvg).OtcFormatMoney(false, 4);
swapPosiReq.TRADEINFO.OCFLAG = "1";
swapPosiReq.TRADEINFO.SETDAYS = "0";
#endregion
return swapPosiReq;
}
private SwapMarginReq PrepareTradeMarginUnwindReq(Client client, trade td, swap_flow_event flowEvent, bool unwind, string posiNumer)
{
SwapMarginReq swapMarginReq = new SwapMarginReq();
if (flowEvent == null)
{
return null;
}
var posi = DbContext.swap_position.FirstOrDefault(x => x.PosiDirection > 0 && x.IsInitial && !x.Invalid);
if (posi == null)
{
return null;
}
var etradeAccount = new EtradeAccountService(UserInfo).GetEtradeAccount(td.AssetBookName);
#region BASEINFO
swapMarginReq.BASEINFO.ORDDATE = flowEvent.UnwindDate.Value.ToString("yyyy-MM-dd");
var payDate = flowEvent.PayDate.HasValue ? flowEvent.PayDate.Value : flowEvent.UnwindDate.Value;
swapMarginReq.BASEINFO.SETDATE = payDate.ToString("yyyy-MM-dd");
// swapMarginReq.BASEINFO.PARTY_ID = client?.Number;
swapMarginReq.BASEINFO.PARTY_NAME = td.ClientName;
swapMarginReq.BASEINFO.ORDSTATUS = "0";
swapMarginReq.BASEINFO.GROUP_NAME = "TRS推送-" + flowEvent.UnwindDate.Value.ToString("yyyyMMdd");
swapMarginReq.BASEINFO.TRDTYPE = flowEvent.InterestDirection == (int)SwapDirectionEnum.收取 ? "128" : "127";
swapMarginReq.BASEINFO.TRADER_ID = etradeAccount?.trader_account;
swapMarginReq.BASEINFO.SECU_INT = etradeAccount?.balance_account_trade;
#endregion
#region TRADEINFO
swapMarginReq.TRADEINFO.PARVALUE = flowEvent.InterestPrincipal.OtcFormatMoney(false, 4);
swapMarginReq.TRADEINFO.INTEREST_AMOUNT = "0";
#endregion
#region RESERVE
if (unwind)
{
swapMarginReq.RESERVE.IN_CUSTORDID = posiNumer;
}
swapMarginReq.RESERVE.CONTRACT_CODE = td.TradeNumber.Replace("XX", "");
swapMarginReq.RESERVE.RATE = flowEvent.InterestRate.OtcFormatMoney(false, 4);
swapMarginReq.RESERVE.DAY_COUNTER = "Actual/365 (Fixed)";
swapMarginReq.RESERVE.CURRENCY = "CNY";
#endregion
return swapMarginReq;
}
/// <summary>
/// 互换预付金请求数据组装
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
private SwapMarginReq PrepareTradeMarginReq(SwapTradePushModel model)
{
model.extNo = "";
SwapMarginReq swapMarginReq = new SwapMarginReq();
var td = model.trade;
var position = model.positions.FirstOrDefault();
if (position == null)
{
return null;
}
model.extNo = position.PosiNumber;
var etradeAccount = new EtradeAccountService(UserInfo).GetEtradeAccount(td.AssetBookName);
#region BASEINFO
var flowEvent = DbContext.swap_flow_event.Where(x=>x.PositionId== position.id&&x.EventType==(int)SwapFlowEventTypeEnum.开仓&&x.DataState==(int)SwapFlowDateStateEnum.完成).FirstOrDefault();
var eventDate = td.StartDate.Value;
var payDate = eventDate;
if (flowEvent!=null&& flowEvent.PayDate.HasValue)
{
payDate=flowEvent.PayDate.Value;
}
swapMarginReq.BASEINFO.ORDDATE = eventDate.ToString("yyyy-MM-dd");
swapMarginReq.BASEINFO.SETDATE = payDate.ToString("yyyy-MM-dd");
// swapMarginReq.BASEINFO.PARTY_ID = client?.Number;
swapMarginReq.BASEINFO.PARTY_NAME = td.ClientName;
swapMarginReq.BASEINFO.ORDSTATUS = "0";
swapMarginReq.BASEINFO.GROUP_NAME = "TRS推送-" + td.StartDate.Value.ToString("yyyyMMdd");
swapMarginReq.BASEINFO.TRDTYPE = position.InterestDirection == (int)SwapDirectionEnum.收取 ? "128" : "127";
swapMarginReq.BASEINFO.TRADER_ID = etradeAccount?.trader_account;
swapMarginReq.BASEINFO.SECU_INT = etradeAccount?.balance_account_trade;
#endregion
#region TRADEINFO
swapMarginReq.TRADEINFO.PARVALUE = position.InterestPrincipalFix.OtcFormatMoney(false, 4);
swapMarginReq.TRADEINFO.INTEREST_AMOUNT = "0";
#endregion
#region RESERVE
//swapMarginReq.RESERVE.IN_CUSTORDID = position.PosiNumber;
swapMarginReq.RESERVE.CONTRACT_CODE = td.TradeNumber.Replace("XX", "");
swapMarginReq.RESERVE.RATE = position.InterestRateDefault.OtcFormatMoney(false, 4);
swapMarginReq.RESERVE.DAY_COUNTER = "Actual/365 (Fixed)";
swapMarginReq.RESERVE.CURRENCY = position.Currency;
#endregion
return swapMarginReq;
}
/// <summary>
/// 交易对手方请求数据组装
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
private ClientPushReq PrepareClientReq(Client client)
{
ClientPushReq clientReq = new ClientPushReq();
clientReq.CRM_ID = client.Number;
clientReq.COUNTERPARTYINFO.MEMBER_LONGNAME = client.Name;
clientReq.COUNTERPARTYINFO.SOCIAL_CREDIT_CODE = client.UnifiedSocialCreditCode;
clientReq.COUNTERPARTYINFO.MEMBER_NAME = client.Abbreviation;
return clientReq;
}
/// <summary>
/// 交易对手方资金账户请求数据组装
/// </summary>
/// <param name="bankCard"></param>
/// <param name="clientNumber"></param>
/// <returns></returns>
private ClientBankReq PrepareClientBankReq(List<ClientBankCard> bankCards, Client client)
{
ClientBankReq clientBankReq = new ClientBankReq();
clientBankReq.CRM_ID = client.Number;
clientBankReq.XIR_PARTY_ID = client.OutNumber;
foreach (ClientBankCard bankCard in bankCards)
{
BankInfo bankInfo = new BankInfo();
bankInfo.ACCID = bankCard.Card;
bankInfo.CASH_ACC_NAME = bankCard.ClientName;
bankInfo.SETTL_BANK_NAME = bankCard.Bank;
bankInfo.PAYMENT_NUMBER = bankCard.Payment;
clientBankReq.COUNTERPARTYTRADELIST.PARTYTRADEINFO.Add(bankInfo);
}
return clientBankReq;
}
private void PushClientData(IKafkaProduce kafkaProduceHelper, List<PushLog> pushLogs)
{
var pushService = new PushLogService(UserInfo);
using var clientDb = new ClientDBContext();
foreach (var pushLog in pushLogs)
{
var intId = Convert.ToInt32(pushLog.data_id);
var client = clientDb.client.FirstOrDefault(x => x.id == intId);
if (client == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
var req = new RequestBase<ClientPushReq>();
req.RECORD = PrepareClientReq(client);
if (req.RECORD == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
req.EXT_NO = client.Number;
req.SERIAL_NO = pushLog.id.ToString();
req.ACTION = "5011";
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(reqCounterPartyInfoInsert, data_req);
}
}
private void PushClientBannkData(IKafkaProduce kafkaProduceHelper, List<PushLog> pushLogs)
{
var pushService = new PushLogService(UserInfo);
using var clientDb = new ClientDBContext();
foreach (var pushLog in pushLogs)
{
var intId = Convert.ToInt32(pushLog.data_id);
var client = clientDb.client.FirstOrDefault(x => x.id == intId);
if (client == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
var bankCards = clientDb.bankcard.Where(x => x.ClientId == client.id && x.ValidState != "InValid").ToList();
var req = new RequestBase<ClientBankReq>();
req.RECORD = PrepareClientBankReq(bankCards, client);
if (req.RECORD == null)
{
pushService.DeleteLog(pushLog.id);
continue;
}
req.EXT_NO = client.Number;
req.SERIAL_NO = pushLog.id.ToString();
req.ACTION = "5013";
var data_req = JsonHelper.Serialize(req);
pushService.UpdateLogReq(pushLog.id, data_req);
kafkaProduceHelper.Produce(reqCounterPartyCashAccoutInsert, data_req);
}
}
/// <summary>
/// 获取交易方向
/// </summary>
/// <param name="positions"></param>
/// <returns></returns>
private string GetTradetype(List<swap_position> positions)
{
string direction = "151";
var interestList = positions.Where(x => ConsTrade.InterestModels.Contains(x.InterestMode)).ToList();
var posiList = positions.Where(x => x.PosiDirection > 0).ToList();
if (interestList.Count == 1)
{
direction = interestList[0].InterestDirection == (int)SwapDirectionEnum.收取 ? "151" : "152";
return direction;
}
if (posiList.Count > 0)
{
direction = posiList[0].PosiDirection == (int)SwapDirectionEnum.支付 ? "151" : "152";
return direction;
}
return direction;
}
/// <summary>
/// 获取结算利息计算方式
/// </summary>
/// <param name="interestCalcMode"></param>
/// <returns></returns>
private string GetInterestRule(string interestCalcMode)
{
if (interestCalcMode == "01")
{
return "1";
}
if (interestCalcMode == "10")
{
return "0";
}
if (interestCalcMode == "11")
{
return "2";
}
return "";
}
}
}