nautechsystems/nautilus_trader · error

add_funding_rate not implemented for PostgreSQL cache adapte

Error message

add_funding_rate not implemented for PostgreSQL cache adapter

What it means

add_funding_rate on the PostgreSQL cache adapter is not implemented: funding rate persistence has no SQL schema/insert path in this adapter, so calls fail with this explicit not-implemented marker rather than silently no-oping.

Source

Thrown at crates/infrastructure/src/sql/cache.rs:1052

                    if let Err(e) = tx.send(trades) {
                        log::error!("Failed to send trades for instrument {instrument_id}: {e:?}");
                    }
                }
                Err(e) => {
                    log::error!("Failed to load trades for instrument {instrument_id}: {e:?}");
                    if let Err(e) = tx.send(Vec::new()) {
                        log::error!(
                            "Failed to send empty trades for instrument {instrument_id}: {e:?}"
                        );
                    }
                }
            }
        });
        Ok(rx.recv()?)
    }

    fn add_funding_rate(&self, _funding_rate: &FundingRateUpdate) -> anyhow::Result<()> {
        anyhow::bail!("add_funding_rate not implemented for PostgreSQL cache adapter")
    }

    fn load_funding_rates(
        &self,
        _instrument_id: &InstrumentId,
    ) -> anyhow::Result<Vec<FundingRateUpdate>> {
        anyhow::bail!("load_funding_rates not implemented for PostgreSQL cache adapter")
    }

    fn add_bar(&self, bar: &Bar) -> anyhow::Result<()> {
        let query = DatabaseQuery::AddBar(bar.to_owned());
        self.tx.send(query).map_err(|e| {
            anyhow::anyhow!("Failed to send query add_bar to database message handler: {e}")
        })
    }

    fn load_bars(&self, instrument_id: &InstrumentId) -> anyhow::Result<Vec<Bar>> {
        let pool = self.pool.clone();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Persist funding rates with the Redis cache adapter, or disable funding-rate persistence in the data engine config
  2. Store funding rates in a separate table/warehouse outside the cache adapter
  3. Implement add_funding_rate (and load_funding_rates) in sql/cache.rs

Example fix

// before
cache_db.add_funding_rate(&update)?; // bails on Postgres
// after
if let Err(e) = cache_db.add_funding_rate(&update) {
    log::warn!("funding rate not persisted: {e}");
}
Defensive patterns

Strategy: fallback

Validate before calling

if is_postgres_cache(&cache_db) { /* persist funding rates elsewhere or skip */ }

Type guard

fn is_postgres_cache(db: &dyn CacheDatabase) -> bool { db.as_any().downcast_ref::<PostgresCache>().is_some() }

Try / catch

if let Err(e) = cache_db.add_funding_rate(&update) {
    if e.to_string().contains("not implemented") {
        log::warn!("funding rate persistence unavailable on SQL adapter");
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: A data engine or strategy writing funding rate updates to a PostgreSQL-backed cache — e.g. perpetuals trading configs that record funding rates via the cache database.

Common situations: Running derivatives (perp) strategies on a Postgres cache deployment; migrating from Redis where funding-rate persistence works; backtesting pipelines that persist funding updates.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/cb13493036a607d8. Report an issue: GitHub.