Get Signal Based On Current Position


Trying to think of the best way to generate a signal based on a current long position in a backtest (I know in live trading you could probably use the blotter for this, but for backtesting I don’t think that would work).

So if on one week you’re long on something, the next week you can generate a signal based on your entry price of that position one week prior?


For path-dependent logic like that, Zipline is a more natural fit. (Live trading coming soon.)


Really struggling to wrap my head around this because I keep running into the same issue as I’m trying to code up strategies…so Quantrocket ignores the fact of whether a position is already held or not? But isn’t that ignoring a fundamental part of stock trading which is profit and return depends on both the entry and the exit?

For example, if I want to enter a position when the RSI drops below 35 and sell the position when the RSI rises above 70, I can’t do that with Quantrocket because my price_to_signal result (0 - sell, or 1- buy) can receive no information as to whether my initial state for that position is currently being held or not (0 - not held, or 1 - held) every time the algorithm runs.

I was trying to get around this by creating ‘sell_signals’ and ‘buy_signals’ dataframes and subtracting them or doing some XOR logic, but neither worked…both subtracting them or XOR’ing them requires knowing whether the security is currently held or not. That information needs to be passed no matter how you skin the cat.

Perhaps I’m not thinking of this correctly, but I’m pulling my hair out here after spending 8 hours coding a strategy and hitting this brick wall on two separate occasions: Quantrocket purely derives buy, sell, and short signals solely from market pricing, not from market pricing relative to portfolio positions?


I think my original comment misunderstood what you’re trying to do. The RSI example is straightforward in Moonshot. Compute your entries and exits separately, combine and forward-fill:

long_entries = rsis < 35
long_exits = rsis > 70

ones = pd.DataFrame(1, index=closes.index, columns=closes.columns)
zeros = pd.DataFrame(0, index=closes.index, columns=closes.columns)
long_signals = ones.where(long_entries).fillna(zeros.where(long_exits)).fillna(method="ffill")

The code library may be helpful here, for example the pairs trading example uses Bollinger Band logic similar to the above.

The goal of prices_to_signals and signals_to_target_weights is to compute your target portfolio. As to your current portfolio, in live trading Moonshot will use the blotter to check your current portfolio and subtract it from your target portfolio to generate the orders necessary to achieve your target portfolio. In backtesting, target_weights_to_positions creates your actual portfolio from your target weights, usually by just shifting or copying the target weights (but you can also model more complicated rules like limit orders).