Skip to content
Open RaamTrade

RC2_DATAFEED_HELPER

Symbol <slot> is a data feed; position properties (.is_flat, .position, …) are only available on the trading symbol.

What it means

Only one slot in a strategy holds a position — the one marked trade=True. Every other Symbol() is a data feed: a read-only OHLCV stream you can compute indicators on and compare prices against, but not something the engine keeps a position book for. So self.spy.is_flat has no answer to give, and returning “flat” would be a lie that reads like a fact.

The position helpers this covers are is_flat, is_long, is_short, has_position, and position. OHLCV (close, open, high, low, volume) and timestamp work on every slot.

Why it happens

The condition was written against the feed you were just reading prices from, rather than the slot you trade:

class FeedPosition(Strategy):
trade = Symbol(trade=True)
spy = Symbol(ticker="SPY")
sizing = FixedCapital()
def execute(self):
spy_sma = SMA(50, on=self.spy)
if self.spy.close > spy_sma.value and self.spy.is_flat:
self.buy(self.trade)

How to fix it

Read the market from the feed, and the position from the trading slot.

class FeedFiltered(Strategy):
trade = Symbol(trade=True)
spy = Symbol(ticker="SPY")
sizing = FixedCapital()
def execute(self):
spy_sma = SMA(50, on=self.spy)
if self.spy.close > spy_sma.value and self.trade.is_flat:
self.buy(self.trade)

That split is the whole idea of a data feed: SPY (or VIX, or a sector ETF) decides whether to be in the market; the trading slot is where you are in it.