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

Instrument Base and Quote values.

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

    Instrument Base and Quote values.

    Hi I am writing a strategy that uses the Pip value of an instrument in a calculation.

    I can write the syntax to determine a pip's value (based upon a standard lot of any instrument pair), as the formula is well documented. But in essence, dependent on the Base and Quote currencies of the instrument and their relationship to the account currency, the method and syntax of the Pip value calculation changes.

    So my starting point is to establish what my account currency is, and weather that corresponds to any of the currencies within the instrument currently loaded to a chart.

    To establish this detail I have been looking at the function.

    Code:
     Bars.Instrument.MasterInstrument.Currency
    . I have been printing out what this returns on various charts.

    In my current testing where the chart is set to GBP/USD this function returns a value of "British Pound".

    When the chart is set to EUR/USD it returns "USD"

    This seems to be the 'Base' currency value where the account currency matches one of the currency pairs. And then the 'Quote' currency value where the account current is not present?

    Can you give me some clarity on what MasterInstrument is returning, and also a steer of if my approach to obtain the Base and quote values of an instrument is correct?

    Thanks

    Duncan

    #2
    Hello EastLondonKiwi,

    Thank you for your post.

    MasterInstrument.Currency is the Currency of the instrument in the Instrument Manager under Tools > Instruments. It looks like the GBPUSD is incorrect as it should be USD.

    I will send this to our development team, thank you for bringing this to our attention.

    Comment


      #3
      Pattrick

      I am glad you help by highlighting a bug. However, do you have any answer to my actual question?

      How do I grab the Base and Quote values from an instrument that has current chart focus?

      Or is there a way to establish a pip value directly?

      Comment


        #4
        Hello EastLondonKiwi,

        Thank you for your response.

        Bars.Instrument.MasterInstrument.Currency will be the base currency. So what are you trying to pull exactly here?

        What do you mean by base and quote values?

        What do you mean by chart that has focus?

        I look forward to your response.

        Comment


          #5
          Patrick

          A currency instrument or Pair is made up of two currencies, the Base, and the Quote. in the instrument EUR/USD the EUR is the Base currency and the USD is the Quote currency. On a chart the vertical price index represents the Quote currency right?

          When I am calling the Instrument detail, I want to be able to determine which way around the currencies are. Because an Instrument EUR/USD, is different from USD/EUR.

          Next the in focus. means which instrument is on the chart, and is what is being displayed to the user (it's in focus). I may also want to call an instrument that is not in focus.

          The formula to value a pip is:

          (0.0001 / The Quote Currency) x 100,000 = The value of 1 pip per standard Lot in the quote currency.

          Now if the Quote currency of the in focus instrument is not in the same denomination as your account currency, you then have to convert the Pip value into the denomination of your account. You do that by dividing the result of the afore mentioned calculation by the Quote price of the an instrument which is AccountCurrency over InFocusQuoteCurrency

          Example:

          My account is in GBP

          If the In Focus instrument is AUD/USD a pip value for that instrument will be:

          (0.0001 / 0.76870) x 100,000 = 13.00 AUD

          To get the value converted into GBP

          I take the quote value from the GBP/AUD instrument which in this example is 1.6227

          13.00 / 1.6227 = 8.01GBP which is the end value I am seeking to get to.

          So the workflow for my method is:

          1. ascertain what the in focus instrument is
          2. ascertain of the in focus instrument contains a currency that is the same as the account currency
          3. Is JPY currency is involved the first value is 0.01 not 0.0001
          4. compute the first result
          5 if you need to convert the result to the account currency, grab the quote price of the Account Currency/the In focus Quote Currency
          6. divide the result by that price

          i hope this explanation helps.

          Can you now assist me in determining what the Base and quote values of an instrument is, and calling a not in focus instrument to harvest the current quote price?

          Thanks

          Comment


            #6
            Hello EastLondonKiwi,

            Thank you for your response.

            There would not be a "Quote" currency you could pull in NinjaScript. It would only be the Base currency that that pair trades in.

            You could develop a simple check of the name of the pair using Instrument.MasterInstrument.Name and then running the logic based on the pair. You can find information on Instrument.MasterInstrument.Name at the following link: http://ninjatrader.com/support/helpG...ument_name.htm

            Please let me know if you have any questions.

            Comment


              #7
              Thanks Patrick I can work with that.

              Can you explain how I call the current price of an instrument not in focus.

              For example. If my chart is set to the instrument AUDUSD

              And without changing the instrument, I want to get the current price value of the instrument GBPAUD captured into a variable.

              Can you point me at the correct function.

              Kind regards

              Duncan

              Comment


                #8
                Hi Duncan,

                We have been working on a similar issue needing to determine the Pip Value of a given currency to properly calculate position size inside a strategy.

                With previous forex platforms we've worked with, they provided a 'PipCost' value for each currency instrument that could be called from the broker's API; Typically that value would be equal to 1000 units of the account's currency per one-PIP movement rounded to the nearest tenth (Ex: AUDNZD = .07 USD)

                What we've done so far to address this is-

                1) use the MasterInstrument.name to split the Base and Quote currency:

                Code:
                	_strBaseCurr = Instrument.MasterInstrument.Name.Substring(Instrument.MasterInstrument.Name.Length - 6, 3);
                	_strQuoteCurr = Instrument.MasterInstrument.Name.Substring(Instrument.MasterInstrument.Name.Length - 3, 3);
                2) then use an if-statement to distinguish if your Acct currency is part of the instrument's Base, Quote or not at all:

                Code:
                if (_strBaseCurr == "USD")
                	{
                		_strBasePair = Instrument.MasterInstrument.Name;
                		_blnUSDBasePair = true;
                	}
                	else if (_strQuoteCurr == "USD")
                	{
                		_strBasePair = Instrument.MasterInstrument.Name;
                		_blnUSDQuotedPair = true;
                	}
                	else
                	{
                		_strBasePair = _strBaseCurr + "USD";
                		_blnNonUSDPair = true;
                	}
                4) if required, add the new data series for your calculation:

                Code:
                	if (_blnNonUSDPair) AddDataSeries(_strBasePair, BarsPeriodType.Minute, 5); // Series[1]
                5) determine which calculation you need to use based on the current Instrument: (this must be done after State.DataLoaded)

                Code:
                	if (Instrument.MasterInstrument.InstrumentType == InstrumentType.Forex)
                	{
                		double dblBasePrice = BarsArray[1].GetClose(BarsArray[1].Count - 1);
                		double dblThisPrice = BarsArray[0].GetClose(BarsArray[0].Count - 1);
                
                		if (_blnUSDQuotedPair)
                		{
                			// [ACCT Currency] is the quoted currency of the Instrument (ThisPrice)
                			_dblPipCost = _dblTickSize;
                		}
                		else if (_blnUSDBasePair)
                		{
                			// [ACCT Currency] is the base currency of the Instrument
                			// the Instrument quote is equal to 1 [ACCT Currency Units] simply divide by the quote
                			_dblPipCost = _dblTickSize / dblThisPrice;
                		}
                		else
                		{
                			// [ACCT Currency] is not part of the Instrument
                			// manually calculate our PipCost using the second Instrument [BASE]/[ACCT]
                			_dblPipCost = (_dblTickSize * dblBasePrice) / dblThisPrice;				
                		}
                	}
                6) That's it, you have your PipValue. Now use it to calculate per-PIP value of a particular lot size or anything else.

                Perhaps in the future NinjaTrader would be willing to provide updated Instrument.MasterInstrument.PointValue records for the FOREX instruments they offer through their brokerage affiliates?

                Best,

                Rian
                Last edited by CDXTrader; 03-24-2017, 12:01 AM.

                Comment


                  #9
                  Thanks Rian that is really helpful

                  Code:
                  BarsArray[1].GetClose(BarsArray[1].Count - 1);
                  I get an error is I use this syntax with the -1 on the end, but without it, the code runs fine.

                  Other than that your suggestion regarding the AddDataSeries was the right direction.

                  Where I am getting stuck is in calling the AddDataSeries

                  I am using a variable GBPCurrencyPair which I load with two strings concatenated together.
                  Code:
                   "GBP" + BaseCurrency
                  BaseCurrency coming from your very helpful
                  Code:
                   BaseCurrency = Instrument.MasterInstrument.Name.Substring.......
                  what I am experiencing is, if my platform's instrument list does not contain an instrument name as presented by my newly populated variable 'GBPCurrencyPair'. AddDataSeries throws and error.

                  So I need a way to access the full list of forex instruments available to AddDataSeries, so I can check the instrument value I want to pass into it, exists before I do, and if it does not, I probably have to reverse the pair name eg. from GBPEUR to EURGBP.

                  Any thoughts on where the full instrument list can be obtained?

                  Thanks

                  Duncan

                  Comment


                    #10
                    Hello EastLondonKiwi,

                    Thank you for your response.

                    There would not be a supported means to query the Instruments through the database for only those that are Forex.

                    Please let me know if you have any questions.

                    Comment


                      #11
                      Hi Duncan,

                      There is essentially only one FX instrument quoted in GBP (EURGBP). Why not just handle that one concatenation in a separate argument?

                      E.g. If your focus instrument is EURAUD
                      Code:
                      if (_strBaseCurr == "EUR") GBPCurrencyPair = _strBaseCurr + "GBP";
                      else GBPCurrencyPair = "GBP" + _strBaseCurr;
                      
                      AddDataSeries(GBPCurrencyPair, BarsPeriodType.Minute, 5); // Series[1]
                      
                      GBPPrice = BarsArray[1].GetClose(BarsArray[1].Count);
                      
                      if (GBPCurrencyPair != "EURGBP") GBPPrice = 1/GBPPrice;
                      Less elegant maybe, but it gets the job done.

                      cheers,
                      Rian

                      Comment


                        #12
                        I like your style Rian.

                        But if I can, I want to create generic code that works in every situation,

                        There must be a way to pull the full list of instruments available to AddDataSeries into a list. Then simply do a Foreach loop through that list validating the name loaded to my GBPCurrencyPair before I pass the same to AddDataSeries?

                        I'll keep plugging away and in the mean time use your approach to solve my immediate problem so I can move the rest of the indicator forward.

                        Thanks, you are a star

                        Comment


                          #13
                          Many thanks to CDXTrader

                          What to ask about checking about additional instrument (if it need to be loaded).

                          As for as I understand from NinjaTrader_PatrickH answer in post #10, we can't check for existence of additional instrument.

                          But we can check is instrument loaded.
                          I tried to load fake instrument and found out, that CurrentBar[1] == -1 always.
                          Is there more elegant way. Say can it be checked in State.DataLoaded?

                          PHP Code:
                          bool is_fake_instrument BarsArray[1].Count == 0;
                          bool is_fake_instrument BarsArray[1].TotalTicks == 0;
                          bool is_fake_instrument BarsArray[1].Instrument.MasterInstrument.Url == null
                          Are these variants acceptable?
                          May be, there are other variants?
                          On screenshots info on fake instrument from debugger on State.DataLoaded.
                          Attached Files
                          Last edited by fx.practic; 09-13-2017, 12:20 PM.
                          fx.practic
                          NinjaTrader Ecosystem Vendor - fx.practic

                          Comment


                            #14
                            Hello fx.practic,

                            Thank you for your post.

                            State.DataLoaded would be occur once all series have loaded and would mean the Instruments would be available.

                            Please let me know if you have any questions.

                            Comment


                              #15
                              Patrik, don't quite understand how to use State.DataLoaded to check if instrument exist.

                              I try to load fake instrument, State.DataLoaded passed and OnBarUpdate() invokes for primary series only:
                              PHP Code:
                              protected override void OnStateChange()
                              {
                                  if (
                              State == State.Configure)
                                  {
                                      
                              AddDataSeries("Fake_Istrument"BarsPeriodType.Minute5);                
                                  }
                                  else if( 
                              State == State.DataLoaded )
                                  {
                                      Print( 
                              "Data Loaded:" );
                                      Print( 
                              "Instruments[0].FullName: "Instruments[0].FullName );
                                      Print( 
                              "Instruments[1].FullName: "Instruments[1].FullName );
                                      Print( 
                              "-------------------" );
                                      Print( 
                              "" );
                                  }
                              }

                              protected 
                              override void OnBarUpdate()
                              {
                                  if( 
                              BarsInProgress == ) Print( Instruments[0].FullName );
                                  if( 
                              BarsInProgress == ) Print( Instruments[1].FullName );

                              Attached Files
                              fx.practic
                              NinjaTrader Ecosystem Vendor - fx.practic

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by stafe, 04-15-2024, 08:34 PM
                              6 responses
                              30 views
                              0 likes
                              Last Post stafe
                              by stafe
                               
                              Started by adeelshahzad, Today, 03:54 AM
                              4 responses
                              25 views
                              0 likes
                              Last Post adeelshahzad  
                              Started by merzo, 06-25-2023, 02:19 AM
                              10 responses
                              823 views
                              1 like
                              Last Post NinjaTrader_ChristopherJ  
                              Started by frankthearm, Today, 09:08 AM
                              5 responses
                              17 views
                              0 likes
                              Last Post NinjaTrader_Clayton  
                              Started by jeronymite, 04-12-2024, 04:26 PM
                              3 responses
                              43 views
                              0 likes
                              Last Post jeronymite  
                              Working...
                              X