从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 期权交易查询导出请求
|
||||
/// </summary>
|
||||
public class OtcOptionTradeExportRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 结构类型
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> TradeTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易状态
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> TradeStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 簿记账户名称
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> AssetBookNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易员名称
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> TraderNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易对手方名称
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> ClientNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易对手方编号,优先使用
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> ClientNumbers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易编号
|
||||
/// </summary>
|
||||
public string TradeNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标的代码
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> UnderlyingCodes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易方向买入|卖出
|
||||
/// </summary>
|
||||
public string BuySell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 看涨看跌 Call|Put
|
||||
/// </summary>
|
||||
public string OptionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 行权方式:American|European
|
||||
/// </summary>
|
||||
public string ExerciseMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 成交日期筛选的起始日期, 格式: yyyy-MM-dd
|
||||
/// </summary>
|
||||
public DateTime? TradeDateStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 成交日期筛选的结束日期, 格式: yyyy-MM-dd
|
||||
/// </summary>
|
||||
public DateTime? TradeDateEnd { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
using YLErp.Model;
|
||||
using YLErp.Modules.TradeModule.QueryModule;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 场外期权交易导出服务
|
||||
/// </summary>
|
||||
public class OtcOptionTradeExportService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte[] ExportToExcel(OtcOptionTradeExportRequest queryModel)
|
||||
{
|
||||
var req = new TradeReq
|
||||
{
|
||||
TradeTypesList = queryModel.TradeTypes?.ToList(),
|
||||
TradeStatusList = queryModel.TradeStatus?.ToList(),
|
||||
TradeNumber = queryModel.TradeNumber,
|
||||
UnderlyingCodeList = queryModel.UnderlyingCodes?.ToList(),
|
||||
BuySell = queryModel.BuySell,
|
||||
OptionType = queryModel.OptionType,
|
||||
ExerciseMode = queryModel.ExerciseMode,
|
||||
TradeDateEnd = queryModel.TradeDateEnd ?? default,
|
||||
TradeDateStart = queryModel.TradeDateStart ?? default
|
||||
};
|
||||
|
||||
//簿记账户名称
|
||||
req.AssetIdList = GetAssetIds(queryModel.AssetBookNames);
|
||||
|
||||
//交易员名称
|
||||
req.TraderNamesList = GetTraderId(queryModel.TraderNames);
|
||||
|
||||
//客户 优先使用客户编号
|
||||
req.ClientIdsInt = GetClientIds(queryModel.ClientNumbers, queryModel.ClientNames);
|
||||
|
||||
return new OtcTradeListExportService(OptUserInfo.SystemUser).ExportOptionTradeListToExcel(req, new TradeQueryRequest
|
||||
{
|
||||
ShowAllTrades = true,
|
||||
UserAssetUnits = null,
|
||||
VolType = "持仓"
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取簿记账户id
|
||||
/// </summary>
|
||||
private List<int> GetAssetIds(IEnumerable<string> assetBookNames)
|
||||
{
|
||||
if (assetBookNames == null || !assetBookNames.HasNonEmptyItem())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var list = DataCacheProvider.GetAssetUnitDataSource().AsQueryable()
|
||||
.Where(x => assetBookNames.Contains(x.Name)).Select(x => x.id).ToList();
|
||||
|
||||
if (!list.Any())
|
||||
{
|
||||
list.Add(-1);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回交易员ID
|
||||
/// </summary>
|
||||
private List<int> GetTraderId(IEnumerable<string> traderNames)
|
||||
{
|
||||
if (traderNames == null || !traderNames.HasNonEmptyItem())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var sysdb = DbContextFactory.GetErpBaseContext())
|
||||
{
|
||||
var list = sysdb.SystemUsers.Where(su => traderNames.Contains(su.LoginName)).Select(n => n.Id).ToList();
|
||||
|
||||
if (!list.Any())
|
||||
{
|
||||
list.Add(-1);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据交易对手方编号或名称返回交易对手方ID
|
||||
/// </summary>
|
||||
private List<int> GetClientIds(IEnumerable<string> clientNumbers, IEnumerable<string> clientNames)
|
||||
{
|
||||
List<int> list = null;
|
||||
|
||||
//编号优先,有编号则不使用客户名称匹配
|
||||
if (clientNumbers != null && clientNumbers.HasNonEmptyItem())
|
||||
{
|
||||
list = DataCacheProvider.GetClientDataSource().AsQueryable()
|
||||
.Where(x => clientNumbers.Contains(x.Number)).Select(x => x.id).ToList();
|
||||
}
|
||||
else if (clientNames != null && clientNames.HasNonEmptyItem())
|
||||
{
|
||||
list = DataCacheProvider.GetClientDataSource().AsQueryable()
|
||||
.Where(x => clientNames.Contains(x.Name)).Select(x => x.id).ToList();
|
||||
}
|
||||
|
||||
if (list == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!list.Any())
|
||||
{
|
||||
list.Add(-1);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace YLErp.Modules.TradeModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 单笔交易查询
|
||||
/// </summary>
|
||||
public class SingleTradeQueryModel
|
||||
{
|
||||
public string TradeNumber { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// api/v2/tradeDetailList
|
||||
/// </summary>
|
||||
public class TradeDetailQueryApiV2Request
|
||||
{
|
||||
/// <summary>
|
||||
/// 结构类型
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> StructureTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易状态
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> TradeStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易对手方名称
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> ClientNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易对手方编号,优先使用
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringArrayConverter))]
|
||||
public IEnumerable<string> ClientNumbers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作起始时间,格式: yyyy-MM-dd HH:mm:ss
|
||||
/// </summary>
|
||||
public DateTime OptDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含组合主交易
|
||||
/// </summary>
|
||||
public bool IncludeGroupMain { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
using System.Data;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// api/v2/tradeDetailList
|
||||
/// </summary>
|
||||
public class TradeDetailQueryApiV2Service : YLBaseService
|
||||
{
|
||||
public TradeDetailQueryApiV2Service(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public TradeDetailQueryApiV2Service(YLBaseService baseService) : base(baseService)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IEnumerable<TradeDetailQueryApiV2Result> GetList(TradeDetailQueryApiV2Request queryModel)
|
||||
{
|
||||
if (queryModel.OptDate == DateTime.MinValue)
|
||||
{
|
||||
throw new ServiceException("操作时间 必须填写");
|
||||
}
|
||||
|
||||
var noneCashStatus = new[] { "新增待确认, 修改待确认, 审批中, 已拒绝, 平仓待复核, 行权待复核, 互换待复核, 提前终止拒绝" };
|
||||
|
||||
CreateTradePredicate(queryModel, out var noneCashPredicate, out var hasCashPredicate);
|
||||
|
||||
List<InnerDto> tempList = new List<InnerDto>();
|
||||
|
||||
DbContext.SetDebugLog();
|
||||
|
||||
if (noneCashPredicate != null)
|
||||
{
|
||||
var list = DbContext.trade.Where(noneCashPredicate)
|
||||
.OrderBy(n => n.OptDate)
|
||||
.Select(n => new InnerDto
|
||||
{
|
||||
td = n,
|
||||
OptDate = n.OptDate
|
||||
}).ToPagedList(new PagedQueryModel { GetTotal = false, PageSize = 10000 });
|
||||
|
||||
tempList.AddRange(list.Items);
|
||||
}
|
||||
|
||||
if (hasCashPredicate != null)
|
||||
{
|
||||
var query = from tc in DbContext.trade_cash
|
||||
join t in DbContext.trade.Where(hasCashPredicate) on tc.TradeId equals t.id
|
||||
where tc.OptDate.Value > queryModel.OptDate && !tc.IsDeleted
|
||||
&& tc.ValidState != ConsGlobal.InValid
|
||||
orderby tc.OptDate.Value
|
||||
select new InnerDto
|
||||
{
|
||||
td = t,
|
||||
tc = tc.Action == "系统操作-期权费" ? null : new TradeCloseInfo
|
||||
{
|
||||
TcAction = tc.Action,
|
||||
TcAmount = tc.Amount,
|
||||
TcFinalPrice = tc.FinalPrice,
|
||||
TcNotional = tc.Notional,
|
||||
TcTradeAmount = tc.TradeAmount,
|
||||
TcUnwindNotional = tc.UnwindNotional,
|
||||
TcUnwindPercent = tc.UnwindPercentRate,
|
||||
TcUnwindPrice = tc.UnwindPrice,
|
||||
TcUnwindPricePercent = tc.UnwindPricePercentRate,
|
||||
TcUnwindTradeAmount = tc.UnwindTradeAmount,
|
||||
TcValueDate = tc.ValueDate,
|
||||
|
||||
TradeNumber = null,
|
||||
TcTradePrice = 0,
|
||||
WinLoss = 0
|
||||
},
|
||||
OptDate = tc.OptDate
|
||||
};
|
||||
|
||||
var list = query.ToPagedList(new PagedQueryModel { GetTotal = false, PageSize = 10000 });
|
||||
|
||||
tempList.AddRange(list.Items);
|
||||
}
|
||||
|
||||
var resultList = tempList.Select(n =>
|
||||
{
|
||||
var otcTrade = new TradeDetailQueryApiV2Result();
|
||||
|
||||
YLAutoMapper.Map<OtcTradeBase, OtcTradeBase>(n.td, otcTrade);
|
||||
|
||||
otcTrade.Notional = otcTrade.OriginalNotional ?? 0;
|
||||
otcTrade.StockEqvNotional = otcTrade.OriginalStockEqvNotional ?? 0;
|
||||
otcTrade.ClientNumber = ClientModule.ClientDataQueryService.GetClient(otcTrade.ClientId)?.Number;
|
||||
|
||||
if (n.tc != null)
|
||||
{
|
||||
var closeInfo = n.tc;
|
||||
closeInfo.TradeNumber = n.td.TradeNumber;
|
||||
closeInfo.TcTradePrice = (otcTrade.TradePrice ?? 0) * (closeInfo.TcUnwindPercent ?? 0) * ((otcTrade.BuySell == "卖出" || otcTrade.TradeType == "远期") ? 1 : -1);
|
||||
closeInfo.WinLoss = (closeInfo.TcAmount ?? 0) + closeInfo.TcTradePrice;
|
||||
otcTrade.CloseInfo = closeInfo;
|
||||
}
|
||||
|
||||
otcTrade.OptDate = n.OptDate;
|
||||
|
||||
return otcTrade;
|
||||
}).ToArray();
|
||||
|
||||
new TradeExtendService(this).SetTradeExtend(resultList, true);
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据查询参数拼接查询条件
|
||||
/// </summary>
|
||||
protected void CreateTradePredicate(TradeDetailQueryApiV2Request queryModel
|
||||
, out Expression<Func<trade, bool>> noneCashPredicate
|
||||
, out Expression<Func<trade, bool>> hasCashPredicate)
|
||||
{
|
||||
noneCashPredicate = hasCashPredicate = null;
|
||||
|
||||
var predicate = PredicateBuilder.Create<trade>(t => t.ValidState != ConsGlobal.InValid);
|
||||
|
||||
if (queryModel.IncludeGroupMain)
|
||||
{
|
||||
predicate = predicate.And(n => n.TradeType != "结构化交易" || n.IsGroup == 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
predicate = predicate.And(n => n.TradeType != "结构化交易");
|
||||
}
|
||||
|
||||
// 结构类型
|
||||
if (queryModel.StructureTypes.HasNonEmptyItem())
|
||||
{
|
||||
predicate = predicate.And(d => queryModel.StructureTypes.Contains(d.TradeType)
|
||||
|| queryModel.StructureTypes.Contains(d.StructureType));
|
||||
}
|
||||
|
||||
//客户 优先使用客户编号
|
||||
var clientIds = GetClientIdsByNumber(queryModel.ClientNumbers)
|
||||
?? GetClientIdsByName(queryModel.ClientNames);
|
||||
|
||||
if (clientIds != null)
|
||||
{
|
||||
predicate = predicate.And(d => clientIds.Contains(d.ClientId));
|
||||
}
|
||||
|
||||
var noneCashStatus = new[] { "新增待确认", "修改待确认", "审批中", "已拒绝", "平仓待复核", "行权待复核", "互换待复核", "提前终止拒绝" };
|
||||
|
||||
//交易状态:确认成交、新增待确认、已平仓、已到期。。。等等
|
||||
if (queryModel.TradeStatus != null && queryModel.TradeStatus.Any())
|
||||
{
|
||||
noneCashStatus = noneCashStatus.Intersect(queryModel.TradeStatus).ToArray();
|
||||
if (noneCashStatus.Any())
|
||||
{
|
||||
noneCashPredicate = predicate.And(d => noneCashStatus.Contains(d.TradeStatus));
|
||||
}
|
||||
|
||||
var hasCashStatus = queryModel.TradeStatus.Except(noneCashStatus).ToArray();
|
||||
if (hasCashStatus.Any())
|
||||
{
|
||||
hasCashPredicate = predicate.And(d => hasCashStatus.Contains(d.TradeStatus));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hasCashPredicate = predicate;
|
||||
noneCashPredicate = predicate.And(d => noneCashStatus.Contains(d.TradeStatus));
|
||||
}
|
||||
|
||||
if (noneCashPredicate != null)
|
||||
{
|
||||
noneCashPredicate = noneCashPredicate.And(n => n.OptDate.Value > queryModel.OptDate);
|
||||
}
|
||||
}
|
||||
|
||||
#region 先转换成id再构建查询条件
|
||||
|
||||
/// <summary>
|
||||
/// 根据交易对手方编号返回交易对手方ID
|
||||
/// </summary>
|
||||
/// <param name="clientNumbers">交易对手方编号</param>
|
||||
private List<int> GetClientIdsByNumber(IEnumerable<string> clientNumbers)
|
||||
{
|
||||
if (!clientNumbers.HasNonEmptyItem())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var clientDbContext = DbContextFactory.GetClientDbContext(OptUser))
|
||||
{
|
||||
return clientDbContext.client.Where(x => clientNumbers.Contains(x.Number)).Select(x => x.id).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据客户名称返回客户ID
|
||||
/// </summary>
|
||||
private List<int> GetClientIdsByName(IEnumerable<string> clientNames)
|
||||
{
|
||||
if (!clientNames.HasNonEmptyItem())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var clientDbContext = DbContextFactory.GetClientDbContext(OptUser))
|
||||
{
|
||||
return clientDbContext.client.Where(x => clientNames.Contains(x.Name)).Select(x => x.id).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
class InnerDto
|
||||
{
|
||||
public trade td { get; set; }
|
||||
|
||||
public TradeCloseInfo tc { get; set; }
|
||||
|
||||
public DateTime? OptDate { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// api/v2/tradeDetailList
|
||||
/// </summary>
|
||||
public class TradeDetailQueryApiV2Result : OtcOptionTradeFull
|
||||
{
|
||||
public TradeCloseInfo CloseInfo { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
namespace YLErp.Modules.TradeModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 组合交易主交易了结请求
|
||||
/// </summary>
|
||||
public class TradeGroupCloseRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 交易编号
|
||||
/// </summary>
|
||||
public string TradeNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 要平仓的子交易编号集合
|
||||
/// </summary>
|
||||
public IEnumerable<string> SubTradeNumbers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 了结方式
|
||||
/// </summary>
|
||||
public string UnwindType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 了结日期
|
||||
/// </summary>
|
||||
public DateTime ValueDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标的价格
|
||||
/// </summary>
|
||||
public double UnderlyingPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 平仓数量/比例/名义本金
|
||||
/// </summary>
|
||||
public double UnwindAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 百分比;名义本金;数量
|
||||
/// </summary>
|
||||
public string UnwindAmountFlag { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
using YLErp.DBModels.Converts;
|
||||
using YLErp.Modules.TradeModule.DealModule;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.ApiModule
|
||||
{
|
||||
/// <summary>
|
||||
/// for api/v1/trade/group_options_close_start
|
||||
/// </summary>
|
||||
public class TradeGroupCloseService : YLBaseService
|
||||
{
|
||||
public TradeGroupCloseService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// for api/v1/trade/group_options_close_start
|
||||
/// </summary>
|
||||
public void ExecuteCloseStart(TradeGroupCloseRequest req)
|
||||
{
|
||||
if (req is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(req));
|
||||
}
|
||||
|
||||
switch (req.UnwindType)
|
||||
{
|
||||
case "全部平仓":
|
||||
case "部分平仓":
|
||||
case "全部提前行权":
|
||||
case "部分提前行权":
|
||||
case "到期行权":
|
||||
case "到期":
|
||||
break;
|
||||
default:
|
||||
var message = string.IsNullOrWhiteSpace(req.UnwindType) ? "了结方式 必须填写" : "不支持的了结方式:" + req.UnwindType;
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(req.TradeNumber))
|
||||
{
|
||||
throw new ServiceException("主交易编号 必须填写");
|
||||
}
|
||||
|
||||
var tradeNumbers = new List<string>()
|
||||
{
|
||||
req.TradeNumber
|
||||
};
|
||||
|
||||
if (req.SubTradeNumbers != null && req.SubTradeNumbers.Any())
|
||||
{
|
||||
tradeNumbers.AddRange(req.SubTradeNumbers);
|
||||
}
|
||||
|
||||
var tdList = DbContext.trade
|
||||
.Where(n => tradeNumbers.Contains(n.TradeNumber))
|
||||
.Select(n => new
|
||||
{
|
||||
n.id,
|
||||
n.TradeNumber,
|
||||
n.TradeType,
|
||||
n.IsGroup,
|
||||
n.IsUsePremiumRate,
|
||||
n.BuySell,
|
||||
n.Notional,
|
||||
n.TradeAmount,
|
||||
n.ParentTradeId,
|
||||
n.ValidState,
|
||||
n.TradeStatus
|
||||
}).ToList();
|
||||
|
||||
var td = tdList.FirstOrDefault(n => n.TradeNumber == req.TradeNumber);
|
||||
|
||||
if (td == null)
|
||||
{
|
||||
throw new ServiceException("交易信息不存在:" + req.TradeNumber);
|
||||
}
|
||||
|
||||
if (td.TradeType != "结构化交易" || td.IsGroup != 1)
|
||||
{
|
||||
throw new ServiceException("所选交易非组合交易主交易,不支持此API调用");
|
||||
}
|
||||
|
||||
var tradeIds = tdList.Select(n => n.id).ToList();
|
||||
|
||||
if (tradeNumbers.Count > 1)
|
||||
{
|
||||
//缺失交易信息的交易编号
|
||||
var missings = tradeNumbers.Where(tn => !tdList.Any(t => t.TradeNumber == tn)).ToArray();
|
||||
if (missings.Any())
|
||||
{
|
||||
throw new ServiceException("交易信息不存在:" + string.Join(",", missings));
|
||||
}
|
||||
|
||||
var errors = tdList.Select(n =>
|
||||
{
|
||||
if (n.ParentTradeId != td.id && n != td)
|
||||
{
|
||||
return $"交易编号:{n.TradeNumber},不属于同一组合;";
|
||||
}
|
||||
if (!ConsGlobal.IsValid(n.ValidState))
|
||||
{
|
||||
return $"交易编号:{n.TradeNumber},已被删除;";
|
||||
}
|
||||
if (n.TradeStatus != "确认成交")
|
||||
{
|
||||
return $"交易编号:{n.TradeNumber},,交易状态:{n.TradeStatus},确认成交状态下才可做了结操作;";
|
||||
}
|
||||
return null;
|
||||
}).Where(n => n != null).ToArray();
|
||||
|
||||
if (errors.Any())
|
||||
{
|
||||
throw new ServiceException(string.Join(string.Empty, errors));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//补全子交易
|
||||
var subIds = DbContext.trade.Where(n => n.ParentTradeId == td.id && n.IsGroup == 2 && n.ValidState != ConsGlobal.InValid && n.TradeStatus == "确认成交")
|
||||
.Select(n => n.id).ToArray();
|
||||
|
||||
tradeIds.AddRange(subIds);
|
||||
}
|
||||
|
||||
if (tradeIds.Count == 1)
|
||||
{
|
||||
throw new ServiceException("该分组交易没有可以了结操的子交易,不支持此API调用");
|
||||
}
|
||||
|
||||
var tc = new trade_cash
|
||||
{
|
||||
id = 0,
|
||||
TradeId = td.id,
|
||||
ValueDate = req.ValueDate,
|
||||
ExceciseType = null,
|
||||
TradeType = BuySellConvert.GetClientBuySell(td.BuySell),
|
||||
CallPut = null,
|
||||
Strike = null,
|
||||
Notional = td.Notional,
|
||||
Amount = 0,
|
||||
Action = req.UnwindType,
|
||||
ValidState = null,
|
||||
Status = null,
|
||||
FinalPrice = req.UnderlyingPrice,
|
||||
UnwindPrice = null,
|
||||
UnwindVol = null,
|
||||
VolType = null,
|
||||
UnwindType = null,
|
||||
UnwindNotional = null,
|
||||
ExtraAmount = null,
|
||||
SettleDate = null,
|
||||
Comments = null,
|
||||
ExerciseWay = null,
|
||||
TradeAmount = td.TradeAmount,
|
||||
UnwindTradeAmount = 0,
|
||||
UnwindPercentRate = null,
|
||||
UnwindPricePercentRate = null,
|
||||
BarrierPrice = null,
|
||||
HappenedDate = null,
|
||||
ConfirmDate = System.DateTime.MinValue,
|
||||
ParentTradeId = 0,
|
||||
ParentTradeCashId = 0,
|
||||
SpotPrice = null,
|
||||
NotionalPercentRate = null,
|
||||
TradePremium = 0,
|
||||
IsDeleted = false,
|
||||
AdvanceMoney = 0,
|
||||
IsLastAction = false
|
||||
};
|
||||
|
||||
if (td.IsUsePremiumRate == true)
|
||||
{
|
||||
if (req.UnwindAmountFlag == "百分比")
|
||||
{
|
||||
tc.UnwindPercentRate = req.UnwindAmount * 100;//要乘以100因为进入实际逻辑以后又会除以100
|
||||
}
|
||||
else if (req.UnwindAmountFlag == "名义本金")
|
||||
{
|
||||
tc.IsUnwindStockEqvNotional = true;
|
||||
tc.UnwindStockEqvNotional = req.UnwindAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ServiceException("交易是以'名义本金方式'成交的,仅支持以'百分比'和'名义本金'方式平仓");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (req.UnwindAmountFlag == "数量")
|
||||
{
|
||||
tc.UnwindTradeAmount = req.UnwindAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ServiceException("交易是以'数量方式'成交的,仅支持'数量'方式平仓");
|
||||
}
|
||||
}
|
||||
|
||||
new TradeUnwindService(this).SaveGroupTradeCash(new Model.SaveGroupTradeCashReq
|
||||
{
|
||||
trade_cash = tc,
|
||||
tradeIds = tradeIds,
|
||||
from_group_options_close_start_v1 = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace YLErp.Modules.TradeModule.ApiModule
|
||||
{
|
||||
public class TradeSettleQueryModel
|
||||
{
|
||||
public string TradeNumber { get; set; }
|
||||
public DateTime ValueDate { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user