Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Collection was modified error

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Collection was modified error

    Hi,

    I'm receiving a random error:

    Error on triggering custom event for NinjaScript 'Depth of Market Scalper v1.2' on bar 21289: Collection was modified; enumeration operation may not execute.
    Disabling NinjaScript strategy 'Depth of Market Scalper v1.2/205452735'

    I'm utilizing the provided project that grabs the elements of the DOM and build out the books. I haven't been able to figure out what's causing this and was hoping you might have some insight.

    Code:
     protected override void OnMarketDepth(MarketDepthEventArgs e)
    {
    List<LadderRow> rows = null;
    
    // Checks to see if the Market Data is of the Ask type
    if (e.MarketDataType == MarketDataType.Ask)
    {
    rows = askRows;
    
    // Due to race conditions, it is possible the first event is an Update operation instead of an Insert. When this happens, populate your Lists via e.MarketDepth first.
    if (firstAskEvent)
    {
    if (e.Operation == Operation.Update)
    {
    // Lock the MarketDepth collection to prevent modification to the collection while we are still processing it
    lock (e.Instrument.MarketDepth.Asks)
    {
    for (int idx = 0; idx < e.Instrument.MarketDepth.Asks.Count; idx++)
    rows.Add(new LadderRow(e.Instrument.MarketDepth.Asks[idx].Price, e.Instrument.MarketDepth.Asks[idx].Volume, e.Instrument.MarketDepth.Asks[idx].MarketMaker));
    }
    }
    firstAskEvent = false;
    }
    }
    
    // Checks to see if the Market Data is of the Bid type
    else if (e.MarketDataType == MarketDataType.Bid)
    {
    rows = bidRows;
    
    // Due to race conditions, it is possible the first event is an Update operation instead of an Insert. When this happens, populate your Lists via e.MarketDepth first.
    if (firstBidEvent)
    {
    if (e.Operation == Operation.Update)
    {
    // Lock the MarketDepth collection to prevent modification to the collection while we are still processing it
    lock (e.Instrument.MarketDepth.Bids)
    {
    for (int idx = 0; idx < e.Instrument.MarketDepth.Bids.Count; idx++)
    rows.Add(new LadderRow(e.Instrument.MarketDepth.Bids[idx].Price, e.Instrument.MarketDepth.Bids[idx].Volume, e.Instrument.MarketDepth.Bids[idx].MarketMaker));
    }
    }
    firstBidEvent = false;
    }
    }
    
    if (rows == null)
    return;
    
    // Checks to see if the action taken was an insertion into the ladder
    if (e.Operation == Operation.Add)
    {
    // Add a new row at the end if the designated position is greater than our current ladder size
    if (e.Position >= rows.Count)
    rows.Add(new LadderRow(e.Price, e.Volume, e.MarketMaker));
    
    // Insert a new row into our ladder at the designated position
    else
    rows.Insert(e.Position, new LadderRow(e.Price, e.Volume, e.MarketMaker));
    }
    
    /* Checks to see if the action taken was a removal of itself from the ladder
    Note: Due to the multi threaded architecture of the NT core, race conditions could occur
    -> check if e.Position is within valid range */
    else if (e.Operation == Operation.Remove && e.Position < rows.Count)
    rows.RemoveAt(e.Position);
    
    /* Checks to see if the action taken was to update a data already on the ladder
    Note: Due to the multi threaded architecture of the NT core, race conditions could occur
    -> check if e.Position is within valid range */
    else if (e.Operation == Operation.Update && e.Position < rows.Count)
    {
    rows[e.Position].MarketMaker = e.MarketMaker;
    rows[e.Position].Price = e.Price;
    rows[e.Position].Volume = e.Volume;
    }
    }

    #2
    Hello DogEars,

    Thanks for your post.

    This error would mean that a collection is modified while it is being accessed. If the collections are written in OnMarketDepth and accessed in OnRender, you could encounter this sort of error, and it would happen "randomly" when the collection is modified as it is accessed.

    The solution is to use lock's to prevent accessing/writing to the collection when it is already in use. I have addressed a similar issue in my conversion of the EdsLevel2 indicator. I have included a link below if you would like to see how the locks are implemented.

    2/8/2019 Fixed issue where bidRows and askRows were not properly locked between MarketDepth and OnRender. Speculator Ed&#8217;s Level 2 indicator Press F5 to refresh indicators if level 2 becomes out of sync. changelog: v2.0: &#8211; combined different depths with same price (good for stocks) &#8211; removed highlighting of 3rd cumulative depth price (complications with combining [&#8230;]


    The link above is publicly available.

    The NinjaTrader Ecosystem website is for educational and informational purposes only and should not be considered a solicitation to buy or sell a futures contract or make any other type of investment decision. The add-ons listed on this website are not to be considered a recommendation and it is the reader's responsibility to evaluate any product, service, or company. NinjaTrader Ecosystem LLC is not responsible for the accuracy or content of any product, service or company linked to on this website.


    We look forward to assisting.
    JimNinjaTrader Customer Service

    Comment


      #3
      Hello,
      I can't find your exemple of code in the link provided.
      Can you please give us here the code that allows lock collection correctly ?
      Thank you

      Comment


        #4
        Hi scalping_Strategy, the example that Jim linked shows how to lock a collection on lines 207, 217, 237, and 263.
        Attached Files
        Chris L.NinjaTrader Customer Service

        Comment

        Latest Posts

        Collapse

        Topics Statistics Last Post
        Started by r68cervera, Today, 05:29 AM
        0 responses
        2 views
        0 likes
        Last Post r68cervera  
        Started by geddyisodin, Today, 05:20 AM
        0 responses
        3 views
        0 likes
        Last Post geddyisodin  
        Started by JonesJoker, 04-22-2024, 12:23 PM
        6 responses
        33 views
        0 likes
        Last Post JonesJoker  
        Started by GussJ, 03-04-2020, 03:11 PM
        12 responses
        3,239 views
        0 likes
        Last Post Leafcutter  
        Started by AveryFlynn, Today, 04:57 AM
        0 responses
        6 views
        0 likes
        Last Post AveryFlynn  
        Working...
        X