Files
gocryptotrader/backtester/report/report_test.go
Adam 08f1b5d5d3 rpcserver/exchanges: Add additional param checks plus other minor bugfixes/improvements (#652)
* deleting the unwanted file created during testing + adding more verbose errors for cli

* wip

* checking params throughout wip

* improving errors

* wip

* thrasher patch

* better err name

* whip

* testing and fixing errors WIP

* upgrades and better errors

* broken test

* wip

* adding some tests

* using tempDir

* mini improvement

* little changes

* better time check

* fixing error

* more glorious changes

* end of day wip

* shazzy changes

* checking error

* appveyor

* last changes:
2021-03-30 13:40:01 +11:00

441 lines
12 KiB
Go

package report
import (
"errors"
"io/ioutil"
"os"
"path/filepath"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/backtester/config"
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/portfolio/compliance"
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/portfolio/holdings"
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/statistics"
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/statistics/currencystatistics"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
gctkline "github.com/thrasher-corp/gocryptotrader/exchanges/kline"
gctorder "github.com/thrasher-corp/gocryptotrader/exchanges/order"
)
const testExchange = "binance"
func TestGenerateReport(t *testing.T) {
e := testExchange
a := asset.Spot
p := currency.NewPair(currency.BTC, currency.USDT)
tempDir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("Problem creating temp dir at %s: %s\n", tempDir, err)
}
defer os.RemoveAll(tempDir)
d := Data{
Config: &config.Config{},
OutputPath: filepath.Join("..", "results"),
TemplatePath: filepath.Join("tpl.gohtml"),
OriginalCandles: []*gctkline.Item{
{
Candles: []gctkline.Candle{
{},
},
},
},
EnhancedCandles: []DetailedKline{
{
Exchange: e,
Asset: a,
Pair: p,
Interval: gctkline.OneHour,
Watermark: "Binance - SPOT - BTC-USDT",
Candles: []DetailedCandle{
{
Time: time.Now().Add(-time.Hour * 5).Unix(),
Open: 1337,
High: 1339,
Low: 1336,
Close: 1338,
Volume: 3,
MadeOrder: true,
OrderDirection: gctorder.Buy,
OrderAmount: 1337,
Shape: "arrowUp",
Text: "hi",
Position: "aboveBar",
Colour: "green",
PurchasePrice: 50,
VolumeColour: "rgba(47, 194, 27, 0.8)",
},
{
Time: time.Now().Add(-time.Hour * 4).Unix(),
Open: 1332,
High: 1332,
Low: 1330,
Close: 1331,
Volume: 2,
MadeOrder: true,
OrderDirection: gctorder.Buy,
OrderAmount: 1337,
Shape: "arrowUp",
Text: "hi",
Position: "aboveBar",
Colour: "green",
PurchasePrice: 50,
VolumeColour: "rgba(252, 3, 3, 0.8)",
},
{
Time: time.Now().Add(-time.Hour * 3).Unix(),
Open: 1337,
High: 1339,
Low: 1336,
Close: 1338,
Volume: 3,
MadeOrder: true,
OrderDirection: gctorder.Buy,
OrderAmount: 1337,
Shape: "arrowUp",
Text: "hi",
Position: "aboveBar",
Colour: "green",
PurchasePrice: 50,
VolumeColour: "rgba(47, 194, 27, 0.8)",
},
{
Time: time.Now().Add(-time.Hour * 2).Unix(),
Open: 1337,
High: 1339,
Low: 1336,
Close: 1338,
Volume: 3,
MadeOrder: true,
OrderDirection: gctorder.Buy,
OrderAmount: 1337,
Shape: "arrowUp",
Text: "hi",
Position: "aboveBar",
Colour: "green",
PurchasePrice: 50,
VolumeColour: "rgba(252, 3, 3, 0.8)",
},
{
Time: time.Now().Unix(),
Open: 1337,
High: 1339,
Low: 1336,
Close: 1338,
Volume: 3,
VolumeColour: "rgba(47, 194, 27, 0.8)",
},
},
},
{
Exchange: "Bittrex",
Asset: a,
Pair: currency.NewPair(currency.BTC, currency.USD),
Interval: gctkline.OneDay,
Watermark: "BITTREX - SPOT - BTC-USD - 1d",
Candles: []DetailedCandle{
{
Time: time.Now().Add(-time.Hour * 5).Unix(),
Open: 1337,
High: 1339,
Low: 1336,
Close: 1338,
Volume: 3,
MadeOrder: true,
OrderDirection: gctorder.Buy,
OrderAmount: 1337,
Shape: "arrowUp",
Text: "hi",
Position: "aboveBar",
Colour: "green",
PurchasePrice: 50,
VolumeColour: "rgba(47, 194, 27, 0.8)",
},
{
Time: time.Now().Add(-time.Hour * 4).Unix(),
Open: 1332,
High: 1332,
Low: 1330,
Close: 1331,
Volume: 2,
MadeOrder: true,
OrderDirection: gctorder.Buy,
OrderAmount: 1337,
Shape: "arrowUp",
Text: "hi",
Position: "aboveBar",
Colour: "green",
PurchasePrice: 50,
VolumeColour: "rgba(252, 3, 3, 0.8)",
},
{
Time: time.Now().Add(-time.Hour * 3).Unix(),
Open: 1337,
High: 1339,
Low: 1336,
Close: 1338,
Volume: 3,
MadeOrder: true,
OrderDirection: gctorder.Buy,
OrderAmount: 1337,
Shape: "arrowUp",
Text: "hi",
Position: "aboveBar",
Colour: "green",
PurchasePrice: 50,
VolumeColour: "rgba(47, 194, 27, 0.8)",
},
{
Time: time.Now().Add(-time.Hour * 2).Unix(),
Open: 1337,
High: 1339,
Low: 1336,
Close: 1338,
Volume: 3,
MadeOrder: true,
OrderDirection: gctorder.Buy,
OrderAmount: 1337,
Shape: "arrowUp",
Text: "hi",
Position: "aboveBar",
Colour: "green",
PurchasePrice: 50,
VolumeColour: "rgba(252, 3, 3, 0.8)",
},
{
Time: time.Now().Unix(),
Open: 1337,
High: 1339,
Low: 1336,
Close: 1338,
Volume: 3,
VolumeColour: "rgba(47, 194, 27, 0.8)",
},
},
},
},
Statistics: &statistics.Statistic{
StrategyName: "testStrat",
ExchangeAssetPairStatistics: map[string]map[asset.Item]map[currency.Pair]*currencystatistics.CurrencyStatistic{
e: {
a: {
p: &currencystatistics.CurrencyStatistic{
MaxDrawdown: currencystatistics.Swing{},
LowestClosePrice: 100,
HighestClosePrice: 200,
MarketMovement: 100,
StrategyMovement: 100,
RiskFreeRate: 1,
CompoundAnnualGrowthRate: 1,
BuyOrders: 1,
SellOrders: 1,
FinalHoldings: holdings.Holding{},
FinalOrders: compliance.Snapshot{},
},
},
},
},
RiskFreeRate: 0.03,
TotalBuyOrders: 1337,
TotalSellOrders: 1330,
TotalOrders: 200,
BiggestDrawdown: &statistics.FinalResultsHolder{
Exchange: e,
Asset: a,
Pair: p,
MaxDrawdown: currencystatistics.Swing{
Highest: currencystatistics.Iteration{
Time: time.Now(),
Price: 1337,
},
Lowest: currencystatistics.Iteration{
Time: time.Now(),
Price: 137,
},
DrawdownPercent: 100,
},
MarketMovement: 1377,
StrategyMovement: 1377,
},
BestStrategyResults: &statistics.FinalResultsHolder{
Exchange: e,
Asset: a,
Pair: p,
MaxDrawdown: currencystatistics.Swing{
Highest: currencystatistics.Iteration{
Time: time.Now(),
Price: 1337,
},
Lowest: currencystatistics.Iteration{
Time: time.Now(),
Price: 137,
},
DrawdownPercent: 100,
},
MarketMovement: 1337,
StrategyMovement: 1337,
},
BestMarketMovement: &statistics.FinalResultsHolder{
Exchange: e,
Asset: a,
Pair: p,
MaxDrawdown: currencystatistics.Swing{
Highest: currencystatistics.Iteration{
Time: time.Now(),
Price: 1337,
},
Lowest: currencystatistics.Iteration{
Time: time.Now(),
Price: 137,
},
DrawdownPercent: 100,
},
MarketMovement: 1337,
StrategyMovement: 1337,
},
},
}
d.OutputPath = tempDir
err = d.GenerateReport()
if err != nil {
t.Error(err)
}
}
func TestEnhanceCandles(t *testing.T) {
tt := time.Now()
var d Data
err := d.enhanceCandles()
if !errors.Is(err, errNoCandles) {
t.Errorf("expected: %v, received %v", errNoCandles, err)
}
d.AddKlineItem(&gctkline.Item{})
err = d.enhanceCandles()
if !errors.Is(err, errStatisticsUnset) {
t.Errorf("expected: %v, received %v", errStatisticsUnset, err)
}
d.Statistics = &statistics.Statistic{}
err = d.enhanceCandles()
if err != nil {
t.Error(err)
}
d.Statistics.ExchangeAssetPairStatistics = make(map[string]map[asset.Item]map[currency.Pair]*currencystatistics.CurrencyStatistic)
d.Statistics.ExchangeAssetPairStatistics[testExchange] = make(map[asset.Item]map[currency.Pair]*currencystatistics.CurrencyStatistic)
d.Statistics.ExchangeAssetPairStatistics[testExchange][asset.Spot] = make(map[currency.Pair]*currencystatistics.CurrencyStatistic)
d.Statistics.ExchangeAssetPairStatistics[testExchange][asset.Spot][currency.NewPair(currency.BTC, currency.USDT)] = &currencystatistics.CurrencyStatistic{}
d.AddKlineItem(&gctkline.Item{
Exchange: testExchange,
Pair: currency.NewPair(currency.BTC, currency.USDT),
Asset: asset.Spot,
Interval: gctkline.OneDay,
Candles: []gctkline.Candle{
{
Time: tt,
Open: 1336,
High: 1338,
Low: 1336,
Close: 1337,
Volume: 1337,
},
},
})
err = d.enhanceCandles()
if err != nil {
t.Error(err)
}
d.AddKlineItem(&gctkline.Item{
Exchange: testExchange,
Pair: currency.NewPair(currency.BTC, currency.USDT),
Asset: asset.Spot,
Interval: gctkline.OneDay,
Candles: []gctkline.Candle{
{
Time: tt,
Open: 1336,
High: 1338,
Low: 1336,
Close: 1336,
Volume: 1337,
},
{
Time: tt,
Open: 1336,
High: 1338,
Low: 1336,
Close: 1335,
Volume: 1337,
},
},
})
err = d.enhanceCandles()
if err != nil {
t.Error(err)
}
d.Statistics.ExchangeAssetPairStatistics[testExchange][asset.Spot][currency.NewPair(currency.BTC, currency.USDT)].FinalOrders = compliance.Snapshot{
Orders: []compliance.SnapshotOrder{
{
ClosePrice: 1335,
VolumeAdjustedPrice: 1337,
SlippageRate: 1,
CostBasis: 1337,
Detail: nil,
},
},
Timestamp: tt,
}
err = d.enhanceCandles()
if err != nil {
t.Error(err)
}
d.Statistics.ExchangeAssetPairStatistics[testExchange][asset.Spot][currency.NewPair(currency.BTC, currency.USDT)].FinalOrders = compliance.Snapshot{
Orders: []compliance.SnapshotOrder{
{
ClosePrice: 1335,
VolumeAdjustedPrice: 1337,
SlippageRate: 1,
CostBasis: 1337,
Detail: &gctorder.Detail{
Date: tt,
Side: gctorder.Buy,
},
},
},
Timestamp: tt,
}
err = d.enhanceCandles()
if err != nil {
t.Error(err)
}
d.Statistics.ExchangeAssetPairStatistics[testExchange][asset.Spot][currency.NewPair(currency.BTC, currency.USDT)].FinalOrders = compliance.Snapshot{
Orders: []compliance.SnapshotOrder{
{
ClosePrice: 1335,
VolumeAdjustedPrice: 1337,
SlippageRate: 1,
CostBasis: 1337,
Detail: &gctorder.Detail{
Date: tt,
Side: gctorder.Sell,
},
},
},
Timestamp: tt,
}
err = d.enhanceCandles()
if err != nil {
t.Error(err)
}
if len(d.EnhancedCandles) == 0 {
t.Error("expected enhanced candles")
}
}