133 lines
3.3 KiB
Go
133 lines
3.3 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/kjannette/trahn-backend/internal/repository"
|
|
)
|
|
|
|
type tradeJSON struct {
|
|
T int64 `json:"t"`
|
|
Side string `json:"side"`
|
|
Price float64 `json:"price"`
|
|
Qty float64 `json:"qty"`
|
|
GridLevel *int `json:"gridLevel,omitempty"`
|
|
USDValue float64 `json:"usdValue"`
|
|
IsPaperTrade bool `json:"isPaperTrade"`
|
|
}
|
|
|
|
// parseTradeMode extracts the ?mode= query parameter.
|
|
// Returns a *bool: nil = all, true = paper, false = live.
|
|
func parseTradeMode(r *http.Request) (*bool, error) {
|
|
v := r.URL.Query().Get("mode")
|
|
switch v {
|
|
case "", "all":
|
|
return nil, nil
|
|
case "paper":
|
|
b := true
|
|
return &b, nil
|
|
case "live":
|
|
b := false
|
|
return &b, nil
|
|
default:
|
|
return nil, fmt.Errorf("invalid mode %q, expected paper|live|all", v)
|
|
}
|
|
}
|
|
|
|
func (s *Server) handleTradesToday(w http.ResponseWriter, r *http.Request) {
|
|
mode, err := parseTradeMode(r)
|
|
if err != nil {
|
|
writeError(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
ctx := r.Context()
|
|
today := repository.TradingDayNow()
|
|
|
|
trades, err := s.tradeRepo.GetByDay(ctx, today, mode)
|
|
if err != nil {
|
|
fmt.Printf("Error fetching today's trades: %v\n", err)
|
|
writeError(w, http.StatusInternalServerError, "failed to fetch trades")
|
|
return
|
|
}
|
|
|
|
out := make([]tradeJSON, len(trades))
|
|
for i, t := range trades {
|
|
out[i] = tradeJSON{
|
|
T: t.Timestamp.UnixMilli(), Side: t.Side,
|
|
Price: t.Price, Qty: t.Quantity,
|
|
GridLevel: t.GridLevel, USDValue: t.USDValue,
|
|
IsPaperTrade: t.IsPaperTrade,
|
|
}
|
|
}
|
|
writeJSON(w, http.StatusOK, out)
|
|
}
|
|
|
|
func (s *Server) handleTradesByDay(w http.ResponseWriter, r *http.Request) {
|
|
date := r.PathValue("date")
|
|
if !validateDate(date) {
|
|
writeError(w, http.StatusBadRequest, "invalid date format, expected YYYY-MM-DD")
|
|
return
|
|
}
|
|
|
|
mode, err := parseTradeMode(r)
|
|
if err != nil {
|
|
writeError(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
ctx := r.Context()
|
|
trades, err := s.tradeRepo.GetByDay(ctx, date, mode)
|
|
if err != nil {
|
|
fmt.Printf("Error fetching trades for %s: %v\n", date, err)
|
|
writeError(w, http.StatusInternalServerError, "failed to fetch trades")
|
|
return
|
|
}
|
|
|
|
out := make([]tradeJSON, len(trades))
|
|
for i, t := range trades {
|
|
out[i] = tradeJSON{
|
|
T: t.Timestamp.UnixMilli(), Side: t.Side,
|
|
Price: t.Price, Qty: t.Quantity,
|
|
GridLevel: t.GridLevel, USDValue: t.USDValue,
|
|
IsPaperTrade: t.IsPaperTrade,
|
|
}
|
|
}
|
|
writeJSON(w, http.StatusOK, out)
|
|
}
|
|
|
|
func (s *Server) handleAllTrades(w http.ResponseWriter, r *http.Request) {
|
|
limit := parseLimit(r, 100)
|
|
|
|
mode, err := parseTradeMode(r)
|
|
if err != nil {
|
|
writeError(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
trades, err := s.tradeRepo.GetAll(r.Context(), limit, mode)
|
|
if err != nil {
|
|
fmt.Printf("Error fetching all trades: %v\n", err)
|
|
writeError(w, http.StatusInternalServerError, "failed to fetch trades")
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, trades)
|
|
}
|
|
|
|
func (s *Server) handleTradeStats(w http.ResponseWriter, r *http.Request) {
|
|
mode, err := parseTradeMode(r)
|
|
if err != nil {
|
|
writeError(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
stats, err := s.tradeRepo.GetStats(r.Context(), mode)
|
|
if err != nil {
|
|
fmt.Printf("Error fetching trade stats: %v\n", err)
|
|
writeError(w, http.StatusInternalServerError, "failed to fetch trade stats")
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, stats)
|
|
}
|