从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YLErp.Configuration;
|
||||
using YLErp.Modules.EodModule.SettlementModule;
|
||||
|
||||
namespace YLErp.Modules.EodModule
|
||||
{
|
||||
[TestClass]
|
||||
public class EodClientBalanceCalcBSTest
|
||||
{
|
||||
[TestMethod("客户买卖权结算")]
|
||||
public void CalcTest()
|
||||
{
|
||||
var service = new EodClientBalanceCalcBS(OptUserInfo.UnitTestUser);
|
||||
List<Client> clients = new List<Client>() { new Client() { id=131,Number= "SDX0010",Name= "山西分形供应链数据管理有限公司" } };
|
||||
service.ClientBalanceByDay(DateTime.Parse("2021-11-15"), clients);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using YLErp.Configuration;
|
||||
using YLErp.Modules.EodModule.SettlementModule;
|
||||
|
||||
namespace YLErp.Modules.EodModule
|
||||
{
|
||||
[TestClass]
|
||||
public class EodClientBalanceCalcTest
|
||||
{
|
||||
[TestMethod("客户结算比较")]
|
||||
public void CompareTest()
|
||||
{
|
||||
var request = new EodSettlementRequest(OptUserInfo.UnitTestUser)
|
||||
{
|
||||
UseClosePrice = true,
|
||||
VolType = "持仓",
|
||||
SettleDate = new DateTime(2022, 6, 1)
|
||||
};
|
||||
var settlementConfig = new SettlementConfig
|
||||
{
|
||||
|
||||
};
|
||||
var cancleSource = new CancellationTokenSource();
|
||||
var context = new EodSettlementContextV2(request, settlementConfig, cancleSource.Token);
|
||||
var service = new EodClientBalanceCalc(context);
|
||||
service.ClientBalanceCalc();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
namespace YLErp.Modules.EodModule
|
||||
{
|
||||
[TestClass]
|
||||
public class EodCurrencyRateServiceTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestGetEodCurrencyRate()
|
||||
{
|
||||
using (var db = DbContextFactory.GetYLDbContext())
|
||||
{
|
||||
db.Database.ExecuteSqlRaw("delete from eod_currency_rate where ValueDate<='1971-01-01'");
|
||||
var rate1 = new eod_currency_rate
|
||||
{
|
||||
ValueDate = new DateTime(1970, 12, 31),
|
||||
BuyRate = 6.45,
|
||||
ForeignCurrency = "USD",
|
||||
LocalCurrency = "CNH",
|
||||
OptDate = DateTime.Now,
|
||||
OptId = 0,
|
||||
OptName = "系统",
|
||||
Rate = 6.45,
|
||||
SellRate = 6.45
|
||||
};
|
||||
|
||||
var rates = new eod_currency_rate[5];
|
||||
rates[0] = rate1;
|
||||
|
||||
for (var i = 1; i < 5; i++)
|
||||
{
|
||||
var rate2 = rates[i - 1].Clone();
|
||||
rate2.ValueDate = rate2.ValueDate.AddDays(-i * 2);
|
||||
rate2.BuyRate = rate2.SellRate = rate2.Rate -= 0.1;
|
||||
rates[i] = rate2;
|
||||
}
|
||||
|
||||
db.eod_currency_rate.AddRange(rates);
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
var service = new EodCurrencyRateService(OptUserInfo.SystemUser);
|
||||
|
||||
var rate = service.GetEodCurrencyRate("USD", "CNH", new DateTime(1970, 12, 31));
|
||||
Assert.IsTrue(rate != null && rate.Rate == 6.45);
|
||||
|
||||
service.GetEodCurrencyRate("USD", "CNH", new DateTime(1970, 12, 31), true);
|
||||
Assert.IsTrue(rate != null && rate.Rate == 6.45);
|
||||
|
||||
rate = service.GetEodCurrencyRate("CNH", "USD", new DateTime(1970, 12, 31));
|
||||
Assert.IsTrue(rate != null && rate.Rate == 1 / 6.45);
|
||||
|
||||
rate = service.GetEodCurrencyRate("CNH", "USD", new DateTime(1970, 12, 31), true);
|
||||
Assert.IsTrue(rate != null && rate.Rate == 1 / 6.45);
|
||||
|
||||
rate = service.GetEodCurrencyRate("USD", "CNY", new DateTime(1970, 12, 31));
|
||||
Assert.IsTrue(rate == null);
|
||||
|
||||
rate = service.GetEodCurrencyRate("USD", "CNY", new DateTime(1970, 12, 31), true);
|
||||
Assert.IsTrue(rate == null);
|
||||
|
||||
rate = service.GetEodCurrencyRate("USD", "CNH", new DateTime(1970, 12, 1), true);
|
||||
Assert.IsTrue(rate == null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
using YLErp.Configuration;
|
||||
using YLErp.Modules.EodModule.SettlementModule;
|
||||
using YLErp.Modules.TradeModule.DealModule;
|
||||
|
||||
namespace YLErp.Modules.EodModule
|
||||
{
|
||||
[TestClass]
|
||||
public class EodSettlementTaskTest : UnitTestBase
|
||||
{
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void TestEodTask()
|
||||
{
|
||||
var eodDate = new DateTime(2020, 9, 2);
|
||||
|
||||
var task = new EodTask
|
||||
{
|
||||
StartDate = eodDate,
|
||||
EndDate = eodDate,
|
||||
VolTypes = "持仓",//"持仓,开仓,对冲";
|
||||
PriceType = EodSettlePriceType.ClosePrice
|
||||
};
|
||||
EodTaskRunner.ExecuteDebugAsync(task).Wait();
|
||||
Assert.IsTrue(task.TaskState == EodTaskState.completed, task.TaskResult);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestReadTrade()
|
||||
{
|
||||
var date = new DateTime(2020, 07, 01);
|
||||
var eodArr = new YLContext().eod_trade.Where(O => O.ValueDate == date).ToArray();
|
||||
var tradeArr = eodArr.Select(O => O.trade).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GetFixingString 测试
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetFixingString()
|
||||
{
|
||||
var underlyingCode = "A00";
|
||||
var settlementType = 1;
|
||||
var futurePriceList = new YLContext().eod_commodity_future_price
|
||||
.Where(e => e.UnderlyingCode == underlyingCode)
|
||||
//.Where(e => e.ValueDate >= startDate)
|
||||
//.Where(e => e.ValueDate >= exerciseDate)
|
||||
.Select(e => new
|
||||
{
|
||||
e.ValueDate,
|
||||
e.ClosePrice,
|
||||
e.SettlePrice,
|
||||
e.ReferencePrice
|
||||
}).ToList();
|
||||
|
||||
var query = from e in futurePriceList
|
||||
orderby e.ValueDate
|
||||
select e.ValueDate + "," + GetPrice(settlementType, e.ClosePrice, e.SettlePrice, e.ReferencePrice);
|
||||
|
||||
var fixing = string.Join(";", query.ToArray());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// GetFixingString 测试
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void ClientBalanceCalc()
|
||||
{
|
||||
var request = new EodSettlementRequest(GetOptUser())
|
||||
{
|
||||
VolType = null,
|
||||
UseClosePrice = true,
|
||||
ClientIds = null,
|
||||
SettleDate = DateTime.Today
|
||||
};
|
||||
CancellationTokenSource cancellationTokenSource;
|
||||
EodSettlementContextV2 _context;
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
var settlementConfig = new SettlementConfig
|
||||
{
|
||||
Version = "V1",
|
||||
CalcPnlExplain = false,
|
||||
PriceType = 3,
|
||||
SupportPart = false,
|
||||
VolTypes = "持仓,开仓,对冲,光证,BidAskVol"
|
||||
};
|
||||
_context = new EodSettlementContextV2(request, settlementConfig, cancellationTokenSource.Token);
|
||||
new EodClientBalanceCalc(_context).ClientBalanceCalc();
|
||||
}
|
||||
|
||||
private double GetPrice(int settlementType, double closePrice, double settlePrice, double? referencePrice)
|
||||
{
|
||||
var price = closePrice;
|
||||
if (settlementType == (int)SettlementTypeEnum.SettlePrice)
|
||||
{
|
||||
price = settlePrice;
|
||||
}
|
||||
else if (settlementType == (int)SettlementTypeEnum.ReferencePrice)
|
||||
{
|
||||
price = referencePrice ?? closePrice;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
public enum SettlementTypeEnum
|
||||
{
|
||||
|
||||
ClosePrice = 0,
|
||||
|
||||
SettlePrice = 1,
|
||||
|
||||
|
||||
ReferencePrice = 2,
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestDividend()
|
||||
{
|
||||
var service = new DividendService(OptUserInfo.UnitTestUser);
|
||||
|
||||
var info = new ex_dividend_info()
|
||||
{
|
||||
UnderlyingCode = "002043.SZ",
|
||||
ExDividendDate = new DateTime(2020, 7, 6),
|
||||
GiveCashAmount = 2.5,
|
||||
GiveShareAmount = 0,
|
||||
RationedSharesAmount = 0,
|
||||
RationedSharesPrice = 0,
|
||||
};
|
||||
var price = service.GetPrice(8.8, info);
|
||||
Assert.IsTrue((price - 8.6126) < 1e-4);
|
||||
|
||||
info = new ex_dividend_info()
|
||||
{
|
||||
UnderlyingCode = "600406.SH",
|
||||
ExDividendDate = new DateTime(2020, 7, 8),
|
||||
GiveCashAmount = 2.9,
|
||||
GiveShareAmount = 0,
|
||||
RationedSharesAmount = 0,
|
||||
RationedSharesPrice = 0,
|
||||
};
|
||||
price = service.GetPrice(20.1893, info);
|
||||
Assert.IsTrue((price - 19.9785) < 1e-4);
|
||||
|
||||
info = new ex_dividend_info()
|
||||
{
|
||||
UnderlyingCode = "600406.SH",
|
||||
ExDividendDate = new DateTime(2020, 7, 8),
|
||||
GiveCashAmount = 2.9,
|
||||
GiveShareAmount = 0,
|
||||
RationedSharesAmount = 0,
|
||||
RationedSharesPrice = 0,
|
||||
};
|
||||
price = service.GetPrice(19.9454, info);
|
||||
Assert.IsTrue((price - 19.7371) < 1e-4);
|
||||
|
||||
info = new ex_dividend_info()
|
||||
{
|
||||
UnderlyingCode = "601021.SH",
|
||||
ExDividendDate = new DateTime(2020, 7, 8),
|
||||
GiveCashAmount = 2.0006,
|
||||
GiveShareAmount = 0,
|
||||
RationedSharesAmount = 0,
|
||||
RationedSharesPrice = 0,
|
||||
};
|
||||
price = service.GetPrice(37.13, info);
|
||||
Assert.IsTrue((price - 36.9776) < 1e-4);
|
||||
|
||||
info = new ex_dividend_info()
|
||||
{
|
||||
UnderlyingCode = "300001.SZ",
|
||||
ExDividendDate = new DateTime(2020, 7, 13),
|
||||
GiveCashAmount = 0.2,
|
||||
GiveShareAmount = 0,
|
||||
RationedSharesAmount = 0,
|
||||
RationedSharesPrice = 0,
|
||||
};
|
||||
price = service.GetPrice(20.381, info);
|
||||
Assert.IsTrue((price - 20.3681) < 1e-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
using Qdp.Pricing.Base.Implementations;
|
||||
using YLErp.Modules.CalculationModule;
|
||||
using YLErp.Modules.EodModule.SettlementModule;
|
||||
using YLErp.QdpModule;
|
||||
|
||||
namespace YLErp.Modules.EodModule
|
||||
{
|
||||
[TestClass]
|
||||
public class EodSettlementTest : UnitTestBase
|
||||
{
|
||||
[TestMethod("收盘估值计算")]
|
||||
public void TestCalcPv()
|
||||
{
|
||||
var settleDate = new DateTime(2021, 4, 27);
|
||||
var predicate = PredicateBuilder.Create<trade>(t => t.TradeNumber == "CW20210016E0002");
|
||||
var otcTrades = new EodSettleDataQueryService(GetOptUser())
|
||||
.GetOtcTrades(settleDate, predicate, out var tradeCashProvider);
|
||||
var td = otcTrades.FirstOrDefault();
|
||||
if (td == null)
|
||||
{
|
||||
Console.WriteLine("没有找到交易");
|
||||
return;
|
||||
}
|
||||
var eodpriceProvider = new YLErp.Modules.DataProviderModule.EodPriceProvider(settleDate);
|
||||
var spotPrice = eodpriceProvider.GetPrice(td.UnderlyingCode, SettlementTypeEnum.ClosePrice);
|
||||
var req = new OptionValueCalcRequest(td.NoRiskRate ?? 0)
|
||||
{
|
||||
correlations = null,//不计算彩虹等多标的期权暂时不需要
|
||||
engineName = null,
|
||||
preciseTimeMode = false, //日终一定是false
|
||||
pricingRequest = QdpPricingRequest.BASIC_GREEKS,
|
||||
spotPrices = new[] { spotPrice }
|
||||
};
|
||||
if (td.TradeType != ConsGlobal.TradeType.CashFlow)
|
||||
{
|
||||
var volProvider = EodVolProviderFactory.GetEodVolProvider(settleDate, "持仓");
|
||||
var vol = volProvider.GetVol(td, spotPrice) ?? ConsGlobal.DefaultVol;
|
||||
req.vols = new[] { vol };
|
||||
}
|
||||
var option = OptionCalculatorV2.GetOptionValueResult(settleDate, td, req, out var underlyings);
|
||||
Console.WriteLine($"[{td.TradeType},{td.TradeNumber},{td.id}] pv:{option.Pv}, delta:{option.Delta}");
|
||||
}
|
||||
|
||||
[TestMethod("测试盈亏分解--当天新开仓的交易")]
|
||||
public void TestCalcPnlExplainV2_NewOtcTradeDeal()
|
||||
{
|
||||
var db = DbContextFactory.GetYLDbContext();
|
||||
|
||||
var td = db.trade.FirstOrDefault(n => n.TradeNumber == "CW20210016C0001");
|
||||
|
||||
YLErp.BLL.tradeBLL.SetFieldsByTradeType(td);
|
||||
|
||||
var pnl = new EodPnl();
|
||||
|
||||
double spot0 = 5910, spot1 = 5911, pv1 = 53796.37;
|
||||
|
||||
var pS0V1Q1T1 = CalcPnlExplainV2(td, new CalcField
|
||||
{
|
||||
spot = spot0,
|
||||
vol = 0.28,
|
||||
dividendRate = 0,
|
||||
riskFreeRate = 0.03,
|
||||
date = new DateTime(2021, 4, 27)
|
||||
}, PricingRequest.Pv | PricingRequest.Delta, x =>
|
||||
{
|
||||
|
||||
});
|
||||
|
||||
if (pS0V1Q1T1 != null)
|
||||
{
|
||||
pnl.PnLVega += NumberHelper.Normalize(pS0V1Q1T1.Pv - ((td.TradeSinglePrice ?? 0) * td.Notional));
|
||||
pnl.PnLDelta += NumberHelper.Normalize(pS0V1Q1T1.Delta * (spot1 - spot0));
|
||||
pnl.PnLGamma += NumberHelper.Normalize(pv1 - pS0V1Q1T1.Pv - pnl.PnLDelta);
|
||||
Console.WriteLine($"pS0V1Q1T1 pv:{pS0V1Q1T1.Pv}, delta:{pS0V1Q1T1.Delta}");
|
||||
}
|
||||
Console.WriteLine("计算失败");
|
||||
}
|
||||
|
||||
//计算pv和delta
|
||||
private static TradeValueResult CalcPnlExplainV2(trade td, CalcField f, PricingRequest pricingRequest
|
||||
, Action<OptionTradeParamBase> paramOverride = null)
|
||||
{
|
||||
td.NoRiskRate = f.riskFreeRate;
|
||||
td.DividendRate = f.dividendRate;
|
||||
|
||||
var req = new OptionValueCalcRequest(f.riskFreeRate)
|
||||
{
|
||||
correlations = null,//不计算彩虹等多标的期权暂时不需要
|
||||
engineName = null,
|
||||
preciseTimeMode = false, //日终一定是false
|
||||
pricingRequest = pricingRequest,
|
||||
spotPrices = new[] { f.spot },
|
||||
vols = new[] { f.vol },
|
||||
ParamOverride = paramOverride
|
||||
};
|
||||
|
||||
return OptionCalculatorV2.GetOptionValueResult(f.date, td, req, out _);
|
||||
}
|
||||
|
||||
class CalcField
|
||||
{
|
||||
//public double pv;
|
||||
|
||||
public DateTime date;
|
||||
|
||||
public double vol;
|
||||
|
||||
public double dividendRate;
|
||||
|
||||
public double spot;
|
||||
|
||||
public double riskFreeRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using YLErp.Configuration;
|
||||
using YLErp.Modules.EodModule.SettlementModule;
|
||||
using YLErp.Modules.TradeDalModule;
|
||||
|
||||
namespace YLErp.Modules.EodModule
|
||||
{
|
||||
[TestClass]
|
||||
public class ExDividendTest
|
||||
{
|
||||
[TestMethod("测试除权除息基础循环处理是否符合预期")]
|
||||
public void Test1()
|
||||
{
|
||||
var startIndex = 0;
|
||||
var priceDic = new Dictionary<DateTime, double> {
|
||||
{new DateTime(2021,1,1),1d },
|
||||
{new DateTime(2021,1,2),1d },
|
||||
{new DateTime(2021,1,3),1d },
|
||||
{new DateTime(2021,1,4),1d },
|
||||
{new DateTime(2021,1,5),1d },
|
||||
{new DateTime(2021,1,6),1d },
|
||||
{new DateTime(2021,1,7),1d },
|
||||
{new DateTime(2021,1,8),1d },
|
||||
{new DateTime(2021,1,9),1d },
|
||||
{new DateTime(2021,1,10),1d },
|
||||
};
|
||||
|
||||
var exDividendInfos = new List<ex_dividend_info> {
|
||||
new ex_dividend_info{ ExDividendDate = new DateTime(2021,1,2)},
|
||||
new ex_dividend_info{ ExDividendDate = new DateTime(2021,1,6)},
|
||||
new ex_dividend_info{ ExDividendDate = new DateTime(2021,1,8)},
|
||||
};
|
||||
|
||||
//日终价格和除权除息信息都按照正序排列
|
||||
//获取除权价格则使用大于日终价格日期的除权信息除权
|
||||
//循环日终价格,如果一个除权日期小于价格日期则被排除掉
|
||||
foreach (var kv in priceDic)
|
||||
{
|
||||
(var date, var price) = (kv.Key, kv.Value);
|
||||
|
||||
Console.WriteLine("===========" + date.ToString("yyyy-MM-dd") + "===========");
|
||||
|
||||
for (var i = startIndex; i < exDividendInfos.Count; i++)
|
||||
{
|
||||
var dividenInfo = exDividendInfos[i];
|
||||
|
||||
//除权日当天的收盘价也需要处理
|
||||
if (date <= dividenInfo.ExDividendDate)
|
||||
{
|
||||
Console.WriteLine(dividenInfo.ExDividendDate.Value.ToString("yyyy-MM-dd"));
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestEodDividend()
|
||||
{
|
||||
var userInfo = OptUserInfo.UnitTestUser;
|
||||
using var db = DbContextFactory.GetYLDbContext();
|
||||
var eodDate = new DateTime(2021, 06, 04);
|
||||
var trades = db.eod_trade.Where(et => et.ValueDate == eodDate && !ConsTrade.TradeCompleteStatus.Contains(et.TradeStatus))
|
||||
.ToArray().Select(O => O.trade).ToList();
|
||||
var tradeIds = trades.Select(O => O.id);
|
||||
var parentTradeIds = trades.Where(O => O.ParentTradeId > 0 && !tradeIds.Contains(O.ParentTradeId)).Select(O => O.ParentTradeId).ToHashSet();
|
||||
if (parentTradeIds.Any())
|
||||
{
|
||||
var parentTrades = new TradeDalService(userInfo).GetTradeOrEodTrade(parentTradeIds, eodDate);
|
||||
trades.AddRange(parentTrades);
|
||||
}
|
||||
var request = new EodSettlementRequest(userInfo) { SettleDate = eodDate };
|
||||
var context = new EodSettlementContextV2(request, new SettlementConfig { }, CancellationToken.None);
|
||||
new EodDividenService(context).Execute(trades);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using Newtonsoft.Json;
|
||||
using YLErp.BLL.EodSettlement;
|
||||
|
||||
namespace YLErp.Modules.EodModule.QueryModule
|
||||
{
|
||||
[TestClass]
|
||||
public class TestEodTradePositionApiService
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestInfoAll()
|
||||
{
|
||||
var req = new EodSettleInfoRequest
|
||||
{
|
||||
ValueDate = new DateTime(2022, 1, 4)
|
||||
};
|
||||
var context = new EodSettleInfoQueryContext(OptUserInfo.SystemUser);
|
||||
|
||||
var positionResult = new EodTradePositionApiService(context).GetEodPositions(req);
|
||||
var closeResult = new EodCloseInfoQueryService(context).GetEodCloseInfoList(req.ValueDate);
|
||||
|
||||
var clientIds = context.GetClientIds();
|
||||
|
||||
var balanceResult = ClientBalanceUtility.GetClientBanlances(
|
||||
clientIdList: clientIds,
|
||||
startDate: DateTime.MinValue,
|
||||
endDate: req.ValueDate,
|
||||
IsGetOuterMarginGap: false,
|
||||
IsClientBalanceGap: false,
|
||||
ParentFlag: false,
|
||||
clientDataSource: context);
|
||||
|
||||
var result = new
|
||||
{
|
||||
positionResult.OptionPositions,
|
||||
positionResult.SwapPositions,
|
||||
positionResult.ForwardPositions,
|
||||
CloseInfos = closeResult,
|
||||
AccountInfos = balanceResult
|
||||
};
|
||||
|
||||
//var result = new { d = 1.2222222255555555555 };
|
||||
|
||||
var serializeSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
|
||||
serializeSettings.Converters ??= new List<JsonConverter>();
|
||||
serializeSettings.Converters.Add(new DoubleJsonWriteConverter(2, 8));
|
||||
|
||||
var json = JsonConvert.SerializeObject(result, serializeSettings);
|
||||
|
||||
Assert.IsNotNull(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user