API -Chart Data 404 when entering YM symbol

Good evening,

I am going through the JS tutorial and I am getting 404 when running EX-10a- solution.
The symbol I am using in the UI is YM and I get 404 but when entering other symbols I do not get that bad request. Can you please let me know what is the symbol in TRADOVATE for futures YM data.

We do have some continuous charts, but charts usually require using a month code as well. Have you tried the YMH2 symbol?

1 Like

Perfect! thank you so much - This worked!!!
Can you please let me know where I can find a list + nomenclature of symbols that I can use with tradovate API. I was looking at this table https://www.tradovate.com/resources/markets/margin/ for symbols and was not aware of the H + month code. Thanks again!

Below is a list of the month symbols:

  • January F
  • February G
  • March H
  • April J
  • May K
  • June M
  • July N
  • August Q
  • September U
  • October V
  • November X
  • December Z

The trailing number is based on the year. H2 is kind of a shorthand for H2022. For example, ESH8 would have referred to the ES contract expiring in March of 2018.

Here’s a good list of markets that we have available.

1 Like

For what it’s worth… if you want to head down the rabbit hole.
It’s possible to use the websocket api to

  • first lookup contracts by string ‘YM’… using contract/suggest
  • Use the received maturity ids to lookup contract info by expiration using: contractMaturity/items
  • Then use that result to find the front month

Here’s a snippit that works for code that I have… took me quite the effort to get working… and is probably missing a few key points… and may be too complicated for you… but is a cool example to show how you can have code that automatically gets the frontmonth contract using the api

in the onmessage event handler where this.instruments is a javascript array of objects [{'SYMBOL': 'YM'}]
//sendContractRequest for each symbol
 for( const instrument of this.instruments ) {
        const request = `contract/suggest\n${++this.messageCount}\nt=${instrument.SYMBOL}&l=10`

        instrument.contractRequestMessageCount = this.messageCount
        log.verbose(`Sending: ${request}`)
    //console.log('instruments:', this.instruments)

let instrument = this.instruments.find(instrument => instrument.contractRequestMessageCount === message.i)
if(message.s == 200 && instrument) {
    //find the contract maturities
    instrument.contracts = message.d

    let maturityIds = []
    for(const contract of instrument.contracts) {

    const request = `contractMaturity/items\n${++this.messageCount}\nids=${maturityIds.toString()}`
    instrument.maturityRequestMessageCount = this.messageCount
    log.verbose(`Sending: ${request}`)

instrument = this.instruments.find(instrument => instrument.maturityRequestMessageCount === message.i)
//if 200 return code and instrument count matches message 
if(message.s == 200 && instrument) {

    log.verbose(`instrument.contracts:${JSON.stringify(instrument.contracts, 0, 4)}`)
    const maturities = message.d

    //from the maturities.. find the 'isFront=true'.. then find the contract that equals that maturity
    const maturity = maturities.find(function({ isFront, expirationDate }) {
        const expiry = new Date(expirationDate)
        const now = new Date()

        const _MS_PER_DAY = 1000 * 60 * 60 * 24;
        const dateDiffInDays = Math.floor((expiry - now) / _MS_PER_DAY)

        //Rollover is 8 days before expiry but..apparently isFront isn't accurrate near rollover - tradovate has value as true through expiration
        //and I don't want to be trading in the final minutes of a contract about to expire

        //expires every 3 months.. so 31 days *3 + 8.. lazy math = 100 days
        return( (isFront && dateDiffInDays > 7) || (!isFront && dateDiffInDays<100 ) )
    log.verbose(`maturity Found:${JSON.stringify(maturity,0,4)}`)
    assert(maturity.id, 'No maturity was found! You like botched the logic near expiration')

    instrument.contract = instrument.contracts.find(({contractMaturityId}) => contractMaturityId === maturity.id)
    log.verbose(`contract found:${JSON.stringify(instrument.contract, 0, 4)}`)

    assert(instrument.contract.id, 'No contract was found!') //throw an error; we are NOT read

    // SEE IF INIT IS DONE now that we've found contracts; use filter to return full array that matches not just one record
    const readyInstruments = this.instruments.filter(instrument => (instrument.contract?.id))
    //now that a contract is found.. check if all instruments are finished.. else continue and dont set ready flag
    if(this.instruments.length === readyInstruments.length){
        this.ready = true  //used to indicate init is done

1 Like

This is great. I love seeing the community help each other out!

Since you’ve gone down the rabbit hole, it is worth noting that the first result that contractSuggest returns is the front-month contract.

I’m happy to share my implementation, which uses the helper function tvGet from @Alexander’s tutorial:

let contract = await tvGet("/contract/suggest", {
            t: symbol,
            l: 1 // Request first result

        contractId = contract[0].id;
        contractName = contract[0].name;

The reason I couldn’t use that was because I ran into trouble right around rollover. Depending on strategy, the last week of a contract’s life is usually not heavily traded. If I’m not mistaken, tradovate supplies frontMonth = true on contracts until expiry… which makes sense in some cases… and not in many others.

I see that if I want a continuous contract for the YM - I need to use @YM - does this support trading through the API?