Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backtester: Futures handling & FTX Cash and Carry example strategy #930

Merged
merged 189 commits into from
Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
189 commits
Select commit Hold shift + click to select a range
a22be78
implements futures functions and GRPC functions on new branch
gloriousCode Jan 6, 2022
44d1780
lint and test fixes
gloriousCode Jan 7, 2022
4f19acc
Fix uneven split pnl. Adds collateral weight test. docs. New clear func
gloriousCode Jan 7, 2022
10cedd3
Test protection if someone has zero collateral
gloriousCode Jan 7, 2022
bc67a86
Uses string instead of double for accuracy
gloriousCode Jan 9, 2022
025452c
Fixes old code panic
gloriousCode Jan 9, 2022
d8bb688
context, match, docs
gloriousCode Jan 10, 2022
ac02d53
Addresses Shazniterinos, var names, expanded tests
gloriousCode Jan 11, 2022
bac9ce7
Returns subaccount name, provides USD values when offlinecalc
gloriousCode Jan 13, 2022
665fcc9
Fixes oopsie
gloriousCode Jan 13, 2022
406d3c2
Fixes cool bug which allowed made up subaccount results
gloriousCode Jan 13, 2022
8f76c78
Subaccount override on FTX, subaccount results for collateral
gloriousCode Jan 14, 2022
f276cff
Strenghten collateral account info checks. Improve FTX test
gloriousCode Jan 17, 2022
1d0d9e0
English is my first language
gloriousCode Jan 17, 2022
13b4878
Fixes oopsies
gloriousCode Jan 17, 2022
d2ee82c
Adds some conceptual futures order details to track PNL
gloriousCode Nov 3, 2021
197bd9e
Initial design of future order processing in the backtester
gloriousCode Nov 4, 2021
bb0be0b
Introduces futures concept for collateral and spot/futures config diffs
gloriousCode Nov 5, 2021
5b653cf
Fixes most tests
gloriousCode Nov 8, 2021
4fbc6f8
Simple designs for collateral funding pair concept
gloriousCode Nov 8, 2021
a6a6a47
Expands interface use so much it hurts
gloriousCode Nov 9, 2021
4621183
Implements more collateral interfaces
gloriousCode Nov 9, 2021
273e82a
Adds liquidation, adds strategy, struggles with Binance
gloriousCode Nov 10, 2021
93df00e
Attempts at getting FTX to work
gloriousCode Nov 12, 2021
6eafb6a
Adds calculatePNL as a wrapper function and adds an `IsFutures` asset…
gloriousCode Nov 15, 2021
0d0ef7f
Successfully loads backtester with collateral currency
gloriousCode Nov 16, 2021
00131fb
Fails to really get much going for supporting futures
gloriousCode Nov 17, 2021
148cfaf
Merges master changes
gloriousCode Nov 19, 2021
35161d6
Fleshes out how FTX processes collateral
gloriousCode Nov 19, 2021
889d388
Further FTX collateral workings
gloriousCode Nov 29, 2021
5e72026
hooks up more ftx collateral and pnl calculations
gloriousCode Nov 30, 2021
b220fb7
more funcs to flesh out handling
gloriousCode Dec 1, 2021
bda70db
Adds more links, just can't fit the pieces together :(
gloriousCode Dec 2, 2021
9696f2c
Greatly expands futures order processing
gloriousCode Dec 6, 2021
8edca3c
Fleshes out position tracker to also handle asset and exchange +testing
gloriousCode Dec 7, 2021
676d51e
RM linkedOrderID. rn positioncontroller, unexport
gloriousCode Dec 8, 2021
048a6af
Successfully tracks futures order positions
gloriousCode Dec 9, 2021
f06542a
Fails to calculate PNL
gloriousCode Dec 13, 2021
6e06e26
Calculates pnl from orders accurately with exception to flipping orders
gloriousCode Dec 14, 2021
ec18f83
Calculates PNL from orders
gloriousCode Dec 15, 2021
8bdd4a2
Adds another controller layer to make it ez from orderstore
gloriousCode Dec 17, 2021
fa48e4d
Backtester now compiles. Adds test coverage
gloriousCode Dec 20, 2021
88b12e1
labels things add scaling collateral test
gloriousCode Dec 20, 2021
3872ea6
Calculates pnl in line with fees
gloriousCode Dec 22, 2021
f848b2f
Mostly accurate PNL, with exception to appending with diff prices
gloriousCode Dec 23, 2021
64ac830
Adds locks, adds rpc function
gloriousCode Dec 24, 2021
1361a8a
grpc implementations
gloriousCode Dec 29, 2021
af3faf1
Gracefully handles rpc function
gloriousCode Dec 30, 2021
e14840d
beautiful tests!
gloriousCode Dec 31, 2021
ca85e3a
rejiggles tests to polish
gloriousCode Jan 4, 2022
61a345d
Finishes FTX testing, adds comments
gloriousCode Jan 5, 2022
8c4e2f4
Exposes collateral calculations to rpc
gloriousCode Jan 5, 2022
7cd16ec
Adds commands and testing for rpcserver.go functions
gloriousCode Jan 6, 2022
51e8713
Increase testing and fix up backtester code
gloriousCode Jan 6, 2022
ebf5fdc
Returns cool changes to original branch
gloriousCode Jan 7, 2022
33c5c90
end of day fixes
gloriousCode Jan 11, 2022
5e1942e
Fixing some tests
gloriousCode Jan 13, 2022
013039c
Fixing tests :tada:
gloriousCode Jan 17, 2022
3b3369a
Fixes all the tests
gloriousCode Jan 18, 2022
b730229
Splits the backtester setup and running into different files
gloriousCode Jan 18, 2022
4e4565a
Merge branch 'future-grpc' into future-order-handling
gloriousCode Jan 19, 2022
558ab70
Merge, minor fixes
gloriousCode Jan 19, 2022
ab1d85b
Messing with some strategy updates
gloriousCode Jan 19, 2022
eb3bbb3
Merge branch 'master' into future-grpc
gloriousCode Jan 19, 2022
e437cfb
Failed understanding at collateral usage
gloriousCode Jan 20, 2022
4ce4195
Begins the creation of cash and carry strategy
gloriousCode Jan 21, 2022
76bf661
Adds underlying pair, adds filldependentevent for futures
gloriousCode Jan 24, 2022
7c5d227
Completes fill prerequsite event implementation. Can't short though
gloriousCode Jan 25, 2022
b3fedb3
Some bug fixes
gloriousCode Jan 25, 2022
5ee9c7b
investigating funds
gloriousCode Jan 25, 2022
1f286af
CAN NOW CREATE A SHORT ORDER
gloriousCode Jan 27, 2022
3daf9f2
Minor change in short size
gloriousCode Jan 27, 2022
406f26c
Fixes for unrealised PNL & collateral rendering
gloriousCode Jan 28, 2022
b4c0ae8
Fixes lint and tests
gloriousCode Jan 28, 2022
932a617
Adds some verbosity
gloriousCode Jan 31, 2022
5be2b86
Merge branch 'future-grpc' into future-order-handling
gloriousCode Jan 31, 2022
596a0b8
Updates to pnl calc
gloriousCode Jan 31, 2022
48666f3
Tracks pnl for short orders, minor update to strategy
gloriousCode Feb 1, 2022
e1260a2
Close and open event based on conditions
gloriousCode Feb 4, 2022
cac4dd8
Adds pnl data for currency statistics
gloriousCode Feb 11, 2022
b917606
Working through PNL calculation automatically. Now panics
gloriousCode Feb 14, 2022
f2bd71f
Adds tracking, is blocked from design
gloriousCode Feb 15, 2022
971ebc9
Work to flesh out closing a position
gloriousCode Feb 16, 2022
96936d0
vain attempts at tracking zeroing out bugs
gloriousCode Feb 22, 2022
e71be13
woww, super fun new subloggers :tada:
gloriousCode Feb 24, 2022
dc60eec
Begins attempt at automatically handling contracts and collateral bas…
gloriousCode Feb 24, 2022
8e106eb
Merge master + fixes
gloriousCode Mar 1, 2022
8e69bc5
Merge branch 'master' into future-order-handling
gloriousCode Mar 1, 2022
831608e
Investigating issues with pnl and holdings
gloriousCode Mar 2, 2022
45d85fc
Minor pnl fixes
gloriousCode Mar 3, 2022
d1be631
Fixes future position sizing, needs contract sizing
gloriousCode Mar 4, 2022
a70231d
Can render pnl results, focussing on funding statistics
gloriousCode Mar 7, 2022
0ff3b32
tracking candles for futures, but why not btc
gloriousCode Mar 7, 2022
69bd71f
Improves funding statistics
gloriousCode Mar 8, 2022
9a7d084
Colours and stats
gloriousCode Mar 9, 2022
47fce53
Fixes collateral and snapshot bugs
gloriousCode Mar 10, 2022
475ec73
Completes test
gloriousCode Mar 10, 2022
fa9a597
Fixes totals bug
gloriousCode Mar 11, 2022
b9f0b9d
Fix double buy, expand stats, fixes usd totals, introduce interface
gloriousCode Mar 14, 2022
e8e844e
Begins report formatting and calculations
gloriousCode Mar 14, 2022
6313ab0
Appends pnl to receiving curr. Fixes map[time]. accurate USD
gloriousCode Mar 15, 2022
365b09a
Improves report output rendering
gloriousCode Mar 16, 2022
f0b1c95
PNL stats in report. New tests for futures
gloriousCode Mar 17, 2022
2a55f3d
Fixes existing tests before adding new coverage
gloriousCode Mar 17, 2022
400d445
Test coverage
gloriousCode Mar 18, 2022
bd37e54
Completes portfolio coverage
gloriousCode Mar 21, 2022
20e5ea6
Increase coverage exchange, portfolio. fix size bug. NEW CHART
gloriousCode Mar 22, 2022
1e6ea3d
WHAT IS GOING ON WITH PNL
gloriousCode Mar 22, 2022
aad0f65
Fixes PNL calculation. Adds ability to skip om futures tracking
gloriousCode Mar 23, 2022
541c7b1
minor commit before merge
gloriousCode Mar 23, 2022
1c07b83
Adds basic liquidation to backtester
gloriousCode Mar 24, 2022
0759fe1
Changes liquidation to order based
gloriousCode Mar 25, 2022
8c19c10
Liquidationnnnnn
gloriousCode Mar 28, 2022
7e1957e
Merge branch 'master' into future-order-handling
gloriousCode Mar 28, 2022
f818f6c
Further fleshes out liquidations
gloriousCode Mar 29, 2022
07b356d
Completes liquidations in a honorable manner. Adds AppendReasonf
gloriousCode Mar 30, 2022
03e4bd1
Beginnings of spot futures gap chart. Needs to link currencies to ren…
gloriousCode Mar 30, 2022
19e60d0
Removes fake liquidation. Adds cool new chart
gloriousCode Mar 31, 2022
1cd629a
Fixes somet tests,allows for zero fee value v nil distinction,New tests
gloriousCode Mar 31, 2022
423ce6a
Some annoying test fixes that took too long
gloriousCode Apr 1, 2022
a9bba1c
portfolio coverage
gloriousCode Apr 4, 2022
c87febe
holding coverage, privatisation funding
gloriousCode Apr 4, 2022
52a58bd
Testwork
gloriousCode Apr 11, 2022
9ce4646
Merge branch 'master' into future-order-handling
gloriousCode Apr 12, 2022
26e0f56
boring tests
gloriousCode Apr 12, 2022
e1fbbe7
engine coverage
gloriousCode Apr 14, 2022
36295dd
More backtesting coverage
gloriousCode Apr 15, 2022
22d0b51
Funding, strategy, report test coverage
gloriousCode Apr 19, 2022
13280b0
Completes coverage of report package
gloriousCode Apr 20, 2022
ae310e2
Documentation, fixes some assumptions on asset errors
gloriousCode Apr 20, 2022
c50291d
Changes before master merge
gloriousCode Apr 20, 2022
52f8c30
Merge branch 'master' into future-order-handling
gloriousCode Apr 20, 2022
a2b3c2a
Lint and Tests
gloriousCode Apr 20, 2022
ae3005a
defaults to non-coloured rendering
gloriousCode Apr 20, 2022
c716b4e
Chart rendering
gloriousCode Apr 20, 2022
61d175a
Fixes surprise non-local-lints
gloriousCode Apr 20, 2022
be9bbf6
Niterinos to the extremeos
gloriousCode Apr 28, 2022
674092d
Merge branch 'master' into future-order-handling
gloriousCode Apr 28, 2022
d06fdaf
Fixes merge problems
gloriousCode Apr 28, 2022
73405ac
The linter splintered across the glinting plinths
gloriousCode Apr 28, 2022
f1f441a
Many nits addressed. Now sells spot position on final candle
gloriousCode Apr 29, 2022
9e7278e
Merge branch 'master' into future-order-handling
gloriousCode May 2, 2022
41f72ad
Adds forgotten coverage
gloriousCode May 2, 2022
e1fcf76
Merge branch 'master' into future-order-handling
gloriousCode May 3, 2022
4257cc0
Adds ability to size futures contracts to match spot positions.
gloriousCode May 3, 2022
c87c45d
Merge branch 'future-order-handling' of https://github.com/gloriousCo…
gloriousCode May 3, 2022
21d55ab
fixes order sell sizing
gloriousCode May 3, 2022
18c74d3
Adds tests to sizing. Fixes charting issue
gloriousCode May 4, 2022
6eeba33
clint splintered the linters with flint
gloriousCode May 4, 2022
25ce60d
Improves stats, stat rendering
gloriousCode May 5, 2022
9a19d9d
minifix
gloriousCode May 5, 2022
bd33b0c
Fixes tests and fee bug
gloriousCode May 6, 2022
b926568
Merge branch 'master' into future-order-handling
gloriousCode May 6, 2022
c89926b
Merge fixeroos
gloriousCode May 6, 2022
b8e33e5
Microfixes
gloriousCode May 6, 2022
2bdb280
Updates orderPNL on first Correctly utilises fees. Adds committed funds
gloriousCode May 10, 2022
f9bc76d
New base funcs. New order summary
gloriousCode May 11, 2022
1df5cc9
Fun test updates
gloriousCode May 12, 2022
dfdc81a
Fix logo colouring
gloriousCode May 12, 2022
a71fd15
Merge branch 'master' into future-order-handling
gloriousCode May 12, 2022
6827d93
Fixes niteroonies
gloriousCode May 13, 2022
604b033
Fix report
gloriousCode May 13, 2022
d9c272c
BAD COMMIT
gloriousCode May 13, 2022
83c7881
Fixes funding issues.Updates default fee rates.Combines cashcarry case
gloriousCode May 16, 2022
f1af608
Merge branch 'master' into future-order-handling
gloriousCode May 16, 2022
2fa83a2
doc regen
gloriousCode May 16, 2022
b8bb2b0
Now returns err
gloriousCode May 16, 2022
456b90e
Fixes sizing bug issue introduced in PR
gloriousCode May 20, 2022
7e47e7d
Fixes fun fee/total US value bug
gloriousCode May 23, 2022
97aa13e
Fix chart bug. Show log charts with disclaimer
gloriousCode May 23, 2022
2f2cbe5
sellside fee
gloriousCode May 23, 2022
2977919
fixes fee and slippage view
gloriousCode May 23, 2022
a756c60
Fixed slippage price issue
gloriousCode May 23, 2022
753b1d0
Fixes calculation and removes rendering
gloriousCode May 23, 2022
65b9141
Fixes stats and some rendering
gloriousCode May 24, 2022
eebf1e8
Merge branch 'master' into future-order-handling
gloriousCode May 26, 2022
21b89ed
Merge fix
gloriousCode May 26, 2022
167fb15
Merge branch 'master' into future-order-handling
gloriousCode Jun 20, 2022
9ae91fb
Fixes merge issues
gloriousCode Jun 21, 2022
05e5523
Merge branch 'master' into future-order-handling
gloriousCode Jun 21, 2022
44e853d
go mod tidy, lint updates
gloriousCode Jun 21, 2022
51b263f
New linter attempt
gloriousCode Jun 21, 2022
94bad88
Version bump in appveyor and makefile
gloriousCode Jun 21, 2022
055fc49
Merge branch 'master' into future-order-handling
gloriousCode Jun 29, 2022
05f752d
Regex filename, config fixes, template h2 fixes
gloriousCode Jun 29, 2022
501b8e7
Removes bad stats.
gloriousCode Jun 30, 2022
97c82a9
neatens config builder. Moves filename generator
gloriousCode Jun 30, 2022
c3cfec4
Fixes issue where linter wants to fix my spelling
gloriousCode Jun 30, 2022
7548c49
Fixes pointers and starts
gloriousCode Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backtester/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,7 @@ func TestGenerateFTXCashAndCarryStrategy(t *testing.T) {
t.Skip()
}
cfg := Config{
Nickname: "Example Cash and Carry",
Nickname: "ExampleCashAndCarry",
Goal: "To demonstrate a cash and carry strategy",
StrategySettings: StrategySettings{
Name: "ftx-cash-carry",
Expand Down
35 changes: 5 additions & 30 deletions backtester/config/configbuilder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,32 +43,7 @@ func main() {
fmt.Print(common.ASCIILogo)
fmt.Println("Welcome to the config generator!")
reader := bufio.NewReader(os.Stdin)
cfg := config.Config{
StrategySettings: config.StrategySettings{
Name: "",
SimultaneousSignalProcessing: false,
CustomSettings: nil,
},
FundingSettings: config.FundingSettings{
UseExchangeLevelFunding: false,
ExchangeLevelFunding: nil,
},
CurrencySettings: []config.CurrencySettings{},
DataSettings: config.DataSettings{
Interval: 0,
DataType: "",
APIData: nil,
DatabaseData: nil,
LiveData: nil,
CSVData: nil,
},
PortfolioSettings: config.PortfolioSettings{
Leverage: config.Leverage{},
BuySide: config.MinMax{},
SellSide: config.MinMax{},
},
StatisticSettings: config.StatisticSettings{},
}
var cfg config.Config
fmt.Println("-----Strategy Settings-----")
var err error
firstRun := true
Expand Down Expand Up @@ -337,7 +312,7 @@ func parseAPI(reader *bufio.Reader, cfg *config.Config) error {
fmt.Printf("What is the start date? Leave blank for \"%v\"\n", defaultStart.Format(gctcommon.SimpleTimeFormat))
startDate = quickParse(reader)
if startDate != "" {
cfg.DataSettings.APIData.StartDate, err = time.Parse(startDate, gctcommon.SimpleTimeFormat)
cfg.DataSettings.APIData.StartDate, err = time.Parse(gctcommon.SimpleTimeFormat, startDate)
if err != nil {
return err
}
Expand All @@ -348,7 +323,7 @@ func parseAPI(reader *bufio.Reader, cfg *config.Config) error {
fmt.Printf("What is the end date? Leave blank for \"%v\"\n", defaultStart.Format(gctcommon.SimpleTimeFormat))
shazbert marked this conversation as resolved.
Show resolved Hide resolved
endDate = quickParse(reader)
if endDate != "" {
cfg.DataSettings.APIData.EndDate, err = time.Parse(endDate, gctcommon.SimpleTimeFormat)
cfg.DataSettings.APIData.EndDate, err = time.Parse(gctcommon.SimpleTimeFormat, endDate)
if err != nil {
return err
}
Expand Down Expand Up @@ -377,7 +352,7 @@ func parseDatabase(reader *bufio.Reader, cfg *config.Config) error {
fmt.Printf("What is the start date? Leave blank for \"%v\"\n", defaultStart.Format(gctcommon.SimpleTimeFormat))
startDate := quickParse(reader)
if startDate != "" {
cfg.DataSettings.DatabaseData.StartDate, err = time.Parse(startDate, gctcommon.SimpleTimeFormat)
cfg.DataSettings.DatabaseData.StartDate, err = time.Parse(gctcommon.SimpleTimeFormat, startDate)
if err != nil {
return err
}
Expand All @@ -387,7 +362,7 @@ func parseDatabase(reader *bufio.Reader, cfg *config.Config) error {

fmt.Printf("What is the end date? Leave blank for \"%v\"\n", defaultStart.Format(gctcommon.SimpleTimeFormat))
shazbert marked this conversation as resolved.
Show resolved Hide resolved
if endDate := quickParse(reader); endDate != "" {
cfg.DataSettings.DatabaseData.EndDate, err = time.Parse(endDate, gctcommon.SimpleTimeFormat)
cfg.DataSettings.DatabaseData.EndDate, err = time.Parse(gctcommon.SimpleTimeFormat, endDate)
if err != nil {
return err
}
Expand Down
8 changes: 0 additions & 8 deletions backtester/eventhandlers/portfolio/holdings/holdings.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,10 @@ func (h *Holding) update(e fill.Event, f funding.IFundReader) error {
case order.Buy,
order.Bid:
h.BoughtAmount = h.BoughtAmount.Add(amount)
h.ScaledBoughtValue = h.BoughtAmount.Mul(price)
h.CommittedFunds = h.BaseSize.Mul(price)
case order.Sell,
order.Ask:
h.SoldAmount = h.SoldAmount.Add(amount)
h.ScaledSoldValue = h.SoldAmount.Mul(price)
h.CommittedFunds = h.BaseSize.Mul(price)
}

Expand All @@ -134,18 +132,12 @@ func (h *Holding) update(e fill.Event, f funding.IFundReader) error {

func (h *Holding) scaleValuesToCurrentPrice(currentPrice decimal.Decimal) {
origPosValue := h.BaseValue
origBoughtValue := h.ScaledBoughtValue
origSoldValue := h.ScaledSoldValue
origTotalValue := h.TotalValue
h.BaseValue = h.BaseSize.Mul(currentPrice)
h.ScaledBoughtValue = h.BoughtAmount.Mul(currentPrice)
h.ScaledSoldValue = h.SoldAmount.Mul(currentPrice)
h.TotalValue = h.BaseValue.Add(h.QuoteSize)

h.TotalValueDifference = h.TotalValue.Sub(origTotalValue)
h.BoughtValueDifference = h.ScaledBoughtValue.Sub(origBoughtValue)
h.PositionsValueDifference = h.BaseValue.Sub(origPosValue)
h.SoldValueDifference = h.ScaledSoldValue.Sub(origSoldValue)

if !origTotalValue.IsZero() {
h.ChangeInTotalValuePercent = h.TotalValue.Sub(origTotalValue).Div(origTotalValue)
Expand Down
12 changes: 0 additions & 12 deletions backtester/eventhandlers/portfolio/holdings/holdings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,6 @@ func TestUpdateBuyStats(t *testing.T) {
if !h.BoughtAmount.Equal(decimal.NewFromInt(1)) {
t.Errorf("expected '%v' received '%v'", 1, h.BoughtAmount)
}
if !h.ScaledBoughtValue.Equal(decimal.NewFromInt(500)) {
t.Errorf("expected '%v' received '%v'", 500, h.ScaledBoughtValue)
}
if !h.SoldAmount.IsZero() {
t.Errorf("expected '%v' received '%v'", 0, h.SoldAmount)
}
Expand Down Expand Up @@ -231,9 +228,6 @@ func TestUpdateBuyStats(t *testing.T) {
if !h.BoughtAmount.Equal(decimal.NewFromFloat(1.5)) {
t.Errorf("expected '%v' received '%v'", 1, h.BoughtAmount)
}
if !h.ScaledBoughtValue.Equal(decimal.NewFromInt(750)) {
t.Errorf("expected '%v' received '%v'", 750, h.ScaledBoughtValue)
}
if !h.SoldAmount.IsZero() {
t.Errorf("expected '%v' received '%v'", 0, h.SoldAmount)
}
Expand Down Expand Up @@ -313,9 +307,6 @@ func TestUpdateSellStats(t *testing.T) {
if !h.BoughtAmount.Equal(decimal.NewFromInt(1)) {
t.Errorf("expected '%v' received '%v'", 1, h.BoughtAmount)
}
if !h.ScaledBoughtValue.Equal(decimal.NewFromInt(500)) {
t.Errorf("expected '%v' received '%v'", 500, h.ScaledBoughtValue)
}
if !h.SoldAmount.IsZero() {
t.Errorf("expected '%v' received '%v'", 0, h.SoldAmount)
}
Expand Down Expand Up @@ -360,9 +351,6 @@ func TestUpdateSellStats(t *testing.T) {
if !h.BoughtAmount.Equal(decimal.NewFromInt(1)) {
t.Errorf("expected '%v' received '%v'", 1, h.BoughtAmount)
}
if !h.ScaledBoughtValue.Equal(decimal.NewFromInt(500)) {
t.Errorf("expected '%v' received '%v'", 500, h.ScaledBoughtValue)
}
if !h.SoldAmount.Equal(decimal.NewFromInt(1)) {
t.Errorf("expected '%v' received '%v'", 1, h.SoldAmount)
}
Expand Down
4 changes: 0 additions & 4 deletions backtester/eventhandlers/portfolio/holdings/holdings_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,14 @@ type Holding struct {
TotalInitialValue decimal.Decimal `json:"total-initial-value"`
QuoteSize decimal.Decimal `json:"quote-size"`
SoldAmount decimal.Decimal `json:"sold-amount"`
ScaledSoldValue decimal.Decimal `json:"scaled-sold-value"`
SoldValue decimal.Decimal `json:"sold-value"`
BoughtAmount decimal.Decimal `json:"bought-amount"`
ScaledBoughtValue decimal.Decimal `json:"scaled-bought-value"`
CommittedFunds decimal.Decimal `json:"committed-funds"`

IsLiquidated bool

TotalValueDifference decimal.Decimal
ChangeInTotalValuePercent decimal.Decimal
BoughtValueDifference decimal.Decimal
SoldValueDifference decimal.Decimal
PositionsValueDifference decimal.Decimal

TotalValue decimal.Decimal `json:"total-value"`
Expand Down
7 changes: 3 additions & 4 deletions backtester/eventhandlers/statistics/printresults.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,15 @@ func (c *CurrencyPairStatistic) PrintResults(e string, a asset.Item, p currency.
log.Infof(common.CurrencyStatistics, "%s Lowest Unrealised PNL: %s at %v", sep, convert.DecimalToHumanFriendlyString(c.LowestUnrealisedPNL.Value, 8, ".", ","), c.LowestUnrealisedPNL.Time)
log.Infof(common.CurrencyStatistics, "%s Highest Realised PNL: %s at %v", sep, convert.DecimalToHumanFriendlyString(c.HighestRealisedPNL.Value, 8, ".", ","), c.HighestRealisedPNL.Time)
log.Infof(common.CurrencyStatistics, "%s Lowest Realised PNL: %s at %v", sep, convert.DecimalToHumanFriendlyString(c.LowestRealisedPNL.Value, 8, ".", ","), c.LowestRealisedPNL.Time)
log.Infof(common.CurrencyStatistics, "%s Highest committed funds: %s %s at %v", sep, convert.DecimalToHumanFriendlyString(c.HighestCommittedFunds.Value, 8, ".", ","), c.UnderlyingPair.Quote, c.HighestCommittedFunds.Time)
} else {
log.Infof(common.CurrencyStatistics, "%s Buy orders: %s", sep, convert.IntToHumanFriendlyString(c.BuyOrders, ","))
log.Infof(common.CurrencyStatistics, "%s Buy amount: %s %s", sep, convert.DecimalToHumanFriendlyString(last.Holdings.BoughtAmount, 8, ".", ","), last.Holdings.Pair.Base)
log.Infof(common.CurrencyStatistics, "%s Bought amount valued at last candle: %s", sep, convert.DecimalToHumanFriendlyString(last.Holdings.ScaledBoughtValue, 8, ".", ","))
log.Infof(common.CurrencyStatistics, "%s Sell orders: %s", sep, convert.IntToHumanFriendlyString(c.SellOrders, ","))
log.Infof(common.CurrencyStatistics, "%s Sell amount: %s", sep, convert.DecimalToHumanFriendlyString(last.Holdings.SoldAmount, 8, ".", ","))
log.Infof(common.CurrencyStatistics, "%s Sold amount valued at last candle: %s", sep, convert.DecimalToHumanFriendlyString(last.Holdings.ScaledSoldValue, 8, ".", ","))
log.Infof(common.CurrencyStatistics, "%s Sell amount: %s %s", sep, convert.DecimalToHumanFriendlyString(last.Holdings.SoldAmount, 8, ".", ","), last.Holdings.Pair.Base)
log.Infof(common.CurrencyStatistics, "%s Highest committed funds: %s %s at %v", sep, convert.DecimalToHumanFriendlyString(c.HighestCommittedFunds.Value, 8, ".", ","), last.Holdings.Pair.Quote, c.HighestCommittedFunds.Time)
}

log.Infof(common.CurrencyStatistics, "%s Highest committed funds: %s at %v", sep, convert.DecimalToHumanFriendlyString(c.HighestCommittedFunds.Value, 8, ".", ","), c.HighestCommittedFunds.Time)
log.Infof(common.CurrencyStatistics, "%s Total orders: %s", sep, convert.IntToHumanFriendlyString(c.TotalOrders, ","))

log.Info(common.CurrencyStatistics, common.ColourH2+"------------------Max Drawdown-------------------------------"+common.ColourDefault)
Expand Down
4 changes: 0 additions & 4 deletions backtester/eventhandlers/statistics/statistics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,14 +284,10 @@ func TestAddHoldingsForTime(t *testing.T) {
BaseSize: eleet,
BaseValue: eleet,
SoldAmount: eleet,
ScaledSoldValue: eleet,
BoughtAmount: eleet,
ScaledBoughtValue: eleet,
QuoteSize: eleet,
TotalValueDifference: eleet,
ChangeInTotalValuePercent: eleet,
BoughtValueDifference: eleet,
SoldValueDifference: eleet,
PositionsValueDifference: eleet,
TotalValue: eleet,
TotalFees: eleet,
Expand Down
31 changes: 23 additions & 8 deletions backtester/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"html/template"
"os"
"path/filepath"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -69,15 +70,10 @@ func (d *Data) GenerateReport() error {
tmpl := template.Must(
template.ParseFiles(d.TemplatePath),
)
var nickName string
if d.Config.Nickname != "" {
nickName = d.Config.Nickname + "-"
fileName, err := generateFileName(d.Config.Nickname, d.Statistics.StrategyName)
if err != nil {
return err
}
fileName := fmt.Sprintf(
"%v%v-%v.html",
nickName,
d.Statistics.StrategyName,
time.Now().Format("2006-01-02-15-04-05"))
var f *os.File
f, err = os.Create(
filepath.Join(d.OutputPath,
Expand All @@ -102,6 +98,25 @@ func (d *Data) GenerateReport() error {
return nil
}

func generateFileName(configNickName, strategyName string) (string, error) {
thrasher- marked this conversation as resolved.
Show resolved Hide resolved
if strategyName == "" {
return "", fmt.Errorf("%w missing strategy name", errCannotGenerateFileName)
}
if configNickName != "" {
configNickName += "-"
}
fileName := fmt.Sprintf(
"%v%v-%v",
configNickName,
strategyName,
time.Now().Format("2006-01-02-15-04-05"))

reg := regexp.MustCompile(`[\w-]`)
result := reg.FindAllString(fileName, -1)
fileName = strings.Join(result, "") + ".html"
return strings.ToLower(fileName), nil
}

// AddKlineItem appends a SET of candles for the report to enhance upon
// generation
func (d *Data) AddKlineItem(k *kline.Item) {
Expand Down
37 changes: 37 additions & 0 deletions backtester/report/report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package report

import (
"errors"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -515,3 +516,39 @@ func TestUseDarkMode(t *testing.T) {
t.Error("expected true")
}
}

func TestGenerateFileName(t *testing.T) {
t.Parallel()
_, err := generateFileName("", "")
if !errors.Is(err, errCannotGenerateFileName) {
t.Errorf("received '%v' expected '%v'", err, errCannotGenerateFileName)
}

_, err = generateFileName("hello", "")
if !errors.Is(err, errCannotGenerateFileName) {
t.Errorf("received '%v' expected '%v'", err, errCannotGenerateFileName)
}

_, err = generateFileName("hello", "moto")
if !errors.Is(err, nil) {
t.Errorf("received '%v' expected '%v'", err, nil)
}

_, err = generateFileName("", "moto")
if !errors.Is(err, nil) {
t.Errorf("received '%v' expected '%v'", err, nil)
}

tt := time.Now().Format("2006-01-02-15-04-05")
name, err := generateFileName("......HELL0. + _", "moto")
if !errors.Is(err, nil) {
t.Errorf("received '%v' expected '%v'", err, nil)
}
if name != "hell0_-moto-"+tt+".html" {
// there's a chance that it's failing due to the second count
nameSplit := strings.Split(name, "-")
if nameSplit[0]+nameSplit[1] != "hell0_moto" {
t.Errorf("received '%v' expected '%v'", nameSplit[0]+nameSplit[1], "hell0_moto")
}
}
}
5 changes: 3 additions & 2 deletions backtester/report/report_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ import (
const maxChartLimit = 1100

var (
errNoCandles = errors.New("no candles to enhance")
errStatisticsUnset = errors.New("unable to proceed with unset Statistics property")
errNoCandles = errors.New("no candles to enhance")
errStatisticsUnset = errors.New("unable to proceed with unset Statistics property")
errCannotGenerateFileName = errors.New("cannot generate filename")
)

// Handler contains all functions required to generate statistical reporting for backtesting results
Expand Down
15 changes: 1 addition & 14 deletions backtester/report/tpl.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@
<script type="application/javascript" src="https://code.highcharts.com/stock/modules/hollowcandlestick.js"></script>
<script type="application/javascript" src="https://code.highcharts.com/modules/exporting.js"></script>
<script type="application/javascript" src="https://code.highcharts.com/modules/export-data.js"></script>
<style>
h2 {
padding-top: 75px;
margin-top: -75px;
}
</style>


</head>
<body>
Expand Down Expand Up @@ -1275,10 +1270,6 @@
<td><b>Buy Orders</b></td>
<td>{{ $.Prettify.Int $val.BuyOrders}}</td>
</tr>
<tr>
<td><b>Buy Value</b></td>
<td>{{ $.Prettify.Decimal8 $val.FinalHoldings.ScaledBoughtValue}} {{$val.FinalHoldings.Pair.Quote}}</td>
</tr>
<tr>
<td><b>Buy Amount</b></td>
<td>{{ $.Prettify.Decimal8 $val.FinalHoldings.BoughtAmount}} {{$val.FinalHoldings.Pair.Base}} </td>
Expand All @@ -1287,10 +1278,6 @@
<td><b>Sell Orders</b></td>
<td>{{ $.Prettify.Int $val.SellOrders}}</td>
</tr>
<tr>
<td><b>Sell Value</b></td>
<td>{{ $.Prettify.Decimal8 $val.FinalHoldings.ScaledSoldValue}} {{$val.FinalHoldings.Pair.Quote}}</td>
</tr>
<tr>
<td><b>Sell Amount</b></td>
<td>{{ $.Prettify.Decimal8 $val.FinalHoldings.SoldAmount}} {{$val.FinalHoldings.Pair.Base}}</td>
Expand Down