""" Web service app """ import json from datetime import datetime, timedelta import pytz from clickhouse_driver import Client from flask import Flask app = Flask(__name__) with open("config.json", "r") as fp: config = json.load(fp) client = Client(**config["clickhouse"]) @app.route("/instruments") def get_instruments(): """ Get list of instruments with the latest quote """ data = client.execute(""" SELECT isin, description, last_value FROM ( SELECT isin, argMax(description, added_on) AS description, argMax(status, added_on) AS status FROM symbols FINAL GROUP BY isin ) ndsymbols LEFT JOIN ( SELECT isin, toString(argMax(last_value, minute_start)) AS last_value FROM ( SELECT isin, minute_start, maxMerge(last_record_timestamp) AS last_record_timestamp, argMinMerge(first_value)/1000000.0 AS first_value, argMaxMerge(last_value)/1000000.0 AS last_value, minMerge(min_value)/1000000.0 AS min_value, maxMerge(max_value)/1000000.0 AS max_value FROM traderepublic.quotes GROUP BY (isin, minute_start) ) aquotes GROUP BY isin ) vals ON vals.isin=ndsymbols.isin WHERE ndsymbols.status=1 ORDER BY isin """) response_rows = [] for row in data: response_rows.append({ "isin": row[0], "description": row[1], "last_value": float(row[2]) if row[2] != "" else None }) return {"data": response_rows} @app.route("/last30m/") def get_last30m(isin: str): """ Get last 30 minutes of candlestick data with 1 minute resolution """ time30m = datetime.utcnow() - timedelta(minutes=30) time30m = time30m.replace(second=0, microsecond=0) data = client.execute( """ SELECT minute_start, first_value, last_value, min_value, max_value FROM ( SELECT isin, minute_start, argMinMerge(first_value)/1000000.0 AS first_value, argMaxMerge(last_value)/1000000.0 AS last_value, minMerge(min_value)/1000000.0 AS min_value, maxMerge(max_value)/1000000.0 AS max_value FROM traderepublic.quotes WHERE isin=%(isin)s AND minute_start > %(time30m)s GROUP BY (isin, minute_start) ORDER BY minute_start ) aquotes """, { "isin": isin, "time30m": time30m, }) if not data: return {} result = {"isin": isin, "candlesticks": []} candlesticks = result["candlesticks"] timezone = pytz.timezone("UTC") for row in data: time_start = row[0].replace(tzinfo=timezone) candlesticks.append({ "time_start": time_start.strftime("%Y-%m-%d %H:%M:%S%z"), "open": row[1], "close": row[2], "min": row[3], "max": row[4] }) return result