init
This commit is contained in:
36
org/day/01.go
Normal file
36
org/day/01.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package day
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
func D01(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
o, c, h, l := e.Open.Get(0), e.Close.Get(0), e.High.Get(0), e.Low.Get(0)
|
||||
solid := math.Abs(o - c)
|
||||
solidRate := solid / math.Abs(h-l)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 15).Get(0)
|
||||
ma := ta.SMA(e.Close, 20).Get(0)
|
||||
if len(s.LongOrders) > 0 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "closeL", Dirt: core.OdDirtLong})
|
||||
} else if len(s.ShortOrders) > 0 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "closeL", Dirt: core.OdDirtShort})
|
||||
} else {
|
||||
if solidRate > 0.7 && solid/atr > 1 {
|
||||
if o > c && c < ma {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long"})
|
||||
} else if c > ma {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "short", Short: true})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
62
org/day/02.go
Normal file
62
org/day/02.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package day
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
视频号:期市萧何:最简单的交易系统 2025/02/18
|
||||
|
||||
80均线向上只开多,向下只开空
|
||||
当20均线和80均线多头排列,且价格上穿20均线开多;反之做空
|
||||
前期压力支撑止损,价格再次触碰20均线止盈
|
||||
|
||||
最小8h才盈利,且21年到35年间几次回撤时间长达1年左右;
|
||||
弃用
|
||||
*/
|
||||
|
||||
func MaDirt(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
lenAtr := 20
|
||||
baseAtrLen := 86
|
||||
slRate := 2.0
|
||||
bigThres := 0.2
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
maSml := ta.SMA(e.Close, 20)
|
||||
maBig := ta.SMA(e.Close, 80)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
bigChg := (maBig.Get(0) - maBig.Get(3)) / atrBase
|
||||
smlChg := (maSml.Get(0) - maSml.Get(3)) / atrBase
|
||||
cSmlX := e.Close.Cross(maSml)
|
||||
if len(s.LongOrders) > 0 {
|
||||
if cSmlX == -1 {
|
||||
// 价格下穿均线止盈
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exitL", Dirt: core.OdDirtLong})
|
||||
}
|
||||
} else if len(s.ShortOrders) > 0 {
|
||||
if cSmlX == 1 {
|
||||
// 价格上穿均线止盈
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exitS", Dirt: core.OdDirtShort})
|
||||
}
|
||||
} else if bigChg > bigThres {
|
||||
// 大均线向上
|
||||
if cSmlX == 1 && maSml.Get(0) > maBig.Get(0) && smlChg > 0 {
|
||||
// 价格上穿20均线,且均线多头排列
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long", StopLossVal: atr.Get(0) * slRate})
|
||||
}
|
||||
} else if bigChg < -bigThres {
|
||||
// 大均线向下
|
||||
if cSmlX == -1 && maSml.Get(0) < maBig.Get(0) && smlChg < 0 {
|
||||
// 价格下穿20均线,且均线空头排列
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "short", Short: true, StopLossVal: atr.Get(0) * slRate})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
47
org/day/03.go
Normal file
47
org/day/03.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package day
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
"github.com/banbox/banexg/utils"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
在大周期4h的前一个小周期入场,检查是否有套利机会。
|
||||
无法盈利
|
||||
*/
|
||||
|
||||
func D03(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
tfMSecs := int64(utils.TFToSecs("4h") * 1000)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "4h", 10},
|
||||
}
|
||||
},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = 0
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
dirt, _ := s.More.(int)
|
||||
if len(s.LongOrders) > 0 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit"})
|
||||
} else if len(s.ShortOrders) > 0 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit"})
|
||||
} else if (e.TimeStop+e.TFMSecs)%tfMSecs == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "ent", Short: dirt < 0})
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
ma := ta.SMA(e.Close, 10).Get(0)
|
||||
if e.Close.Get(0) > ma {
|
||||
s.More = 1
|
||||
} else {
|
||||
s.More = -1
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
73
org/day/04.go
Normal file
73
org/day/04.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package day
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
视频号:山居听雨楼:渣男战法
|
||||
5日和10日均线,10日均线向上向下确定方向
|
||||
收盘价小均线金叉,且多头排列,做多;反之做空
|
||||
|
||||
效果较差
|
||||
*/
|
||||
|
||||
func D04(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
lenAtr := 20
|
||||
baseAtrLen := 86
|
||||
//slRate := 2.0
|
||||
bigThres := 0.2
|
||||
upNum, dnNum, zeroNum := 0, 0, 0
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
maSml := ta.SMA(e.Close, 5)
|
||||
maBig := ta.SMA(e.Close, 10)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
bigChg := (maBig.Get(0) - maBig.Get(2)) / atrBase
|
||||
smlChg := (maSml.Get(0) - maSml.Get(2)) / atrBase
|
||||
cSmlX := e.Close.Cross(maSml)
|
||||
ph := ta.Highest(e.High, 2).Get(0)
|
||||
pl := ta.Lowest(e.Low, 2).Get(0)
|
||||
if len(s.LongOrders) > 0 {
|
||||
if cSmlX == -1 {
|
||||
// 价格下穿均线止盈
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exitL", Dirt: core.OdDirtLong})
|
||||
}
|
||||
} else if len(s.ShortOrders) > 0 {
|
||||
if cSmlX == 1 {
|
||||
// 价格上穿均线止盈
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exitS", Dirt: core.OdDirtShort})
|
||||
}
|
||||
} else if bigChg > bigThres {
|
||||
// 大均线向上
|
||||
if cSmlX == 1 && maSml.Get(0) > maBig.Get(0) && smlChg > 0 {
|
||||
// 价格上穿20均线,且均线多头排列
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long", StopLossVal: pl})
|
||||
}
|
||||
} else if bigChg < -bigThres {
|
||||
// 大均线向下
|
||||
if cSmlX == -1 && maSml.Get(0) < maBig.Get(0) && smlChg < 0 {
|
||||
// 价格下穿20均线,且均线空头排列
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "short", Short: true, StopLossVal: ph})
|
||||
}
|
||||
}
|
||||
if bigChg > bigThres {
|
||||
upNum++
|
||||
} else if bigChg < -bigThres {
|
||||
dnNum++
|
||||
} else {
|
||||
zeroNum++
|
||||
}
|
||||
},
|
||||
OnShutDown: func(s *strat.StratJob) {
|
||||
fmt.Printf("up: %d, dn: %d, zero: %d\n", upNum, dnNum, zeroNum)
|
||||
},
|
||||
}
|
||||
}
|
||||
58
org/day/05.go
Normal file
58
org/day/05.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package day
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
视频号:漫谈期事:高手能稳定盈利的交易系统到底有多简单?
|
||||
截断亏损让利润奔跑
|
||||
任意阳K第二根开多,开仓k前一根k最低点止损,反之做空
|
||||
没止损就拿30根bar后平仓
|
||||
|
||||
无法盈利
|
||||
*/
|
||||
|
||||
func D05(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
o, c := e.Open.Get(0), e.Close.Get(0)
|
||||
_ = o
|
||||
ma := ta.SMA(e.Close, 30).Get(0)
|
||||
ph := ta.Highest(e.High, 2).Get(0)
|
||||
pl := ta.Lowest(e.Low, 2).Get(0)
|
||||
rsi := ta.RSI(e.Close, 4).Get(0)
|
||||
if len(s.LongOrders) > 0 {
|
||||
for _, od := range s.LongOrders {
|
||||
sl := od.GetStopLoss()
|
||||
if pl > sl.Price {
|
||||
sl.Price = pl
|
||||
}
|
||||
num := e.BarCount(od.EnterAt)
|
||||
if num > 10 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exitL", OrderID: od.ID})
|
||||
}
|
||||
}
|
||||
} else if len(s.ShortOrders) > 0 {
|
||||
for _, od := range s.ShortOrders {
|
||||
sl := od.GetStopLoss()
|
||||
if ph < sl.Price {
|
||||
sl.Price = ph
|
||||
}
|
||||
num := e.BarCount(od.EnterAt)
|
||||
if num > 10 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exitS", OrderID: od.ID})
|
||||
}
|
||||
}
|
||||
} else if rsi < 10 && c < ma {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long", StopLoss: pl})
|
||||
} else if rsi > 90 && c > ma {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "short", Short: true, StopLoss: ph})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
40
org/day/06.go
Normal file
40
org/day/06.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package day
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
bilibili 生财茶馆pro 98%胜率的5分钟终极剥头皮交易策略-测试
|
||||
|
||||
很差,一路向下
|
||||
*/
|
||||
|
||||
func d06(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
EachMaxLong: 1,
|
||||
EachMaxShort: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 6)
|
||||
utBot := ta.UTBot(e.Close, atr, 2).Get(0)
|
||||
stc := ta.STC(e.Close, 80, 27, 50, 0.5)
|
||||
stcVal := stc.Get(0)
|
||||
stcUp := stcVal > stc.Get(1)
|
||||
hma := ta.HMA(e.Close, 55).Get(0)
|
||||
hh := ta.Highest(e.High, 3).Get(0)
|
||||
ll := ta.Lowest(e.Low, 3).Get(0)
|
||||
if utBot > 0 && stcVal < 25 && stcUp && c > hma {
|
||||
slVal := c - ll
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long", StopLossVal: slVal, TakeProfitVal: slVal * 1.5})
|
||||
} else if utBot < 0 && stcVal > 75 && !stcUp && c < hma {
|
||||
slVal := hh - c
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "short", Short: true, StopLossVal: slVal, TakeProfitVal: slVal * 1.5})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
162
org/day/07.go
Normal file
162
org/day/07.go
Normal file
@@ -0,0 +1,162 @@
|
||||
package day
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/banbox/banbot/btime"
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func D07(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
symVols := make(map[int32]float64) // 成交量记录
|
||||
allowSyms := make(map[int32]bool) // 允许交易的品种sid
|
||||
timeDirts := make(map[int32]*TimeDirt) // 记录每个品种的触发时间和方向,只做顺势信号
|
||||
holds := make(map[int32]int) // 各个品种持仓情况
|
||||
var lock sync.Mutex
|
||||
var bigTime int64
|
||||
var allowConfirm bool // allowSyms是否已刷新
|
||||
const volRateThs = 1.1 // 成交量最低倍数
|
||||
const topNRate = 0.1 // 交易前n个品种比例
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
DrawDownExit: true,
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "1h", 1},
|
||||
}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
if !allowConfirm && e.TimeStart > bigTime {
|
||||
// 确定当前小时,可交易的品种
|
||||
allowConfirm = true
|
||||
topNum := int(math.Round(float64(len(symVols)) * topNRate))
|
||||
allowSyms = GetTopNKeys(symVols, topNum)
|
||||
}
|
||||
sid := s.Symbol.ID
|
||||
_, allow := allowSyms[sid]
|
||||
hold, hasPos := holds[sid]
|
||||
if hasPos {
|
||||
if hold > 0 {
|
||||
if len(s.LongOrders) == 0 {
|
||||
delete(holds, sid)
|
||||
}
|
||||
} else if len(s.ShortOrders) == 0 {
|
||||
delete(holds, sid)
|
||||
}
|
||||
}
|
||||
// 要求最近3bar成交量加速,实体颜色一致,且实体至少70%;最新成交量是平均成交量2倍
|
||||
volMa := ta.SMA(e.Volume, 100).Get(0)
|
||||
v0, v1, v2 := e.Volume.Get(0), e.Volume.Get(1), e.Volume.Get(2)
|
||||
prevVolRate := v1 / v2
|
||||
if v0 > volMa*2 && prevVolRate > volRateThs && v0/v1 > prevVolRate*volRateThs {
|
||||
// 成交量爆发
|
||||
flag0, solid0 := BarStat(e, 0)
|
||||
flag1, solid1 := BarStat(e, 1)
|
||||
flag2, solid2 := BarStat(e, 2)
|
||||
if flag0 == flag1 && flag1 == flag2 && min(solid0, solid1, solid2) > 0.7 {
|
||||
// 颜色一致,且实体至少70%
|
||||
lock.Lock()
|
||||
timeDirts[sid] = &TimeDirt{Time: e.TimeStart, Dirt: flag0}
|
||||
lock.Unlock()
|
||||
if allow && expDirt(timeDirts, e.TimeStart-e.TFMSecs) == flag0 {
|
||||
dateStr := btime.ToDateStr(e.TimeStart, core.DefaultDateFmt)
|
||||
fmt.Printf("[%s] enter %s dirt: %d\n", dateStr, s.Symbol.Symbol, flag0)
|
||||
// 只交易成交量top,且顺应大趋势的
|
||||
if len(s.ShortOrders) == 0 && len(s.LongOrders) == 0 && len(holds) <= 1 {
|
||||
holds[sid] = flag0
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "enter",
|
||||
Short: flag0 < 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
lock.Lock()
|
||||
if e.TimeStop > bigTime {
|
||||
symVols = make(map[int32]float64)
|
||||
bigTime = e.TimeStop
|
||||
allowConfirm = false
|
||||
}
|
||||
// 计算所有品种过去1小时成交量
|
||||
avgPrice := ta.AvgPrice(e).Get(0)
|
||||
symVols[s.Symbol.ID] = e.Volume.Get(0) * avgPrice
|
||||
lock.Unlock()
|
||||
},
|
||||
GetDrawDownExitRate: func(s *strat.StratJob, od *ormo.InOutOrder, maxChg float64) float64 {
|
||||
return 0.4
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func expDirt(dirts map[int32]*TimeDirt, minStamp int64) int {
|
||||
up, dn := 0, 0
|
||||
for k, d := range dirts {
|
||||
if d.Time < minStamp {
|
||||
delete(dirts, k)
|
||||
continue
|
||||
}
|
||||
if d.Dirt > 0 {
|
||||
up++
|
||||
} else {
|
||||
dn++
|
||||
}
|
||||
}
|
||||
if up+dn >= 3 {
|
||||
if up >= dn*2 {
|
||||
return 1
|
||||
} else if dn >= up*2 {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func BarStat(e *ta.BarEnv, i int) (int, float64) {
|
||||
o, h, l, c := e.Open.Get(i), e.High.Get(i), e.Low.Get(i), e.Close.Get(i)
|
||||
solid := float64(0)
|
||||
if h > l {
|
||||
solid = math.Abs(c-o) / (h - l)
|
||||
}
|
||||
flag := 1
|
||||
if o > c {
|
||||
flag = -1
|
||||
}
|
||||
return flag, solid
|
||||
}
|
||||
|
||||
type TimeDirt struct {
|
||||
Time int64
|
||||
Dirt int
|
||||
}
|
||||
|
||||
type kv struct {
|
||||
key int32
|
||||
value float64
|
||||
}
|
||||
|
||||
func GetTopNKeys(symVols map[int32]float64, n int) map[int32]bool {
|
||||
pairs := make([]kv, 0, len(symVols))
|
||||
for k, v := range symVols {
|
||||
pairs = append(pairs, kv{k, v})
|
||||
}
|
||||
|
||||
sort.Slice(pairs, func(i, j int) bool {
|
||||
return pairs[i].value > pairs[j].value
|
||||
})
|
||||
|
||||
keys := make(map[int32]bool)
|
||||
for i := 0; i < n && i < len(pairs); i++ {
|
||||
keys[pairs[i].key] = true
|
||||
}
|
||||
return keys
|
||||
}
|
||||
15
org/day/main.go
Normal file
15
org/day/main.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package day
|
||||
|
||||
import "github.com/banbox/banbot/strat"
|
||||
|
||||
func init() {
|
||||
strat.AddStratGroup("day", map[string]strat.FuncMakeStrat{
|
||||
"01": D01,
|
||||
"02": MaDirt,
|
||||
"03": D03,
|
||||
"04": D04,
|
||||
"05": D05,
|
||||
"06": d06,
|
||||
"07": D07,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user