first commit
This commit is contained in:
117
web/app.py
Normal file
117
web/app.py
Normal file
@@ -0,0 +1,117 @@
|
||||
""" 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
|
||||
Reference in New Issue
Block a user