You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: chart.go
    path of file: ./repos/gocryptotrader/backtester/report
    
    the code of the file until where you have to start completion: package report

import (
	"fmt"

	"github.com/shopspring/decimal"
	"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/statistics"
	gctcommon "github.com/thrasher-corp/gocryptotrader/common"
	"github.com/thrasher-corp/gocryptotrader/common/key"
	"github.com/thrasher-corp/gocryptotrader/currency"
)

// createUSDTotalsChart used for creating a chart in the HTML report
// to show how much the overall assets are worth over time
func createUSDTotalsChart(items []statistics.ValueAtTime, stats []statistics.FundingItemStatistics) (*Chart, error) {
	if items == nil {
		return nil, fmt.Errorf("%w missing values at time", gctcommon.ErrNilPointer)
	}
	if stats == nil {
		return nil, fmt.Errorf("%w missing funding item statistics", gctcommon.ErrNilPointer)
	}
	response := &Chart{
		AxisType: "logarithmic",
	}
	usdTotalChartPlot := make([]LinePlot, len(items))
	for i := range items {
		usdTotalChartPlot[i] = LinePlot{
			Value:     items[i].Value.InexactFloat64(),
			UnixMilli: items[i].Time.UTC().UnixMilli(),
		}
	}
	response.Data = append(response.Data, 
    
func createFuturesSpotDiffChart(items map[key.ExchangePairAsset]*statistics.CurrencyPairStatistic) (*Chart, error) {
	if items == nil {
		return nil, fmt.Errorf("%w missing currency pair statistics", gctcommon.ErrNilPointer)
	}
	currs := make(map[currency.Pair]linkCurrencyDiff)
	response := &Chart{
		AxisType: "linear",
	}

	for mapKey, result := range items {
		cp := currency.NewPair(mapKey.Base.Currency(), mapKey.Quote.Currency())
		if mapKey.Asset.IsFutures() {
			p := result.UnderlyingPair.Format(currency.EMPTYFORMAT)
			diff, ok := currs[p]
			if !ok {
				diff = linkCurrencyDiff{}
			}
			diff.FuturesPair = cp
			diff.SpotPair = p
			diff.FuturesEvents = result.Events
			currs[p] = diff
		} else {
			p := cp.Format(currency.EMPTYFORMAT)
			diff, ok := currs[p]
			if !ok {
				diff = linkCurrencyDiff{}
			}
			diff.SpotEvents = result.Events
			currs[p] = diff
		}
	}

	for i := range currs {
		if currs[i].FuturesEvents == nil || currs[i].SpotEvents == nil {
			continue
		}
		if len(currs[i].SpotEvents) != len(currs[i].FuturesEvents) {
			continue
		}
		line := ChartLine{
			Name: fmt.Sprintf("%v %v diff %%", currs[i].FuturesPair, currs[i].SpotPair),
		}
		for j := range currs[i].SpotEvents {
			spotPrice := currs[i].SpotEvents[j].DataEvent.GetClosePrice()
			futuresPrice := currs[i].FuturesEvents[j].DataEvent.GetClosePrice()
			diff := futuresPrice.Sub(spotPrice).Div(spotPrice).Mul(decimal.NewFromInt(100))
			line.LinePlots = append(line.LinePlots, LinePlot{
				Value:     diff.InexactFloat64(),
				UnixMilli: currs[i].SpotEvents[j].Time.UnixMilli(),
			})
		}
		response.Data = append(response.Data, line)
	}
	return response, nil
}