You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.1 KiB
118 lines
3.1 KiB
""" 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/<string:isin>")
|
|
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
|