Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New way to get technical analysis from investing.com #614

Open
danielWagnerr opened this issue Oct 14, 2022 · 2 comments
Open

New way to get technical analysis from investing.com #614

danielWagnerr opened this issue Oct 14, 2022 · 2 comments

Comments

@danielWagnerr
Copy link

I used the techincal_indicators function to get analysis of currency crosses, but with these new changes from Investing, this method stopped working.

I created one that gets the analyzes ONLY OF CURRENCY CROSSES:

technical.py:

def currency_crosses_analysis(name, interval):
    """
    This function retrieves the technical analysis calculated by Investing.com for a given currency cross for different
    time intervals. So on, the user must provide the name of the currency cross and the interval which defines the update frequency of the calculations of the technical indicators (mainly momentum indicators).

    Args:
        name (:obj:`str`):
            name of the currency cross to retrieve the technical indicators table from. (e.g. 'eur/usd').
        interval (:obj:`str`):
            time interval of the resulting calculations, available values are: `5mins`, `15mins`, `30mins`, `1hour`,
            `5hours`, `daily`, `weekly` and `monthly`.

    Returns:
        :obj:`str` - A string containing the current analysis calculated by Investing.com

    Raises:
        ValueError: raised if any of the introduced parameters is not valid or errored.
        ConnectionError: raised if the connection to Investing.com errored or could not be established.
    """

    if not name or not isinstance(name, str):
        raise ValueError("ERR#0116: the parameter name must be specified and must be a string.")

    if not interval or not isinstance(interval, str):
        raise ValueError("ERR#0121: interval value is mandatory and must be a string.")

    if interval not in cst.INTERVAL_FILTERS.keys():
        raise ValueError(
            "ERR#0120: introduced interval value does not exist. Available values are: "
            + ", ".join(cst.INTERVAL_FILTERS.keys())
        )

    currency_data = resource_to_data(path_to_data=cst.PRODUCT_TYPE_FILES["currency_cross"], technical_analysis=True)
    name = unidecode(name.lower().strip())
    check = "name"

    if name not in list(currency_data[check].apply(unidecode).str.lower()):
        raise ValueError("ERR#0122: introduced name does not exist in the introduced country (if required).")

    url = "https://br.investing.com/technical/Service/GetSummaryTable"
    headers = CaseInsensitiveDict(
        {
            "authority": "www.investing.com",
            "accept": "application/json, text/javascript, */*; q=0.01",
            "accept-language": "en-US,en;q=0.9",
            "content-type": "application/x-www-form-urlencoded",
            "origin": "https://www.investing.com",
            "referer": "https://www.investing.com/technical/technical-summary",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-origin",
            "x-requested-with": "XMLHttpRequest",
            "user-agent": random_user_agent(),
        }
    )

    product_id = currency_data.loc[(currency_data[check].apply(unidecode).str.lower() == name).idxmax(), "id"]
    data = f"tab=forex&options%5Bperiods%5D%5B%5D={cst.INTERVAL_FILTERS[interval]}&options%5Breceive_email%5D=false&options%5Bcurrencies%5D%5B%5D={product_id}"

    response = requests.post(url, headers=headers, data=data)
    if response.status_code != 200:
        raise ConnectionError("ERR#0015: error " + str(response.status_code) + ", try again later.")

    root = fromstring(json.loads(response.text)["html"])

    for element in cst.TECHNICAL_INDICATORS_CSS_CLASSES:
        summary_root = root.xpath(f"//td[@class='{element}']")
        if summary_root:
            break

    action = summary_root[0].text_content()
    return action

constant.py:

TECHNICAL_INDICATORS_CSS_CLASSES = [
    "redFont bold left arial_14 js-socket-elem",
    "lightgrayFont bold left arial_14 js-socket-elem",
    "greenFont bold left arial_14 js-socket-elem",
]

I didn't open a pull request because I don't know if my code complies with the standards, I created this issue to help in case anyone has the same problem

@alvarobartt
Copy link
Owner

Hi @danielWagnerr thanks for posting this alternate solution, I'll try to test it on investiny in the meantime!

@InnovArul
Copy link

@alvarobartt Is this method useful in investiny?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants