153 lines
5.8 KiB
C#
153 lines
5.8 KiB
C#
using YLErp.DBModels.Enums;
|
|
using YLErp.Modules.CalculationModule.Abstract;
|
|
|
|
namespace YLErp.Modules.CalculationModule
|
|
{
|
|
/// <summary>
|
|
/// 交易佣金计算
|
|
/// </summary>
|
|
public class ExchangeTradeCommissionCalc : IExchangeTradeCommissionCalc
|
|
{
|
|
/// <summary>
|
|
/// 计算交易手续费
|
|
/// </summary>
|
|
public ITradeCommissionCalcResult GetTradeCommission(IEnumerable<ExchangeTrade> tradeList, bool actualTrade = true)
|
|
{
|
|
if (tradeList == null || !tradeList.Any())
|
|
{
|
|
return TradeCommissionResult.Empty;
|
|
}
|
|
|
|
var dic = new Dictionary<int, double>();
|
|
|
|
//当日成交的对冲交易计算
|
|
var futureTradeDict = tradeList.Where(t => t.TradeType == "商品期货").ToLookup(t => t.UnderlyingId);
|
|
|
|
foreach (var item in futureTradeDict)
|
|
{
|
|
var trads = item.ToList();
|
|
var underlying = GetUnderlying(item.Key);
|
|
if (underlying == null) { continue; }
|
|
var vareity = GetVariety(underlying.UnderlyingTypeId);
|
|
var commissionDict = CommissionCalcHelper.GetCommissionForFutureTrades(vareity, trads);
|
|
if (commissionDict != null && commissionDict.Count > 0)
|
|
{
|
|
foreach (var tempItem in commissionDict)
|
|
{
|
|
dic[tempItem.Key] = tempItem.Value;
|
|
}
|
|
}
|
|
}
|
|
|
|
var insiteTradeList = tradeList.Where(t => t.TradeType == "场内期权").ToList();
|
|
Dictionary<string, double> insiteTradeContractSizeDic = null;
|
|
if (insiteTradeList != null&& insiteTradeList.Count>0)
|
|
{
|
|
insiteTradeContractSizeDic = GetInsiteTradeContractSize(insiteTradeList.Select(p => p.OptionCode).Distinct().ToList());
|
|
}
|
|
if (insiteTradeContractSizeDic == null)
|
|
{
|
|
insiteTradeContractSizeDic = new Dictionary<string, double>();
|
|
}
|
|
|
|
foreach (var td in tradeList)
|
|
{
|
|
if (td.TradeType == "商品期货" || td.TradeType == "信用债")
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (td.CommissionType == CommissionType.手动录入)
|
|
{
|
|
dic[td.id] = td.Commission;
|
|
continue;
|
|
}
|
|
|
|
if (td.TradeType == "场内期权") //当日成交的场内期权交易计算手续费
|
|
{
|
|
var underlying = GetUnderlying(td.UnderlyingId);
|
|
if (underlying == null)
|
|
{
|
|
continue;
|
|
}
|
|
var variety = GetVariety(underlying.UnderlyingTypeId);
|
|
if (variety == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dic[td.id] = CommissionCalcHelper.GetRegularCommissionForOptionTrade(variety, td.Notional, td.TradeSinglePrice, insiteTradeContractSizeDic.ContainsKey(td.OptionCode) ? insiteTradeContractSizeDic[td.OptionCode] : 0);
|
|
}
|
|
else if (td.TradeType == "股票") //股票交易交易费计算
|
|
{
|
|
var stockCommissionConfig = GetStock_Commission_Config(td.ExchangeAccountId);
|
|
if (stockCommissionConfig != null && stockCommissionConfig.Enabled == 1)
|
|
{
|
|
dic[td.id] = StockTradeCalcHelper.GetStockAllTradeExpenses(td, stockCommissionConfig, actualTrade);
|
|
}
|
|
}
|
|
}
|
|
|
|
return new TradeCommissionResult(dic);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取场内期权合约乘数
|
|
/// </summary>
|
|
/// <param name="contractCodes"></param>
|
|
/// <returns></returns>
|
|
private Dictionary<string, double> GetInsiteTradeContractSize(List<string> contractCodes)
|
|
{
|
|
using (var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
return db.exchange_list_option.AsNoTracking().Where(p => contractCodes.Contains(p.ContractCode)).ToDictionary(p => p.ContractCode, p => p.ContractSize);
|
|
}
|
|
}
|
|
|
|
|
|
protected virtual StockCommissionConfig GetStock_Commission_Config(int exchangeAccountId)
|
|
{
|
|
|
|
// 同步簿记账户 对应 多个 对冲账户的情况下,可能出现异常问题,取不到正确的值,需产品重新规划
|
|
var account = DataCacheProvider.GetExchangeAccountDataSource().AsQueryable().FirstOrDefault(n => n.id == exchangeAccountId);
|
|
return account == null ? null : DataCacheProvider.GetStockCommissionDataSource().AsQueryable().FirstOrDefault(n => n.ExchangeAccountCode == account.AccountCode);
|
|
}
|
|
|
|
protected virtual underlying_manager GetUnderlying(int underlyingId)
|
|
{
|
|
return DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingId);
|
|
}
|
|
|
|
protected virtual Variety GetVariety(int varietyId)
|
|
{
|
|
return DataCacheProvider.GetVarietyDataSource().GetData(varietyId);
|
|
}
|
|
|
|
class TradeCommissionResult : ITradeCommissionCalcResult
|
|
{
|
|
readonly Dictionary<int, double> _dic;
|
|
|
|
public TradeCommissionResult(Dictionary<int, double> dic)
|
|
{
|
|
_dic = dic;
|
|
}
|
|
|
|
public double GetTradeCommission(int tradeId)
|
|
{
|
|
if (_dic != null && _dic.TryGetValue(tradeId, out double dd))
|
|
{
|
|
return dd;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public static readonly TradeCommissionResult Empty;
|
|
|
|
static TradeCommissionResult()
|
|
{
|
|
Empty = new TradeCommissionResult(null);
|
|
}
|
|
}
|
|
}
|
|
}
|