using BaseOUDAL;
using YieldChain.Security;
using YLErp.BLL;
using YLErp.DBModels.Enums;
using YLErp.Model;
namespace YLErp.Modules.ScenarioModule
{
///
/// 情景分析数据查询服务
///
public class TradeScenarioQueryService : YLBaseService
{
public TradeScenarioQueryService(OptUserInfo userInfo) : base(userInfo)
{
}
//获取日终持仓
private SearchListResult GetEodPosition(TradeScenarioSearchModel searchModel)
{
var predicate = PredicateBuilder.Create(
t => t.ValueDate == searchModel.PositionDate
&& !ScenarioHelper.ExcludeTradeTypes.Contains(t.TradeType) && t.UnderlyingCode != null);
if (searchModel.UserAssets != null || searchModel.UserClients != null)
{
predicate = predicate.And(n => searchModel.UserAssets.Contains(n.BookId) || searchModel.UserClients.Contains(n.ClientId));
}
if (searchModel.UnderlyingIds != null && searchModel.UnderlyingIds.Any(n => n > 0))
{
predicate = predicate.And(x => searchModel.UnderlyingIds.Contains(x.UnderlyingId));
}
if (searchModel.VarietyIds != null && searchModel.VarietyIds.Any(n => n > 0))
{
predicate = predicate.And(
x => DbContext.underlying_manager.Any(n => n.UnderlyingCode == x.UnderlyingCode && searchModel.VarietyIds.Contains(n.UnderlyingTypeId)));
}
if (searchModel.TradeTypes != null && searchModel.TradeTypes.Any(n => !string.IsNullOrEmpty(n)))
{
if (searchModel.TradeTypes.Contains("场外期权"))
{
predicate = predicate.And(x => x.TradeId > 0 || searchModel.TradeTypes.Contains(x.TradeType));
}
else
{
predicate = predicate.And(x => searchModel.TradeTypes.Contains(x.TradeType));
}
}
if (searchModel.AssetIds != null && searchModel.AssetIds.Any())
{
predicate = predicate.And(x => searchModel.AssetIds.Contains(x.BookId));
}
if (searchModel.ClientIds != null && searchModel.ClientIds.Any())
{
predicate = predicate.And(x => searchModel.ClientIds.Contains(x.ClientId));
}
var tradePredicate = PredicateBuilder.Create(t => t.ValidState != ConsGlobal.InValid);
var query = from et in DbContext.eod_trade_position.Where(predicate)
join td in DbContext.trade.Where(tradePredicate) on et.TradeId equals td.id into temptd
from td in temptd.DefaultIfEmpty()
orderby td.TradeNumber descending, et.UnderlyingCode
select new
{
et.id,
et.TradeId,
et.ClientId,
et.BookId,
et.TradeType,
et.UnderlyingId,
et.UnderlyingCode,
BuySell = td != null ? td.BuySell : et.PositionType == "long" ? "买入" : "卖出",
td.TradeNumber,
td.ExerciseDate,
td.OptionType,
td.Strike,
td.IsMoneynessOption,
td.TradeDate,
// Notional = td == null ? (et.PositionType == "long" ? et.Amount : - et.Amount) : et.Amount,
Notional = et.Amount,
ExchangeOptionCode = et.ExchangeOptionCode
};
var searchResult = query.ToSearchList(searchModel);
var list = new List(searchResult.rows.Count());
foreach (var td in searchResult.rows)
{
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
if (underlying == null)
{
continue;
}
var tm = new TradePositionMerge
{
id = td.id + "_历史",
//EncryptId = DataProtect.Encrypt(td.id) + "_历史",
TradeEncryptId = td.TradeId > 0 ? DataProtect.Encrypt(td.TradeId) : string.Empty,
TradeNumber = td.TradeNumber,
BookId = td.BookId,
ClientId = td.ClientId,
ClientName = DataCacheProvider.GetClientDataSource().GetData(td.ClientId)?.Name,
AssetBookName = DataCacheProvider.GetAssetUnitDataSource().GetData(td.BookId)?.Name,
BuySell = td.BuySell,
ExerciseDate = td.ExerciseDate,
OptionType = td.OptionType,
Strike = td.Strike,
IsMoneynessOption = td.IsMoneynessOption,
TradeDate = td.TradeDate,
TradeType = td.TradeType,
UnderlyingCode = td.UnderlyingCode,
UnderlyingId = underlying.id,
VarietyId = underlying.UnderlyingTypeId,
UnderlyingAssetClass = underlying.UnderlyingType,
TradeAmount = 0,
};
tm.TradeAmount = td.Notional / underlying.CountRatio;
if (td.TradeType == "场内期权")
{
var exchangeOption = DataCacheProvider.GetExchangeListOptionDataSource().GetData(td.ExchangeOptionCode);
if (exchangeOption == null)
{
continue;
}
tm.ExerciseDate = exchangeOption.MaturityDate;
tm.OptionType = exchangeOption.OptionType;
tm.Strike = exchangeOption.Strike;
}
tm.CountRatio = underlying.CountRatio;
list.Add(tm);
}
return new SearchListResult(searchResult, list);
}
//获取日间持仓
private SearchListResult GetIntradayPosition(TradeScenarioSearchModel searchModel)
{
var blQuery = true;
#region----场外交易持仓过滤条件----
var tdPredicate = PredicateBuilder.Create(
t => t.ExerciseDate >= valuedateBLL.ValueDate && ConsTrade.NeedMarginTradeStatusList.Contains(t.TradeStatus)
&& !ScenarioHelper.ExcludeTradeTypes.Contains(t.TradeType) && t.ClientId > 0 && t.ValidState != "InValid");
if (searchModel.UserAssets != null || searchModel.UserClients != null)
{
tdPredicate = tdPredicate.And(a => searchModel.UserAssets.Contains(a.AssetId) || searchModel.UserClients.Contains(a.ClientId));
}
if (searchModel.TradeTypes != null && searchModel.TradeTypes.Any(n => !string.IsNullOrEmpty(n)))
{
if (!searchModel.TradeTypes.Contains("场外期权"))
{
blQuery = false;
tdPredicate = PredicateBuilder.False();
}
}
if (blQuery)
{
if (searchModel.ClientIds != null && searchModel.ClientIds.Any(n => n > 0))
{
tdPredicate = tdPredicate.And(x => searchModel.ClientIds.Contains(x.ClientId));
}
if (searchModel.UnderlyingIds != null && searchModel.UnderlyingIds.Any(n => n > 0))
{
tdPredicate = tdPredicate.And(x => searchModel.UnderlyingIds.Contains(x.UnderlyingId));
}
if (searchModel.AssetIds != null&&searchModel.AssetIds.Any())
{
tdPredicate = tdPredicate.And(x => searchModel.AssetIds.Contains(x.AssetId));
}
if (searchModel.VarietyIds != null && searchModel.VarietyIds.Any(n => n > 0))
{
tdPredicate = tdPredicate.And(
x => DbContext.underlying_manager.Any(n => n.UnderlyingCode == x.UnderlyingCode && searchModel.VarietyIds.Contains(n.UnderlyingTypeId)));
}
}
#endregion
#region----场内交易持仓过滤条件----
blQuery = true;
var exPredicate = PredicateBuilder.True();
if (searchModel.ClientIds != null && searchModel.ClientIds.Any(n => n > 0))
{
blQuery = false;
}
if (blQuery && searchModel.TradeTypes != null && searchModel.TradeTypes.Any(n => !string.IsNullOrEmpty(n)))
{
var tradeTypes = searchModel.TradeTypes.Intersect(ConsTrade.TradeTypesForHedge).ToArray();
if (blQuery = tradeTypes.Any())
{
exPredicate = exPredicate.And(x => tradeTypes.Contains(x.TradeType));
}
}
if (blQuery)
{
if (searchModel.UserAssets != null)
{
exPredicate = exPredicate.And(x => searchModel.UserAssets.Contains(x.BookId));
}
if (searchModel.UnderlyingIds != null && searchModel.UnderlyingIds.Any(n => n > 0))
{
exPredicate = exPredicate.And(x => searchModel.UnderlyingIds.Contains(x.UnderlyingId));
}
if (searchModel.AssetIds != null && searchModel.AssetIds.Any())
{
exPredicate = exPredicate.And(x => searchModel.AssetIds.Contains(x.BookId));
}
if (searchModel.VarietyIds != null && searchModel.VarietyIds.Any(n => n > 0))
{
exPredicate = exPredicate.And(
x => DbContext.underlying_manager.Any(n => n.UnderlyingCode == x.UnderlyingCode && searchModel.VarietyIds.Contains(n.UnderlyingTypeId)));
}
}
else
{
exPredicate = PredicateBuilder.False();
}
#endregion
#region----查询Linq----
var tdQuery = from td in DbContext.trade.Where(tdPredicate)
select new
{
torder = 1,
id = (long)td.id,
td.ClientId,
td.AssetId,
td.TradeType,
td.UnderlyingId,
td.UnderlyingCode,
BuySell = td.BuySell,
td.TradeNumber,
td.ExerciseDate,
td.OptionType,
td.Strike,
td.IsMoneynessOption,
td.TradeDate,
Notional = td.Notional,
ExchangeOptionCode = string.Empty
};
var extdQuery = from td in DbContext.TradePosition.Where(exPredicate)
select new
{
torder = 2,
id = td.id,
ClientId = 0,
AssetId = td.BookId,
td.TradeType,
td.UnderlyingId,
td.UnderlyingCode,
BuySell = td.PositionType == PositionTypeFlag.Long ? "买入" : "卖出",
TradeNumber = string.Empty,
ExerciseDate = default(DateTime?),
OptionType = string.Empty,
Strike = default(double?),
IsMoneynessOption = "否",
TradeDate = default(DateTime?),
Notional = td.Position,
ExchangeOptionCode = td.InstrumentCode
};
#endregion
var searchResult = tdQuery.Concat(extdQuery).OrderBy(n => n.torder)
.ThenByDescending(n => n.TradeNumber).ThenByDescending(n => n.UnderlyingCode).ToSearchList(searchModel);
var list = new List(searchResult.rows.Count());
foreach (var td in searchResult.rows)
{
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
if (underlying == null)
{
continue;
}
var isOtcTrade = td.torder == 1;
var tm = new TradePositionMerge
{
id = td.id + (isOtcTrade ? "_场外" : "_场内"),
TradeEncryptId = string.Empty,
TradeNumber = td.TradeNumber,
BookId = td.AssetId,
ClientId = td.ClientId,
ClientName = DataCacheProvider.GetClientDataSource().GetData(td.ClientId)?.Name,
AssetBookName = DataCacheProvider.GetAssetUnitDataSource().GetData(td.AssetId)?.Name,
BuySell = td.BuySell,
ExerciseDate = td.ExerciseDate,
OptionType = td.OptionType,
Strike = td.Strike,
IsMoneynessOption = td.IsMoneynessOption,
TradeDate = td.TradeDate,
TradeType = td.TradeType,
UnderlyingCode = td.UnderlyingCode,
UnderlyingId = underlying.id,
VarietyId = underlying.UnderlyingTypeId,
UnderlyingAssetClass = underlying.UnderlyingType,
TradeAmount = 0,
};
tm.TradeAmount = td.Notional / underlying.CountRatio;
if (isOtcTrade)
{
tm.TradeEncryptId = DataProtect.Encrypt(td.id);
}
else if (td.TradeType == "场内期权")
{
var exchangeOption = DataCacheProvider.GetExchangeListOptionDataSource().GetData(td.ExchangeOptionCode);
if (exchangeOption == null)
{
continue;
}
tm.ExerciseDate = exchangeOption.MaturityDate;
tm.OptionType = exchangeOption.OptionType;
tm.Strike = exchangeOption.Strike;
}
tm.CountRatio = underlying.CountRatio;
list.Add(tm);
}
return new SearchListResult(searchResult, list);
}
public SearchListResult GetDatas(TradeScenarioSearchModel req, out bool isEodPosition)
{
if (req.PositionDate != null && req.PositionDate < valuedateBLL.ValueDate)
{
isEodPosition = true;
return GetEodPosition(req);
}
else
{
isEodPosition = false;
return GetIntradayPosition(req);
}
}
}
}