money-money/main_test.go
2022-07-05 01:47:54 +08:00

269 lines
5.6 KiB
Go

package moneymoney
import (
"encoding/gob"
"log"
"os"
"sort"
"testing"
"time"
"github.com/474420502/structure/tree/treelist"
"github.com/klauspost/compress/zstd"
)
const 亿 = 100000000
func GetDate(date string) time.Time {
ts, err := time.ParseInLocation("2006-01-02", date, time.Local)
if err != nil {
panic(err)
}
return ts
}
func GetStocksByCondition(cday time.Time) []*Stock {
var stocks []*Stock
// cday := GetDate(CurrentDay)
start := cday.Add(-time.Hour * 24 * 14)
log.Println("重新从", start.Local().Format("2006-01-02"), cday.Local().Format("2006-01-02"), "策略选股")
// istartStock, _ := DateStocks.Get(start.Unix())
siter := DateStocks.Iterator()
siter.SeekGE(start.Unix())
siter.Valid()
{
ssiter := siter.Value().(*treelist.Tree[int64]).Iterator()
ssiter.SeekToFirst()
// ss := ssiter.Value().(*Stock)
// log.Printf("%s", ss.Date.Local().Format("2006-01-02"))
}
iter := DateStocks.Iterator()
// log.Println(iter.SeekLE(cday.Unix()), iter.Valid())
iter.SeekLE(cday.Unix())
endStock := iter.Value().(*treelist.Tree[int64])
// log.Println(DateStocks.Size(), endStock.Size())
endStock.Traverse(func(s *treelist.Slice[int64]) bool {
var ok bool
citer := siter.Clone()
stock := s.Value.(*Stock)
if stock.MarketValue <= 100*亿 {
return true
}
startStock := citer.Value().(*treelist.Tree[int64])
var istock any
for {
istock, ok = startStock.Get(stock.Code)
if ok {
break
}
citer.Next()
if !citer.Valid() {
return true
}
}
fstock := istock.(*Stock)
if fstock.ClosingPrice == 0 {
return true
}
if stock.ClosingPrice == 0 {
return true
}
stock.MinPrice = fstock.ClosingPrice
stock.MaxPrice = stock.ClosingPrice
stock.UpsDownsRatio = ((stock.ClosingPrice - fstock.ClosingPrice) / fstock.ClosingPrice)
// 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
}
func TestMoney(t *testing.T) {
var money float64 = 1000000.0
cday := GetDate("2017-04-01")
ALL_LOOP:
for money < 1000000*3 {
selectStocks := GetStocksByCondition(cday)
// log.Println(len(selectStocks))
for _, s := range selectStocks[0:15] {
log.Printf("%.4f%% %s %s %f", s.UpsDownsRatio*100.0, s.Date.Local().Format("2006-01-02"), s.Name, s.ClosingPrice)
// log.Println(s.UpsDownsRatio, s)
}
selectStocks = selectStocks[0:15]
start := (len(selectStocks) - 10) / 2
selectStocks = selectStocks[start : start+10]
// for _, s := range selectStocks {
// log.Printf("%.4f%% %s", s.UpsDownsRatio*100.0, s.Name)
// }
// 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().(*treelist.Tree[int64])
var cs *Stock
for _, s := range selectStocks {
itf, ok := cstocks.Get(s.Code)
if ok {
cs = itf.(*Stock)
total += (cs.ClosingPrice - s.ClosingPrice) / s.ClosingPrice
// log.Printf("%.2f", (cs.ClosingPrice-s.ClosingPrice)/s.ClosingPrice)
}
}
csdate := cs.Date.Local().Format("2006-01-02")
if csdate == "2017-12-07" {
for _, s := range selectStocks {
log.Printf("%.4f%% %s %s %f %f %f", s.UpsDownsRatio*100.0, s.Date.Local().Format("2006-01-02"), s.Name, s.ClosingPrice, s.MinPrice, s.MaxPrice)
// log.Println(s.UpsDownsRatio, s)
}
log.Println()
}
total = total / float64(len(selectStocks))
log.Printf("%s 总收益:%.2f%%", csdate, total*100)
if total >= 0.10 || total <= -0.20 {
money = money + money*total
cday = cs.Date
log.Printf("最后总财富 1000000 -> money: %f", money)
break
}
}
}
log.Printf("最后总财富 1000000 -> money: %f", money)
}
func TestCase3(t *testing.T) {
cday := GetDate("2017-04-01")
citer := DateStocks.Iterator()
citer.SeekToFirst()
citer.SeekGE(cday.Unix())
for citer.Valid() {
stocks := citer.Value().(*treelist.Tree[int64])
todayIter := stocks.Iterator()
cmpiter := citer.Clone()
var i = 0
// 向前移动的天数
for cmpiter.Valid() {
todayIter.SeekToFirst()
cmpday := cmpiter.Value().(*treelist.Tree[int64])
for todayIter.Valid() {
s := todayIter.Value().(*Stock)
ic, ok := cmpday.Get(s.Code)
if ok {
c := ic.(*Stock)
if c.Extend == nil {
c.Extend = &StockExtend{}
}
// 满足相邻天数的处理
if len(c.Extend.UpsDownsRatioDays) == 0 {
if _, ok := CountedDays[i]; ok {
UpsDownsRatioDays := ((c.ClosingPrice - s.ClosingPrice) / c.ClosingPrice)
c.Extend.UpsDownsRatioDays = append(c.Extend.UpsDownsRatioDays, UpsDownsRatioDays)
}
}
// TODO: 其他的统计处理
}
todayIter.Next()
}
if i >= 1<<7 {
break
}
cmpiter.Prev()
i++
}
citer.Next()
}
var stocks []*Stock
DateStocks.Traverse(func(s *treelist.Slice[int64]) bool {
s.Value.(*treelist.Tree[int64]).Traverse(func(s *treelist.Slice[int64]) bool {
stocks = append(stocks, s.Value.(*Stock))
return true
})
return true
})
if stocks != nil {
f, err := os.OpenFile("./stocks1.gob", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644)
if err != nil {
panic(err)
}
defer f.Close()
enc, err := zstd.NewWriter(f)
if err != nil {
panic(err)
}
defer enc.Close()
err = gob.NewEncoder(enc).Encode(stocks)
if err != nil {
panic(err)
}
}
}
func TestCase2(t *testing.T) {
GetFromAPI() // 获取基础数据
}
func TestCase1(t *testing.T) {
main()
}