rodrigo-brito / ninjabot

A fast trading bot platform for cryptocurrency in Go (Binance)
https://rodrigo-brito.github.io/ninjabot/
MIT License
1.39k stars 171 forks source link

Does it support multi data feeds ? #282

Open evanlaw3 opened 1 year ago

evanlaw3 commented 1 year ago

Somethings like https://www.backtrader.com/blog/posts/2017-04-09-multi-example/multi-example/

rodrigo-brito commented 1 year ago

you can plot multiple informations in the chart, you have to include a chart indicator inside the strategy


func (e CrossEMA) Indicators(df *ninjabot.Dataframe) []strategy.ChartIndicator {
    df.Metadata["custom-data"] = fetchYourCustomData()

    return []strategy.ChartIndicator{
        {
            Overlay:   true, // plot over the price
            GroupName: "Custom Data",
            Time:      df.Time,
            Metrics: []strategy.IndicatorMetric{
                {
                    Values: df.Metadata["custom-data"]
                    Name:   "Custom",
                    Color:  "red",
                    Style:  strategy.StyleLine,
                },
            },
        },
    }
}
`` 
evanlaw3 commented 1 year ago

What I meant to say was that I can feed multiple data souces into one strategy. Let's say that my strategy find out pairs with top 3 chg and buy in. So I should import all live datas of trading pairs and ranking them.

andreimerfu commented 6 months ago

@rodrigo-brito How can we implement this feature? We should generate multiple dataframes by timeframe or maybe a single dataframe that has some child dataframes? I think the goal is to have something like this in strategies:

  if df.Metadata["rsi"] < 30 && df.OtherDFs["weekly"].Metadata["rsi"] > 60 {
    // buy
  }

@evanlaw3 Correct me if I'm wrong.

rodrigo-brito commented 3 months ago

For the same currency pair, you can resample the data if you are in a smaller dataframe and want to view a larger one. But to visualize a different data frame you have to implement a custom data fetcher, like this:


// exchange initalization
binance, err = exchange.NewBinance(ctx,
    exchange.WithBinanceCredentials(cfg.BinanceKey, cfg.BinanceSecret),
    exchange.WithMetadataFetcher(fetchFundingRate), // FETCH CUSTOM DATA
)

// your custom data
func fetchFundingRate(pair string, t time.Time) (string, float64) {
    fr, err := futureClient.NewPremiumIndexService().Symbol(pair).Do(context.Background())
    if err != nil {
        log.Printf("error fetching funding rate: %s", err)
        return "fr", 0
    }

    if len(fr) == 0 {
        return "fr", 0
    }

    value, err := strconv.ParseFloat(fr[0].LastFundingRate, 64)
    if err != nil {
        log.Printf("error fetching funding rate: %s", err)
        return "fr", 0
    }

    return "fr", value
}

The function must return the name of the index and the current value. It will be called for each iteration given a timeframe. That is, every new candle. Then, the date will be available in your strategy with the index fr, like this df.Metadata["fr"]

rodrigo-brito commented 3 months ago

For backtesting with custom metadata, your CSV must have a custom column with the same index name fr. And all will work fine.