I have following object getting return from one of the API.
{{
"status": "success",
"data": {
"candles": [
[
"2020-11-01T18:30:00+00:00",
1065,
1079.95,
1051.1,
1072.3,
7183119
],
[
"2020-11-02T18:30:00+00:00",
1072,
1079.4,
1057.5,
1062.55,
7204782
],]
}
}}
I want to convert candle data into List<Historical>
Here is what I have tried
foreach (ArrayList item in historicalData["data"]["candles"])
historicals.Add(new Historical(item));
But this gives me following error:
Cannot convert type 'Newtonsoft.Json.Linq.JArray' to 'System.Collections.ArrayList
I have tried using JsonConvert.DeserializeObject to diretly convert the string into the object using following code:
foreach (var item in historicalData["data"]["candles"]) {
var historical = JsonConvert.DeserializeObject<Historical>(item.ToString());
But got this error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'QuantConnect.Brokerages.Zerodha.Messages.Historical' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.
Historical definition:
public struct Historical
{
public Historical(dynamic data)
{
TimeStamp = Convert.ToDateTime(data[0], CultureInfo.InvariantCulture);
Open = Convert.ToDecimal(data[1], CultureInfo.InvariantCulture);
High = Convert.ToDecimal(data[2], CultureInfo.InvariantCulture);
Low = Convert.ToDecimal(data[3], CultureInfo.InvariantCulture);
Close = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture);
Volume = Convert.ToUInt32(data[5], CultureInfo.InvariantCulture);
OI = data.Count > 6 ? Convert.ToUInt32(data[6], CultureInfo.InvariantCulture) : 0;
}
public DateTime TimeStamp { get; }
public decimal Open { get; }
public decimal High { get; }
public decimal Low { get; }
public decimal Close { get; }
public UInt32 Volume { get; }
public UInt32 OI { get; }
}
Is there a correct/elegant way to make it work. Also what I am missing something over here?
Given
{
"status":"success",
"data":{
"candles":[
[
"2020-11-01T18:30:00+00:00",
1065,
1079.95,
1051.1,
1072.3,
7183119
],
[
"2020-11-02T18:30:00+00:00",
1072,
1079.4,
1057.5,
1062.55,
7204782
]
]
}
}
And
public class Historical
{
public DateTime TimeStamp { get; set; }
public decimal Open { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Close { get; set; }
public UInt32 Volume { get; set; }
public UInt32 OI { get; set; }
}
Usage
var jtoken = JToken.Parse(input);
var data = jtoken["data"]["candles"]
.Select(x => new Historical
{
TimeStamp = x[0].Value<DateTime>(),
Open = x[1].Value<decimal>(),
Low = x[2].Value<decimal>(),
High = x[3].Value<decimal>(),
Close = x[4].Value<decimal>()
//...
});
foreach (var item in data)
Console.WriteLine($"{item.TimeStamp},Open {item.Open},Low {item.Low} ...");
Output
2/11/2020 4:30:00 AM, Open 1065, Low 1079.95 ...
3/11/2020 4:30:00 AM, Open 1072, Low 1079.4 ...
Note : there are also many ways to deal with the datatime and how to configure Json.net or TryParse
to give you the results you want. This is example is leaving this up to you and focusing solely on the projection.
If you need this done in the constructor
public struct Historical
{
public Historical(JToken x)
{
TimeStamp = x[0].Value<DateTime>();
Open = x[1].Value<decimal>();
Low = x[2].Value<decimal>();
High = x[3].Value<decimal>();
Close = x[4].Value<decimal>();
...
}
public DateTime TimeStamp { get; }
public decimal Open { get; }
public decimal High { get; }
public decimal Low { get; }
public decimal Close { get; }
...
}
...
var data = jtoken["data"]["candles"].Select(x => new Historical(x));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.