我想重新组织对象列表,并按并排视图中的输入日期对它们进行分类,以便我可以按天比较不同工具的交易。 所以这个视图需要重新组织
如下
我创建的唯一逻辑是使用发电机对象字典。然而,它迫使我每次都定义列。有没有更有效的方法?
linqpad 分享中的代码。 linqpad 分享
void Main()
{
List<STSmyTrade> testoj = new List<STSmyTrade>(); // object 1
STSmyTrade a1 = new STSmyTrade();
a1.instrument = "eurusd";
a1.entryPrice = 3;
a1.entryTime = DateTime.Now.AddDays(1);
testoj.Add(a1);
STSmyTrade a2 = new STSmyTrade();
a2.instrument = "eurusd";
a2.entryPrice = 6;
a2.entryTime = DateTime.Now.AddDays(2);
testoj.Add(a2);
STSmyTrade a3 = new STSmyTrade();
a3.instrument = "audusd";
a3.entryPrice = 3;
a3.entryTime = DateTime.Now;
testoj.Add(a3);
STSmyTrade a4 = new STSmyTrade();
a4.instrument = "audusd";
a4.entryPrice = 6;
a4.entryTime = DateTime.Now.AddDays(2);
testoj.Add(a4);
testoj.Dump();
// need to compare the 2 instruments sorted by date
Dictionary<DateTime, ExpandoObject> analysiscompare = new Dictionary<DateTime, ExpandoObject>();
foreach (STSmyTrade t in testoj ) // loop first time comparing before and after
{
dynamic eo;
if (!analysiscompare.Keys.Contains(t.entryTime.Date))// if i dont have a record in the dictionary object, create it.
{
eo = new ExpandoObject();
eo.day=t.entryTime.Date.ToString("yyyy-MM-dd");// just assign the day.
eo.eurusdentryTime = null;
eo.eurusdentryPrice = null;
eo.audusdentryTime = null;
eo.audusdentryPrice = null;
analysiscompare.Add(t.entryTime.Date, eo);
}
//dynamic eo;
eo = analysiscompare[t.entryTime.Date];
switch (t.instrument)
{
case "eurusd":
eo.eurusdentryTime = t.entryTime;
eo.eurusdentryPrice = t.entryPrice;
break;
case "audusd":
eo.audusdentryTime = t.entryTime;
eo.audusdentryPrice = t.entryPrice;
break;
}
}
analysiscompare.Values.ToList().Dump("side_by_side_view");
}
class STSmyTrade
{
public DateTime entryTime { get; set; }
public string instrument { get; set; }
public double entryPrice { get; set; }
}
我可以完成这项工作的唯一方法是创建一个映射到每个唯一对象(audusd、eurusd)的自定义列。然而,这是不可扩展的。
假设上课:
class STSmyTrade
{
public string instrument;
public decimal entryPrice;
public DateTime entryTime;
}
我们为结果创建一个新类:
class SideBySideEntry
{
public DateOnly day;
public TimeOnly? eurUsdTime, audUsdTime;
public decimal? eurUsdPrice, audUsdPrice;
}
我们可以使用对象和集合初始化器来初始化测试:
var testoj = new List<STSmyTrade> {
new() {
instrument = "eurusd",
entryPrice = 3,
entryTime = DateTime.Now.AddDays(1)
},
new() {
instrument = "eurusd",
entryPrice = 6,
entryTime = DateTime.Now.AddDays(2)
},
new() {
instrument = "audusd",
entryPrice = 3,
entryTime = DateTime.Now
},
new() {
instrument = "audusd",
entryPrice = 6,
entryTime = DateTime.Now.AddDays(2)
}
};
我们可以使用 LINQ 和一些模式匹配来转换这样的条目:
var sideBySideList = testoj
.GroupBy(x => DateOnly.FromDateTime(x.entryTime))
.Select(g => new SideBySideEntry {
day = g.Key,
eurUsdTime = g.FirstOrDefault(e => e.instrument == "eurusd")
is { entryTime: var dt } ? TimeOnly.FromDateTime(dt) : null,
eurUsdPrice = g.FirstOrDefault(e => e.instrument == "eurusd")?.entryPrice,
audUsdTime = g.FirstOrDefault(e => e.instrument == "audusd")
is { entryTime: var dt2 } ? TimeOnly.FromDateTime(dt2) : null,
audUsdPrice = g.FirstOrDefault(e => e.instrument == "audusd")?.entryPrice,
})
.OrderBy(x => x.day)
.ToList();
此控制台测试...
foreach (var e in sideBySideList) {
Console.WriteLine($"{e.day} | {e.eurUsdTime,8} | {e.eurUsdPrice,8:n2} | {e.audUsdTime,8} | {e.audUsdPrice,8:n2}");
}
...产生以下输出:
30.12.2023 | | | 18:05 | 3.00
31.12.2023 | 18:05 | 3.00 | |
01.01.2024 | 18:05 | 6.00 | 18:05 | 6.00