Skip to content

Commit

Permalink
update advanced-chart api, websocket
Browse files Browse the repository at this point in the history
  • Loading branch information
IGSON2 committed May 15, 2024
1 parent 46877a7 commit b53ecd6
Show file tree
Hide file tree
Showing 13 changed files with 381 additions and 65 deletions.
178 changes: 178 additions & 0 deletions backend/api/advanced.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package api

import (
db "bitmoi/backend/db/sqlc"
"bitmoi/backend/utilities"
"context"
"errors"
"fmt"

"github.com/gofiber/fiber/v2"
)

type AdvancedPracticeQuery struct {
From int64 `json:"from" query:"from"`
To int64 `json:"to" query:"to"`
Identifier string `json:"identifier" query:"identifier"`
}

func (s *Server) GetAdvancedPractice(c *fiber.Ctx) error {
payload := new(AdvancedPracticeQuery)
err := c.QueryParser(payload)
if err != nil {
s.logger.Err(err).Msg("cannot get advanced practice chart due to parsing query failed")
return c.SendStatus(fiber.StatusBadRequest)
}

if payload.Identifier == "" {
nextPair := utilities.FindDiffPair(s.pairs, []string{})
aOc, err := s.makeAdvancedChartToRef(db.FifM, nextPair, c.Context())
if err != nil {
s.logger.Err(err).Msg("cannot get advanced practice chart")
return c.SendStatus(fiber.StatusInternalServerError)
}
return c.Status(fiber.StatusOK).JSON(aOc)
}

info, err := utilities.DecodeIdentificationData(payload.Identifier)
if err != nil {
s.logger.Err(err).Msg("cannot unmarshal chart identifier.")
return c.Status(fiber.StatusBadRequest).SendString("cannot unmarshal chart identifier.")
}

pvData, err := s.selectAdvancedInterChart(info, db.FifM, payload.From, payload.To, c.Context())
if err != nil {
s.logger.Err(err).Msg("cannot select intermediate chart to reference timestamp.")
return c.Status(fiber.StatusInternalServerError).SendString("cannot select intermediate chart to reference timestamp.")
}

return c.Status(fiber.StatusOK).JSON(fiber.Map{"pvdata": pvData})
}

type AdvancedOnePairChart struct {
Name string `json:"name"`
PvDatas []PriceVolumeData `json:"pvdata"`
Identifier string `json:"identifier"`
}

func (s *Server) makeAdvancedChartToRef(interval, name string, ctx context.Context) (*AdvancedOnePairChart, error) {

min, max, err := s.store.SelectMinMaxTime(interval, name, ctx)
if err != nil {
return nil, fmt.Errorf("cannot count all rows. name : %s, interval : %s, err : %w", name, interval, err)
}

refTimestamp := max - calculateRefTimestamp(max-min)
if refTimestamp == max {
return nil, ErrShortRange
}
pvDatas, err := s.selectAdvancedChart(name, interval, refTimestamp, ctx)
if err != nil {
return nil, fmt.Errorf("cannot make chart to reference timestamp. name : %s, interval : %s, err : %w", name, interval, err)
}

identifier := utilities.EncrtpByASE(utilities.IdentificationData{
Name: name,
Interval: interval,
RefTimestamp: refTimestamp,
})
var aOc = &AdvancedOnePairChart{
Name: name,
PvDatas: pvDatas,
Identifier: identifier,
}
return aOc, nil
}

const oneTimeAdvancedLoad = 10000

func (s *Server) selectAdvancedChart(name, interval string, refTimestamp int64, ctx context.Context) ([]PriceVolumeData, error) {
var pvDatas []PriceVolumeData

switch interval {
case db.OneD:
candles, err := s.store.Get1dCandles(ctx, db.Get1dCandlesParams{Name: name, Time: refTimestamp, Limit: oneTimeAdvancedLoad})
if err != nil {
return nil, err
}
cs := Candles1dSlice(candles)
pvDatas = (cs).InitAdvancedCandleData()
case db.FourH:
candles, err := s.store.Get4hCandles(ctx, db.Get4hCandlesParams{Name: name, Time: refTimestamp, Limit: oneTimeAdvancedLoad})
if err != nil {
return nil, err
}
cs := Candles4hSlice(candles)
pvDatas = (cs).InitAdvancedCandleData()
case db.OneH:
candles, err := s.store.Get1hCandles(ctx, db.Get1hCandlesParams{Name: name, Time: refTimestamp, Limit: oneTimeAdvancedLoad})
if err != nil {
return nil, err
}
cs := Candles1hSlice(candles)
pvDatas = (cs).InitAdvancedCandleData()
case db.FifM:
candles, err := s.store.Get15mCandles(ctx, db.Get15mCandlesParams{Name: name, Time: refTimestamp, Limit: oneTimeAdvancedLoad})
if err != nil {
return nil, err
}
cs := Candles15mSlice(candles)
pvDatas = (cs).InitAdvancedCandleData()
case db.FiveM:
candles, err := s.store.Get5mCandles(ctx, db.Get5mCandlesParams{Name: name, Time: refTimestamp, Limit: oneTimeStageLoad})
if err != nil {
return nil, err
}
cs := Candles5mSlice(candles)
pvDatas = (cs).InitAdvancedCandleData()
}
if len(pvDatas) == 0 {
return nil, ErrGetStageChart
}
return pvDatas, nil
}

func (s *Server) selectAdvancedInterChart(info *utilities.IdentificationData, interval string, minTime, maxTime int64, ctx context.Context) ([]PriceVolumeData, error) {
var pvDatas []PriceVolumeData

switch interval {
case db.OneD:
candles, err := s.store.Get1dCandlesRnage(ctx, db.Get1dCandlesRnageParams{Name: info.Name, Time: minTime, Time_2: maxTime})
if err != nil {
s.logger.Error().Err(err).Str("name", info.Name).Int64("min", minTime).Int64("max", maxTime).Msg("cannot get 1d intermediate chart.")
return nil, err
}
cs := Candles1dSlice(candles)
pvDatas = cs.InitAdvancedCandleData()
case db.FourH:
candles, err := s.store.Get4hCandlesRnage(ctx, db.Get4hCandlesRnageParams{Name: info.Name, Time: minTime, Time_2: maxTime})
if err != nil {
s.logger.Error().Err(err).Str("name", info.Name).Int64("min", minTime).Int64("max", maxTime).Msg("cannot get 4h intermediate chart.")
return nil, err
}
cs := Candles4hSlice(candles)
pvDatas = cs.InitAdvancedCandleData()
case db.OneH:
candles, err := s.store.Get1hCandlesRnage(ctx, db.Get1hCandlesRnageParams{Name: info.Name, Time: minTime, Time_2: maxTime})
if err != nil {
s.logger.Error().Err(err).Str("name", info.Name).Int64("min", minTime).Int64("max", maxTime).Msg("cannot get 1h intermediate chart.")
return nil, err
}
cs := Candles1hSlice(candles)
pvDatas = cs.InitAdvancedCandleData()
case db.FifM:
candles, err := s.store.Get15mCandlesRnage(ctx, db.Get15mCandlesRnageParams{Name: info.Name, Time: minTime, Time_2: maxTime})
if err != nil {
s.logger.Error().Err(err).Str("name", info.Name).Int64("min", minTime).Int64("max", maxTime).Msg("cannot get 15m intermediate chart.")
return nil, err
}
cs := Candles15mSlice(candles)
pvDatas = cs.InitAdvancedCandleData()
}
if len(pvDatas) == 0 {
s.logger.Debug().Str("name", info.Name).Str("interval", interval).Int64("min", minTime).Int64("max", maxTime).Msg("No intermediate chart data.")
return nil, errors.New("no chart data")
}

return pvDatas, nil
}
7 changes: 2 additions & 5 deletions backend/api/another_interval_maker.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ package api
import (
db "bitmoi/backend/db/sqlc"
"bitmoi/backend/utilities"
"encoding/json"
"fmt"

"github.com/gofiber/fiber/v2"
)

func (s *Server) sendAnotherInterval(a *AnotherIntervalRequest, c *fiber.Ctx) (*OnePairChart, error) {
originInfo := new(utilities.IdentificationData)
infoByte := utilities.DecryptByASE(a.Identifier)
err := json.Unmarshal(infoByte, originInfo)
originInfo, err := utilities.DecodeIdentificationData(a.Identifier)
if err != nil {
return nil, fmt.Errorf("cannot unmarshal chart identifier. err : %w", err)
}

cdd, err := s.selectStageChart(originInfo.Name, a.ReqInterval, originInfo.RefTimestamp+db.GetIntervalStep(db.OneH)-1, c)
cdd, err := s.selectStageChart(originInfo.Name, a.ReqInterval, originInfo.RefTimestamp+db.GetIntervalStep(db.OneH)-1, c.Context())
if err != nil {
return nil, fmt.Errorf("cannot make chart to reference timestamp. name : %s, interval : %s, err : %w", originInfo.Name, a.ReqInterval, err)
}
Expand Down
81 changes: 81 additions & 0 deletions backend/api/candles_Interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type CandlesInterface interface {
Name() string
EntryTime() string
InitCandleData() *CandleData
InitAdvancedCandleData() []PriceVolumeData
}

type Candles1dSlice []db.Candles1d
Expand Down Expand Up @@ -49,6 +50,22 @@ func (c *Candles1dSlice) InitCandleData() *CandleData {
return &CandleData{pDataSlice, vDataSlice}
}

func (c *Candles1dSlice) InitAdvancedCandleData() []PriceVolumeData {
var pvDataSlice []PriceVolumeData
for _, row := range *c {
newPvData := PriceVolumeData{
Open: row.Open,
Close: row.Close,
High: row.High,
Low: row.Low,
Volume: row.Volume,
Time: row.Time * 1000,
}
pvDataSlice = append([]PriceVolumeData{newPvData}, pvDataSlice...)
}
return pvDataSlice
}

type Candles4hSlice []db.Candles4h

func (c *Candles4hSlice) EntryTime() string {
Expand Down Expand Up @@ -86,6 +103,22 @@ func (c *Candles4hSlice) InitCandleData() *CandleData {
return &CandleData{pDataSlice, vDataSlice}
}

func (c *Candles4hSlice) InitAdvancedCandleData() []PriceVolumeData {
var pvDataSlice []PriceVolumeData
for _, row := range *c {
newPvData := PriceVolumeData{
Open: row.Open,
Close: row.Close,
High: row.High,
Low: row.Low,
Volume: row.Volume,
Time: row.Time * 1000,
}
pvDataSlice = append([]PriceVolumeData{newPvData}, pvDataSlice...)
}
return pvDataSlice
}

type Candles1hSlice []db.Candles1h

func (c *Candles1hSlice) EntryTime() string {
Expand Down Expand Up @@ -123,6 +156,22 @@ func (c *Candles1hSlice) InitCandleData() *CandleData {
return &CandleData{pDataSlice, vDataSlice}
}

func (c *Candles1hSlice) InitAdvancedCandleData() []PriceVolumeData {
var pvDataSlice []PriceVolumeData
for _, row := range *c {
newPvData := PriceVolumeData{
Open: row.Open,
Close: row.Close,
High: row.High,
Low: row.Low,
Volume: row.Volume,
Time: row.Time * 1000,
}
pvDataSlice = append([]PriceVolumeData{newPvData}, pvDataSlice...)
}
return pvDataSlice
}

type Candles15mSlice []db.Candles15m

func (c *Candles15mSlice) EntryTime() string {
Expand Down Expand Up @@ -160,6 +209,22 @@ func (c *Candles15mSlice) InitCandleData() *CandleData {
return &CandleData{pDataSlice, vDataSlice}
}

func (c *Candles15mSlice) InitAdvancedCandleData() []PriceVolumeData {
var pvDataSlice []PriceVolumeData
for _, row := range *c {
newPvData := PriceVolumeData{
Open: row.Open,
Close: row.Close,
High: row.High,
Low: row.Low,
Volume: row.Volume,
Time: row.Time * 1000,
}
pvDataSlice = append([]PriceVolumeData{newPvData}, pvDataSlice...)
}
return pvDataSlice
}

type Candles5mSlice []db.Candles5m

func (c *Candles5mSlice) EntryTime() string {
Expand Down Expand Up @@ -196,3 +261,19 @@ func (c *Candles5mSlice) InitCandleData() *CandleData {
}
return &CandleData{pDataSlice, vDataSlice}
}

func (c *Candles5mSlice) InitAdvancedCandleData() []PriceVolumeData {
var pvDataSlice []PriceVolumeData
for _, row := range *c {
newPvData := PriceVolumeData{
Open: row.Open,
Close: row.Close,
High: row.High,
Low: row.Low,
Volume: row.Volume,
Time: row.Time * 1000,
}
pvDataSlice = append([]PriceVolumeData{newPvData}, pvDataSlice...)
}
return pvDataSlice
}
Loading

0 comments on commit b53ecd6

Please sign in to comment.