create backend forn the app
Browse files- backend.py +136 -0
- index.html +23 -1
backend.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
```python
|
| 2 |
+
from fastapi import FastAPI, HTTPException, Depends
|
| 3 |
+
from fastapi.middleware.cors import CORSMiddleware
|
| 4 |
+
from fastapi.security import OAuth2PasswordBearer
|
| 5 |
+
from pydantic import BaseModel
|
| 6 |
+
import requests
|
| 7 |
+
import uvicorn
|
| 8 |
+
from typing import Optional, List
|
| 9 |
+
import datetime
|
| 10 |
+
import json
|
| 11 |
+
import os
|
| 12 |
+
|
| 13 |
+
app = FastAPI(title="AlgoTradeAI Backend", version="1.0.0")
|
| 14 |
+
|
| 15 |
+
# CORS Configuration
|
| 16 |
+
app.add_middleware(
|
| 17 |
+
CORSMiddleware,
|
| 18 |
+
allow_origins=["*"],
|
| 19 |
+
allow_credentials=True,
|
| 20 |
+
allow_methods=["*"],
|
| 21 |
+
allow_headers=["*"],
|
| 22 |
+
)
|
| 23 |
+
|
| 24 |
+
# Fake database for demo purposes
|
| 25 |
+
fake_db = {
|
| 26 |
+
"users": {},
|
| 27 |
+
"strategies": {},
|
| 28 |
+
"trades": {},
|
| 29 |
+
"market_data": {}
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
# Models
|
| 33 |
+
class User(BaseModel):
|
| 34 |
+
username: str
|
| 35 |
+
email: str
|
| 36 |
+
full_name: Optional[str] = None
|
| 37 |
+
disabled: Optional[bool] = None
|
| 38 |
+
|
| 39 |
+
class UserInDB(User):
|
| 40 |
+
hashed_password: str
|
| 41 |
+
|
| 42 |
+
class TradeSignal(BaseModel):
|
| 43 |
+
symbol: str
|
| 44 |
+
exchange: str
|
| 45 |
+
signal_type: str # BUY/SELL
|
| 46 |
+
price: float
|
| 47 |
+
quantity: int
|
| 48 |
+
timestamp: datetime.datetime
|
| 49 |
+
|
| 50 |
+
class Strategy(BaseModel):
|
| 51 |
+
name: str
|
| 52 |
+
description: str
|
| 53 |
+
risk_level: str
|
| 54 |
+
created_at: datetime.datetime
|
| 55 |
+
active: bool
|
| 56 |
+
|
| 57 |
+
# Market Data API (Using Alpha Vantage as example)
|
| 58 |
+
ALPHA_VANTAGE_API_KEY = os.getenv("ALPHA_VANTAGE_API_KEY", "demo")
|
| 59 |
+
|
| 60 |
+
def get_market_data(symbol: str):
|
| 61 |
+
url = f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={symbol}.BSE&apikey={ALPHA_VANTAGE_API_KEY}"
|
| 62 |
+
response = requests.get(url)
|
| 63 |
+
return response.json()
|
| 64 |
+
|
| 65 |
+
# Authentication
|
| 66 |
+
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
| 67 |
+
|
| 68 |
+
def fake_decode_token(token):
|
| 69 |
+
return User(
|
| 70 |
+
username=token + "fakedecoded", email="[email protected]", full_name="John Doe"
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
async def get_current_user(token: str = Depends(oauth2_scheme)):
|
| 74 |
+
user = fake_decode_token(token)
|
| 75 |
+
return user
|
| 76 |
+
|
| 77 |
+
# API Endpoints
|
| 78 |
+
@app.get("/")
|
| 79 |
+
async def root():
|
| 80 |
+
return {"message": "Welcome to AlgoTradeAI API"}
|
| 81 |
+
|
| 82 |
+
@app.get("/market/{symbol}", tags=["market"])
|
| 83 |
+
async def get_symbol_data(symbol: str):
|
| 84 |
+
try:
|
| 85 |
+
data = get_market_data(symbol)
|
| 86 |
+
return {"symbol": symbol, "data": data}
|
| 87 |
+
except Exception as e:
|
| 88 |
+
raise HTTPException(status_code=400, detail=str(e))
|
| 89 |
+
|
| 90 |
+
@app.post("/signals/", tags=["signals"])
|
| 91 |
+
async def create_signal(signal: TradeSignal, current_user: User = Depends(get_current_user)):
|
| 92 |
+
signal_id = f"signal_{len(fake_db['trades']) + 1}"
|
| 93 |
+
fake_db['trades'][signal_id] = signal.dict()
|
| 94 |
+
return {"signal_id": signal_id, **signal.dict()}
|
| 95 |
+
|
| 96 |
+
@app.get("/signals/", response_model=List[TradeSignal], tags=["signals"])
|
| 97 |
+
async def get_signals(limit: int = 10):
|
| 98 |
+
return list(fake_db['trades'].values())[:limit]
|
| 99 |
+
|
| 100 |
+
@app.post("/strategies/", tags=["strategies"])
|
| 101 |
+
async def create_strategy(strategy: Strategy, current_user: User = Depends(get_current_user)):
|
| 102 |
+
strategy_id = f"strategy_{len(fake_db['strategies']) + 1}"
|
| 103 |
+
fake_db['strategies'][strategy_id] = strategy.dict()
|
| 104 |
+
return {"strategy_id": strategy_id, **strategy.dict()}
|
| 105 |
+
|
| 106 |
+
@app.get("/strategies/", response_model=List[Strategy], tags=["strategies"])
|
| 107 |
+
async def get_strategies(active: Optional[bool] = None):
|
| 108 |
+
strategies = list(fake_db['strategies'].values())
|
| 109 |
+
if active is not None:
|
| 110 |
+
strategies = [s for s in strategies if s['active'] == active]
|
| 111 |
+
return strategies
|
| 112 |
+
|
| 113 |
+
@app.get("/indices/", tags=["market"])
|
| 114 |
+
async def get_indices():
|
| 115 |
+
# Mock data for Indian indices
|
| 116 |
+
return {
|
| 117 |
+
"NIFTY 50": {
|
| 118 |
+
"price": 21856.10,
|
| 119 |
+
"change": 0.72,
|
| 120 |
+
"direction": "up"
|
| 121 |
+
},
|
| 122 |
+
"BANKNIFTY": {
|
| 123 |
+
"price": 46325.45,
|
| 124 |
+
"change": 1.12,
|
| 125 |
+
"direction": "up"
|
| 126 |
+
},
|
| 127 |
+
"INDIA VIX": {
|
| 128 |
+
"price": 14.25,
|
| 129 |
+
"change": 2.45,
|
| 130 |
+
"direction": "down"
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
if __name__ == "__main__":
|
| 135 |
+
uvicorn.run("backend:app", host="0.0.0.0", port=8000, reload=True)
|
| 136 |
+
```
|
index.html
CHANGED
|
@@ -378,7 +378,6 @@
|
|
| 378 |
</p>
|
| 379 |
</div>
|
| 380 |
</footer>
|
| 381 |
-
|
| 382 |
<script>
|
| 383 |
// Initialize Vanta.js globe animation
|
| 384 |
VANTA.GLOBE({
|
|
@@ -397,6 +396,29 @@
|
|
| 397 |
|
| 398 |
// Initialize feather icons
|
| 399 |
feather.replace();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
</script>
|
| 401 |
</body>
|
| 402 |
</html>
|
|
|
|
| 378 |
</p>
|
| 379 |
</div>
|
| 380 |
</footer>
|
|
|
|
| 381 |
<script>
|
| 382 |
// Initialize Vanta.js globe animation
|
| 383 |
VANTA.GLOBE({
|
|
|
|
| 396 |
|
| 397 |
// Initialize feather icons
|
| 398 |
feather.replace();
|
| 399 |
+
|
| 400 |
+
// Fetch market data from backend
|
| 401 |
+
async function fetchMarketData() {
|
| 402 |
+
try {
|
| 403 |
+
const response = await fetch('http://localhost:8000/indices/');
|
| 404 |
+
const data = await response.json();
|
| 405 |
+
|
| 406 |
+
// Update NIFTY 50
|
| 407 |
+
document.querySelector('dt:contains("NIFTY 50")').nextElementSibling.querySelector('div:first-child').textContent =
|
| 408 |
+
data["NIFTY 50"].price.toFixed(2);
|
| 409 |
+
|
| 410 |
+
// Update other indices similarly...
|
| 411 |
+
} catch (error) {
|
| 412 |
+
console.error('Error fetching market data:', error);
|
| 413 |
+
}
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
// Initialize
|
| 417 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 418 |
+
fetchMarketData();
|
| 419 |
+
// Set interval to refresh data every 60 seconds
|
| 420 |
+
setInterval(fetchMarketData, 60000);
|
| 421 |
+
});
|
| 422 |
</script>
|
| 423 |
</body>
|
| 424 |
</html>
|