This chart was created and published using charte.ca online editor once, and it is updated and re-published by a script that runs every hour and performs the following tasks:
- obtain stock quotes for specific symbols from Yahoo;
- compare them with the data currently displayed by the chart, and, if the data is different:
- upload new data to the chart;
- update chart subtitle so it reflects the latest update
- re-publish the chart
- Download data
- Put config
- Upload data
- Publish chart
This particular example uses Python as scripting language, but it could be any language or framework capable of performing HTTP requests. The script is scheduled to run every hour on a system integrator's infrastructure. Full source code is below.
import urllib2 import json import sys import time def call_charteca_api(url, method, content_type=None, data=None): opener = urllib2.build_opener(urllib2.HTTPHandler) request = urllib2.Request(url, data=data) request.add_header('api-key', api_key) if content_type != None: request.add_header('Content-Type', content_type) request.get_method = lambda: method return opener.open(request) # Retrieve data as TSV, as it is stored in the datagrid def download_quote_data(symbols, symbol_short_name_map, symbol_long_name_map): data = [["Symbol"],["P/E Ratio"],["Price to book"],["Market cap (billions)"],["Performance today"],["Name"],["Symbol"]] for symbol in symbols: # Yahoo ditched YQL on Nov 2, 2017. Get it right from the website opener = urllib2.build_opener(urllib2.HTTPHandler) req = 'https://finance.yahoo.com/quote/' + symbol request = urllib2.Request(req) request.add_header('Cache-Control', "no-cache") request.get_method = lambda: 'GET' r = opener.open(request).read() i1=0 i1=r.find('root.App.main', i1) i1=r.find('{', i1) i2=r.find("\n", i1) i2=r.rfind(';', i1, i2) jsonstr=r[i1:i2] #load the raw json data into a python data object json_data = json.loads(jsonstr) qss = json_data['context']['dispatcher']['stores']['QuoteSummaryStore'] #pull the values that we are interested in change_sign = "" if float(qss['price']['regularMarketChange']['fmt']) <= 0.0 else "+" data[0].append(symbol_short_name_map[symbol] + ": " + change_sign + qss['price']['regularMarketChange']['fmt']) data[1].append(qss['summaryDetail']['trailingPE']['fmt']) data[2].append(qss['defaultKeyStatistics']['priceToBook']['fmt']) data[3].append(qss['summaryDetail']['marketCap']['fmt']) data[4].append(change_sign+qss['price']['regularMarketChangePercent']['fmt']) data[5].append(symbol_long_name_map[symbol]) data[6].append(symbol) # Print out tab-separated values tsv_data = "" for data_row in data: tsv_data += "\t".join(data_row) + "\n" return tsv_data # Rertrieve existing chart grid data as it is def download_chart_data(charteca_root, api_key, chart_id): print "Downloading existing chart data..." download_response = call_charteca_api(charteca_root + '/chart_integration/data/' + chart_id, "GET") download_response_data = download_response.read() download_response_headers = download_response.info().dict if "content-type" not in download_response_headers: print "Error: no content-type in the response" sys.exit(-1); if "application/json" in download_response_headers["content-type"]: # We got an error print download_response_data sys.exit(-1); if "text/tab-separated-values" not in download_response_headers["content-type"]: # We expected TSV data print " Error: expected TSV data in the response" sys.exit(-1); return download_response_data # Update chart config: change the subtitle to reflect the date def update_chart_title(charteca_root, api_key, chart_id): print "Updating chart config..." updated_on = time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime()) update_response = call_charteca_api(charteca_root + '/chart_integration/config/' + chart_id, "PUT", content_type="application/json", data='{"config": {"subtitle": {"text1": "Data from Yahoo Finance: %s"}}}' % updated_on) update_respose_object = json.loads(update_response.read()) if update_respose_object["code"] != "SUCCESS": print json.dumps(update_respose_object) sys.exit(-1); def update_chart_data(charteca_root, api_key, chart_id, new_data): print "Uploading data..." upload_response = call_charteca_api(charteca_root + '/chart_integration/data/' + chart_id, "PUT", content_type=None, data=new_data) upload_respose_object = json.loads(upload_response.read()) if upload_respose_object["code"] != "SUCCESS": print json.dumps(upload_respose_object) sys.exit(-1); def republish_chart(charteca_root, api_key, chart_id): print "Publishing chart..." publish_response = call_charteca_api(charteca_root + '/chart_integration/publication/' + chart_id, "POST") publish_respose_object = json.loads(publish_response.read()) if publish_respose_object["code"] != "SUCCESS": print json.dumps(publish_respose_object) sys.exit(-1); charteca_root = "https://api.charte.ca" api_key = "INSERT_YOUR_KEY_HERE" chart_id = "g7h9GRRPqk23GRZW" # Stock exchange symbols we are interested in. Order matters. symbols = ["TD","BMO","BNS","CM","RY"] symbol_short_name_map ={"TD":"TD","RY":"RBC", "BMO":"BMO", "BNS":"Scotia Bank","CM":"CIBC"} symbol_long_name_map ={"TD":"Toronto Dominion","RY":"Royal Bank of Canada", "BMO":"Bank of Montreal", "BNS":"Scotia Bank","CM":"Canadian Imperial Bank of Commerce"} # Retrieve new data from Yahoo, existing data from charteca integration API new_data = download_quote_data(symbols, symbol_short_name_map, symbol_long_name_map) old_data = download_chart_data(charteca_root, api_key, chart_id) # Compare existing data with what we got from Yahoo old_lines = filter(None, [line.replace("\r", "") for line in old_data.split("\n")]) new_lines = filter(None, [line.replace("\r", "") for line in new_data.split("\n")]) # Compare first few lines: performance, P/E, PriceBook, Capitalization if old_lines[0] == new_lines[0] and old_lines[1] == new_lines[1] and old_lines[2] == new_lines[2] and old_lines[3] == new_lines[3] and old_lines[4] == new_lines[4]: print "Nothing to update, the data is the same" sys.exit(0) else: print "Data changed, uploading updates..." print old_lines print new_lines update_chart_title(charteca_root, api_key, chart_id) update_chart_data(charteca_root, api_key, chart_id, new_data) republish_chart(charteca_root, api_key, chart_id) sys.exit(0)
Hmm , very interesting thoughhttps://viplikes.net/ts! I think In order for more interested people to read your thoughts, you should post it on Instagram, and use the services of https://viplikes.net/ to quickly increase the amount of followers.
ReplyDeleteThe Casino Hotel in Phoenix - Temecula - JTM Hub
ReplyDeleteJTM Hotels is 광양 출장마사지 a hospitality company based out of Temecula, Arizona and is part 밀양 출장안마 of the Temecula Casinos 천안 출장마사지 of 수원 출장안마 the 광주광역 출장안마 Americas.
Buy Facebook Page Likes
ReplyDelete