From ea5da7d746a4ae942fd4523e95957a250ca080e4 Mon Sep 17 00:00:00 2001 From: tktk4751 Date: Wed, 31 Jan 2024 13:04:43 +0900 Subject: [PATCH] =?UTF-8?q?Goroutin=E3=81=AB=E3=82=88=E3=82=8B=E6=9C=80?= =?UTF-8?q?=E9=81=A9=E5=8C=96=E9=96=A2=E6=95=B0=E3=81=AE=E9=AB=98=E9=80=9F?= =?UTF-8?q?=E5=8C=96=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 2 + cmd/main.go | 13 +- config.yml | 2 +- pkg/execute/signal.go | 16 +- pkg/strategey/bb.go | 347 +++++++++++++++++++---------- pkg/strategey/donchain.go | 138 +++++++++--- pkg/strategey/rsi.go | 69 +++++- pkg/strategey/strategy.go | 4 +- pkg/utils/get_csv_data/get_data.py | 2 +- 9 files changed, 427 insertions(+), 166 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go index 6a112d3..e79341c 100755 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "time" "v1/pkg/strategey" // "v1/pkg/analytics/metrics" // "v1/pkg/db/models" @@ -44,6 +45,7 @@ import ( // }) // } func main() { + start := time.Now() // account := trader.NewAccount(1000) @@ -134,6 +136,7 @@ func main() { // query.GetCloseData("BTCUSDT", "4h") + //DBにデータを追加するための関数 // var assets_names []string = []string{"RUNEUSDT", "BTCUSDT", "AAVEUSDT", "ORDIUSDT", "SANUSDT", "LTCUSDT", "OKBUSDT", "ASTRUSDT", "MNTUSDT", "FTMUSDT", "SNXUSDT", "DYDXUSDT", "BONKUSDT", "LUNAUSDT", "MAGICUSDT", "XLMUSDT", "DOGEUSDT", "TRSUSDT", "LINKUSDT", "TONUSDT", "ISPUSDT", "BONKUSDT", "GMXUSDT", "INJUSDT", "ETHUSDT", "SOLUSDT", "AVAXUSDT", "MATICUSDT", "ATOMUSDT", "UNIUSDT", "ARBUSDT", "OPUSDT", "PEPEUSDT", "SEIUSDT", "SUIUSDT", "TIAUSDT", "WLDUSDT", "XRPUSDT", "NEARUSDT", "DOTUSDT", "APTUSDT", "XMRUSDT", "LDOUSDT", "FILUSDT", "KASUSDT", "STXUSDT", "RNDRUSDT", "GRTUSDT"} // var durations []string = []string{"1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "6h", "8h", "12h"} @@ -146,7 +149,7 @@ func main() { // log.Fatalf("Error loading OHLCV data: %v", err) // } - // // data.SaveAssetDatasCSV(asset_data) + // // // data.SaveAssetDatasCSV(asset_data) // // DBに接続する関数を呼び出し // db, err := data.ConnectDB("./db/kline.db") @@ -160,6 +163,7 @@ func main() { // if err != nil { // log.Fatal(err) // } + //ここまで // for key, paths := range groupedPaths { @@ -176,6 +180,13 @@ func main() { // fs := http.FileServer(http.Dir("pkg/charts/html")) // log.Println("running server at http://localhost:8089") // log.Fatal(http.ListenAndServe("localhost:8089", logRequest(fs))) + end := time.Now() + + // 処理時間を計算 + duration := end.Sub(start) + + // 処理時間を表示 + fmt.Printf("処理時間: %v\n", duration) } diff --git a/config.yml b/config.yml index 84ceda3..f4e8223 100644 --- a/config.yml +++ b/config.yml @@ -4,5 +4,5 @@ assetName: "TIAUSDT" -duration: "5m" +duration: "1h" diff --git a/pkg/execute/signal.go b/pkg/execute/signal.go index cabbb80..aaa605f 100755 --- a/pkg/execute/signal.go +++ b/pkg/execute/signal.go @@ -218,13 +218,13 @@ func (s *SignalEvents) Buy(strategyName string, assetName string, duration strin Price: price, Size: size, } - if save { - signalEvent.Save() + // if save { + // signalEvent.Save() - } else { + // } else { - return false - } + // return false + // } s.Signals = append(s.Signals, signalEvent) return true @@ -246,10 +246,10 @@ func (s *SignalEvents) Sell(strategyName string, assetName string, duration stri Size: size, } - if save { - signalEvent.Save() + // if save { + // signalEvent.Save() - } + // } s.Signals = append(s.Signals, signalEvent) return true diff --git a/pkg/strategey/bb.go b/pkg/strategey/bb.go index 1e8f8bb..9583e6d 100644 --- a/pkg/strategey/bb.go +++ b/pkg/strategey/bb.go @@ -1,118 +1,233 @@ package strategey -// import ( -// "fmt" -// "math" -// "v1/pkg/analytics" -// "v1/pkg/execute" - -// "github.com/markcheno/go-talib" -// ) - -// func (df *DataFrameCandle) BBStrategy(n int, k float64, account *Account) *execute.SignalEvents { - -// var StrategyName = "BB" -// lenCandles := len(df.Candles) - -// if lenCandles <= n { -// return nil -// } - -// signalEvents := execute.NewSignalEvents() -// bbUp, _, bbDown := talib.BBands(df.Closes(), n, k, k, 0) - -// buySize := 0.0 -// isBuyHolding := false -// for i := 1; i < lenCandles; i++ { -// if i < n { -// continue -// } -// if bbDown[i-1] > df.Candles[i-1].Close && bbDown[i] <= df.Candles[i].Close && !isBuyHolding { -// buySize = account.TradeSize(0.9) / df.Candles[i].Close -// signalEvents.Buy(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, true) -// isBuyHolding = true -// } -// if bbUp[i-1] < df.Candles[i-1].Close && bbUp[i] >= df.Candles[i].Close && isBuyHolding { -// signalEvents.Sell(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, true) -// isBuyHolding = false -// } -// } -// return signalEvents -// } - -// func (df *DataFrameCandle) OptimizeBbProfit() (performance float64, bestN int, bestK float64) { -// bestN = 20 -// bestK = 2.0 - -// for n := 13; n < 200; n++ { -// for k := 2.0; k < 3.5; k += 0.1 { -// signalEvents := df.BBStrategy(n, k, accountBlance) -// if signalEvents == nil { -// continue -// } -// profit := analytics.Profit(signalEvents) -// if performance < profit { -// performance = profit -// bestN = n -// bestK = k -// } -// } -// } - -// fmt.Println("最高利益", performance, "最適なピリオド", bestN, "最適な標準偏差", bestK) - -// return performance, bestN, bestK -// } - -// func (df *DataFrameCandle) OptimizeBbLoss() (performance float64, bestN int, bestK float64) { -// bestN = 20 -// bestK = 2.0 -// performance = math.MaxFloat64 - -// for n := 5; n < 120; n++ { -// for k := 1.8; k < 3.8; k += 0.1 { -// signalEvents := df.BBStrategy(n, k, accountBlance) -// if signalEvents == nil { -// continue -// } -// loss := analytics.Loss(signalEvents) -// if performance < loss { -// performance = loss -// bestN = n -// bestK = k -// } -// } -// } - -// fmt.Println("損失", performance, "最適なピリオド", bestN, "最適な標準偏差", bestK) - -// return performance, bestN, bestK -// } - -// func (df *DataFrameCandle) OptimizeBbWinRate() (performance float64, bestN int, bestK float64) { -// bestN = 20 -// bestK = 2.0 - -// for n := 13; n < 200; n++ { -// for k := 2.0; k < 3.5; k += 0.1 { -// signalEvents := df.BBStrategy(n, k, accountBlance) -// if signalEvents == nil { -// continue -// } - -// if analytics.TotalTrades(signalEvents) < 5 { -// continue -// } -// winrate := analytics.WinRate(signalEvents) -// if performance < winrate { -// performance = winrate -// bestN = n -// bestK = k -// } -// } -// } - -// fmt.Println("最高勝率", performance, "最適なピリオド", bestN, "最適な標準偏差", bestK) - -// return performance, bestN, bestK -// } +import ( + "fmt" + "log" + "math" + "v1/pkg/analytics" + "v1/pkg/config" + "v1/pkg/execute" + "v1/pkg/trader" + + "github.com/markcheno/go-talib" +) + +func getStrageyNameBb() string { + return "BB" +} + +func (df *DataFrameCandle) BbStrategy(n int, k float64, account *trader.Account) *execute.SignalEvents { + + var StrategyName = "BB" + lenCandles := len(df.Candles) + + if lenCandles <= n { + return nil + } + + signalEvents := execute.NewSignalEvents() + bbUp, _, bbDown := talib.BBands(df.Closes(), n, k, k, 0) + + buySize := 0.0 + isBuyHolding := false + for i := 1; i < lenCandles; i++ { + if i < n { + continue + } + if bbDown[i-1] > df.Candles[i-1].Close && bbDown[i] <= df.Candles[i].Close && !isBuyHolding { + buySize = account.TradeSize(0.9) / df.Candles[i].Close + signalEvents.Buy(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, true) + isBuyHolding = true + } + if bbUp[i-1] < df.Candles[i-1].Close && bbUp[i] >= df.Candles[i].Close && isBuyHolding { + signalEvents.Sell(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, true) + isBuyHolding = false + } + } + return signalEvents +} + +func (df *DataFrameCandle) OptimizeBbProfit() (performance float64, bestN int, bestK float64) { + + account := trader.NewAccount(1000) + bestN = 20 + bestK = 2.0 + + for n := 13; n < 200; n++ { + for k := 2.0; k < 3.5; k += 0.1 { + signalEvents := df.BbStrategy(n, k, account) + if signalEvents == nil { + continue + } + if analytics.TotalTrades(signalEvents) < 50 { + continue + } + profit := analytics.NetProfit(signalEvents) + if performance < profit { + performance = profit + bestN = n + bestK = k + } + } + } + + fmt.Println("最高利益", performance, "最適なピリオド", bestN, "最適な標準偏差", bestK) + + return performance, bestN, bestK +} + +func (df *DataFrameCandle) OptimizeBbLoss() (performance float64, bestN int, bestK float64) { + + account := trader.NewAccount(1000) + + bestN = 20 + bestK = 2.0 + performance = math.MaxFloat64 + + for n := 5; n < 120; n++ { + for k := 1.8; k < 3.8; k += 0.1 { + signalEvents := df.BbStrategy(n, k, account) + if signalEvents == nil { + continue + } + loss := analytics.Loss(signalEvents) + if performance < loss { + performance = loss + bestN = n + bestK = k + } + } + } + + fmt.Println("損失", performance, "最適なピリオド", bestN, "最適な標準偏差", bestK) + + return performance, bestN, bestK +} + +func (df *DataFrameCandle) OptimizeBbWinRate() (performance float64, bestN int, bestK float64) { + account := trader.NewAccount(1000) + + bestN = 20 + bestK = 2.0 + + for n := 13; n < 200; n++ { + for k := 1.8; k < 3.5; k += 0.1 { + signalEvents := df.BbStrategy(n, k, account) + if signalEvents == nil { + continue + } + + if analytics.TotalTrades(signalEvents) < 20 { + continue + } + winrate := analytics.WinRate(signalEvents) + if performance < winrate { + performance = winrate + bestN = n + bestK = k + } + } + } + + fmt.Println("最高勝率", performance, "最適なピリオド", bestN, "最適な標準偏差", bestK) + + return performance, bestN, bestK +} + +func (df *DataFrameCandle) OptimizeBbProfitFactor() (performance float64, bestN int, bestK float64) { + account := trader.NewAccount(1000) + + bestN = 20 + bestK = 2.0 + + for n := 13; n < 200; n++ { + for k := 1.8; k < 3.5; k += 0.1 { + signalEvents := df.BbStrategy(n, k, account) + if signalEvents == nil { + continue + } + + if analytics.TotalTrades(signalEvents) < 20 { + continue + } + winrate := analytics.ProfitFactor(signalEvents) + if performance < winrate { + performance = winrate + bestN = n + bestK = k + } + } + } + + fmt.Println("プロフィットファクター", performance, "最適なピリオド", bestN, "最適な標準偏差", bestK) + + return performance, bestN, bestK +} + +func (df *DataFrameCandle) OptimizeBbPayOffRatio() (performance float64, bestN int, bestK float64) { + account := trader.NewAccount(1000) + + bestN = 20 + bestK = 2.0 + + for n := 13; n < 200; n++ { + for k := 1.8; k < 3.5; k += 0.1 { + signalEvents := df.BbStrategy(n, k, account) + if signalEvents == nil { + continue + } + + if analytics.TotalTrades(signalEvents) < 20 { + continue + } + winrate := analytics.PayOffRatio(signalEvents) + if performance < winrate { + performance = winrate + bestN = n + bestK = k + } + } + } + + fmt.Println("ペイオフレシオ", performance, "最適なピリオド", bestN, "最適な標準偏差", bestK) + + return performance, bestN, bestK +} + +func RunBacktestBb() { + + var err error + + // account := trader.NewAccount(1000) + btcfg, err := config.Yaml() + if err != nil { + log.Fatalf("error: %v", err) + } + + fmt.Println(btcfg.AssetName) + + strategyName := getStrageyNameBb() + assetName := btcfg.AssetName + duration := btcfg.Dration + + account := trader.NewAccount(1000) + + df, _ := GetCandleData(assetName, duration) + + tableName := strategyName + "_" + assetName + "_" + duration + + _, err = execute.CreateDBTable(tableName) + if err != nil { + log.Fatal(err) + } + + performance, bestN, bestK := df.OptimizeBbProfitFactor() + + if performance > 0 { + + df.Signal = df.BbStrategy(bestN, bestK, account) + Result(df.Signal) + + } + +} diff --git a/pkg/strategey/donchain.go b/pkg/strategey/donchain.go index b50d047..018cd59 100644 --- a/pkg/strategey/donchain.go +++ b/pkg/strategey/donchain.go @@ -3,6 +3,8 @@ package strategey import ( "fmt" "log" + "math" + "sync" "v1/pkg/analytics" "v1/pkg/config" "v1/pkg/execute" @@ -25,6 +27,7 @@ func (df *DataFrameCandle) DonchainStrategy(period int, account *trader.Account) signalEvents := execute.NewSignalEvents() donchain := indicators.Donchain(df.Highs(), df.Low(), period) + // atr := talib.Atr(df.Highs(), df.Low(), df.Closes(), 21) close := df.Closes() @@ -37,15 +40,17 @@ func (df *DataFrameCandle) DonchainStrategy(period int, account *trader.Account) continue } if close[i] > donchain.High[i-1] && !isHolding { + buySize = account.TradeSize(riskSize) / df.Candles[i].Close + if account.Buy(df.Candles[i].Close, buySize) { - signalEvents.Buy(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, true) + signalEvents.Buy(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, false) isHolding = true } } if close[i] < donchain.Low[i-1] && isHolding { if account.Sell(df.Candles[i].Close) { - signalEvents.Sell(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, true) + signalEvents.Sell(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, false) isHolding = false buySize = 0.0 account.PositionSize = buySize @@ -69,9 +74,6 @@ func (df *DataFrameCandle) OptimizeDonchainProfit() (performance float64, bestPe for period := 5; period < 350; period++ { - account.Balance = initialBalance - account.PositionSize = 0.0 - signalEvents := df.DonchainStrategy(period, account) if signalEvents == nil { continue @@ -90,6 +92,36 @@ func (df *DataFrameCandle) OptimizeDonchainProfit() (performance float64, bestPe return performance, bestPeriod } +func (df *DataFrameCandle) OptimizeDonchainLoss() (performance float64, bestPeriod int) { + if df == nil { + return 0.0, 0 + } + + account := trader.NewAccount(1000) + + bestPeriod = 40 + performance = math.MaxFloat64 + + for period := 5; period < 350; period++ { + + signalEvents := df.DonchainStrategy(period, account) + if signalEvents == nil { + continue + } + loss := analytics.Loss(signalEvents) + if performance > loss { + performance = loss + bestPeriod = period + + } + + } + + fmt.Println("最高利益", performance, "最適なピリオド", bestPeriod) + + return performance, bestPeriod +} + func (df *DataFrameCandle) OptimizeDonchainWinRate() (performance float64, bestPeriod int) { bestPeriod = 40 @@ -97,9 +129,6 @@ func (df *DataFrameCandle) OptimizeDonchainWinRate() (performance float64, bestP for period := 10; period < 333; period++ { - account.Balance = initialBalance - account.PositionSize = 0.0 - signalEvents := df.DonchainStrategy(period, account) if signalEvents == nil { continue @@ -124,9 +153,6 @@ func (df *DataFrameCandle) OptimizeDonchainProfitFactor() (performance float64, for period := 10; period < 333; period++ { - account.Balance = initialBalance - account.PositionSize = 0.0 - signalEvents := df.DonchainStrategy(period, account) if signalEvents == nil { continue @@ -152,14 +178,11 @@ func (df *DataFrameCandle) OptimizeDonchainPayOffRatio() (performance float64, b for period := 10; period < 333; period++ { - account.Balance = initialBalance - account.PositionSize = 0.0 - signalEvents := df.DonchainStrategy(period, account) if signalEvents == nil { continue } - pf := analytics.ProfitFactor(signalEvents) + pf := analytics.PayOffRatio(signalEvents) if performance < pf { performance = pf bestPeriod = period @@ -168,7 +191,39 @@ func (df *DataFrameCandle) OptimizeDonchainPayOffRatio() (performance float64, b } - fmt.Println("プロフィットファクター", performance, "最適なピリオド", bestPeriod) + fmt.Println("ペイオフレシオ", performance, "最適なピリオド", bestPeriod) + + return performance, bestPeriod +} + +func (df *DataFrameCandle) OptimizeDonchainGoroutin() (performance float64, bestPeriod int) { + + bestPeriod = 40 + var mu sync.Mutex + var wg sync.WaitGroup + + for period := 10; period < 333; period++ { + wg.Add(1) + go func(period int) { + defer wg.Done() + account := trader.NewAccount(1000) + signalEvents := df.DonchainStrategy(period, account) + if signalEvents == nil { + return + } + pf := analytics.PayOffRatio(signalEvents) + mu.Lock() + if performance < pf { + performance = pf + bestPeriod = period + } + mu.Unlock() + }(period) + } + + wg.Wait() + + fmt.Println("ペイオフレシオ", performance, "最適なピリオド", bestPeriod) return performance, bestPeriod } @@ -200,31 +255,60 @@ func RunBacktestDonchain() { log.Fatal(err) } - // df, _ := strategey.GetCandleData(assetName, duration) + // performanceProfit, bestProfit := df.OptimizeDonchainProfit() + + // if performanceProfit > 0 { + + // df.Signal = df.DonchainStrategy(bestProfit, account) + // fmt.Println("🔺利益最適化") + // Result(df.Signal) + + // } - // profit, period := df.OptimizeProfitDonchain() + // performanceLoss, bestLoss := df.OptimizeDonchainLoss() - // if profit > 0 { + // if performanceLoss > 0 { - // df.Signal = df.DonchainStrategy(period) + // df.Signal = df.DonchainStrategy(bestLoss, account) + // fmt.Println("🔺損失最適化") + // Result(df.Signal) // } - // winrate, bestWinRateperiod := df.OptimizeDonchainWinRate() + // performanceWinRate, bestWinRate := df.OptimizeDonchainWinRate() - // if winrate > 0 { + // if performanceWinRate > 0 { - // df.Signal = df.DonchainStrategy(bestWinRateperiod, account) + // df.Signal = df.DonchainStrategy(bestWinRate, account) + // fmt.Println("🔺勝率最適化") + // Result(df.Signal) // } + // performanceProfitPeriod, bestProfitPeriod := df.OptimizeDonchainProfitFactor() - // Result(df.Signal) + // if performanceProfitPeriod > 0 { + + // df.Signal = df.DonchainStrategy(bestProfitPeriod, account) + // fmt.Println("🔺プロフィットファクター最適化") + // Result(df.Signal) + + // } + // goperformancePayOffRatio, gobestPayOffRatioPeriod := df.OptimizeDonchainGoroutin() + + // if goperformancePayOffRatio > 0 { + + // df.Signal = df.DonchainStrategy(gobestPayOffRatioPeriod, account) + // fmt.Println("🔺goroutinペイオフレシオ最適化") + // Result(df.Signal) + + // } - performance, bestProfitPeriod := df.OptimizeDonchainProfitFactor() + performancePayOffRatio, bestPayOffRatioPeriod := df.OptimizeDonchainPayOffRatio() - if performance > 0 { + if performancePayOffRatio > 0 { - df.Signal = df.DonchainStrategy(bestProfitPeriod, account) + df.Signal = df.DonchainStrategy(bestPayOffRatioPeriod, account) + fmt.Println("🔺ペイオフレシオ最適化") Result(df.Signal) } diff --git a/pkg/strategey/rsi.go b/pkg/strategey/rsi.go index fbac3f3..84bdfec 100644 --- a/pkg/strategey/rsi.go +++ b/pkg/strategey/rsi.go @@ -4,6 +4,8 @@ import ( "fmt" "log" "math" + "runtime" + "sync" "v1/pkg/analytics" "v1/pkg/config" "v1/pkg/execute" @@ -30,6 +32,8 @@ func (df *DataFrameCandle) RsiStrategy(period int, buyThread float64, sellThread values := talib.Rsi(close, period) buySize := 0.0 + buyPrice := 0.0 + slRatio := 0.9 isBuyHolding := false for i := 1; i < lenCandles; i++ { @@ -39,18 +43,18 @@ func (df *DataFrameCandle) RsiStrategy(period int, buyThread float64, sellThread if values[i-1] < buyThread && values[i] >= buyThread && !isBuyHolding { buySize = account.TradeSize(riskSize) / df.Candles[i].Close - + buyPrice = df.Candles[i].Close if account.Buy(df.Candles[i].Close, buySize) { - signalEvents.Buy(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, true) + signalEvents.Buy(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, false) isBuyHolding = true } } - if values[i-1] > float64(sellThread) && values[i] <= float64(sellThread) && isBuyHolding { + if values[i-1] > sellThread && values[i] <= sellThread || (df.Candles[i].Close <= buyPrice*slRatio) && isBuyHolding { if account.Sell(df.Candles[i].Close) { - signalEvents.Sell(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, true) + signalEvents.Sell(StrategyName, df.AssetName, df.Duration, df.Candles[i].Date, df.Candles[i].Close, buySize, false) isBuyHolding = false buySize = 0.0 account.PositionSize = buySize @@ -271,7 +275,7 @@ func (df *DataFrameCandle) OptimizeRsiProfitFactor() (performance float64, bestP continue } - if analytics.TotalTrades(signalEvents) < 40 { + if analytics.TotalTrades(signalEvents) < 20 { continue } @@ -297,7 +301,7 @@ func (df *DataFrameCandle) OptimizeRsiPayOffRatio() (performance float64, bestPe bestPeriod = 14 bestBuyThread, bestSellThread = 20.0, 80.0 - for period := 4; period < 25; period++ { + for period := 3; period < 25; period++ { for buyThread := 30.0; buyThread > 10; buyThread -= 1 { for sellThread := 75.0; sellThread < 96; sellThread += 1 { @@ -306,12 +310,12 @@ func (df *DataFrameCandle) OptimizeRsiPayOffRatio() (performance float64, bestPe continue } - if analytics.TotalTrades(signalEvents) < 40 { + if analytics.TotalTrades(signalEvents) < 20 { continue } payOffRatio := analytics.PayOffRatio(signalEvents) - if performance < payOffRatio { + if performance == 0 || performance < payOffRatio { performance = payOffRatio bestPeriod = period bestBuyThread = buyThread @@ -341,7 +345,7 @@ func (df *DataFrameCandle) OptimizeRsiSharpRatio() (performance float64, bestPer continue } - if analytics.TotalTrades(signalEvents) < 40 { + if analytics.TotalTrades(signalEvents) < 20 { continue } @@ -362,6 +366,51 @@ func (df *DataFrameCandle) OptimizeRsiSharpRatio() (performance float64, bestPer return performance, bestPeriod, bestBuyThread, bestSellThread } +func (df *DataFrameCandle) OptimizeRsiGoroutin() (performance float64, bestPeriod int, bestBuyThread, bestSellThread float64) { + runtime.GOMAXPROCS(10) + + bestPeriod = 13 + bestBuyThread, bestSellThread = 20.0, 80.0 + var mu sync.Mutex + var wg sync.WaitGroup + + for period := 2; period < 28; period++ { + for buyThread := 30.0; buyThread > 10; buyThread -= 1 { + for sellThread := 70.0; sellThread < 96; sellThread += 1 { + wg.Add(1) + go func(period int, buyThread, sellThread float64) { + defer wg.Done() + account := trader.NewAccount(1000) // Move this line inside the goroutine + signalEvents := df.RsiStrategy(period, buyThread, sellThread, account) + if signalEvents == nil { + return + } + + if analytics.TotalTrades(signalEvents) < 20 { + return + } + + payOffRatio := analytics.NetProfit(signalEvents) + mu.Lock() + if performance == 0 || performance < payOffRatio { + performance = payOffRatio + bestPeriod = period + bestBuyThread = buyThread + bestSellThread = sellThread + } + mu.Unlock() + }(period, buyThread, sellThread) + } + } + } + + wg.Wait() + + fmt.Println("ペイオフレシオ", performance, "最適なピリオド", bestPeriod, "最適な買いライン", bestBuyThread, "最適な売りライン", bestSellThread) + + return performance, bestPeriod, bestBuyThread, bestSellThread +} + func RunBacktestRsi() { var err error @@ -389,7 +438,7 @@ func RunBacktestRsi() { log.Fatal(err) } - performance, bestPeriod, bestBuyThread, bestSellThread := df.OptimizeRsiPayOffRatio() + performance, bestPeriod, bestBuyThread, bestSellThread := df.OptimizeRsiGoroutin() if performance > 0 { diff --git a/pkg/strategey/strategy.go b/pkg/strategey/strategy.go index a907087..b2254c6 100755 --- a/pkg/strategey/strategy.go +++ b/pkg/strategey/strategy.go @@ -142,7 +142,7 @@ func (df *DataFrameCandle) Volume() []float64 { func Result(s *execute.SignalEvents) { - if s == nil { + if s == nil || len(s.Signals) == 0 { return } @@ -180,5 +180,5 @@ func Result(s *execute.SignalEvents) { fmt.Println("1トレードの最大損失と日時", ml, mt) // fmt.Println("バルサラの破産確率", analytics.BalsaraAxum(s)) - fmt.Println(s) + // fmt.Println(s) } diff --git a/pkg/utils/get_csv_data/get_data.py b/pkg/utils/get_csv_data/get_data.py index 4172afe..f77da30 100755 --- a/pkg/utils/get_csv_data/get_data.py +++ b/pkg/utils/get_csv_data/get_data.py @@ -19,6 +19,6 @@ tickers=tickers, date_start=None, date_end=None, - is_to_update_existing=False, + is_to_update_existing=True, tickers_to_exclude=["UST"], )