204 lines
5.7 KiB
Go
204 lines
5.7 KiB
Go
package arb
|
|
|
|
import (
|
|
_ "embed"
|
|
"github.com/banbox/banbot/btime"
|
|
"github.com/banbox/banbot/config"
|
|
"github.com/banbox/banbot/core"
|
|
"github.com/banbox/banbot/exg"
|
|
"github.com/banbox/banbot/opt"
|
|
"github.com/banbox/banbot/orm"
|
|
"github.com/banbox/banexg"
|
|
"github.com/banbox/banexg/errs"
|
|
"github.com/banbox/banexg/utils"
|
|
"github.com/banbox/banta"
|
|
"math"
|
|
"strings"
|
|
)
|
|
|
|
func GenTwoPairRatio() *errs.Error {
|
|
//LineExamples()
|
|
//return nil
|
|
//groups := []string{"1000PEPE/USDT:USDT", "1000BONK/USDT:USDT"}
|
|
groups := []string{
|
|
"LPT,ATH,MOODENG,RNDR,APT,TRUMP,DOT,HYPE,BAKE,SPX,BOME,TUT,PUMP,BERA,OG,EOS,MERL,TAO,NMR,FET,TIA,FHE,ZORA,LINK,POL,TRX,1000PEPE,ETHFI,PROVE,TREE",
|
|
"RED,SUI,VIRTUAL,NEIRO,GALA,TON,PAXG,XNY,CRV,NAORIS,XRP,NEAR,AVAX,ETC,XLM,MATIC,AAVE,SEI,1000SHIB,DAM,SPK,MEME,OP,FIL,KAITO,FARTCOIN,EIGEN,BCH,IP,XPL",
|
|
}
|
|
//startMS := config.TimeRange.StartMS
|
|
endMS, _ := btime.ParseTimeMS("20250921")
|
|
tf := "15m"
|
|
core.Market = "linear"
|
|
tfMSecs := int64(utils.TFToSecs(tf) * 1000)
|
|
barLimit := 30000
|
|
startMS := endMS - tfMSecs*int64(barLimit)
|
|
barsArr := make([][]*TimeFlt, 0, len(groups))
|
|
allPairs := strings.Split(strings.Join(groups, ","), ",")
|
|
allPairs, err := config.ParsePairs(allPairs...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
exsMap := make(map[int32]*orm.ExSymbol)
|
|
for _, pair := range allPairs {
|
|
exs, err := orm.GetExSymbolCur(pair)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
exsMap[exs.ID] = exs
|
|
}
|
|
err = orm.BulkDownOHLCV(exg.Default, exsMap, tf, startMS, endMS, 0, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, group := range groups {
|
|
pairs := strings.Split(group, ",")
|
|
prices, err := GetGroupPrices(pairs, tf, startMS, endMS)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
barsArr = append(barsArr, prices)
|
|
}
|
|
rateArr := make([]*TimeFlt, len(barsArr[0]))
|
|
for i, va := range barsArr[0] {
|
|
rateArr[i] = &TimeFlt{
|
|
Stamp: va.Stamp,
|
|
Val: va.Val / barsArr[1][i].Val,
|
|
}
|
|
}
|
|
path := "D:/ratios.html"
|
|
title := "price ratio"
|
|
return dumpRateChart(rateArr, tf, path, title)
|
|
}
|
|
|
|
// GetGroupPrices 计算分组内多个品种的平均价格
|
|
func GetGroupPrices(pairs []string, tf string, startMS, endMS int64) ([]*TimeFlt, *errs.Error) {
|
|
var groupBar [][]*banexg.Kline
|
|
pairs, err := config.ParsePairs(pairs...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tfMSecs := int64(utils.TFToSecs(tf) * 1000)
|
|
barLimit := (endMS - startMS) / tfMSecs
|
|
for _, pair := range pairs {
|
|
exs, err := orm.GetExSymbolCur(pair)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_, bars, err := orm.GetOHLCV(exs, tf, startMS, endMS, 0, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if float64(len(bars)) > float64(barLimit)*0.8 {
|
|
groupBar = append(groupBar, bars)
|
|
}
|
|
}
|
|
// 对分组内品种计算价格归一化均值
|
|
groupBar = getAlignBars(groupBar...)
|
|
if len(groupBar) == 0 {
|
|
return nil, errs.NewMsg(errs.CodeParamInvalid, "align bars fail for %v", pairs)
|
|
}
|
|
for _, gp := range groupBar {
|
|
base := gp[0].Close
|
|
gp[0].Close = 1
|
|
for i := 1; i < len(gp); i++ {
|
|
gp[i].Close /= base
|
|
}
|
|
}
|
|
barNum := len(groupBar[0])
|
|
bars := make([]*TimeFlt, 0, barNum)
|
|
for j := 0; j < barNum; j++ {
|
|
var sumVal float64
|
|
for _, gp := range groupBar {
|
|
sumVal += gp[j].Close
|
|
}
|
|
bars = append(bars, &TimeFlt{
|
|
Stamp: groupBar[0][j].Time,
|
|
Val: sumVal / float64(len(groupBar)),
|
|
})
|
|
}
|
|
return bars, nil
|
|
}
|
|
|
|
type TimeFlt struct {
|
|
Stamp int64
|
|
Val float64
|
|
}
|
|
|
|
func dumpRateChart(rates []*TimeFlt, tf string, path, title string) *errs.Error {
|
|
if len(rates) == 0 {
|
|
return nil
|
|
}
|
|
var labels []string
|
|
var arrRaw []float64
|
|
var arrFast []float64
|
|
var arrSlow []float64
|
|
var arrMdMa []float64
|
|
var arrBigMa []float64
|
|
var arrBigUp []float64
|
|
var arrBigDn []float64
|
|
var arrHH, arrLL []float64
|
|
|
|
bollWid := 0.0043
|
|
showNum := 1440
|
|
stepFlt := float64(len(rates)) / float64(showNum)
|
|
stepSize := int(math.Round(stepFlt))
|
|
tfMSecs := int64(utils.TFToSecs(tf) * 1000)
|
|
|
|
lenFast := int(stepFlt * 5.77)
|
|
lenSlow := int(stepFlt * 31.25)
|
|
lenMid := int(stepFlt * 96.5)
|
|
lenBig := int(stepFlt * 320.2)
|
|
lenStd := int(stepFlt * 96.3)
|
|
lenHL := int(stepFlt * 14.42)
|
|
|
|
var idx = 0
|
|
env, _ := banta.NewBarEnv(core.ExgName, core.Market, "", tf)
|
|
env.TimeStart = rates[idx].Stamp
|
|
env.TimeStop = rates[idx].Stamp + tfMSecs
|
|
rate := env.NewSeries(nil)
|
|
rowId := 0
|
|
dateFmt := "01-02 15:04"
|
|
for idx < len(rates) {
|
|
item := rates[idx]
|
|
env.TimeStart += tfMSecs
|
|
env.TimeStop += tfMSecs
|
|
env.BarNum += 1
|
|
rowId += 1
|
|
ratio := item.Val
|
|
rate.Append(ratio)
|
|
maFast := banta.EMA(rate, lenFast)
|
|
maSlow := banta.EMA(rate, lenSlow) //66
|
|
maMid := banta.EMA(rate, lenMid).Get(0)
|
|
maBig := banta.EMA(rate, lenBig)
|
|
dev := banta.StdDev(rate, lenStd)
|
|
stdDev := banta.SMA(dev, lenStd).Get(0) * 1.7
|
|
bollWidAvg := bollWid*maMid*0.5 + stdDev*0.5
|
|
hh := banta.Highest(rate, lenHL).Get(0)
|
|
ll := banta.Lowest(rate, lenHL).Get(0)
|
|
bigVal := maBig.Get(0)
|
|
if rowId%stepSize == 0 && !math.IsNaN(maMid) {
|
|
labels = append(labels, btime.ToDateStr(item.Stamp, dateFmt))
|
|
arrRaw = append(arrRaw, ratio)
|
|
arrFast = append(arrFast, maFast.Get(0))
|
|
arrSlow = append(arrSlow, maSlow.Get(0))
|
|
arrMdMa = append(arrMdMa, maMid)
|
|
arrBigMa = append(arrBigMa, bigVal)
|
|
arrBigUp = append(arrBigUp, maMid+bollWidAvg)
|
|
arrBigDn = append(arrBigDn, maMid-bollWidAvg)
|
|
arrHH = append(arrHH, hh)
|
|
arrLL = append(arrLL, ll)
|
|
}
|
|
idx += 1
|
|
}
|
|
return opt.DumpChart(path, title, labels, 5, nil, []*opt.ChartDs{
|
|
{Label: "raw", Data: arrRaw},
|
|
{Label: "ma5", Data: arrFast, Hidden: true},
|
|
{Label: "ma10", Data: arrSlow, Hidden: true},
|
|
{Label: "mid", Data: arrMdMa},
|
|
{Label: "big", Data: arrBigMa, Hidden: true},
|
|
{Label: "upp", Data: arrBigUp, Hidden: false},
|
|
{Label: "dnn", Data: arrBigDn, Hidden: false},
|
|
//{Label: "hh", Data: arrHH, Hidden: true},
|
|
//{Label: "ll", Data: arrLL, Hidden: true},
|
|
})
|
|
}
|