money-money/test_histroy.go

226 lines
5.3 KiB
Go
Raw Permalink Normal View History

package moneymoney
import (
"hash"
"log"
"sort"
"time"
"github.com/474420502/random"
"github.com/474420502/structure/tree/treelist"
"github.com/davecgh/go-spew/spew"
)
func HistoryRun() {
rd := random.New()
var money float64 = 1000000.0
cday := GetDate("2017-05-01")
p := &Policy{
MarketValue: &RangeValue[float64]{MinLimt: 10, MaxLimit: 20000, Step: 1},
UpsDownsRatioDays: []*RangeValue[float64]{{MinLimt: 0, MaxLimit: 0.2, Step: 0.01}, {MinLimt: 0, MaxLimit: 0.3, Step: 0.01}, {MinLimt: 0, MaxLimit: 0.5, Step: 0.01}, {MinLimt: 0, MaxLimit: 0.5, Step: 0.01}},
UpsCount: &RangeValue[int]{MinLimt: 0, MaxLimit: 100, Step: 1},
DownsCount: &RangeValue[int]{MinLimt: 0, MaxLimit: 100, Step: 1},
MaxPriceRatio: &RangeValue[float64]{MinLimt: 0, MaxLimit: 1, Step: 0.01},
MinPriceRatio: &RangeValue[float64]{MinLimt: 0, MaxLimit: 1, Step: 0.01},
}
RESET:
for {
RandomRange(rd, p.MarketValue)
for _, rv := range p.UpsDownsRatioDays {
RandomRange(rd, rv)
}
RandomRange(rd, p.UpsCount)
RandomRange(rd, p.DownsCount)
RandomRange(rd, p.MaxPriceRatio)
RandomRange(rd, p.MinPriceRatio)
spew.Println(p)
ALL_LOOP:
for {
// log.Println(p)
selectStocks := GetStocksByCondition(cday, p)
// log.Println(len(selectStocks))
if len(selectStocks) == 0 {
cday = cday.Add(time.Hour * 24)
if cday.After(GetDate("2022-07-02")) {
cday = GetDate("2017-05-01")
money = 1000000.0
continue RESET
}
continue
}
if len(selectStocks) >= 15 {
selectStocks = selectStocks[3:13]
}
// ShowSelectStocks(selectStocks)
// TODO: 测试 收益
iter := DateStocks.Iterator()
iter.SeekGT(cday.Unix())
if !iter.Valid() {
break
}
for {
var total float64 = 0.0
iter.Next()
if !iter.Valid() {
break ALL_LOOP
}
cstocks := iter.Value() // 当天的股票数据
// 当前股票
var cs *Stock
for _, s := range selectStocks {
itf, ok := cstocks.Get(s.Code)
if ok {
cs = itf
var ClosePrice float64
if cs.ClosingPrice == 0 {
ClosePrice = cs.PreviousClosingPrice
} else {
ClosePrice = cs.ClosingPrice
}
total += (ClosePrice - s.ClosingPrice) / s.ClosingPrice
// log.Printf("%.2f", (cs.ClosingPrice-s.ClosingPrice)/s.ClosingPrice)
}
}
total = total / float64(len(selectStocks))
// log.Printf("%s 总收益: money: %f, 涨跌幅:%.2f%%", cs.Date.Local().Format("2006-01-02"), money+money*total, total*100)
if total >= 0.08 || total <= -0.08 {
for _, s := range selectStocks {
show, ok := cstocks.Get(s.Code) // 当前股票
if ok {
log.Printf("%s %s 买入:%f 当前:%f", s.Date.Local().Format("2006-01-02"), s.Name, s.ClosingPrice, show.ClosingPrice)
}
}
money = money + money*total
cday = cs.Date
log.Printf("最后总财富 1000000 -> money: %f, 涨跌幅: %.2f%%", money, (money-1000000)/1000000*100)
break
}
}
}
log.Printf("最后总财富 本金:1000000 -> money: %f, 涨跌幅: %.2f%%", money, (money-1000000)/1000000*100)
}
}
type RangeValue[T float32 | float64 | int | int64 | uint32 | uint64] struct {
Min T
MinLimt T
Max T
MaxLimit T
Step T
}
func (rv *RangeValue[T]) In(v T) bool {
return v >= rv.Min && v <= rv.Max
}
type Policy struct {
Hash hash.Hash
MarketValue *RangeValue[float64]
UpsDownsRatioDays []*RangeValue[float64]
UpsCount *RangeValue[int]
DownsCount *RangeValue[int]
MaxPriceRatio *RangeValue[float64]
MinPriceRatio *RangeValue[float64]
}
func GetStocksByCondition(cday time.Time, policy *Policy) []*Stock {
var stocks []*Stock
// cday := GetDate(CurrentDay)
// log.Println("重新从", cday.Local().Format("2006-01-02"), "策略选股")
iter := DateStocks.Iterator()
// log.Println(iter.SeekLE(cday.Unix()), iter.Valid())
iter.SeekGE(cday.Unix())
if !iter.Valid() {
return nil
}
endStock := iter.Value()
// log.Println(DateStocks.Size(), endStock.Size())
endStock.Traverse(func(s *treelist.Slice[int64, *Stock]) bool {
stock := s.Value
if stock.Name[0] == '*' {
return true
}
if len(stock.Extend.UpsDownsRatioDays) < 4 {
return true
}
// if !(stock.MarketValue >= 50*亿) {
// return true
// }
if !(policy.MarketValue.In(stock.MarketValue / 亿)) {
return true
}
udDays := stock.Extend.UpsDownsRatioDays
// if !(udDays[0].Ratio < -0.02 && udDays[3].Ratio > 0.03) {
// return true
// }
for i, ratio := range policy.UpsDownsRatioDays {
if !ratio.In(udDays[i].Ratio) {
return true
}
if !policy.UpsCount.In(udDays[i].UpsCount) {
return true
}
if !policy.DownsCount.In(udDays[i].DownsCount) {
return true
}
}
maxRatio := (stock.Extend.MaxPriceDays - stock.ClosingPrice) / stock.ClosingPrice
if !policy.MaxPriceRatio.In(maxRatio) {
return true
}
minRatio := (stock.ClosingPrice - stock.Extend.MinPriceDays) / stock.ClosingPrice
if !policy.MaxPriceRatio.In(minRatio) {
return true
}
if stock.ClosingPrice == 0 {
return true
}
// log.Println(stock.UpsDownsRatio, s)
stocks = append(stocks, stock)
return true
})
sort.Slice(stocks, func(i, j int) bool {
return stocks[i].UpsDownsRatio < stocks[j].UpsDownsRatio
})
return stocks
}