|
|
|
|
@ -4,12 +4,14 @@ import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"log/slog"
|
|
|
|
|
"net/http"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"github.com/gomodule/redigo/redis"
|
|
|
|
|
"github.com/sasha-s/go-deadlock"
|
|
|
|
|
uuid "github.com/satori/go.uuid"
|
|
|
|
|
"github.com/shopspring/decimal"
|
|
|
|
|
|
|
|
|
|
"quantex.com/qfixdpl/src/app"
|
|
|
|
|
"quantex.com/qfixdpl/src/app/version"
|
|
|
|
|
@ -316,7 +318,8 @@ func (cont *Controller) GetLogs(ctx *gin.Context) {
|
|
|
|
|
|
|
|
|
|
logs, err := cont.store.GetLogsByQuoteReqID(quoteReqID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
slog.Error("GetLogs: error fetching logs", "quoteReqID", quoteReqID, "error", err)
|
|
|
|
|
err = tracerr.Errorf("GetLogs: error fetching logs (quoteReqID=%s): %w", quoteReqID, err)
|
|
|
|
|
slog.Error(err.Error())
|
|
|
|
|
ctx.JSON(http.StatusInternalServerError, HTTPError{Error: "error fetching logs"})
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
@ -325,3 +328,57 @@ func (cont *Controller) GetLogs(ctx *gin.Context) {
|
|
|
|
|
ctx.JSON(http.StatusOK, logs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPendingQuoteRequests godoc
|
|
|
|
|
// @Summary List pending QuoteRequests
|
|
|
|
|
// @Description Returns all QuoteRequests received from TW that have not been quoted yet by the dealer
|
|
|
|
|
// @Tags fix
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Success 200 {array} domain.ListTrade
|
|
|
|
|
// @Router /qfixdpl/v1/quote-requests [get]
|
|
|
|
|
func (cont *Controller) GetPendingQuoteRequests(ctx *gin.Context) {
|
|
|
|
|
pending := cont.tradeProvider.GetPendingQuoteRequests()
|
|
|
|
|
ctx.JSON(http.StatusOK, pending)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SendQuote godoc
|
|
|
|
|
// @Summary Send a Quote for a pending QuoteRequest
|
|
|
|
|
// @Description Builds and sends a Quote (35=S) to TW for an existing QuoteRequest at the given price
|
|
|
|
|
// @Tags fix
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Param body body SendQuoteRequest true "Quote to send"
|
|
|
|
|
// @Success 200 {object} Msg
|
|
|
|
|
// @Failure 400 {object} HTTPError
|
|
|
|
|
// @Failure 404 {object} HTTPError
|
|
|
|
|
// @Failure 409 {object} HTTPError
|
|
|
|
|
// @Failure 500 {object} HTTPError
|
|
|
|
|
// @Router /qfixdpl/v1/quotes [post]
|
|
|
|
|
func (cont *Controller) SendQuote(ctx *gin.Context) {
|
|
|
|
|
var req SendQuoteRequest
|
|
|
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
ctx.JSON(http.StatusBadRequest, HTTPError{Error: err.Error()})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
price, err := decimal.NewFromString(req.Price)
|
|
|
|
|
if err != nil {
|
|
|
|
|
ctx.JSON(http.StatusBadRequest, HTTPError{Error: "invalid price: " + err.Error()})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := cont.tradeProvider.SendQuote(req.QuoteReqID, price); err != nil {
|
|
|
|
|
msg := err.Error()
|
|
|
|
|
switch {
|
|
|
|
|
case strings.Contains(msg, "not found"):
|
|
|
|
|
ctx.JSON(http.StatusNotFound, HTTPError{Error: "quoteReqID not found"})
|
|
|
|
|
case strings.Contains(msg, "already sent"):
|
|
|
|
|
ctx.JSON(http.StatusConflict, HTTPError{Error: "quote already sent for this quoteReqID"})
|
|
|
|
|
default:
|
|
|
|
|
ctx.JSON(http.StatusInternalServerError, HTTPError{Error: "failed to send quote"})
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx.JSON(http.StatusOK, Msg{Text: "Quote sent"})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|