This repository has been archived on 2025-01-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
mexc-trade/app.py
dongho 82216daaf8
All checks were successful
SonarQube Scan / SonarQube Trigger (push) Successful in 1m15s
migrationt to websocket
2024-12-22 00:57:07 +09:00

207 lines
6.6 KiB
Python

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from pymongo import MongoClient
from datetime import datetime
import uvicorn
from urllib.parse import quote_plus
from dotenv import load_dotenv
import os
import yaml
with open("coin.yaml", "r") as file:
data = yaml.safe_load(file)
interest_coins = data["interest"]
load_dotenv()
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
data_points = []
# Setup templates directory
templates = Jinja2Templates(directory="templates")
MONGO_URI = f'mongodb://{quote_plus(os.getenv("DB_USER"))}:{quote_plus(os.getenv("DB_PWD"))}@{os.getenv("DB_HOST")}:{os.getenv("DB_PORT")}'
client = MongoClient(MONGO_URI)
db = client[os.getenv("DB_NAME")] # Replace with your database name
# collection = db["XRP"]
@app.get("/", response_class=HTMLResponse)
async def read_data(request: Request):
return templates.TemplateResponse(
request=request, name="index.html", context={"coins": interest_coins}
)
@app.get("/coin/{coin}")
async def view_coin_graph(request: Request, coin: str):
if coin in interest_coins:
return templates.TemplateResponse(
request=request, name="coin.html", context={"coin": coin}
)
else:
return {"coin": "not found"}
@app.get("/coin/{coin}/candle1min")
async def view_coin_candle_graph(request: Request, coin: str):
if coin in interest_coins:
return templates.TemplateResponse(
request=request, name="candle_coin.html", context={"coin": coin}
)
else:
return {"coin": "not found"}
@app.post("/update-data")
async def update_data(data: dict):
data_points.append(data)
# Keep only last 300 points to ensure we have enough data to generate 100 candles
if len(data_points) > 300:
data_points.pop(0)
return {"status": "success"}
@app.get("/data/{coin}")
async def get_data(coin):
collection = db[coin]
# Get last 100 data points, sorted by time
cursor = (
collection.find({}, {"_id": 0, "timestamp": 1, "price": 1})
.sort("timestamp", -1)
.limit(100)
)
data = list(cursor)
# Format the data for Chart.js
times = []
prices = []
for item in reversed(data): # Reverse to show oldest to newest
times.append(str(item["timestamp"]))
prices.append(float(item["price"]))
return {"times": times, "prices": prices}
@app.get("/data/{coin}/get-candle/all")
async def get_candle_data_all(coin):
if coin in interest_coins:
target = coin + "USDT" + "_kline"
collection = db[target.lower()]
latest_doc = collection.find_one(sort=[("T", -1)])
latest_end_time = latest_doc["T"]
time_threshold = latest_end_time - (
3000
) # 60 seconds before the latest endTime
pipeline = [
# Filter based on endTime
{"$match": {"T": {"$gte": time_threshold}}},
# Group by start time and end time
{
"$group": {
"_id": {"startTime": "$t", "endTime": "$T"},
"open": {"$first": "$o"},
"high": {"$max": "$h"},
"low": {"$min": "$l"},
"close": {"$last": "$c"},
"volume": {"$sum": "$v"},
"weighted_price": {"$sum": {"$multiply": ["$c", "$v"]}},
"count": {"$sum": 1},
}
},
# Sort by start time
{"$sort": {"_id.startTime": 1}},
# Reshape for output
{
"$project": {
"_id": 0,
"time": {"$multiply": ["$_id.startTime", 1000]},
"open": 1,
"high": 1,
"low": 1,
"close": 1,
"volume": 1,
"vwap": {
"$cond": {
"if": {"$eq": ["$volume", 0]},
"then": 0,
"else": {"$divide": ["$weighted_price", "$volume"]},
}
},
"trades": "$count",
"endTime": "$_id.endTime",
}
},
]
candles = list(collection.aggregate(pipeline))
return candles
else:
return None
@app.get("/data/{coin}/get-candle")
async def get_candle_data(coin):
if coin in interest_coins:
target = coin + "USDT" + "_kline"
collection = db[target.lower()]
latest_doc = collection.find_one(sort=[("T", -1)])
latest_end_time = latest_doc["T"]
time_threshold = latest_end_time - (20) # 60 seconds before the latest endTime
pipeline = [
# Filter based on endTime
{"$match": {"T": {"$gte": time_threshold}}},
# Group by start time and end time
{
"$group": {
"_id": {"startTime": "$t", "endTime": "$T"},
"open": {"$first": "$o"},
"high": {"$max": "$h"},
"low": {"$min": "$l"},
"close": {"$last": "$c"},
"volume": {"$sum": "$v"},
"weighted_price": {"$sum": {"$multiply": ["$c", "$v"]}},
"count": {"$sum": 1},
}
},
# Sort by start time
{"$sort": {"_id.startTime": 1}},
# Reshape for output
{
"$project": {
"_id": 0,
"time": {"$multiply": ["$_id.startTime", 1000]},
"open": 1,
"high": 1,
"low": 1,
"close": 1,
"volume": 1,
"vwap": {
"$cond": {
"if": {"$eq": ["$volume", 0]},
"then": 0,
"else": {"$divide": ["$weighted_price", "$volume"]},
}
},
"trades": "$count",
"endTime": "$_id.endTime",
}
},
]
candles = list(collection.aggregate(pipeline))
return candles[0]
else:
return None
if __name__ == "__main__":
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)