Sunday, February 12, 2017

Least Correlated Forex Currency Pairs

Minimizing risk trough Un-correlation

The number of possible major/minor currency is large and trading currencies that are correlated logically increases risk. My Google search for least correlated Forex pairs came up empty so I decided to run the analysis myself.

Using information from this list on Oanda I created a JS script that would loop through the table entires and return the least correlated pairs based on the 1 year value. To my surprise I had to permit high correlations of >0.80 for the major currencies, and >0.95 for the major and minor currencies together to get values returned.

Major Currencies

["AUD/USD", "EUR/AUD", "EUR/CHF", "EUR/GBP", "EUR/USD", "NZD/USD"]

Major + Minor Currencies

["AUD/CAD", "AUD/CHF", "AUD/HKD", "AUD/JPY", "AUD/NZD", "AUD/SGD", "CAD/CHF", "CAD/HKD", "CAD/JPY", "CAD/SGD", "CHF/HKD", "CHF/JPY", "CHF/ZAR", "EUR/AUD", "EUR/CAD", "EUR/CHF", "EUR/CZK", "EUR/DKK", "EUR/GBP", "EUR/HKD", "EUR/HUF", "EUR/NOK", "EUR/NZD", "EUR/PLN", "EUR/SEK", "EUR/SGD", "EUR/TRY", "GBP/AUD", "GBP/JPY"]

Feel free to comment or follow me @danielsokolows.

Console JS Snippet


document.querySelector('#Table_button').click(); // swithc to table mode which shows numbers
var aPairElementList = Array.prototype.slice.call(document.querySelector('#Table').querySelectorAll('.currency_pair'),0);
var aReturnedPairs = aPairElementList.map(function(oElement) {return oElement.innerText}); // whatever remains in this array is our uncorrelated pairs
var aPairsCompared = [];
// for each pair select it
for (var i = 0; i < aPairElementList.length; i++) {
 aPairElementList[i].querySelector('button').click();
    // NEED TO RESCAN THE aPairElementList as the nodes have been destroyed and re-created so our aPairElementList is outdated
    aPairElementList = Array.prototype.slice.call(document.querySelector('#Table').querySelectorAll('.currency_pair'),0);

    // no loop over the entire list and prune any correlated pairs from our aReturnedPairs
    for (var j = 0; j < aPairElementList.length; j++) {
        // go to the nth sibling and check for corelation, and remove from our returned list if correlated positively
        // 7th  next sibling is 1 Year
        if (aPairElementList[i].innerText != aPairElementList[j].innerText && aPairsCompared.indexOf(aPairElementList[i].innerText + aPairElementList[j].innerText) == -1) {
            var nCorelationValue = Number(aPairElementList[j].nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.nextElementSibling.innerText);
            //console.assert(nCorelationValue != NaN, 'Must never have failed to parse correlation');
            if (nCorelationValue == NaN) {throw new Exception('Must never have failed to parse correlation')};
            if (nCorelationValue >= 0.95) {
               console.log('Removing because \'' + aPairElementList[i].innerText + '\' correlation with \'' + aPairElementList[j].innerText + '\' is ' + nCorelationValue);
               aReturnedPairs.splice(aReturnedPairs.indexOf(aPairElementList[j].innerText), 1);
               // store the reverse of the pair so we don't don't compare it
               aPairsCompared.push(aPairElementList[j].innerText + aPairElementList[i].innerText);
            }
        }
    }
}
console.log(aReturnedPairs)

1 comment: