Files
banstagy/ent/fund_rate.go
2026-08-24 20:53:21 +08:00

125 lines
3.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package ent
import (
"fmt"
"github.com/banbox/banbot/btime"
"github.com/banbox/banbot/config"
"github.com/banbox/banbot/core"
"github.com/banbox/banbot/exg"
"github.com/banbox/banbot/orm"
utils2 "github.com/banbox/banbot/utils"
"github.com/banbox/banexg"
"github.com/banbox/banexg/errs"
"github.com/banbox/banexg/utils"
"github.com/banbox/banstagy/com"
"math"
"path/filepath"
"sort"
"strconv"
)
/*
永续合约资金费率结算后一段时间,如果资金费率<-0.0035,未来5分钟有较大概率下降
*/
type FRate struct {
Time int64
Data []*com.CodeVal
}
func runFundEnter() *errs.Error {
exgId := "binance"
exchange, err := exg.GetWith(exgId, banexg.MarketLinear, banexg.MarketSwap)
if err != nil {
return err
}
_, err = orm.LoadMarkets(exchange, false)
if err != nil {
return err
}
dumpDir := filepath.Join(config.GetDataDir(), "dump")
err_ := utils2.EnsureDir(dumpDir, 0755)
if err_ != nil {
return errs.New(errs.CodeIOWriteFail, err_)
}
dumpPath := filepath.Join(dumpDir, exgId+"_fundingRate.json")
his := make(map[string]map[int64]float64)
err_ = utils.ReadJsonFile(dumpPath, &his, utils.JsonNumDefault)
if err_ != nil {
return errs.New(errs.CodeIOReadFail, err_)
}
dates := make(map[int64]*FRate)
for code, timeMap := range his {
for dateMS, val := range timeMap {
sta, ok := dates[dateMS]
if !ok {
sta = &FRate{Time: dateMS}
dates[dateMS] = sta
}
sta.Data = append(sta.Data, &com.CodeVal{
Code: code,
Val: val,
})
}
}
arr := make([]*FRate, 0, len(dates))
for _, it := range dates {
arr = append(arr, it)
}
sort.Slice(arr, func(i, j int) bool {
return arr[i].Time < arr[j].Time
})
// 按时间戳,对资金费率绝对值较大的,筛选K线并记录价格
rows := make([][]string, 0)
barNum := 20
backOff := 5
head := []string{"time", "code", "rate", "price"}
for i := 0; i < barNum; i++ {
sid := i - backOff
if sid >= 0 {
sid += 1
}
head = append(head, "p"+strconv.Itoa(sid))
}
rows = append(rows, head)
for _, dt := range arr {
sort.Slice(dt.Data, func(i, j int) bool {
return math.Abs(dt.Data[i].Val) > math.Abs(dt.Data[j].Val)
})
startMS := dt.Time - int64(backOff)*60000
for _, it := range dt.Data {
if math.Abs(it.Val) < 0.0005 {
break
}
exs, err := orm.GetExSymbol(exchange, it.Code)
if err != nil {
return err
}
_, bars, err := orm.GetOHLCV(exs, "1m", startMS, 0, barNum, false)
if err != nil {
return err
}
if len(bars) < barNum {
continue
}
row := make([]string, 0, 4+barNum)
initPrice := bars[backOff].Open
row = append(row, btime.ToDateStr(dt.Time, core.DefaultDateFmt), it.Code,
strconv.FormatFloat(it.Val, 'f', 6, 64),
fmt.Sprintf("%.4e", initPrice))
var pct float64
for i, b := range bars {
if i < backOff {
pct = (1 - b.Open/initPrice) * 100
} else {
pct = (b.Close/initPrice - 1) * 100
}
row = append(row, strconv.FormatFloat(pct, 'f', 4, 64))
}
rows = append(rows, row)
}
}
outPath := filepath.Join(dumpDir, exgId+"_fr.csv")
return utils2.WriteCsvFile(outPath, rows, false)
}