无法解析 OHCLV 数据
Unable to parse OHCLV data
我无法将 OHCLV 数据从 JSON 解析为 List<Candle>
。
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Models.Candle' 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 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 '[0]', line 1, position 2.'
它只允许我用 List<List<double>>
来做。我怎样才能做到这一点?
[[1604666100000,0.02585,0.02585,0.02577,0.02577,2346260.5],[1604666400000,0.02577,0.02577,0.02571,0.02572,3853038.7000000002],[1604666700000,0.02572,0.02573,0.02568,0.02573,2525735.5],[1604667000000,0.02573,0.02578,0.02573,0.02574,2519284.3999999999],[1604667300000,0.02575,0.02582,0.02574,0.02578,1463562.6000000001],[1604667600000,0.02578,0.02587,0.02577,0.02585,2074134.3]]
代码:
public class Candle
{
public DateTime OpenTime { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Open { get; set; }
public decimal Close { get; set; }
public decimal Volume { get; set; }
}
public static List<Candle> LoadCandles(string path)
{
var basePath = AppDomain.CurrentDomain.BaseDirectory;
var filePath = Path.Combine(basePath, path);
if (!File.Exists(filePath))
throw new FileNotFoundException($"The .json '{filePath}' file used to load the candles from was not found.");
var data = File.ReadAllText(filePath);
//var candles3 = JsonConvert.DeserializeObject<List<List<double>>>(data); // this one works
var candles = JsonConvert.DeserializeObject<List<Candle>>(data);
return candles;
}
也许 select 就足够了 :
var data = JsonConvert.DeserializeObject<List<List<decimal>>>(json);
var candles = data.Select(d => new Candle {OpenTime = new DateTime((long)d[0]), High = d[1], ... }).ToList();
如果你真的想直接反序列化到 Candle,你可以使用自定义转换器:
class Program
{
static void Main(string[] args)
{
var json = "[[1604666100000,0.02585,0.02585,0.02577,0.02577,2346260.5],[1604666400000,0.02577,0.02577,0.02571,0.02572,3853038.7000000002],[1604666700000,0.02572,0.02573,0.02568,0.02573,2525735.5],[1604667000000,0.02573,0.02578,0.02573,0.02574,2519284.3999999999],[1604667300000,0.02575,0.02582,0.02574,0.02578,1463562.6000000001],[1604667600000,0.02578,0.02587,0.02577,0.02585,2074134.3]]";
var candles = JsonConvert.DeserializeObject<List<Candle>>(json);
}
}
[JsonConverter(typeof(CandleConverter))]
public class Candle
{
public DateTime OpenTime { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Open { get; set; }
public decimal Close { get; set; }
public decimal Volume { get; set; }
}
public class CandleConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
var array = JArray.Load(reader);
return new Candle {
OpenTime = new DateTime(array[0].Value<long>()),
High = array[1].Value<decimal>(),
Low = array[2].Value<decimal>(),
Open = array[2].Value<decimal>(),
Close = array[2].Value<decimal>(),
Volume = array[2].Value<decimal>()
};
}
throw new NotImplementedException();
}
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return false;
}
}
低技术方法
用法
var input = "[[1604666100000,0.02585,0.02585,0.02577,0.02577,2346260.5],[1604666400000,0.02577,0.02577,0.02571,0.02572,3853038.7000000002],[1604666700000,0.02572,0.02573,0.02568,0.02573,2525735.5],[1604667000000,0.02573,0.02578,0.02573,0.02574,2519284.3999999999],[1604667300000,0.02575,0.02582,0.02574,0.02578,1463562.6000000001],[1604667600000,0.02578,0.02587,0.02577,0.02585,2074134.3]]";
var results = JArray
.Parse(input)
.Select(x => new Candle(){
OpenTime = DateTimeOffset.FromUnixTimeMilliseconds(x[0].Value<long>()).DateTime,
Open = x[1].Value<decimal>(),
High = x[2].Value<decimal>(),
Low = x[3].Value<decimal>(),
Close = x[4].Value<decimal>(),
Volume = x[5].Value<decimal>()
}).ToList();
foreach(var item in results)
Console.WriteLine($"Open : {item.Open}, High : {item.High}, Low : {item.Low}, Close : {item.Close}, Volume : {item.Volume}");
输出
Open : 0.02585, High : 0.02585, Low : 0.02577, Close : 0.02577, Volume : 2346260.5
Open : 0.02577, High : 0.02577, Low : 0.02571, Close : 0.02572, Volume : 3853038.7
Open : 0.02572, High : 0.02573, Low : 0.02568, Close : 0.02573, Volume : 2525735.5
Open : 0.02573, High : 0.02578, Low : 0.02573, Close : 0.02574, Volume : 2519284.4
Open : 0.02575, High : 0.02582, Low : 0.02574, Close : 0.02578, Volume : 1463562.6
Open : 0.02578, High : 0.02587, Low : 0.02577, Close : 0.02585, Volume : 2074134.3
我无法将 OHCLV 数据从 JSON 解析为 List<Candle>
。
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Models.Candle' 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 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 '[0]', line 1, position 2.'
它只允许我用 List<List<double>>
来做。我怎样才能做到这一点?
[[1604666100000,0.02585,0.02585,0.02577,0.02577,2346260.5],[1604666400000,0.02577,0.02577,0.02571,0.02572,3853038.7000000002],[1604666700000,0.02572,0.02573,0.02568,0.02573,2525735.5],[1604667000000,0.02573,0.02578,0.02573,0.02574,2519284.3999999999],[1604667300000,0.02575,0.02582,0.02574,0.02578,1463562.6000000001],[1604667600000,0.02578,0.02587,0.02577,0.02585,2074134.3]]
代码:
public class Candle
{
public DateTime OpenTime { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Open { get; set; }
public decimal Close { get; set; }
public decimal Volume { get; set; }
}
public static List<Candle> LoadCandles(string path)
{
var basePath = AppDomain.CurrentDomain.BaseDirectory;
var filePath = Path.Combine(basePath, path);
if (!File.Exists(filePath))
throw new FileNotFoundException($"The .json '{filePath}' file used to load the candles from was not found.");
var data = File.ReadAllText(filePath);
//var candles3 = JsonConvert.DeserializeObject<List<List<double>>>(data); // this one works
var candles = JsonConvert.DeserializeObject<List<Candle>>(data);
return candles;
}
也许 select 就足够了 :
var data = JsonConvert.DeserializeObject<List<List<decimal>>>(json);
var candles = data.Select(d => new Candle {OpenTime = new DateTime((long)d[0]), High = d[1], ... }).ToList();
如果你真的想直接反序列化到 Candle,你可以使用自定义转换器:
class Program
{
static void Main(string[] args)
{
var json = "[[1604666100000,0.02585,0.02585,0.02577,0.02577,2346260.5],[1604666400000,0.02577,0.02577,0.02571,0.02572,3853038.7000000002],[1604666700000,0.02572,0.02573,0.02568,0.02573,2525735.5],[1604667000000,0.02573,0.02578,0.02573,0.02574,2519284.3999999999],[1604667300000,0.02575,0.02582,0.02574,0.02578,1463562.6000000001],[1604667600000,0.02578,0.02587,0.02577,0.02585,2074134.3]]";
var candles = JsonConvert.DeserializeObject<List<Candle>>(json);
}
}
[JsonConverter(typeof(CandleConverter))]
public class Candle
{
public DateTime OpenTime { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Open { get; set; }
public decimal Close { get; set; }
public decimal Volume { get; set; }
}
public class CandleConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
var array = JArray.Load(reader);
return new Candle {
OpenTime = new DateTime(array[0].Value<long>()),
High = array[1].Value<decimal>(),
Low = array[2].Value<decimal>(),
Open = array[2].Value<decimal>(),
Close = array[2].Value<decimal>(),
Volume = array[2].Value<decimal>()
};
}
throw new NotImplementedException();
}
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return false;
}
}
低技术方法
用法
var input = "[[1604666100000,0.02585,0.02585,0.02577,0.02577,2346260.5],[1604666400000,0.02577,0.02577,0.02571,0.02572,3853038.7000000002],[1604666700000,0.02572,0.02573,0.02568,0.02573,2525735.5],[1604667000000,0.02573,0.02578,0.02573,0.02574,2519284.3999999999],[1604667300000,0.02575,0.02582,0.02574,0.02578,1463562.6000000001],[1604667600000,0.02578,0.02587,0.02577,0.02585,2074134.3]]";
var results = JArray
.Parse(input)
.Select(x => new Candle(){
OpenTime = DateTimeOffset.FromUnixTimeMilliseconds(x[0].Value<long>()).DateTime,
Open = x[1].Value<decimal>(),
High = x[2].Value<decimal>(),
Low = x[3].Value<decimal>(),
Close = x[4].Value<decimal>(),
Volume = x[5].Value<decimal>()
}).ToList();
foreach(var item in results)
Console.WriteLine($"Open : {item.Open}, High : {item.High}, Low : {item.Low}, Close : {item.Close}, Volume : {item.Volume}");
输出
Open : 0.02585, High : 0.02585, Low : 0.02577, Close : 0.02577, Volume : 2346260.5
Open : 0.02577, High : 0.02577, Low : 0.02571, Close : 0.02572, Volume : 3853038.7
Open : 0.02572, High : 0.02573, Low : 0.02568, Close : 0.02573, Volume : 2525735.5
Open : 0.02573, High : 0.02578, Low : 0.02573, Close : 0.02574, Volume : 2519284.4
Open : 0.02575, High : 0.02582, Low : 0.02574, Close : 0.02578, Volume : 1463562.6
Open : 0.02578, High : 0.02587, Low : 0.02577, Close : 0.02585, Volume : 2074134.3