commit f9814ac7884101715af25d44a011102c8abad4ea Author: lychiyu Date: Wed Jun 26 00:22:51 2024 +0800 first commit diff --git a/define.go b/define.go new file mode 100644 index 0000000..8a1f2de --- /dev/null +++ b/define.go @@ -0,0 +1,49 @@ +package strategy + +import ( + "git.qtrade.icu/coin-quant/base/common" + "git.qtrade.icu/coin-quant/base/engine" + . "git.qtrade.icu/coin-quant/trademodel" +) + +type CandleFn func(candle *Candle) +type Engine = engine.Engine +type Param = common.Param +type ParamData = common.ParamData + +var StringParam = common.StringParam +var IntParam = common.IntParam +var FloatParam = common.FloatParam +var BoolParam = common.BoolParam + +func min(a, b float64) float64 { + return 0 +} + +func max(a, b float64) float64 { + return 0 +} + +func formatFloat(n float64, precision int) float64 { + return 0 +} + +// FloatMul return a*b +func FloatMul(a, b float64) float64 { + return 0 +} + +// FloatAdd return a*b +func FloatAdd(a, b float64) float64 { + return 0 +} + +// FloatSub return a-b +func FloatSub(a, b float64) float64 { + return 0 +} + +// FloatDiv return a/b +func FloatDiv(a, b float64) float64 { + return 0 +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b4490f2 --- /dev/null +++ b/go.mod @@ -0,0 +1,15 @@ +module git.qtrade.icu/coin-quant/strategy + +go 1.22.0 + +require ( + git.qtrade.icu/coin-quant/base v0.0.0-20240625154116-db5c83a1dd97 + git.qtrade.icu/coin-quant/indicator v0.0.0-20240625151736-c23020eee562 + git.qtrade.icu/coin-quant/trademodel v0.0.0-20240625151548-cef4b6fc28b9 +) + +require ( + github.com/shopspring/decimal v1.4.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..1ddc2b6 --- /dev/null +++ b/go.sum @@ -0,0 +1,25 @@ +git.qtrade.icu/coin-quant/base v0.0.0-20240625154116-db5c83a1dd97 h1:3Mx0bvsodQg0XgQbFZEUTJ8KFOW2yXMBM25qjHDXNf0= +git.qtrade.icu/coin-quant/base v0.0.0-20240625154116-db5c83a1dd97/go.mod h1:UGO6cehLrOO0xEgEzVosvlakoTyxPz1rpvUtT7WDN8M= +git.qtrade.icu/coin-quant/indicator v0.0.0-20240625151736-c23020eee562 h1:oA06Mq/hJtzJ6k7ZW6kd3RY9EBDLVCEPDFADiP9JwIk= +git.qtrade.icu/coin-quant/indicator v0.0.0-20240625151736-c23020eee562/go.mod h1:x1+rqPrwJqPLETFdMQGhzp71Z3ZxAlNFExGVOhk+IT0= +git.qtrade.icu/coin-quant/trademodel v0.0.0-20240625151548-cef4b6fc28b9 h1:9T1u+MzfbG9jZU1wzDtmBoOwN1m/fRX0iX7NbLwAHgU= +git.qtrade.icu/coin-quant/trademodel v0.0.0-20240625151548-cef4b6fc28b9/go.mod h1:SZnI+IqcRlKVcDSS++NIgthZX4GG1OU4UG+RDrSOD34= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/macd.go b/macd.go new file mode 100644 index 0000000..5ac8afa --- /dev/null +++ b/macd.go @@ -0,0 +1,100 @@ +package strategy + +import ( + "fmt" + "git.qtrade.icu/coin-quant/indicator" +) + +/* +./trade backtest --fee 0.0002 --balance 5000 --start "2022-01-01 00:00:00" --end "2022-06-01 00:00:00" +--exchange binance --symbol ETHUSDT --script macd.go +--param '{"bin": "30m", "fast": 7, "slow": 20, "dea": 9, "amount": 2}' +*/ + +type MACD struct { + engine Engine + macd indicator.CommonIndicator + position float64 + + binSize string + fast int + slow int + dea int + amount float64 +} + +func NewMACD() *MACD { + s := new(MACD) + return s +} + +func (s *MACD) Param() (paramInfo []Param) { + paramInfo = []Param{ + StringParam("bin", "Kline binsize", "kline binsize", "15m", &s.binSize), + IntParam("fast", "macd fast", "macs fast", 12, &s.fast), + IntParam("slow", "macd slow", "macs slow", 26, &s.slow), + IntParam("dea", "macd dea", "macs dea", 9, &s.dea), + FloatParam("amount", "amount", "amount", 1, &s.amount), + } + return +} + +// OnCandleLarge call when binSize candle +func (s *MACD) OnCandleLarge(candle *Candle) { + // update macd indicator + s.macd.Update(candle.Close) + // get macd indicator: crossDown,crossUp,fast,slow,result + inds := s.macd.Indicator() + down := inds["crossDown"] + up := inds["crossUp"] + if up == 1 { + // macd cross up + if s.position < 0 { + s.engine.CloseShort(candle.Close, s.amount) + } else if s.position > 0 { + return + } + s.engine.OpenLong(candle.Close, s.amount) + } else if down == 1 { + // macd cross down + if s.position > 0 { + s.engine.CloseLong(candle.Close, s.amount) + } else if s.position < 0 { + return + } + s.engine.OpenShort(candle.Close, s.amount) + } +} +func (s *MACD) Init(engine Engine, params ParamData) error { + s.engine = engine + s.macd = engine.AddIndicator("macd", s.fast, s.slow, s.dea) + engine.Merge("1m", s.binSize, s.OnCandleLarge) + fmt.Printf("fast: %d, slow: %d, dea: %d, binsize: %s, amount: %f\n", s.fast, s.slow, s.dea, s.binSize, s.amount) + return nil +} + +// OnCandle call every 1m candle +func (s *MACD) OnCandle(candle *Candle) { + // fmt.Println(candle) +} + +func (s *MACD) OnPosition(pos, price float64) { + s.position = pos +} + +// OnTrade call when own order filled +func (s *MACD) OnTrade(trade *Trade) { + // fmt.Println("trade:", trade) +} + +// OnTradeMarket call when market has new trade +// only called in real trading +func (s *MACD) OnTradeMarket(trade *Trade) { + // fmt.Println("tradeHistory:", trade) +} + +// OnDepth call when order book update +// only called in real trading +func (s *MACD) OnDepth(depth *Depth) { + // fmt.Println("depth:", depth) +}