Sunday, October 27, 2019

Trading on Trump's Tweets


Summary

There have been several articles during President Trump's term regarding his use of Twitter and his influence on stock prices.  Below is one such article:

https://fortune.com/2017/02/24/trump-tweet-stocks/ 

This post explores development of a programmatic analysis of Trump's tweets that are focused on publicly traded companies.  I use a variety of APIs to ferret out the tweets of interest and then take action on them.  In this exercise, I simply generate an alert email; however, one could envision automated trading as the action.

This post represents the culmination of the my Twitter API blog series:

Architecture

This is a Node-based architecture that uses various publicly accessible REST APIs.

 

Processing Logic

 

 

Code Excerpt - Tweet Processing

The function below accepts tweet text as input and then sends that text through Google's NL engine for entity analysis. If the top entity, ranked by salience, is an "ORGANIZATION" - then there's a chance the tweet is regarding a company. The next step is to use the IEX Cloud API to determine if the entity does in fact corresponds to a publicly traded company.  If so, then perform full processing of the tweet:  gather further NL + stock analytics and then package them for an email alert.

async function processTweet(tweet) {
    logger.debug(`processTweet()`);
    try {
        const esnt = await entitySentiment(GOOGLE_KEY, ENTITY_SENTIMENT_URL, tweet);

        if (esnt.type === 'ORGANIZATION') { //entity corresponds to a type that might be a company
            let stock;
            if (Array.isArray(symbolArray)) {
                stock = symbolArray.find(obj => {
                    return obj.name.match(esnt.name);
                });
                if (stock) {  //name corresponds to a publicly traded company - fetch full tweet sentiment
                    //and stock data
                    const snt = await sentiment(GOOGLE_KEY, SENTIMENT_URL, tweet);
                    const data = await getStockData(IEX_KEY, STOCK_URL, stock.symbol);

                    let analytics = {};
                    analytics.tweet = tweet;
                    analytics.name = esnt.name;
                    analytics.salience = esnt.salience;
                    analytics.entitySentiment = esnt.entitySentiment;
                    analytics.documentSentiment = snt;
                    let mag = (analytics.entitySentiment.magnitude + analytics.documentSentiment.magnitude) / 2;
                    let score = (analytics.entitySentiment.score + analytics.documentSentiment.score) / 2;
                    analytics.aggregate = mag * score;
                    analytics.symbol = stock.symbol;
                    analytics.data = data;
                    sendEmail(SENDGRID_KEY, SENDGRID_URL, analytics);
                }
            }
        }
    }
    catch(err) {
        logger.error(err);
    }
}

Code Excerpt - Fetch Stock Data

Excerpt below exercises IEX's API to fetch a few simple stock data items.  This API is quite rich.  There is significantly more analytics available that what I've pulled below:  current stock price and previous day's history.

async function getStockData(token, url, symbol) {
    logger.debug(`getStockData() - name:${symbol}`);
    
    let data = {};
    const price = await getPrice(token, url, symbol);
    const previous = await getPrevious(token, url, symbol);
    data.current_price = price;
    data.date = previous.date;
    data.open = previous.open;
    data.close = previous.close;
    data.high = previous.high;
    data.low = previous.low
    return data;
}

Code Excerpt - Test

Test function below submits a tweet President Trump unleashed on Harley-Davidson on June 25, 2018.
async function test() {
    symbolArray = await getSymbols(IEX_KEY, SYMBOL_URL);
    const tweet1 = "Surprised that Harley-Davidson, of all companies, would be the first to wave the White Flag. I
fought hard for them and ultimately they will not pay tariffs selling into the E.U., 
which has hurt us badly on trade, down $151 Billion. Taxes just a Harley excuse - be patient!";
    await processTweet(tweet1);
}

test()
.then(() => {
    console.log('complete');
});

Results

Excerpt below of the raw email text that was generated.

Date: Sun, 27 Oct 2019 17:54:52 +0000 (UTC)
From: twitterTrade@example.com
Mime-Version: 1.0
To: joey.whelan@gmail.com
Message-ID: 
Content-type: multipart/alternative; boundary="----------=_1572198892-24558-282"
Subject: Twitter Trade Alert - Negative Tweet: Harley-Davidson

{
    "tweet": "Surprised that Harley-Davidson, of all companies, would be th=
e first to wave the White Flag. I fought hard for them and ultimately they =
will not pay tariffs selling into the E.U., which has hurt us badly on trad=
e, down $151 Billion. Taxes just a Harley excuse - be patient!",
    "name": "Harley-Davidson",
    "salience": 0.35687405,
    "entitySentiment": {
        "magnitude": 0.4,
        "score": 0
    },
    "documentSentiment": {
        "magnitude": 0.9,
        "score": -0.1
    },
    "aggregate": -0.0325,
    "symbol": "HOG",
    "data": {
        "current_price": 39.39,
        "date": "2019-10-25",
        "open": 38.64,
        "close": 39.39,
        "high": 39.69,
        "low": 38.64
    }
}

Source

https://github.com/joeywhelan/twitterTrade

Copyright ©1993-2024 Joey E Whelan, All rights reserved.