无法将 DateFrame JSON 解析为 C#

Unable to parse DateFrame JSON into C#

我无法将下面的 JSON 文件解析为相应的 class。它由 pandas' DateFrame 导出。我无法解析它的原因是格式有点奇怪。我该怎么做?

private static List<BacktestResult> LoadFromJson(string path)
{
    var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);

    if (!File.Exists(filePath))
        throw new FileNotFoundException($"The data file '{filePath}' was not found.");

    var data = File.ReadAllText(filePath);
    var deserializedData = JsonConvert.DeserializeObject<List<BacktestResult>>(data);

    return deserializedData;
}

它有效,但我希望 Pair 在没有 / 的情况下被解析,并且 SellReason 被解析为 SellType (枚举)。 OpenDate和CloseDate不能直接解析为DateTime,因为要通过下面的DateTimeOffset.FromUnixTimeMilliseconds(OpenDate).

进行转换
public class BacktestResult
{
    public string Pair { get; set; }
    public decimal ProfitPercentage { get; set; }
    public decimal ProfitAbs { get; set; }
    public decimal OpenRate { get; set; }
    public decimal CloseRate { get; set; }
    public DateTime OpenDate { get; set; }
    public DateTime CloseDate { get; set; }
    public decimal OpenFee { get; set; }
    public decimal CloseFee { get; set; }
    public decimal Amount { get; set; }
    public decimal TradeDuration { get; set; }
    public bool OpenAtEnd { get; set; }
    public SellType SellReason { get; set; }
}

public enum SellType
{
    None,
    TakeProfit,
    StopLoss,
    TrailingStopLoss,
    SellSignal
}

JSON:

https://pastebin.com/KHH2fgm7(pastebin 因为它超出了 SO 限制)

编辑:

感谢@Panagiotis Kanavos,JSON 现在看起来像:https://pastebin.com/jNdRC23k。我将其从 pandas 导出如下:results.to_json(r'dateFrame_json.json', orient='split').

public class BacktestResult2
{
    [JsonProperty("pair")]
    public string Pair { get; set; }

    [JsonProperty("profit_percent")]
    public decimal ProfitPercentage { get; set; }

    [JsonProperty("profit_abs")]
    public decimal ProfitAbs { get; set; }

    [JsonProperty("open_rate")]
    public decimal OpenRate { get; set; }

    [JsonProperty("close_rate")]
    public decimal CloseRate { get; set; }

    [JsonProperty("open_date")]
    public long OpenDate { get; set; }

    [JsonProperty("close_date")]
    public long CloseDate { get; set; }

    [JsonProperty("open_fee")]
    public decimal OpenFee { get; set; }

    [JsonProperty("close_fee")]
    public decimal CloseFee { get; set; }

    [JsonProperty("amount")]
    public decimal Amount { get; set; }

    [JsonProperty("trade_duration")]
    public decimal TradeDuration { get; set; }

    [JsonProperty("sell_reason")]
    public SellReason SellReason { get; set; }
}

public partial class SellReason
{
    [JsonProperty("name")]
    public string Name { get; set; }
}

private static List<BacktestResult> LoadFromJson(string path)
{
    var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);

    if (!File.Exists(filePath))
        throw new FileNotFoundException($"The JSON file '{filePath}' was not found.");

    var data = File.ReadAllText(filePath);

    // results.to_json(r'dateFrame_json.json', orient='split')
    var deserializedData = JsonConvert.DeserializeObject<List<BacktestResult2>>(data);

    return null;
}

BacktestResult class 字段的名称必须与 json 文件字段的名称完全相同。

如果那是你的整个 json 文件,那么我会建议重塑你的数据结构以使用 Dictionary<string, T>

public class BacktestResult
{
    public Dictionary<string, string> Pair { get; set; }
    public Dictionary<string, decimal> ProfitPercentage { get; set; }
    public Dictionary<string, decimal> ProfitAbs { get; set; }
    public Dictionary<string, decimal> OpenRate { get; set; }
    public Dictionary<string, decimal> CloseRate { get; set; }
    public Dictionary<string, DateTime> OpenDate { get; set; }
    public Dictionary<string, DateTime> CloseDate { get; set; }
    public Dictionary<string, decimal> OpenFee { get; set; }
    public Dictionary<string, decimal> CloseFee { get; set; }
    public Dictionary<string, decimal> Amount { get; set; }
    public Dictionary<string, decimal> TradeDuration { get; set; }
    public Dictionary<string, bool> OpenAtEnd { get; set; }
    public Dictionary<string, Dictionary<string, string>> SellReason { get; set; }
}

然后你只需要将它反序列化为一个对象,就像这样:

BacktestResult result = JsonConvert.DeserializeObject<BacktestResult>(content);

rextester

上测试