0

I'm unable to parse the JSON file below to the corresponding class. It was exported by pandas' DateFrame. The reason I can't parse it, is because the format is a bit weird. How can I do that?

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;
}

It works but I want the Pair to be parsed without the / and SellReason to be parsed as SellType (the enum). OpenDate and CloseDate cannot be parsed directly to DateTime, because they have to be converted through the following 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 because it's exceeds the SO limits)

Edit:

Thanks to @Panagiotis Kanavos, the JSON now looks like: https://pastebin.com/jNdRC23k. I exported it from pandas as following: 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;
}
8
  • IMO you have 2 options. One is to deserialzie it using JsonReader and assign values by hand and the second one is to use Dictionary<string, T> foreach entry on the root object. Commented Jan 25, 2021 at 11:47
  • @Mateusz, would you like to type it as an answer? Commented Jan 25, 2021 at 11:49
  • 1
    Post a sample of the JSON string in the question itself. The question makes little sense as-is. There are no dataframes in JSON, only arrays and objects Commented Jan 25, 2021 at 11:51
  • The Python code would help as well. Pandas uses different well-defined layouts through the orient parameter. Which one are you using? Can you change it to something other JSON libraries can handle? Commented Jan 25, 2021 at 11:55
  • @nop what you linked to could be either the row or column orientation. Which one did you use? You don't need a JsonReader, although it could improve performance. You could use JObject.Parse to parse that JSON string and use eg LINQ to query it, but you still need to know if it's per row or per column Commented Jan 25, 2021 at 12:00

2 Answers 2

1

If that's your whole json file then I would suggest remodeling your datastructures to use 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; }
}

Then you just have to deserialize it as one object, like such:

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

Test this on rextester

Sign up to request clarification or add additional context in comments.

Comments

0

The names of the BacktestResult class fields must be exactly the same as the json file fields.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.