I am trying to build a logic for a Foreign currency calculator.
I have got below foreign currencies mapping and their rates given ( coming from application_input.properties ) :
EURUSD=1.2
USDJPY=11.95
AUDUSD=21.83
CADUSD=2.87
USDCNY=6.17
GBPUSD=1.56
NZDUSD=3.77
EURCZK=2.60
EURDKK=7.44
EURNOK=8.66
If I have to find EUR to USD conversion then I got that.. as its given directly EUR - USD = 1.2
If I need DKK to EUR that is also given but by inverse .. i.e. 1/7.44
If I need AUD to CZK that can be found by linking (a Cross) AUD -> USD -> EUR ( Inverse of EURUSD ) -> CZK
I am trying to think through the logic ( In Java with any API ) but couldn't find as of now.
Can anyone help me here, please?
I tried to create a table(sheet) having mapping of all the currencies. So that I can visit that sheet and see how to find the link between the currencies. I was able to generate the Currencies having Direct rates/Inverse rates and stuck at generating links between cross currency rates.
Here is the code:
package com.nitin.fxcalculator;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) throws IOException {
App app = new App();
/*Scanner scanner = new Scanner(System. in);
String input = scanner.nextLine();
String [] inputParams = input.split("\\s+");
if(ifValidParams(inputParams) == false) {
System.exit(1);
}*/
Properties propFile = app.loadInputFile();
Set<String> currencies = findCurrencyAvailable(propFile);
Map<String, Double> currencyRate = getCurrencyRates(propFile);
System.out.println("Rates given - "+ currencyRate.size());
System.out.println(currencyRate);
generateCurrencyLink(currencies, currencyRate);
}
public static boolean ifValidParams(String [] inputParams) {
if(inputParams.length != 4) {
System.out.println("Incorrect no of arguments");
return false;
}
if(!inputParams[2].equals("in")) {
System.out.println("Invalid args at position - " + 3);
return false;
}
return true;
}
/*************
*
* @return
* @throws IOException
*/
public Properties loadInputFile() throws IOException {
Properties prop = new Properties();
InputStream input = null;
ClassLoader classLoader = this.getClass().getClassLoader();
File file = new File(classLoader.getResource("application_input.properties").getFile());
input = new FileInputStream(file);
prop.load(input);
return prop;
}
/*******************************************
* Read the input properties file
* where initial currencies and values
* are given.
* Determine the total currencies available
* and return a set of those
* @return
* @throws IOException
*******************************************/
public static Set<String> findCurrencyAvailable(Properties prop) throws IOException {
Set<String> setOfCurrencies = new TreeSet<String>();
for(Object setItem : prop.keySet()) {
String key = (String)setItem;
setOfCurrencies.add(key.substring(0, 3));
setOfCurrencies.add(key.substring(3, 6));
}
return setOfCurrencies;
}
public static Map<String, Double> getCurrencyRates(Properties prop) {
Map<String, Double> currencyRate = new HashMap<String, Double>();
for(Entry<Object, Object> property : prop.entrySet()) {
currencyRate.put((String)property.getKey(), Double.valueOf((String)property.getValue()));
}
return currencyRate;
}
public static void generateCurrencyLink(Set<String> currencies, Map<String, Double> currencyRate) throws IOException {
FileOutputStream file = new FileOutputStream (new File("C:\\temp.xls"));
//Get the workbook instance for XLS file
HSSFWorkbook workbook = new HSSFWorkbook();
//Get first sheet from the workbook
HSSFSheet sheet = workbook.createSheet("sample");
Row row = sheet.createRow(0);
int cellnum = 1;
for (String currency : currencies) {
Cell cell = row.createCell(cellnum++);
cell.setCellValue(currency);
}
int rowNum = 1;
String key = null;
String keyInverse = null;
String value = null;
for(int i = 0 ; i < currencies.size();i++) {
row = sheet.createRow(rowNum);
int cellNum = 0;
for (int j = 0;j < currencies.size();j++) {
Cell cell = null;
if(cellNum == 0) {
cell = row.createCell(cellNum++);
cell.setCellValue((String)currencies.toArray()[i]);
}
if(rowNum == cellNum) {
cell = row.createCell(cellNum);
cell.setCellValue("1:1");
} else {
//create a key like : audcad/audeur/audusd
key = row.getCell(0).getStringCellValue() + (String)currencies.toArray()[j] ;
keyInverse = (String)currencies.toArray()[j] + row.getCell(0).getStringCellValue();
if(currencyRate.get(key) != null) {
cell = row.createCell(cellNum);
cell.setCellValue("D");
} else if(currencyRate.get(keyInverse) != null) {
cell = row.createCell(cellNum);
cell.setCellValue("Inv");
} else {
for(String currencyKey : currencyRate.keySet()) {
int len = row.getCell(0).getStringCellValue().length();
String crossKey = currencyKey.substring(3) + (String)currencies.toArray()[j];
String crossKeyInv = (String)currencies.toArray()[j] + currencyKey.substring(3);
if(currencyRate.containsKey(crossKey) || currencyRate.containsKey(crossKeyInv)) {
cell = row.createCell(cellNum);
cell.setCellValue(currencyKey.substring(3));
}
}
}
}
cellNum++;
}
rowNum++;
}
workbook.write(file);
file.close();
}
}
Above code has generated the sheet like : ForexCurrencyMapping
I have written the code for generating the sheet as of now. Once the sheet is populated through the appropriate cross links, I will start with writing the code for actual calculations.
Input to run this code would be:
console> AUD 100.00 in DKK
But this is the next stage. Right now I am just launching the main class from Eclipse to populate the sheet.