dero-swaps/price.go
2024-04-20 22:23:48 +02:00

203 lines
4.3 KiB
Go

package main
import (
"encoding/json"
"io"
"log"
"net/http"
"strconv"
"swap-client/cfg"
"swap-client/clients"
"swap-client/coin"
"swap-client/dero"
"swap-client/monero"
"time"
)
func GetMarket(pair string, provider int) (prices Swap_Price) {
resp, err := http.Get(pair)
if err != nil {
log.Printf("Market: HTTP Get: %v\n", err)
return Swap_Price{}
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Printf("Market: Read Body: %v\n", err)
return Swap_Price{}
}
var market Price_Provider
if err := json.Unmarshal(body, &market); err != nil {
log.Printf("Market: Cannot unmarshal data: %v\n", err)
return Swap_Price{}
}
switch provider {
case TO:
prices.Ask, err = strconv.ParseFloat(market.Ask, 64)
prices.Bid, err = strconv.ParseFloat(market.Bid, 64)
prices.Median, err = strconv.ParseFloat(market.Price, 64)
case XEGGEX:
prices.Ask, err = strconv.ParseFloat(market.BestAsk, 64)
prices.Bid, err = strconv.ParseFloat(market.BestBid, 64)
prices.Median, err = strconv.ParseFloat(market.LastPrice, 64)
}
if err != nil {
log.Printf("Market: Cannot convert string: %v\n", err)
return
}
return
}
// Get Pair values
// TODO: configurable fees; clean-up
func GetPrice(pair string) (bid float64, ask float64) {
var base, base_usd Swap_Price
var atomicUnits uint = 8
var simple bool
switch pair {
case coin.BTCDERO, coin.DEROBTC:
simple = true
for i := range DERO_BTC {
if base = GetMarket(DERO_BTC[i], i); base.Ask > 0 && base.Bid > 0 {
break
}
}
case coin.LTCDERO, coin.DEROLTC:
for i := range LTC_USDT {
if base = GetMarket(LTC_USDT[i], i); base.Ask > 0 && base.Bid > 0 {
break
}
}
case coin.XMRDERO, coin.DEROXMR:
atomicUnits = 12
for i := range XMR_USDT {
if base = GetMarket(XMR_USDT[i], i); base.Ask > 0 && base.Bid > 0 {
break
}
}
case coin.ARRRDERO, coin.DEROARRR:
base = GetMarket(ARRR_USDT, TO)
}
if base.Ask == 0 || base.Bid == 0 {
return 0, 0
}
if simple {
bid = base.Bid - (base.Bid * cfg.SwapFees.Swap.Bid / 100)
bid = coin.RoundFloat(bid, atomicUnits)
ask = base.Ask + (base.Ask * cfg.SwapFees.Swap.Ask / 100)
ask = coin.RoundFloat(ask, atomicUnits)
return
}
for i := range DERO_USDT {
if base_usd = GetMarket(DERO_USDT[i], i); base_usd.Ask > 0 && base_usd.Bid > 0 {
break
}
}
if base_usd.Ask == 0 || base_usd.Bid == 0 {
return 0, 0
}
bid = base_usd.Bid - (base_usd.Bid * cfg.SwapFees.Swap.Bid / 100)
ask = base_usd.Ask + (base_usd.Ask * cfg.SwapFees.Swap.Ask / 100)
bid = coin.RoundFloat(bid/base.Bid, atomicUnits)
ask = coin.RoundFloat(ask/base.Ask, atomicUnits)
return
}
// TODO: simplify
func UpdateMarkets() {
var xmr float64
var deroxmr float64
for p := range coin.SimplePairs {
switch p {
case coin.XMRDERO, coin.DEROXMR:
deroxmr, xmr = GetPrice(p)
}
// sometimes TradeOgre's BID/ASK values are swapped
if deroxmr > 0 && xmr > 0 && deroxmr > xmr {
swap := xmr
xmr = deroxmr
deroxmr = swap
}
mk.Lock()
defer mk.Unlock()
// TODO: simplify
if xmr > 0 {
mk.Pairs.XMR = xmr
mk.Update[coin.XMRDERO] = time.Now().UnixMilli()
IsPairAvailable[coin.XMRDERO] = true
} else {
t := time.UnixMilli(mk.Update[coin.XMRDERO])
if time.Since(t) > time.Minute*2 {
IsPairAvailable[coin.XMRDERO] = false
log.Println("XMR->DERO disabled")
}
}
if deroxmr > 0 {
mk.Pairs.DEROXMR = deroxmr
mk.Update[coin.DEROXMR] = time.Now().UnixMilli()
IsPairAvailable[coin.DEROXMR] = true
} else {
t := time.UnixMilli(mk.Update[coin.DEROXMR])
if time.Since(t) > time.Minute*2 {
IsPairAvailable[coin.DEROXMR] = false
log.Println("DERO->XMR disabled")
}
}
}
balance := UpdatePool()
var out WS_Message
out.Method = "client"
out.Params = balance
Connection.WriteJSON(out)
}
func UpdatePool() clients.ClientInfo {
lock.Lock()
defer lock.Unlock()
var info clients.ClientInfo
var pair clients.PairInfo
info.Nickname = cfg.Settings.Nickname
for p := range coin.Pairs {
switch p {
case coin.DEROXMR:
pair.Balance = monero.GetBalance() - coin.Locked.GetLockedBalance(p)
pair.Pair = p
case coin.XMRDERO:
pair.Balance = dero.GetBalance() - coin.Locked.GetLockedBalance(p)
pair.Pair = p
default:
continue
}
info.PairInfo = append(info.PairInfo, pair)
}
return info
}