292 lines
13 KiB
C#
292 lines
13 KiB
C#
using BaseOUDAL;
|
|
using System.Data;
|
|
using YLErp.Commons;
|
|
using YLErp.Model.Enum;
|
|
|
|
namespace YLErp.Modules.MarginModule
|
|
{
|
|
public class MarginRateSwapService : YLBaseService
|
|
{
|
|
public MarginRateSwapService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 导入预付金率
|
|
/// </summary>
|
|
public void ImportMarginRate(Stream streamIn, out int totalNum, out int successNum)
|
|
{
|
|
totalNum = 0;
|
|
successNum = 0;
|
|
|
|
var rowIndex = 0;
|
|
|
|
try
|
|
{
|
|
var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 1);
|
|
|
|
if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 1)
|
|
{
|
|
throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" };
|
|
}
|
|
|
|
var table = ds.Tables[0];
|
|
var reader = new DataRowReader(table);
|
|
|
|
rowIndex = 0;
|
|
totalNum = table.Rows.Count - rowIndex;
|
|
|
|
foreach (var row in table.Rows.Cast<DataRow>())
|
|
{
|
|
rowIndex++;
|
|
|
|
if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString())))
|
|
{
|
|
totalNum--;
|
|
continue;
|
|
}
|
|
|
|
reader.SetDataRow(row);
|
|
|
|
using (var trans = BeginTransaction())
|
|
{
|
|
//映射导入数据到交易对象
|
|
var maginRate = MapMarginRate(reader);
|
|
|
|
saveMarginRate(maginRate, true);
|
|
successNum++;
|
|
|
|
trans.Commit();
|
|
}
|
|
}
|
|
}
|
|
catch (ServiceException se)
|
|
{
|
|
if (se.Tag != null)
|
|
{
|
|
throw;
|
|
}
|
|
|
|
throw new ServiceException($"已成功导入{successNum}条;\n第{rowIndex}行,{se.Message}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogFactory.GetLogger("导入互换预付金率").Error(ex);
|
|
throw new ServiceException($"已成功导入{successNum}条,\n第{rowIndex}行,发生错误:{ex.Message}", ex);
|
|
}
|
|
}
|
|
|
|
private client_marginrate MapMarginRate(DataRowReader reader)
|
|
{
|
|
var marginRate = new client_marginrate()
|
|
{
|
|
ClientName = reader.GetString("客户名称", false),
|
|
ValueDate = reader.GetDate("起效日期", true) ?? DateTime.Now,
|
|
InitMarginRate = reader.GetPercent("初始保证金率", true) ?? 0,
|
|
MaintenanceRate = reader.GetPercent("维持保证金率", true) ?? 0,
|
|
SwapEndDays =reader.GetInt("互换默认期限",true)
|
|
};
|
|
var client = new Client();
|
|
marginRate.Type = "普通";
|
|
if (!string.IsNullOrWhiteSpace(marginRate.ClientName))
|
|
{
|
|
client = DataCacheProvider.GetClientDataSource().AsQueryable().Where(o => o.Name == marginRate.ClientName).FirstOrDefault();
|
|
if (client == null)
|
|
{
|
|
throw new ServiceException("未找到客户:" + marginRate.ClientName);
|
|
}
|
|
marginRate.ClientId = client.id;
|
|
}
|
|
marginRate.VarietyId = null;
|
|
return marginRate;
|
|
}
|
|
|
|
public void saveMarginRate(client_marginrate marginrate, bool canCover = false)
|
|
{
|
|
if (marginrate == null)
|
|
{
|
|
throw new ServiceException("无数据");
|
|
}
|
|
if (marginrate.InitMarginRate < 0)
|
|
{
|
|
throw new ServiceException("预付金率数据格式错");
|
|
}
|
|
var dbMarginRate = new client_marginrate();
|
|
var marginrateType = "普通";
|
|
if (marginrate.id != 0)
|
|
{
|
|
dbMarginRate = DbContext.client_marginrate.Find(marginrate.id);
|
|
if (dbMarginRate == null)
|
|
{
|
|
throw new ServiceException("未找到该记录");
|
|
}
|
|
dbMarginRate.ClientId = marginrate.ClientId;
|
|
dbMarginRate.VarietyId = marginrate.VarietyId;
|
|
dbMarginRate.Type = marginrate.Type;
|
|
dbMarginRate.InitMarginRate = marginrate.InitMarginRate;
|
|
dbMarginRate.ClosePositionLine = marginrate.ClosePositionLine;
|
|
dbMarginRate.WarningLine = marginrate.WarningLine;
|
|
dbMarginRate.ValueDate = marginrate.ValueDate;
|
|
dbMarginRate.InitMarginRebateRate = marginrate.InitMarginRebateRate;
|
|
dbMarginRate.AddToMarginRebateRate= marginrate.AddToMarginRebateRate;
|
|
dbMarginRate.LongInitMarginRate = marginrate.LongInitMarginRate;
|
|
dbMarginRate.ShortInitMarginRate = marginrate.ShortInitMarginRate;
|
|
dbMarginRate.SwapEndDays = marginrate.SwapEndDays;
|
|
dbMarginRate.MaintenanceRate= marginrate.MaintenanceRate;
|
|
dbMarginRate.OptId = UserId;
|
|
dbMarginRate.OptName = UserName;
|
|
dbMarginRate.OptDate = DateTime.Now;
|
|
if (DbContext.client_marginrate.Any(o =>marginrate.Type == marginrateType && o.VarietyId == marginrate.VarietyId
|
|
&& o.ClientId == marginrate.ClientId
|
|
&& o.ValueDate == marginrate.ValueDate
|
|
&& o.id != marginrate.id))
|
|
{
|
|
throw new ServiceException("同一客户同一" + marginrateType + "不支持在同一生效日有多条记录!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dbMarginRate = DbContext.client_marginrate.Where(o =>marginrate.Type == marginrateType && o.VarietyId == marginrate.VarietyId
|
|
&& o.Type == marginrate.Type
|
|
&& o.ClientId == marginrate.ClientId
|
|
&& o.ValueDate == marginrate.ValueDate).FirstOrDefault();
|
|
if (dbMarginRate == null)
|
|
{
|
|
marginrate.OptId = UserId;
|
|
marginrate.OptName = UserName;
|
|
marginrate.OptDate = DateTime.Now;
|
|
DbContext.client_marginrate.Add(marginrate);
|
|
}
|
|
else if (canCover)
|
|
{
|
|
dbMarginRate.InitMarginRate = marginrate.InitMarginRate;
|
|
dbMarginRate.ClosePositionLine = marginrate.ClosePositionLine;
|
|
dbMarginRate.WarningLine = marginrate.WarningLine;
|
|
dbMarginRate.InitMarginRebateRate = marginrate.InitMarginRebateRate;
|
|
dbMarginRate.AddToMarginRebateRate = marginrate.AddToMarginRebateRate;
|
|
dbMarginRate.LongInitMarginRate = marginrate.LongInitMarginRate;
|
|
dbMarginRate.ShortInitMarginRate = marginrate.ShortInitMarginRate;
|
|
dbMarginRate.SwapEndDays = marginrate.SwapEndDays;
|
|
dbMarginRate.MaintenanceRate = marginrate.MaintenanceRate;
|
|
dbMarginRate.OptId = UserId;
|
|
dbMarginRate.OptName = UserName;
|
|
dbMarginRate.OptDate = DateTime.Now;
|
|
}
|
|
else
|
|
{
|
|
throw new ServiceException("同一客户同一" + marginrateType + "不支持在同一天有多条记录");
|
|
}
|
|
}
|
|
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
private void checkMarginRate(client_marginrate marginrate)
|
|
{
|
|
if (ClientMarginTypeEnum.多空组合.ToString().Equals(marginrate.Type))
|
|
{
|
|
if (marginrate.InitMarginRate < 0.25)
|
|
{
|
|
throw new ServiceException("根据监管要求权益类多空组合型收益互换预付金不得低于25%");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var variety = DbContext.variety.Find(marginrate.VarietyId);
|
|
if (variety == null)
|
|
{
|
|
throw new ServiceException("所设置标的品种不存在!");
|
|
}
|
|
else
|
|
{
|
|
//股票、窄基股票指数及其产品、信用债 初始预付金比率 必须大于等于100%
|
|
if ((variety.AssetType == "个股" || (variety.AssetType == "指数" && "窄基指数".Equals(variety.IndexType))) && marginrate.InitMarginRate < 1)
|
|
{
|
|
throw new ServiceException("所设置品种包含股票或窄基指数及其产品、信用债,初始预付金比例不得低于100%!");
|
|
}
|
|
else if ((variety.AssetType == "指数" && "宽基指数".Equals(variety.IndexType)) && marginrate.InitMarginRate < 0.5)
|
|
{
|
|
//挂钩宽基股票指数及其产品,无对应期货品种的 向单一交易对手方收取的预付金比例不得低于50%
|
|
throw new ServiceException("所设置品种挂钩宽基股票指数及其产品,无对应期货品种的,初始预付金比例不得低于50%!");
|
|
}
|
|
else if (marginrate.InitMarginRate < (variety.Margin ?? 0.0))
|
|
{
|
|
//有对应期货或集中交易品种的 不得低于品种设置的最低预付金比例
|
|
throw new ServiceException(String.Format("所设置品种有对应期货或集中交易品种的,初始预付金比例不得低于品种[{0}]所设置最低预付金比例{1}%!", variety.VarietyName, variety.Margin * 100));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public SearchListResult<client_marginrate> SearchList(MarginRateSwapReq req)
|
|
{
|
|
var query = from source in DbContext.client_marginrate select source;
|
|
if (req.ClientId > 0)
|
|
{
|
|
query = query.Where(o => o.ClientId == req.ClientId);
|
|
}
|
|
|
|
if (req.VarietyId > 0)
|
|
{
|
|
query = query.Where(o => o.VarietyId == req.VarietyId);
|
|
}
|
|
|
|
if (req.Type != null)
|
|
{
|
|
query = query.Where(o => o.Type == req.Type);
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(req.sidx))
|
|
{
|
|
req.sidx = "id";
|
|
req.sord = "desc";
|
|
}
|
|
|
|
return query.ToSearchList(req);
|
|
}
|
|
|
|
public double GetMarginRate(int clientId, int varietyId, DateTime searchDate)
|
|
{
|
|
var marginRates = DbContext.client_marginrate.Where(o => o.VarietyId == varietyId && o.ValueDate < searchDate).OrderByDescending(o => o.ValueDate);
|
|
var marginRate = marginRates.Any(o => o.ClientId == clientId) ? marginRates.FirstOrDefault(o => o.ClientId == clientId) : marginRates.FirstOrDefault(o => o.ClientId == 0);
|
|
if (marginRate == null)
|
|
{
|
|
throw new Exception($"ClientId:{clientId} - VarietyId:{varietyId} 未找到对应的预付金率");
|
|
}
|
|
else
|
|
{
|
|
var credit = DbContext.credit.Where(o => o.ClientId == clientId && o.CreditStartDate <= searchDate).FirstOrDefault();
|
|
if (credit == null || credit.PFECredit == null || credit.PFECredit == 0)
|
|
{
|
|
return marginRate.InitMarginRate;
|
|
}
|
|
return marginRate.InitMarginRate;
|
|
}
|
|
}
|
|
|
|
public class MarginRateSwapReq : BaseSearchReq
|
|
{
|
|
public int ClientId { get; set; }
|
|
public int VarietyId { get; set; }
|
|
public string Type { get; set; }
|
|
}
|
|
|
|
public class MarginRateSwapMonitorReq : BaseSearchReq
|
|
{
|
|
public IEnumerable<string> WarnningTypes { get; set; }
|
|
public IEnumerable<int> ClientIds { get; set; }
|
|
public IEnumerable<int> VarietyIds { get; set; }
|
|
public DateTime? ValueDate { get; set; }
|
|
public IEnumerable<int> AssetIds { get; set; }
|
|
public IEnumerable<int> UnderlyingIds { get; set; }
|
|
public IEnumerable<int> UnderlyingCodes { get; set; }
|
|
public string SwapType { get; set; }
|
|
public string TradeNumber { get; set; }
|
|
public bool OpenWaringLineMonitor { get; set; }
|
|
public bool OpenCloseLineMonitor { get; set; }
|
|
public DateTime? DateFromTradeDate { get; set; }
|
|
public DateTime? DateToTradeDate { get; set; }
|
|
}
|
|
}
|
|
}
|