How to download split adjusted open/close price of stocks using API

hi P123 staff,
I tried to download some stock open/close data, but found they are not split adjusted data, one example: between Nov/28/2020 ~ Dec/1/2020 for ticker NVNO , there was a 25-shares merge into 1 share, bit I got the merged close price when I use API to pull its close price during that period.
How can I download split adjusted open/close price of stocks ?

thanks

Taofen

Hello Taofen,
I am getting the split adjusted prices for NVNO when I use the Data endpoint in the API. Please provide some more details so I can reproduce the issue → Are you using the Data endpoint or are you using some other endpoint? Are you using the API directly or are you using DataMiner?

import p123api
import pandas as pd

try:
    client = p123api.Client(api_id='<your id>', api_key='<your key>')
    data = client.data(
        {
            'tickers': ['NVNO:USA'],
            'formulas': ['open(0)','close(0)'],
            'startDt': '2020-08-10',
            'endDt': '2020-12-01',
            'frequency': 'Every Week',
        }, True)  # True to output to dataframe

    pd.set_option('display.max_rows', None)
    print(data)

except p123api.ClientException as e:
    print(e)

Thanks for you quick reply. I’m using java to call rest api directly:

  1. first get token by calling entry /auth with my api id and key
  2. after token received, call entry /rank/ranks to get rank data with some additional data i.e. close(0),open(-1)
    All work well but i can’t get split adjusted open/close price.

I also tried your python code, it does not work for my account, i got the below error message:
API request failed: You can only test historical data with IBM, INTC, & MSFT

thanks
Taofen

Hello Taofen,
Sorry for the delay in getting back to you. As you know, the ranks endpoint returns the data with the point in time price. There is currently no way for the API to return the prices adjusted for future splits.

I did create a task to fix the Data endpoint so that it does not require a vendor data license for pricing data. However, that endpoint uses weekly dates, so that might not be useful to you. I also created a request to create a function that would return the Close adjusted for splits even when used in the past. I cant tell you when those requests will be completed, but I wanted to let you know the process was started.

Thanks Dan. Can you elaborate a bit more about the data point you’ve fixed " that endpoint uses weekly dates" ? that may be some workaround for me at the moment. Certainly I hope the final solution will be the ranks endpoint can directly return adjusted price.

How about my another issue regarding using your python code with my account but get the error message?

Thanks
Taofen

The change to the Data endpoint will be that pricing and technical data will not require a vendor data license. That restriction is why you got the error when you ran my python code. They are working on this one now.

The other request was for functions that would return the Close and Open adjusted for splits. You could use those function everywhere including the Ranks endpoint. Sorry, but I dont have any update on when that will be done.

1 Like

Thank you Dan. More clear now to me. But i’m still confused for this:
“The change to the Data endpoint will be that pricing and technical data will not require a vendor data license. That restriction is why you got the error when you ran my python.”
Actually I copied your code and i only replace the api key and id with mine:
data = client.data(
{
‘tickers’: [‘NVNO:USA’],
‘formulas’: [‘open(0)’,‘close(0)’],
‘startDt’: ‘2020-08-10’,
‘endDt’: ‘2020-12-01’,
‘frequency’: ‘Every Week’,
}, True) # True to output to dataframe

Does that mean the above code also call the ranks end point?

That code I posted earlier is for the data endpoint. I posted that to mention another way to get the price data. FYI - The developers are still researching the request to remove the license requirement for pricing data from the data endpoint.

The code for the ranks endpoint would be different. Here is a very basic example of what it would look like. The Pandas parts are optional but it makes the results easy to read:

import p123api
import pandas as pd

try:
    client = p123api.Client(api_id='<your id>', api_key='<your key>')

    data = client.rank_ranks(
        {
            'rankingSystem': 'Core: Value',
            'asOfDt': '2020-12-05',  #this is the date it goes to $7+ from $.30
            'rankingMethod': 2, #2 - Percentile NAs Negative, 4 - Percentile NAs Neutral
            #'universe': 'DJIA',
            'tickers': 'NVNO:USA, ibm, msft',
            'nodeDetails': 'composite', #'factor',
            'additionalData': [
                'Close(0)',
                'Open(0)',
            ]
        },True)
    pd.set_option('display.max_rows', None)
    pd.set_option('display.max_columns', None)
    pd.set_option('display.width', None)
    print(data)

except p123api.ClientException as e:
    print(e)

There is additional information on the API here:
Knowledgebase article: [url=https://portfolio123.customerly.help/dataminer-api/the-api-wrapper-p123api]https://portfolio123.customerly.help/dataminer-api/the-api-wrapper-p123api[/url]
API documentation: [url=https://api.portfolio123.com:8443/docs/index.html#/Data/_data_universe]https://api.portfolio123.com:8443/docs/index.html#/Data/_data_universe[/url]

1 Like

Many thanks Dan for all your detailed replies.

hi Dan,
Do you have any updates for this issue? or any workaround can be provided for example , you can provide another separated price data end point without license so I can pull the adjusted price data and merge them with rank data on my side? thanks

Taofen

1 Like

Hi Taofen.

The request was submitted, but the developers have been fully allocated to other projects. I will mention this request again and see if I can get it prioritized.

1 Like

hi P123,
do you have any updates for this defect? We need to fix the issue rather than leave it there just because I’m the only person who is using this part of data, fixing all data issue can help end users build up high confidence on P123. Thanks

Taofen

1 Like

Hi,

I’m also attempting to use this historical price information. I would love to stay in P123 for everything I need and I hope that the historical price data is accessible for us soon.

Thanks

There’s an easier solution than altering the Data endpoint. There’s an undocumented factor FutureSplitFactor that you can use to reverse out future splits. Can you try to add it in the AdditionalData in the Ranks endpoint?

I will add the documentation soon

Hi Dan,

I definitely don’t want to flood this thread with the same question or bother you and the team too much but are the devs still looking into removing license requirement for pricing data?

Thank You,
Andrew

Sorry Andrew but the Dev team looked into the option of removing pricing factors from the license requirements for the Data endpoint and it is a bigger project then we expected, so that option is off the table.

The FutureSplitFactor factor that Marco mentioned above should do what you guys have been asking for. Here is some sample code:

import p123api
import pandas as pd

try:
    client = p123api.Client(api_id='YOUR ID', api_key='YOUR KEY')

    weekmask = "Sat"
    daterange = pd.bdate_range("08/21/2020", "09/13/2020", freq="C", weekmask=weekmask)  # Returns Saturdays.
    for single_date in daterange:

        data = client.rank_ranks(
            {
                'asOfDt': single_date.strftime("%Y-%m-%d"),
                'rankingSystem': 'Core: Value',
                'tickers': 'AAPL:usa',  # AAPL split 4:1 on 8/31/20
                'additionalData': [
                    'Close(0)',  #unadjusted price
                    'Close(0)/FutureSplitFactor',  # adjusted for splits
                    'FutureSplitFactor']
            },True)

        df2 = data.rename({'formula1': 'Unadjusted', 'formula2': 'Adjusted', 'formula3': 'SplitFactor'}, axis='columns')

        print(single_date.strftime("%Y-%m-%d"))
        print(df2)

except p123api.ClientException as e:
    print(e)

image

Understood. Thank you.

Thanks Dan, at least this is some workaround and works for me.