Hello NinjaTrader Community,
I’ve been developing a NinjaScript strategy that integrates with my live ATM template and I’m running into a timing challenge that I hope someone has solved.
My Setup:
- Strategy uses limit orders for entries via
AtmStrategyCreate()
- Custom ATM template with multiple stop/target orders
- Strategy needs to dynamically adjust stop levels and one target price based on calculated risk after entry fills
- Currently using
AtmStrategyChangeStopTarget() for adjustments
The Problem: I need the stop and target adjustments to happen as close to instantly as possible after the entry fills, but I’m experiencing approximately a 1-minute delay (using 1 min chart) using the standard polling approach.
What I’ve Tried:
- Bar-close polling: Using
GetAtmStrategyEntryOrderStatus() with Calculate.OnBarClose - works reliably but has ~1 minute delay
- Tick-based monitoring: Attempted
Calculate.OnEachTick with the same polling method - caused issues with existing bar-close setup detection logic
- Timer-based rapid polling: Scheduling frequent ATM status checks - still not instant enough for fast-moving NQ
The Core Issue: In fast-moving markets like NQ, that 1-minute delay between entry fill and risk adjustment can be the difference between a $100 loss and a $1000+ loss. I need the stop and target adjustments to trigger within seconds of the entry fill, not after the next bar closes.
Specific Question: Is there a way to detect ATM entry fills and trigger immediate AtmStrategyChangeStopTarget() adjustments without relying on the typical 1-bar polling delay? Are there ATM-specific events, callbacks, or alternative methods that can provide near-instant fill detection?
Any insights from those who’ve tackled similar real-time risk management challenges would be greatly appreciated.
Thanks in advance!
I don’t think I’ve actually used AtmStrategyChangeStopTarget or programatically created an ATM. So you create an ATM strategy with I’m assuming a stop and right after you create it you want to change the stop? Why not just include the stop when your ATM strategy gets created?
Thanks for the response. Yes, I have an ATM strategy that I use live. I enter for 5 contracts with 3 targets and 1 stop. The targets are static at 10, 50, and 100 points, and the stop is static at 25 points. However, I want the stop and second target to be dynamic based on risk provided by my setup. The second target needs to always be two times the risk, and the risk varies +/- based on the setup that triggers the entry. This is done easily when I trade live, and I’ve gotten it to work in my strategy, for the most part, just have approximately 1 minute delay between when entry triggers and adjustments happen due to polling OnBarClose. Would like to be able to trigger adjustment in OnExecution, so they are made immediately, similar to when I do it live, but so far haven’t been able to figure out how to make that work.
Have you tried adding a 1 tick data series and using that as the polling? Also, OnExecutionUpdate (assuming you meant that), is owned by the strategy and not the ATM so it won’t work. “Only orders which have been submitted and managed by the strategy will call OnExecutionUpdate()” https://ninjatrader.com/support/helpguides/nt8/NT%20HelpGuide%20English.html?onexecutionupdate.htm
Thanks again! I have not tried adding a 1 tick data series. I did try Calculate.OnEachTick, unsuccessfully. I know what you’re saying about the strategy ownership. However, I did find documentation that seemed to suggest that it could be done by calling the strategy through EnterLong or EnterShort, but my strategy uses limit orders and I couldn’t get EnterLongLimit to call the ATM. Also, I have tried making the process 3 separate entries, and ditching the ATM all together. This would be ideal, because it has backtest functionality that using the ATM does not. However, I ran into OCO issues and order chaos. I really didn’t think it should be that hard to have 3 entries trigger at the same price, use the same stop price, and just have different targets… but here I am.
I don’t see your code so I’m just assuming a lot here. If you are trying to make a more complex ATM, why not just manually create one and call that in your strategy?
FYI, after much back and forth on my part with the ATM integration, i re-vamped the procedure for individually managed entries. It seems to work now without OCO issues and order chaos, though additional testing is needed. I am hopeful that my strategy will now work as intended.
2 Likes
Great! Glad it’s working for you.