mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
CI: Fix golangci-lint linter issues, add prealloc linter and bump version depends for Go 1.18 (#915)
* Bump CI versions * Specifically set go version as 1.17.x bumps it to 1.18 * Another * Adjust AppVeyor * Part 1 of linter issues * Part 2 * Fix various linters and improvements * Part 3 * Finishing touches * Tests and EqualFold * Fix nitterinos plus bonus requester jobs bump for exchanges with large number of tests * Fix nitterinos and bump golangci-lint timeout for AppVeyor * Address nits, ensure all books are returned on err due to syncer regression * Fix the wiggins * Fix duplication * Fix nitterinos
This commit is contained in:
25
common/cache/cache_test.go
vendored
25
common/cache/cache_test.go
vendored
@@ -2,6 +2,8 @@ package cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
||||
)
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
@@ -16,12 +18,11 @@ func TestCache(t *testing.T) {
|
||||
if v == nil {
|
||||
t.Fatal("expected cache to contain \"hello\" key")
|
||||
}
|
||||
if v.(string) != "world" {
|
||||
if convert.InterfaceToStringOrZeroValue(v) != "world" {
|
||||
t.Fatal("expected \"hello\" key to contain value \"world\"")
|
||||
}
|
||||
|
||||
r := lruCache.Remove("hello")
|
||||
if !r {
|
||||
if r := lruCache.Remove("hello"); !r {
|
||||
t.Fatal("expected \"hello\" key to be removed from cache")
|
||||
}
|
||||
|
||||
@@ -77,39 +78,39 @@ func TestAdd(t *testing.T) {
|
||||
if v == nil {
|
||||
t.Fatal("expected cache to contain \"2\" key")
|
||||
}
|
||||
if v.(int) != 2 {
|
||||
if convert.InterfaceToIntOrZeroValue(v) != 2 {
|
||||
t.Fatal("expected \"2\" key to contain value \"2\"")
|
||||
}
|
||||
k, v := lruCache.getNewest()
|
||||
if k.(int) != 2 {
|
||||
if convert.InterfaceToIntOrZeroValue(k) != 2 {
|
||||
t.Fatal("expected latest key to be 2")
|
||||
}
|
||||
if v.(int) != 2 {
|
||||
if convert.InterfaceToIntOrZeroValue(v) != 2 {
|
||||
t.Fatal("expected latest value to be 2")
|
||||
}
|
||||
lruCache.Add(3, 3)
|
||||
k, _ = lruCache.getNewest()
|
||||
if k.(int) != 3 {
|
||||
if convert.InterfaceToIntOrZeroValue(k) != 3 {
|
||||
t.Fatal("expected latest key to be 3")
|
||||
}
|
||||
k, _ = lruCache.getOldest()
|
||||
if k.(int) != 2 {
|
||||
if convert.InterfaceToIntOrZeroValue(k) != 2 {
|
||||
t.Fatal("expected oldest key to be 2")
|
||||
}
|
||||
k, v = lruCache.getOldest()
|
||||
if k.(int) != 2 {
|
||||
if convert.InterfaceToIntOrZeroValue(k) != 2 {
|
||||
t.Fatal("expected oldest key to be 2")
|
||||
}
|
||||
if v.(int) != 2 {
|
||||
if convert.InterfaceToIntOrZeroValue(v) != 2 {
|
||||
t.Fatal("expected latest value to be 2")
|
||||
}
|
||||
lruCache.Add(2, 2)
|
||||
k, _ = lruCache.getNewest()
|
||||
if k.(int) != 2 {
|
||||
if convert.InterfaceToIntOrZeroValue(k) != 2 {
|
||||
t.Fatal("expected latest key to be 2")
|
||||
}
|
||||
k, _ = lruCache.getOldest()
|
||||
if k.(int) != 3 {
|
||||
if convert.InterfaceToIntOrZeroValue(k) != 3 {
|
||||
t.Fatal("expected oldest key to be 3")
|
||||
}
|
||||
}
|
||||
|
||||
20
common/cache/lru.go
vendored
20
common/cache/lru.go
vendored
@@ -24,7 +24,9 @@ func NewLRUCache(capacity uint64) *LRU {
|
||||
func (l *LRU) Add(key, value interface{}) {
|
||||
if f, o := l.items[key]; o {
|
||||
l.l.MoveToFront(f)
|
||||
f.Value.(*item).value = value
|
||||
if v, ok := f.Value.(*item); ok {
|
||||
v.value = value
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -40,7 +42,9 @@ func (l *LRU) Add(key, value interface{}) {
|
||||
func (l *LRU) Get(key interface{}) interface{} {
|
||||
if i, f := l.items[key]; f {
|
||||
l.l.MoveToFront(i)
|
||||
return i.Value.(*item).value
|
||||
if v, ok := i.Value.(*item); ok {
|
||||
return v.value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -48,7 +52,9 @@ func (l *LRU) Get(key interface{}) interface{} {
|
||||
// GetOldest returns the oldest entry
|
||||
func (l *LRU) getOldest() (key, value interface{}) {
|
||||
if x := l.l.Back(); x != nil {
|
||||
return x.Value.(*item).key, x.Value.(*item).value
|
||||
if v, ok := x.Value.(*item); ok {
|
||||
return v.key, v.value
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -56,7 +62,9 @@ func (l *LRU) getOldest() (key, value interface{}) {
|
||||
// GetNewest returns the newest entry
|
||||
func (l *LRU) getNewest() (key, value interface{}) {
|
||||
if x := l.l.Front(); x != nil {
|
||||
return x.Value.(*item).key, x.Value.(*item).value
|
||||
if v, ok := x.Value.(*item); ok {
|
||||
return v.key, v.value
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -99,5 +107,7 @@ func (l *LRU) removeOldestEntry() {
|
||||
// removeElement element from the cache
|
||||
func (l *LRU) removeElement(e *list.Element) {
|
||||
l.l.Remove(e)
|
||||
delete(l.items, e.Value.(*item).key)
|
||||
if v, ok := e.Value.(*item); ok {
|
||||
delete(l.items, v.key)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -18,6 +17,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common/file"
|
||||
"github.com/thrasher-corp/gocryptotrader/log"
|
||||
)
|
||||
|
||||
@@ -257,7 +257,7 @@ func SendHTTPRequest(ctx context.Context, method, urlPath string, headers map[st
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
contents, err := ioutil.ReadAll(resp.Body)
|
||||
contents, err := io.ReadAll(resp.Body)
|
||||
|
||||
if verbose {
|
||||
log.Debugf(log.Global, "HTTP status: %s, Code: %v",
|
||||
@@ -348,7 +348,7 @@ func CreateDir(dir string) error {
|
||||
}
|
||||
|
||||
log.Warnf(log.Global, "Directory %s does not exist.. creating.\n", dir)
|
||||
return os.MkdirAll(dir, 0770)
|
||||
return os.MkdirAll(dir, file.DefaultPermissionOctal)
|
||||
}
|
||||
|
||||
// ChangePermission lists all the directories and files in an array
|
||||
@@ -357,8 +357,8 @@ func ChangePermission(directory string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Mode().Perm() != 0770 {
|
||||
return os.Chmod(path, 0770)
|
||||
if info.Mode().Perm() != file.DefaultPermissionOctal {
|
||||
return os.Chmod(path, file.DefaultPermissionOctal)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -14,6 +14,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common/file"
|
||||
)
|
||||
|
||||
func TestSendHTTPRequest(t *testing.T) {
|
||||
@@ -509,7 +511,7 @@ func TestChangePermission(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Fatal("expected an error on non-existent path")
|
||||
}
|
||||
err = os.Mkdir(testDir, 0777)
|
||||
err = os.Mkdir(testDir, 0o777)
|
||||
if err != nil {
|
||||
t.Fatalf("Mkdir failed. Err: %v", err)
|
||||
}
|
||||
@@ -530,7 +532,7 @@ func TestChangePermission(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Fatal("expected an error on non-existent path")
|
||||
}
|
||||
err = os.Mkdir(testDir, 0777)
|
||||
err = os.Mkdir(testDir, 0o777)
|
||||
if err != nil {
|
||||
t.Fatalf("Mkdir failed. Err: %v", err)
|
||||
}
|
||||
@@ -543,8 +545,8 @@ func TestChangePermission(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("os.Stat failed. Err: %v", err)
|
||||
}
|
||||
if a.Mode().Perm() != 0770 {
|
||||
t.Fatalf("expected file permissions differ. expecting 0770 got %#o", a.Mode().Perm())
|
||||
if a.Mode().Perm() != file.DefaultPermissionOctal {
|
||||
t.Fatalf("expected file permissions differ. expecting file.DefaultPermissionOctal got %#o", a.Mode().Perm())
|
||||
}
|
||||
err = os.Remove(testDir)
|
||||
if err != nil {
|
||||
|
||||
@@ -119,8 +119,7 @@ func DecimalToHumanFriendlyString(number decimal.Decimal, rounding int, decPoint
|
||||
neg = true
|
||||
}
|
||||
str := number.String()
|
||||
rnd := strings.Split(str, ".")
|
||||
if len(rnd) == 1 {
|
||||
if rnd := strings.Split(str, "."); len(rnd) == 1 {
|
||||
rounding = 0
|
||||
} else if len(rnd[1]) < rounding {
|
||||
rounding = len(rnd[1])
|
||||
@@ -164,3 +163,27 @@ func numberToHumanFriendlyString(str string, dec int, decPoint, thousandsSep str
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// InterfaceToFloat64OrZeroValue returns the type assertion value or variable zero value
|
||||
func InterfaceToFloat64OrZeroValue(r interface{}) float64 {
|
||||
if v, ok := r.(float64); ok {
|
||||
return v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// InterfaceToIntOrZeroValue returns the type assertion value or variable zero value
|
||||
func InterfaceToIntOrZeroValue(r interface{}) int {
|
||||
if v, ok := r.(int); ok {
|
||||
return v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// InterfaceToStringOrZeroValue returns the type assertion value or variable zero value
|
||||
func InterfaceToStringOrZeroValue(r interface{}) string {
|
||||
if v, ok := r.(string); ok {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -282,3 +282,36 @@ func TestNumberToHumanFriendlyString(t *testing.T) {
|
||||
t.Error("expected no comma")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceToFloat64OrZeroValue(t *testing.T) {
|
||||
var x interface{}
|
||||
if r := InterfaceToFloat64OrZeroValue(x); r != 0 {
|
||||
t.Errorf("expected 0, got: %v", r)
|
||||
}
|
||||
x = float64(420)
|
||||
if r := InterfaceToFloat64OrZeroValue(x); r != 420 {
|
||||
t.Errorf("expected 420, got: %v", x)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceToIntOrZeroValue(t *testing.T) {
|
||||
var x interface{}
|
||||
if r := InterfaceToIntOrZeroValue(x); r != 0 {
|
||||
t.Errorf("expected 0, got: %v", r)
|
||||
}
|
||||
x = int(420)
|
||||
if r := InterfaceToIntOrZeroValue(x); r != 420 {
|
||||
t.Errorf("expected 420, got: %v", x)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceToStringOrZeroValue(t *testing.T) {
|
||||
var x interface{}
|
||||
if r := InterfaceToStringOrZeroValue(x); r != "" {
|
||||
t.Errorf("expected empty string, got: %v", r)
|
||||
}
|
||||
x = string("meow")
|
||||
if r := InterfaceToStringOrZeroValue(x); r != "meow" {
|
||||
t.Errorf("expected meow, got: %v", x)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ func TestGetHMAC(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(sha1) != string(expectedSha1) {
|
||||
if !bytes.Equal(sha1, expectedSha1) {
|
||||
t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'",
|
||||
expectedSha1, sha1,
|
||||
)
|
||||
@@ -157,7 +157,7 @@ func TestGetHMAC(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(sha256) != string(expectedsha256) {
|
||||
if !bytes.Equal(sha256, expectedsha256) {
|
||||
t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'",
|
||||
expectedsha256, sha256,
|
||||
)
|
||||
@@ -166,7 +166,7 @@ func TestGetHMAC(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(sha512) != string(expectedsha512) {
|
||||
if !bytes.Equal(sha512, expectedsha512) {
|
||||
t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'",
|
||||
expectedsha512, sha512,
|
||||
)
|
||||
@@ -175,7 +175,7 @@ func TestGetHMAC(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(sha512384) != string(expectedsha512384) {
|
||||
if !bytes.Equal(sha512384, expectedsha512384) {
|
||||
t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'",
|
||||
expectedsha512384, sha512384,
|
||||
)
|
||||
@@ -184,7 +184,7 @@ func TestGetHMAC(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(md5) != string(expectedmd5) {
|
||||
if !bytes.Equal(md5, expectedmd5) {
|
||||
t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'",
|
||||
expectedmd5, md5,
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common/file"
|
||||
"github.com/thrasher-corp/gocryptotrader/log"
|
||||
)
|
||||
|
||||
@@ -52,7 +53,7 @@ func UnZip(src, dest string) (fileList []string, err error) {
|
||||
continue
|
||||
}
|
||||
|
||||
err = os.MkdirAll(filepath.Dir(fPath), 0770)
|
||||
err = os.MkdirAll(filepath.Dir(fPath), file.DefaultPermissionOctal)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,22 +6,25 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// DefaultPermissionOctal is the default file and folder permission octal used throughout GCT
|
||||
const DefaultPermissionOctal fs.FileMode = 0o770
|
||||
|
||||
// Write writes selected data to a file or returns an error if it fails. This
|
||||
// func also ensures that all files are set to this permission (only rw access
|
||||
// for the running user and the group the user is a member of)
|
||||
func Write(file string, data []byte) error {
|
||||
basePath := filepath.Dir(file)
|
||||
if !Exists(basePath) {
|
||||
if err := os.MkdirAll(basePath, 0770); err != nil {
|
||||
if err := os.MkdirAll(basePath, DefaultPermissionOctal); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return ioutil.WriteFile(file, data, 0770)
|
||||
return os.WriteFile(file, data, DefaultPermissionOctal)
|
||||
}
|
||||
|
||||
// Writer creates a writer to a file or returns an error if it fails. This
|
||||
@@ -30,11 +33,11 @@ func Write(file string, data []byte) error {
|
||||
func Writer(file string) (*os.File, error) {
|
||||
basePath := filepath.Dir(file)
|
||||
if !Exists(basePath) {
|
||||
if err := os.MkdirAll(basePath, 0770); err != nil {
|
||||
if err := os.MkdirAll(basePath, DefaultPermissionOctal); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0770)
|
||||
return os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, DefaultPermissionOctal)
|
||||
}
|
||||
|
||||
// Move moves a file from a source path to a destination path
|
||||
@@ -59,7 +62,7 @@ func Move(sourcePath, destPath string) error {
|
||||
|
||||
destDir := filepath.Dir(destPath)
|
||||
if !Exists(destDir) {
|
||||
err = os.MkdirAll(destDir, 0770)
|
||||
err = os.MkdirAll(destDir, DefaultPermissionOctal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ func TestWrite(t *testing.T) {
|
||||
func TestMove(t *testing.T) {
|
||||
tester := func(in, out string, write bool) error {
|
||||
if write {
|
||||
if err := ioutil.WriteFile(in, []byte("GoCryptoTrader"), 0770); err != nil {
|
||||
if err := os.WriteFile(in, []byte("GoCryptoTrader"), DefaultPermissionOctal); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ func TestMove(t *testing.T) {
|
||||
return err
|
||||
}
|
||||
|
||||
contents, err := ioutil.ReadFile(out)
|
||||
contents, err := os.ReadFile(out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -124,7 +124,7 @@ func TestExists(t *testing.T) {
|
||||
t.Error("non-existent file should not exist")
|
||||
}
|
||||
tmpFile := filepath.Join(os.TempDir(), "gct-test.txt")
|
||||
if err := ioutil.WriteFile(tmpFile, []byte("hello world"), os.ModeAppend); err != nil {
|
||||
if err := os.WriteFile(tmpFile, []byte("hello world"), os.ModeAppend); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if e := Exists(tmpFile); !e {
|
||||
@@ -258,7 +258,7 @@ func TestWriter(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if data, err := ioutil.ReadFile(got.Name()); err != nil || string(data) != testData {
|
||||
if data, err := os.ReadFile(got.Name()); err != nil || string(data) != testData {
|
||||
t.Errorf("Could not write the file, or contents were wrong: expected = %s, got =%s", testData, string(data))
|
||||
}
|
||||
})
|
||||
@@ -274,7 +274,7 @@ func TestWriterNoPermissionFails(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(temp)
|
||||
err = os.Chmod(temp, 0555)
|
||||
err = os.Chmod(temp, 0o555)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -89,9 +89,9 @@ func InformationRatio(returnsRates, benchmarkRates []float64, averageValues, ave
|
||||
if len(benchmarkRates) != len(returnsRates) {
|
||||
return 0, errInformationBadLength
|
||||
}
|
||||
var diffs []float64
|
||||
diffs := make([]float64, len(returnsRates))
|
||||
for i := range returnsRates {
|
||||
diffs = append(diffs, returnsRates[i]-benchmarkRates[i])
|
||||
diffs[i] = returnsRates[i] - benchmarkRates[i]
|
||||
}
|
||||
stdDev, err := PopulationStandardDeviation(diffs)
|
||||
if err != nil {
|
||||
@@ -135,11 +135,11 @@ func SampleStandardDeviation(values []float64) (float64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var superMean []float64
|
||||
superMean := make([]float64, len(values))
|
||||
var combined float64
|
||||
for i := range values {
|
||||
result := math.Pow(values[i]-mean, 2)
|
||||
superMean = append(superMean, result)
|
||||
superMean[i] = result
|
||||
combined += result
|
||||
}
|
||||
avg := combined / (float64(len(superMean)) - 1)
|
||||
@@ -232,9 +232,9 @@ func SharpeRatio(movementPerCandle []float64, riskFreeRatePerInterval, average f
|
||||
if totalIntervals == 0 {
|
||||
return 0, errZeroValue
|
||||
}
|
||||
var excessReturns []float64
|
||||
excessReturns := make([]float64, len(movementPerCandle))
|
||||
for i := range movementPerCandle {
|
||||
excessReturns = append(excessReturns, movementPerCandle[i]-riskFreeRatePerInterval)
|
||||
excessReturns[i] = movementPerCandle[i] - riskFreeRatePerInterval
|
||||
}
|
||||
standardDeviation, err := PopulationStandardDeviation(excessReturns)
|
||||
if err != nil {
|
||||
@@ -284,9 +284,9 @@ func DecimalInformationRatio(returnsRates, benchmarkRates []decimal.Decimal, ave
|
||||
if len(benchmarkRates) != len(returnsRates) {
|
||||
return decimal.Zero, errInformationBadLength
|
||||
}
|
||||
var diffs []decimal.Decimal
|
||||
diffs := make([]decimal.Decimal, len(returnsRates))
|
||||
for i := range returnsRates {
|
||||
diffs = append(diffs, returnsRates[i].Sub(benchmarkRates[i]))
|
||||
diffs[i] = returnsRates[i].Sub(benchmarkRates[i])
|
||||
}
|
||||
stdDev, err := DecimalPopulationStandardDeviation(diffs)
|
||||
if err != nil && !errors.Is(err, ErrInexactConversion) {
|
||||
@@ -339,11 +339,11 @@ func DecimalSampleStandardDeviation(values []decimal.Decimal) (decimal.Decimal,
|
||||
if err != nil {
|
||||
return decimal.Zero, err
|
||||
}
|
||||
var superMean []decimal.Decimal
|
||||
superMean := make([]decimal.Decimal, len(values))
|
||||
var combined decimal.Decimal
|
||||
for i := range values {
|
||||
pow := values[i].Sub(mean).Pow(decimal.NewFromInt(2))
|
||||
superMean = append(superMean, pow)
|
||||
superMean[i] = pow
|
||||
combined.Add(pow)
|
||||
}
|
||||
avg := combined.Div(decimal.NewFromInt(int64(len(superMean))).Sub(decimal.NewFromInt(1)))
|
||||
@@ -380,9 +380,7 @@ func DecimalGeometricMean(values []decimal.Decimal) (decimal.Decimal, error) {
|
||||
// DecimalPow is lovely because shopspring decimal cannot
|
||||
// handle ^0.x and instead returns 1
|
||||
func DecimalPow(x, y decimal.Decimal) decimal.Decimal {
|
||||
fX, _ := x.Float64()
|
||||
fY, _ := y.Float64()
|
||||
pow := math.Pow(fX, fY)
|
||||
pow := math.Pow(x.InexactFloat64(), y.InexactFloat64())
|
||||
return decimal.NewFromFloat(pow)
|
||||
}
|
||||
|
||||
@@ -405,7 +403,7 @@ func DecimalFinancialGeometricMean(values []decimal.Decimal) (decimal.Decimal, e
|
||||
// as we cannot have negative or zero value geometric numbers
|
||||
// adding a 1 to the percentage movements allows for differentiation between
|
||||
// negative numbers (eg -0.1 translates to 0.9) and positive numbers (eg 0.1 becomes 1.1)
|
||||
modVal, _ := values[i].Add(decimal.NewFromInt(1)).Float64()
|
||||
modVal := values[i].Add(decimal.NewFromInt(1)).InexactFloat64()
|
||||
product *= modVal
|
||||
}
|
||||
prod := 1 / float64(len(values))
|
||||
@@ -461,9 +459,9 @@ func DecimalSharpeRatio(movementPerCandle []decimal.Decimal, riskFreeRatePerInte
|
||||
if totalIntervals.IsZero() {
|
||||
return decimal.Zero, errZeroValue
|
||||
}
|
||||
var excessReturns []decimal.Decimal
|
||||
excessReturns := make([]decimal.Decimal, len(movementPerCandle))
|
||||
for i := range movementPerCandle {
|
||||
excessReturns = append(excessReturns, movementPerCandle[i].Sub(riskFreeRatePerInterval))
|
||||
excessReturns[i] = movementPerCandle[i].Sub(riskFreeRatePerInterval)
|
||||
}
|
||||
standardDeviation, err := DecimalPopulationStandardDeviation(excessReturns)
|
||||
if err != nil && !errors.Is(err, ErrInexactConversion) {
|
||||
|
||||
@@ -184,9 +184,9 @@ func TestInformationRatio(t *testing.T) {
|
||||
t.Error(avgComparison)
|
||||
}
|
||||
|
||||
var eachDiff []float64
|
||||
eachDiff := make([]float64, len(figures))
|
||||
for i := range figures {
|
||||
eachDiff = append(eachDiff, figures[i]-comparisonFigures[i])
|
||||
eachDiff[i] = figures[i] - comparisonFigures[i]
|
||||
}
|
||||
stdDev, err := PopulationStandardDeviation(eachDiff)
|
||||
if err != nil {
|
||||
@@ -583,9 +583,9 @@ func TestDecimalInformationRatio(t *testing.T) {
|
||||
t.Error(avgComparison)
|
||||
}
|
||||
|
||||
var eachDiff []decimal.Decimal
|
||||
eachDiff := make([]decimal.Decimal, len(figures))
|
||||
for i := range figures {
|
||||
eachDiff = append(eachDiff, figures[i].Sub(comparisonFigures[i]))
|
||||
eachDiff[i] = figures[i].Sub(comparisonFigures[i])
|
||||
}
|
||||
stdDev, err := DecimalPopulationStandardDeviation(eachDiff)
|
||||
if err != nil && !errors.Is(err, ErrInexactConversion) {
|
||||
@@ -703,14 +703,13 @@ func TestDecimalStandardDeviation2(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
var superMean []decimal.Decimal
|
||||
superMean := make([]decimal.Decimal, len(r))
|
||||
for i := range r {
|
||||
result := r[i].Sub(mean).Pow(decimal.NewFromInt(2))
|
||||
superMean = append(superMean, result)
|
||||
superMean[i] = result
|
||||
}
|
||||
superMeany := superMean[0].Add(superMean[1].Add(superMean[2].Add(superMean[3].Add(superMean[4].Add(superMean[5]))))).Div(decimal.NewFromInt(5))
|
||||
fSuperMeany, _ := superMeany.Float64()
|
||||
manualCalculation := decimal.NewFromFloat(math.Sqrt(fSuperMeany))
|
||||
manualCalculation := decimal.NewFromFloat(math.Sqrt(superMeany.InexactFloat64()))
|
||||
var codeCalcu decimal.Decimal
|
||||
codeCalcu, err = DecimalSampleStandardDeviation(r)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user