I get the following Json output from url:
{
"Meta Data": {
"1. Information": "FX Intraday (5min) Time Series",
"2. From Symbol": "USD",
"3. To Symbol": "TRY",
"4. Last Refreshed": "2020-12-18 21:55:00",
"5. Interval": "5min",
"6. Output Size": "Full size",
"7. Time Zone": "UTC"
},
"Time Series FX (5min)": {
"2020-12-18 21:55:00": {
"1. open": "7.6181",
"2. high": "7.6256",
"3. low": "7.6181",
"4. close": "7.6181"
},
"2020-12-18 21:50:00": {
"1. open": "7.6232",
"2. high": "7.6244",
"3. low": "7.6181",
"4. close": "7.6181"
},
"2020-12-18 21:45:00": {
"1. open": "7.6244",
"2. high": "7.6244",
"3. low": "7.6208",
"4. close": "7.6232"
},
"2020-12-18 21:40:00": {
"1. open": "7.6234",
"2. high": "7.6262",
"3. low": "7.6201",
"4. close": "7.6244"
},
.
.
.
} }
I need to sort the 'Time Series FX(5min)' values by the keys (date) in reverse order , so the first position has the latest date time. Then I want to extact the first (latest) 288 elements.
What I need in the returned list(s) is only the date time and the value of '4. close'
for example something like this:
list<String> Date_time = [2020-12-18 21:55:00, 2020-12-18 21:50:00, 2020-12-18 21:45:00,...]
list<double> values = [7.6181, 7.6181, 7.6232,...]
Here is part of the code:
void fetchDayValues() async {
final response = await http.get(
'https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol=' +
symbol.substring(0, 3) +
'&to_symbol=' +
symbol.substring(4) +
'&interval=5min&outputsize=full&apikey=NS8IP79OIRVVH7Q0');
if (response.statusCode == 200) {
final jsonInput = json.decode(response.body) as Map;
final data = jsonInput["Time Series FX (5min)"] as Map;
}
}
I looked at other answers but cannot find a solution to my problem. How to do it? Thanks
This code sorts the data by the date. It uses string comparison for simplicity.
You can try it on Dartpad.
import 'dart:convert';
void main() {
final raw_string = '''{"Time Series FX (5min)": {
"2020-12-18 21:50:00": {
"1. open": "7.6232",
"2. high": "7.6244",
"3. low": "7.6181",
"4. close": "7.6181"
},
"2020-12-18 21:55:00": {
"1. open": "7.6181",
"2. high": "7.6256",
"3. low": "7.6181",
"4. close": "7.6181"
},
"2020-12-18 21:40:00": {
"1. open": "7.6234",
"2. high": "7.6262",
"3. low": "7.6201",
"4. close": "7.6244"
},
"2020-12-18 21:45:00": {
"1. open": "7.6244",
"2. high": "7.6244",
"3. low": "7.6208",
"4. close": "7.6232"
}}}''';
final decoded = jsonDecode(raw_string)["Time Series FX (5min)"] as Map;
final sortedKeys = decoded.keys.toList()..sort((a,b)=> b.toString().compareTo(a.toString()));
final sortedValues = sortedKeys.map((k)=> decoded[k]["4. close"]).toList();
print(sortedKeys);
print(sortedValues);
}
Related
I encountered the below message on "anonymous closure" in the TimeSeriesAdjusted.fromJson which I think may be the issue but I could not figure where may have gone wrong.
[VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: type 'Null' is not a subtype of type 'String'
#0 new PriceData.fromJson (package:flutter_app_watchlist/model/TimeSeriesAdjusted.dart:60:28)
#1 new TimeSeriesAdjusted.fromJson. *****anonymous closure>** (package:flutter_app_watchlist/model/TimeSeriesAdjusted.dart:87:116)
#2 MapMixin.map (dart:collection/maps.dart:170:28)
#3 new TimeSeriesAdjusted.fromJson (package:flutter_app_watchlist/model/TimeSeriesAdjusted.dart:87:62)
#4 getData (package:flutter_app_watchlist/main.dart:21:52)
*****asynchronous suspension>**
Below is the time series json (saved as data.json in folder assets) which I would like to parse.
{
"Meta Data": {
"1. Information": "Daily Time Series with Splits and Dividend Events",
"2. Symbol": "IBM",
"3. Last Refreshed": "2021-06-07",
"4. Output Size": "Compact",
"5. Time Zone": "US/Eastern"
},
"Time Series (Daily)": {
"2021-06-07": {
"1. open": "147.55",
"2. high": "148.74",
"3. low": "147.17",
"4. close": "148.02",
"5. adjusted close": "148.02",
"6. volume": "3462712",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0"
},
"2021-06-04": {
"1. open": "146.0",
"2. high": "147.55",
"3. low": "145.76",
"4. close": "147.42",
"5. adjusted close": "147.42",
"6. volume": "3117905",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0"
},
"2021-06-03": {
"1. open": "144.91",
"2. high": "145.88",
"3. low": "144.04",
"4. close": "145.55",
"5. adjusted close": "145.55",
"6. volume": "4130741",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0"
},
"2021-06-02": {
"1. open": "144.62",
"2. high": "145.75",
"3. low": "144.11",
"4. close": "145.72",
"5. adjusted close": "145.72",
"6. volume": "2786916",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0"
},
"2021-06-01": {
"1. open": "145.0",
"2. high": "145.83",
"3. low": "143.75",
"4. close": "144.19",
"5. adjusted close": "144.19",
"6. volume": "2417455",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0"
}
}
}
Below are the codes:
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;
getData() async {
String data = await rootBundle.loadString('assets/data.json');
TimeSeriesAdjusted jsonData = TimeSeriesAdjusted.fromJson(json.decode(data));
print(jsonData.toString());
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
getData();
} // main
class TimeSeriesMetaData {
final String information; // "1. Information": "Daily Time Series with Splits and Dividend Events"
final String symbol; // "2. Symbol": "IBM"
final String lastRefreshed; // "3. Last Refreshed": "2021-06-07"
final String outputSize; // "4. Output Size": "Compact"
final String timezone; // "5. Time Zone": "US/Eastern"
TimeSeriesMetaData({
required this.information,
required this.symbol,
required this.lastRefreshed,
required this.outputSize,
required this.timezone});
factory TimeSeriesMetaData.fromJson(dynamic json) {
return TimeSeriesMetaData(
information: json["1. Information"],
symbol: json["2. Symbol"],
lastRefreshed: json["3. Last Refreshed"],
outputSize: json["4. Output Size"],
timezone: json["5. Time Zone"]);
} // factory TimeSeriesMetaData.fromJson
#override
String toString() {
return 'TimeSeriesMetaData: {1. Information = $information, '
'2. Symbol = $symbol, '
'3. Last Refreshed = $lastRefreshed, '
'4. Output Size = $outputSize, '
'5. Time Zone = $timezone, }';
} // toString
} // class TimeSeriesMetaData
class PriceData {
final String open; // "1. open": "147.55"
final String high; // "2. high": "148.74"
final String low; // "3. low": "147.17"
final String close; // "4. close": "148.02"
final String adjustedClose; // "5. adjusted close": "148.02"
final String volume; // "6. volume": "3462712"
final String dividendAmount; // "7. dividend amount": "0.0000"
final String splitCoefficient; // "8. split coefficient": "1.0"
PriceData({
required this.open,
required this.high,
required this.low,
required this.close,
required this.adjustedClose,
required this.volume,
required this.dividendAmount,
required this.splitCoefficient});
factory PriceData.fromJson(dynamic json) {
return PriceData(
open: json["1. open"],
high: json["2. high"],
low: json["3. low"],
close: json["4. close"],
adjustedClose: json["5. adjustedClose"],
volume: json["6. volume"],
dividendAmount: json["7. dividendAmount"],
splitCoefficient: json["8. splitCoefficient"]);
} // factory TimeSeriesMetaData.fromJson
#override
String toString() {
return 'PriceData: {1. open = $open, 2. high = $high, '
'3. low = $low, 4. close = $close, 5. adjustedClose = $adjustedClose, '
'6. volume = $volume, 7. dividendAmount = $dividendAmount, '
'8. splitCoefficient = $splitCoefficient}';
} // toString
} // class TimeSeriesMetaData
class TimeSeriesAdjusted {
final TimeSeriesMetaData timeSeriesMetaData;
final Map<String, PriceData> timeSeriesDaily;
TimeSeriesAdjusted({
required this.timeSeriesMetaData, // security symbol e.g. IBM
required this.timeSeriesDaily, // security type e.g. common stock
});
factory TimeSeriesAdjusted.fromJson(Map<String, dynamic> json) {
return TimeSeriesAdjusted(
timeSeriesMetaData: TimeSeriesMetaData.fromJson(json["Meta Data"]),
timeSeriesDaily: Map.from(json["Time Series (Daily)"]).map((k,v) => MapEntry<String, PriceData>(k, PriceData.fromJson(v))),
);
} // fromJson - extract from Json
#override
String toString() {
//return 'TimeSeriesAdjusted: $timeSeriesMetaData';
return 'TimeSeriesAdjusted: $timeSeriesMetaData, $timeSeriesDaily';
} // toString
} // class TimeSeriesAdjusted
ah... i realised where the mistake lies.. i got the attribute name incorrect in PriceData.fromJson when i called json['xxx]. below corrected for 5, 7, 8
factory PriceData.fromJson(dynamic json) {
return PriceData(
open: json["1. open"],
high: json["2. high"],
low: json["3. low"],
close: json["4. close"],
adjustedClose: json["5. adjusted close"],
volume: json["6. volume"],
dividendAmount: json["7. dividend amount"],
splitCoefficient: json["8. split coefficient"]);
} // factory TimeSeriesMetaData.fromJson
{
"Meta Data": {
"1. Information": "Daily Time Series with Splits and Dividend Events",
"2. Symbol": "IBM",
"3. Last Refreshed": "2020-04-17",
"4. Output Size": "Compact",
"5. Time Zone": "US/Eastern"
},
"Time Series (Daily)": {
"2020-04-17": {
"1. open": "119.3000",
"2. high": "120.3900",
"3. low": "117.9200",
"4. close": "120.1200",
"5. adjusted close": "120.1200",
"6. volume": "4944745",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2020-04-16": {
"1. open": "119.0100",
"2. high": "119.7500",
"3. low": "114.4200",
"4. close": "115.7300",
"5. adjusted close": "115.7300",
"6. volume": "6438128",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
Here is my code
JSONObject json = await timeSeries.getDaily(stock);
var data = json.getJSONMap()["Time Series (Daily)"];
var data2 = Map<String, dynamic>.from(data);
data2.forEach((k, v) => open.add(double.parse(v["1. open"])));
data2.forEach((k, v) => close.add(double.parse(v["4. close"])));
i only want to get the first high, and the first low. 119.300 and 120.390.
The code shown works, but instead of for every V, i want to get just the first one.
Try this
JSONObject json = await timeSeries.getDaily(stock);
var data = json.getJSONMap()["Time Series (Daily)"];
var data2 = Map<String, dynamic>.from(data);
var firstKey = data2.keys.toList()[0];
open.add(data2[firstKey]["1. open"]);
close.add(data2[firstKey]["4. close"]);
While trying to parse a time-series data I found a key field in the JSON data is the timestamp(obviously in string format). But creating a struct for the same beforehand is not possible as I cannot know the timestamp string anyway.
This is how the JSON looks like:
"Time Series (5min)": {
"2020-01-17 16:00:00": {
"1. open": "167.2000",
"2. high": "167.3400",
"3. low": "167.0100",
"4. close": "167.0500",
"5. volume": "1646699"
},
"2020-01-17 15:55:00": {
"1. open": "166.9000",
"2. high": "167.1600",
"3. low": "166.8500",
"4. close": "167.1500",
"5. volume": "622999"
},
"2020-01-17 15:50:00": {
"1. open": "166.7241",
"2. high": "166.9200",
"3. low": "166.7200",
"4. close": "166.8999",
"5. volume": "271723"
}
}
The struct for the some may look like :
type TIMESTAMP struct {
Open string `json:"1. open"`
High string `json:"2. high"`
Low string `json:"3. low"`
Close string `json:"4. close"`
Volumn string `json:"5. volumn"`
}
type TIMESERIES struct {
TimeStamp TIMESTAMP `json:""` //DON'T KNOW HOW TO IMPLEMENT THIS
}
How to handle such a situation? Is there any Go struct tag for the same?
Keys like 2020-01-17 16:00:00 seems to by dynamically generated and are not fixed, so you can use map for arbitary keys like this
package main
import (
"fmt"
"encoding/json"
)
type TIMESTAMP struct {
Open string `json:"1. open"`
High string `json:"2. high"`
Low string `json:"3. low"`
Close string `json:"4. close"`
Volumn string `json:"5. volumn"`
}
type TIMESERIES map[string]map[string]TIMESTAMP
func main() {
test := []byte(`{
"Time Series (5min)": {
"2020-01-17 16:00:00": {
"1. open": "167.2000",
"2. high": "167.3400",
"3. low": "167.0100",
"4. close": "167.0500",
"5. volume": "1646699"
},
"2020-01-17 15:55:00": {
"1. open": "166.9000",
"2. high": "167.1600",
"3. low": "166.8500",
"4. close": "167.1500",
"5. volume": "622999"
},
"2020-01-17 15:50:00": {
"1. open": "166.7241",
"2. high": "166.9200",
"3. low": "166.7200",
"4. close": "166.8999",
"5. volume": "271723"
}
}
}`)
var response TIMESERIES
if err := json.Unmarshal(test, &response); err != nil {
fmt.Println(err)
return
}
fmt.Printf("%+v", response)
}
I am trying to parse json and things are not working quite correctly...
I have this json code, which from some stock information retrieval api:
{
"Meta Data": {
"1. Information": "Daily Time Series with Splits and Dividend Events",
"2. Symbol": "UNG",
"3. Last Refreshed": "2018-01-29",
"4. Output Size": "Full size",
"5. Time Zone": "US/Eastern"
},
"Time Series (Daily)": {
"2018-01-29": {
"1. open": "26.0700",
"2. high": "26.9000",
"3. low": "26.0400",
"4. close": "26.8400",
"5. adjusted close": "26.8400",
"6. volume": "7056837",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-01-26": {
"1. open": "26.7500",
"2. high": "27.0000",
"3. low": "26.6700",
"4. close": "26.7700",
"5. adjusted close": "26.7700",
"6. volume": "6329877",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-01-25": {
"1. open": "26.2800",
"2. high": "26.7600",
"3. low": "25.9800",
"4. close": "26.1700",
"5. adjusted close": "26.1700",
"6. volume": "6235136",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-01-24": {
"1. open": "26.0500",
"2. high": "26.4400",
"3. low": "25.5400",
"4. close": "25.7200",
"5. adjusted close": "25.7200",
"6. volume": "7197720",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-01-23": {
"1. open": "25.6200",
"2. high": "26.4200",
"3. low": "25.4400",
"4. close": "25.9400",
"5. adjusted close": "25.9400",
"6. volume": "7943240",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-01-22": {
"1. open": "24.6500",
"2. high": "24.8800",
"3. low": "24.5800",
"4. close": "24.8500",
"5. adjusted close": "24.8500",
"6. volume": "3674144",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-01-19": {
"1. open": "25.0000",
"2. high": "25.3200",
"3. low": "24.7250",
"4. close": "24.8600",
"5. adjusted close": "24.8600",
"6. volume": "4292913",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
}
I created the following classes because I wanted to be able to deserialize the json into the following objects...
Public Class JJSON
Public json As JSON_Container
End Class
Public Class MetaData
<JsonProperty(PropertyName:="1. Information")>
Public Property information
<JsonProperty(PropertyName:="2. Symbol")>
Public Property symbol
<JsonProperty(PropertyName:="3. Last Refreshed")>
Public Property last_refreshed
<JsonProperty(PropertyName:="4. Output Size")>
Public Property output_size
<JsonProperty(PropertyName:="5. Time Zone")>
Public Property time_zone
End Class
Public Class JSON_Container
<JsonProperty(PropertyName:="Meta Data")>
Private Meta As MetaData
<JsonProperty(PropertyName:="Time Series (Daily)")>
Public Time_Series_Daily As StockDate
End Class
Public Class StockDate
Public Dt As List(Of StockInfo)
End Class
Public Class StockInfo
<JsonProperty(PropertyName:="1. open")>
Public Property open As String
<JsonProperty(PropertyName:="2. high")>
Public Property high As String
<JsonProperty(PropertyName:="3. low")>
Public Property low As String
<JsonProperty(PropertyName:="4. close")>
Public Property close As String
<JsonProperty(PropertyName:="5. adjusted close")>
Public Property adjusted_close As String
<JsonProperty(PropertyName:="6. volume")>
Public Property volume As String
<JsonProperty(PropertyName:="7. dividend amount")>
Public Property dividend_amount As String
<JsonProperty(PropertyName:="8. split coefficient")>
Public Property split_coefficient As String
End Class
And, when I execute this code:
Dim obj1 = JsonConvert.DeserializeObject(Of JSON_Container)(json)
It works partially since only the "Meta Data" gets parsed correctly. I have tried everything I could think of at this point.
Any help would be appreciated..
I created the following code that serializes/deserializes JSON literals: http://www.vbforums.com/showthread.php?858459-Serialize-and-Deserialize-JSON
If you used the code, then you use the following:
Dim obj As JSON.Object = JSON.Convert.Deserialize(literal)
Dim meta_data As JSON.Object = obj.Values.Item("Meta Data")
Dim time_series As JSON.Object = obj.Values.Item("Time Series (Daily)")
Dim dates() As JSON.Object = time_series.Values.Select(Function(kvp) DirectCast(kvp.Value, JSON.Object)).ToArray()
{
"Meta Data": {
"1. Information": "Daily Prices (open, high, low, close) and Volumes",
"2. Symbol": "FB",
"3. Last Refreshed": "2017-08-23 16:00:00",
"4. Output Size": "Compact",
"5. Time Zone": "US/Eastern"
},
"Time Series (Daily)": {
"2017-08-23 16:00:00": {
"1. open": "168.8400",
"2. high": "169.3600",
"3. low": "168.2000",
"4. close": "168.7100",
"5. volume": "8198515"
},
"2017-08-22": {
"1. open": "168.2800",
"2. high": "169.8700",
"3. low": "167.1500",
"4. close": "169.6400",
"5. volume": "11333260"
},
"2017-08-21": {
"1. open": "167.1600",
"2. high": "168.0000",
"3. low": "165.8200",
"4. close": "167.7800",
"5. volume": "11880823"
},
"2017-08-18": {
"1. open": "166.8400",
"2. high": "168.6700",
"3. low": "166.2100",
"4. close": "167.4100",
"5. volume": "14933261"
},
"2017-08-17": {
"1. open": "169.3400",
"2. high": "169.8600",
"3. low": "166.8500",
"4. close": "166.9100",
"5. volume": "16791591"
},
"2017-08-16": {
"1. open": "171.2500",
"2. high": "171.3800",
"3. low": "169.2400",
"4. close": "170.0000",
"5. volume": "15580549"
}
}
}
My problem is how can I get all the information (ex: 4.close) from the JSON date if the days (ex: 2017-08-02) are constantly changing.
So far in my project I can only get a data of a certain date.
func fetchStockDataCalendar() {
let url = URL(string: "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=\(symbol)&apikey=\(apiKey)")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print ("ERROR")
} else {
if let content = data {
do {
//Array
let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if let Time = myJson["Time Series (Daily)"] as? NSDictionary {
if let Day = Time["2017-06-21"] as? NSDictionary {
if let CloseStockData = Day["4. close"] as? String {
print("2017-06-21 CloseStock-> \(CloseStockData)$")
}
}
}
} catch {
print(error.localizedDescription)
}
}
}
}
task.resume()
}
Here is your func with the above code but as an NSDictionary. My console is showing all of the closes.
2017-10-24 CloseStock-> 256.5600
2018-02-22 CloseStock-> 270.4000
func fetchStockDataCalendar() {
let url = URL(string: "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=\("SPY")&apikey=\(alphaApiKey)")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print ("ERROR")
} else {
if let content = data {
do {
let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if let time = myJson["Time Series (Daily)"] as? NSDictionary {
for (key, value) in time {
if let value = value as? Dictionary<String, String> {
if let close = value["4. close"] {
print("\(key) CloseStock-> \(close)")
}
}
}
}
} catch {
print(error.localizedDescription)
}
}
}
}
task.resume()
}
Use a for loop to iterate over the dictionary keys and values like this:
if let time = myJson["Time Series (Daily)"] {
for (key, value) in time {
if let close = value["4. close"] {
print("\(key) CloseStock-> \(close)")
}
}
}
Based on your comments I've added this too
if let time = myJson["Time Series (Daily)"] {
for (key, value) in time {
if let value = value as? Dictionary<String, String> {
if let close = value["close"] {
print("\(key) CloseStock-> \(close)")
}
}
}
}