// Combined /fileadmin/jslib/fxconsulting/tools/utilities.js
var Utilities={getURLParameters:function(){var a={};if(top.location.search.length>0){var c;var e=unescape(top.location.search.substr(1)).split("&");for(c=0;c<e.length;c++){var b=e[c].split("=")[0];var d=e[c].split("=")[1];if(!d){d=null}else{if(!isNaN(d)){d=parseFloat(d)}}if(!a[b]){a[b]=d}else{if(typeof(a[b])=="object"){a[b].push(d)}else{a[b]=[a[b],d]}}}}return a},getDaysInMonth:function(b,a){if(b<0){b+=12}return[31,((!(a%4)&&((a%100)||!(a%400)))?29:28),31,30,31,30,31,31,30,31,30,31][b]},getFormattedDate:function(b){var a=b.getDate()<10?"0"+b.getDate():b.getDate();var c=b.getMonth()<9?"0"+(b.getMonth()+1):(b.getMonth()+1);return a+"/"+c+"/"+b.getFullYear()},fireCustomEvent:function(c,b){var d=$(c);var a;if(typeof(document.createEventObject)!="undefined"){a=document.createEventObject();a.type=b;d.fireEvent("on"+b,a)}else{a=document.createEvent("Events");a.initEvent(b,true,true);d.dispatchEvent(a)}}};var Calendar=Class.create({parent:null,container:null,tbody:null,date:new Date(),months:["January","February","March","April","May","June","July","August","September","October","November","December"],initialize:function(b,a){this.parent=b;this.container=new Element("div",{"class":"calendarContainer"});this.container.style.top=b.cumulativeOffset()[1]+b.getHeight()+"px";this.container.style.left=b.cumulativeOffset()[0]+"px";if(b.value.strip()&&b.value.match(a)){var c=b.value.split("/");this.date=new Date(c[2],parseFloat(c[1])-1,parseFloat(c[0]))}this.generateCalendar();b.parentNode.appendChild(this.container);b.observe("keydown",this.checkHide.bind(this));b.observe("change",this.hide.bind(this));this.bl=this.hide.bindAsEventListener(this);Event.observe(document,"click",this.bl)},checkHide:function(a){if(a.type=="keydown"&&(a.keyCode==27||a.keyCode==9)){setTimeout(this.hide.bind(this),1)}},hide:function(){if(arguments.length>0){if(arguments[0].type=="click"&&arguments[0].target==this.parent){return}}this.parent.calendar=null;if(this.container.ancestors().size()>0){this.parent.parentNode.removeChild(this.container)}Event.stopObserving(document,"click",this.bl);this.bl=null},generateCalendar:function(){this.container.descendants().invoke("remove");this.generateHeader();var d=new Date(this.date.getFullYear(),this.date.getMonth(),1);var a=new Element("tbody");var c=new Element("tr",{"class":"calendarWeekHeading"}).insert(new Element("td").insert("S")).insert(new Element("td").insert("M")).insert(new Element("td").insert("T")).insert(new Element("td").insert("W")).insert(new Element("td").insert("T")).insert(new Element("td").insert("F")).insert(new Element("td").insert("S"));a.insert(c);var b;for(b=1;b<=this.daysInMonth();b++){d.setDate(b);if(!d.getDay()||b==1){a.insert(this.generateWeek(d))}}this.container.insert(new Element("table",{"class":"calendarTable"}).insert(a))},generateHeader:function(){this.container.insert(this.generateNavButton("&laquo; ",new Date(this.date.getFullYear()-1,this.date.getMonth(),this.date.getDate()))).insert(this.generateNavButton("&lt; ",new Date(this.date.getFullYear(),this.date.getMonth()-1,this.date.getDate()))).insert((new Element("div",{"class":"calendarMonthDisplay"}).insert(this.months[this.date.getMonth()]+"<br />"+this.date.getFullYear()))).insert(this.generateNavButton(" &gt;",new Date(this.date.getFullYear(),this.date.getMonth()+1,this.date.getDate()))).insert(this.generateNavButton(" &raquo;",new Date(this.date.getFullYear()+1,this.date.getMonth(),this.date.getDate())))},generateNavButton:function(c,b){var a=new Element("div",{"class":"calendarNavButton"});a.insert(c);a.observe("mousedown",function(){this.date=b;this.generateCalendar()}.bind(this));return a},generateWeek:function(d){var b=new Element("tr");var a;var c;for(c=d.getDay();c>0;c--){a=this.generateDay(new Date(d.getFullYear(),d.getMonth(),d.getDate()-c)).addClassName("calendarPrevMonth");b.insert(a)}for(c=0;c<=6-d.getDay();c++){a=this.generateDay(new Date(d.getFullYear(),d.getMonth(),d.getDate()+c));if(d.getDate()+c>this.daysInMonth(d.getMonth(),d.getFullYear())){a.addClassName("calendarNextMonth")}b.insert(a)}return b},generateDay:function(b){var a=new Element("td");if(this.date.getFullYear()==b.getFullYear()&&this.date.getMonth()==b.getMonth()&&this.date.getDate()==b.getDate()){a.addClassName("calendarCurrentDay")}if(b.getDay()===0||b.getDay()===6){a.addClassName("calendarWeekend")}else{a.addClassName("calendarDay")}a.innerHTML=b.getDate();a.observe("mousedown",this.setDate.bind(this,b));return a},setDate:function(a){this.date=a;this.parent.value=Utilities.getFormattedDate(a);this.hide();setTimeout(Utilities.fireCustomEvent.bind(Utilities,this.parent,"change"),1)},daysInMonth:function(c,b){var a=this.date.getMonth();var d=this.date.getFullYear();if(arguments.length==2){a=c;d=b}return Utilities.getDaysInMonth(a,d)}});var CalendarManager={showCalendar:function(b,a){if(!b.calendar){b.calendar=new Calendar(b,a)}}};var ErrorHandler={errorTypes:$A([{name:"string",pattern:/^(.+)$/gi,message:"Please fill in the field"},{name:"number",pattern:/^-?[0-9]*\.?[0-9]+$/gi,message:"Please enter a valid number."},{name:"integer",pattern:/^-?[0-9]+$/gi,message:"Please enter a valid integer."},{name:"alphanumeric",pattern:/^[0-9A-Z_\-]+$/ig,message:"Please enter a valid alphanumeric string."},{name:"email",pattern:/^[A-Z0-9._%+\-]+@[A-Z0-9.\-]+\.[A-Z]{2,4}$/i,message:"Please enter a valid email address."},{name:"positiveNumber",pattern:/^[0-9]*\.?[0-9]+$/i,message:"Please enter a positive number."},{name:"date",pattern:/^(0[1-9]|[12][0-9]|3[012])\/(0[1-9]|1[012])\/\d{4}$/i,message:"Please enter a valid date in DD/MM/YYYY format"}]),initialize:function(){this.addErrorHandlers()},addErrorHandlers:function(){this.errorTypes.each(function(a){$$("."+a.name).each(function(b){if(b.hasClassName("date")){b.observe("focus",CalendarManager.showCalendar.bind(window,b,a.pattern))}b.observe("blur",this.dispatchError.bind(this,b,a.pattern,a.message));this.attachFormListener(b)},this)},this)},dispatchError:function(a,d,c,b){if(!(!a.value.strip()&&a.hasClassName("optional"))&&!a.value.match(d)){this.displayError(a,c);return true}else{this.removeErrorMessage(a);return false}},displayError:function(c,d){var b=0.1;if(!c.errorConfig){var a=new Element("div",{style:"background-color:#FF6347;padding:3px;color:#000000;font-size:12px;position:absolute;z-index:9999;text-align:left;left:"+c.cumulativeOffset()[0]+"px;top:"+(c.cumulativeOffset()[1]+c.getHeight())+"px;"}).insert(d);a.setOpacity(b);if(typeof document.body.style.maxHeight=="undefined"){a.setStyle({width:"200px"})}c.errorConfig={messageNode:a,bgcolor:c.getStyle("backgroundColor"),animation:false};c.setStyle({backgroundColor:"#FF6347"});if(c.errorConfig.bgcolor=="transparent"||c.errorConfig.bgcolor=="rgb(255, 255, 255)"){c.errorConfig.bgcolor="#FFFFFF"}if(c.nextSibling){c.parentNode.insertBefore(a,c.nextSibling)}else{c.parentNode.appendChild(a)}this.animateErrorMessage(c,b,0.02);c.observe("mouseover",function(e){if(e.errorConfig){this.animateErrorMessage(e,b,0.02)}}.bind(this,c))}},removeErrorMessage:function(a){if(a.errorConfig){a.setStyle({backgroundColor:a.errorConfig.bgcolor});a.parentNode.removeChild(a.errorConfig.messageNode);a.errorConfig=null}},animateErrorMessage:function(d,c,a,b){if(d.errorConfig){d.errorConfig.messageNode.setStyle({top:(d.cumulativeOffset()[1]+d.getHeight())+"px",left:(d.cumulativeOffset()[0])+"px"});if(c<0){d.errorConfig.animation=false}else{if(c>1){setTimeout(this.animateErrorMessage.bind(this,d,c-a,-0.01,true),1000)}else{if(!d.errorConfig.animation||b){d.errorConfig.animation=true;d.errorConfig.messageNode.setOpacity(c);setTimeout(this.animateErrorMessage.bind(this,d,c+a,a,true),10)}}}}},errorsPresent:function(){var a=false;this.errorTypes.each(function(b){$$("."+b.name).each(function(c){if(this.dispatchError(c,b.pattern,b.message)){a=true}},this)},this);return a},attachFormListener:function(a){if(!a.parentNode){return false}else{if(a.parentNode.nodeName.toLowerCase()=="form"){$(a.parentNode.id).observe("submit",function(b){if(this.errorsPresent()){b.preventDefault()}}.bind(this))}else{this.attachFormListener(a.parentNode)}}}};Event.observe(window,"load",ErrorHandler.initialize.bind(ErrorHandler));var UI={createDropDown:function(c,d,b){var a=new Element("select",{id:d,name:d});c.each(function(f){var e={value:f.code};if(b.toLowerCase()==f.code.toLowerCase()){e.selected="selected"}a.insert(new Element("option",e).update(f.code+" - "+f.name))});return a},addRolloverImages:function(){$$("img.TwoStateRollover").each(this.add2StateRollover.bind(this));$$("img.ThreeStateRollover").each(this.add3StateRollover.bind(this))},add2StateRollover:function(a){a.originalSource=a.src.match(/_((selected)|(up))\./gi);new Element("img",{src:a.src.replace(a.originalSource,"_over.")});a.observe("mouseover",function(b){b.target.src=b.target.src.replace(a.originalSource,"_over.")});a.observe("mouseout",function(b){b.target.src=b.target.src.replace(/_((over)|(down))\./gi,a.originalSource)});return a},add3StateRollover:function(a){this.add2StateRollover(a);new Element("img",{src:a.src.replace(a.originalSource,"_down.")});a.observe("mousedown",function(b){b.target.src=b.target.src.replace("_over.","_down.")});a.observe("mouseup",function(b){b.target.src=b.target.src.replace("_down.","_over.")});return a}};Event.observe(window,"load",UI.addRolloverImages.bind(UI));
// Combined /fileadmin/jslib/fxconsulting/tools/CurrencyBase.js
var Currency=Class.create({amount:0,initialize:function(c,b,a,d){this.isoCode=c;this.name=b||c;this.lendRate=parseFloat(a||1);this.borrowRate=parseFloat(d||1)}});var CurrencyPair=Class.create({base:null,quote:null,sellRate:null,buyRate:null,direction:null,inverted:false,composition:[],initialize:function(d,a,b){this.base=d;this.quote=a;b=b||{};for(var c in b){this[c]=b[c]}},getSellRate:function(){return this.getCurrencyRate("sellRate")},getBuyRate:function(){return this.getCurrencyRate("buyRate")},getCurrencyRate:function(a){if(!this.composition.length){return this[a]}else{return this.composition.invoke("getCurrencyRate",a).inject(1,function(b,c){return b*c})}},getLendRate:function(){return this.getInterestRate("lendRate")},getBorrowRate:function(){return this.getInterestRate("borrowRate")},getInterestRate:function(c,b){if(this.direction!==null){if(!this.composition.length){var a;if(this.direction=="LONG"&&c=="lendRate"){a={currency:this.base,rate:this.base.lendRate}}else{if(this.direction=="SHORT"&&c=="lendRate"){a={currency:this.quote,rate:this.quote.lendRate}}else{if(this.direction=="LONG"&&c=="borrowRate"){a={currency:this.quote,rate:this.quote.borrowRate}}else{if(this.direction=="SHORT"&&c=="borrowRate"){a={currency:this.base,rate:this.base.borrowRate}}}}}if(b=="composition"){return a}else{return[a]}}else{return this.composition.invoke("getInterestRate",c,"composition")}}else{throw"Pair Direction is null - cannot retrive interest rates"}},setDirection:function(a){var b=a.toUpperCase();if(b!="LONG"&&b!="SHORT"){throw"Invalid Direction"}this.direction=b;this.composition.invoke("setDirection",b);return this},setAmount:function(d,f,e){var c=d.toUpperCase();var a=Math.abs(f);if(!this.direction){throw"cannot set amount without setting direction"}if(c==this.base.isoCode&&this.direction=="LONG"){this.base.amount=a;this.quote.amount=a*this.getBuyRate()}else{if(c==this.base.isoCode&&this.direction=="SHORT"){this.base.amount=a;this.quote.amount=a*this.getSellRate()}else{if(c==this.quote.isoCode&&this.direction=="SHORT"){this.quote.amount=a;this.base.amount=a/this.getSellRate()}else{if(c==this.quote.isoCode&&this.direction=="LONG"){this.quote.amount=a;this.base.amount=a/this.getBuyRate()}else{throw"Invalid currency code or amount"}}}}var b={currency:this.base.isoCode,amount:this.base.amount};this.composition.each(function(g){b=g.setAmount(b.currency,b.amount,"composition")},this);if(e=="composition"){return{currency:this.quote.isoCode,amount:this.quote.amount}}else{return this}},convert:function(a,b){this.setAmount(a,b);if(a==this.base.isoCode){return this.quote.amount}else{return this.base.amount}},getUnits:function(){return Math.floor(this.base.amount)},getSpread:function(){return Math.abs(this.getBuyRate()-this.getSellRate())},getFXTradePairs:function(b){if(!this.composition.length){var a=Object.clone(this);if(this.inverted){a.reverse()}if(b=="composition"){return a}else{return[a]}}else{return this.composition.invoke("getFXTradePairs","composition")}},reverse:function(){if(this.direction&&this.direction=="LONG"){this.direction="SHORT"}else{if(this.direction&&this.direction=="SHORT"){this.direction="LONG"}}this.inverted=this.inverted?null:true;var b=this.base;this.base=this.quote;this.quote=b;if(!this.composition.length){var a=this.buyRate;this.buyRate=1/this.sellRate;this.sellRate=1/a}else{this.composition.reverse().invoke("reverse")}return this},toString:function(){var a=this.base.isoCode+"/"+this.quote.isoCode+" at "+this.getSellRate()+"/"+this.getBuyRate();if(this.direction){a+=" "+this.direction}if(this.base.amount){a+="   "+this.base.amount+"/"+this.quote.amount}return a},getName:function(){return this.base.isoCode+"/"+this.quote.isoCode}});var PairFactory=Class.create({currencies:null,initialize:function(a){if(typeof(a)=="function"){this.getNewData(a)}else{this.rawData=a;this.loadData()}},getNewData:function(b,a){this.dataHandler=a;new Ajax.Request(b,{method:"GET",onComplete:this.receiveData.bind(this),onFailure:function(){throw"Server Error"}})},receiveData:function(a){this.rawData=a.responseText.evalJSON();return this.dataHandler(this)},loadData:function(){var b;this.currencies=new Hash();if(!this.rawData.currencies){var a=[];for(b=0;b<this.rawData.pairs.length;b++){a.push(this.rawData.pairs[b].split("/")[0]);a.push(this.rawData.pairs[b].split("/")[1])}this.rawData.currencies=a.uniq().map(function(d){return{isoCode:d}})}if(!this.rawData.selectPairs){this.rawData.selectPairs=this.rawData.pairs}for(b=0;b<this.rawData.currencies.length;b++){var c=this.rawData.currencies[b];this.currencies.set(c.isoCode,new Currency(c.isoCode,c.name,c.lendRate,c.borrowRate))}},createPair:function(){var f,b;if(arguments.length==1){f=arguments[0].split("/")[0].toUpperCase();b=arguments[0].split("/")[1].toUpperCase()}else{if(arguments.length==2){f=arguments[0];b=arguments[1]}else{throw"Invalid currency pair specified"}}var g=f+"/"+b;var a=b+"/"+f;for(var d=0;d<this.rawData.selectPairs.length;d++){var c,h,e;if(f==b){return new CurrencyPair(Object.clone(this.currencies.get(f)),Object.clone(this.currencies.get(b)),{buyRate:1,sellRate:1})}else{if(g==this.rawData.selectPairs[d]){c=$A(this.rawData.pairs).indexOf(g);h=this.rawData.bidRates[c];e=this.rawData.askRates[c];return new CurrencyPair(Object.clone(this.currencies.get(f)),Object.clone(this.currencies.get(b)),{buyRate:e,sellRate:h})}else{if(a==this.rawData.selectPairs[d]){c=$A(this.rawData.pairs).indexOf(a);h=this.rawData.bidRates[c];e=this.rawData.askRates[c];return new CurrencyPair(Object.clone(this.currencies.get(f)),Object.clone(this.currencies.get(b)),{buyRate:(1/h),sellRate:(1/e),inverted:true})}}}}return new CurrencyPair(Object.clone(this.currencies.get(f)),Object.clone(this.currencies.get(b)),{buyRate:0,sellRate:0,composition:this.generateComposition(f,b)})},generateComposition:function(b,a){var c=function(e,d){if($A(this.rawData.selectPairs).indexOf(d+"/"+e)!=-1||$A(this.rawData.selectPairs).indexOf(e+"/"+d)!=-1){return true}else{return false}}.bind(this);if(c(b,"USD")&&c(a,"USD")){return[this.createPair(b+"/USD"),this.createPair("USD/"+a)]}else{if(c(b,"EUR")&&c(a,"EUR")){return[this.createPair(b+"/EUR"),this.createPair("EUR/"+a)]}else{if(c(b,"EUR")&&c(a,"USD")){return[this.createPair(b+"/EUR"),this.createPair("EUR/USD"),this.createPair("USD/"+a)]}else{if(c(b,"USD")&&c(a,"EUR")){return[this.createPair(b+"/USD"),this.createPair("USD/EUR"),this.createPair("EUR/"+a)]}else{throw"invalid composition!"}}}}},getCurrencyCodes:function(){var a=[];this.currencies.each(function(b){a.push({code:b.value.isoCode,name:b.value.name})},this);return a}});
// Combined /fileadmin/jslib/fxconsulting/tools/HedgeCostCalculator.js
var currencyData=new PairFactory(rawCurrencyData);var Field=Class.create({value:null,listeners:[],initialize:function(b,a){this.value=b;this.listeners=[];this.options=a||{}},setValue:function(a){this.value=a;this.listeners.invoke("calculateValue")},getDisplayValue:function(){if(typeof(this.value)=="string"){return this.value}if(!isFinite(this.value)){return""}var e=this.value;var b=2;if(!isNaN(this.options.round)){b=this.options.round}if(this.options.abs){e=Math.abs(e)}if(this.options.percent){e=e*100}e=Math.round(e*Math.pow(10,b))/Math.pow(10,b);var c=e.toString().indexOf(".");if(c!=-1){var a=b-e.toString().substr(c+1).length;e=e.toString();for(var d=0;d<a;d++){e=e.concat("0")}}else{e=e.toString()+".00"}if(this.value<0){e=("("+e.toString().replace(/-/gi,"").replace(/\B(?=(...)*\.)/gi,",")+")").fontcolor("red");if(!b){e=e.replace(/(.*)(\.[0-9]+)(\).*)?/gi,function(){return arguments[1]+arguments[3]})}}else{e=e.toString().replace(/\B(?=(...)*\.)/gi,",");if(!b){e=e.substring(0,e.indexOf("."))}}if(this.options.interest||this.options.percent){e+="%"}return e},listen:function(a){this.listeners.push(a)},addListeners:function(){}});var CalculationField=Class.create(Field,{formula:null,options:null,dependers:null,hc:null,initialize:function($super,c,b,a){$super(0,a);this.formula=c;this.dependers=$A(this.formula.replace(/[+-\/()*]/gi," ").replace(/[0-9]+.?[0-9]+/gi," ").replace(/[\s]+/gi," ").strip().split(" "));this.hc=b},calculateValue:function(){var expression=this.formula;this.dependers.each(function(field){expression=expression.replace(eval("/"+field+"/gi"),function(){return"("+this.hc.fields.get(field).value+")"}.bind(this))},this);if(this.options.abs){this.setValue(Math.abs(eval(expression)))}else{this.setValue(eval(expression))}},addListeners:function(){this.calculateValue();this.hc.fields.each(function(a){if(this.dependers.indexOf(a.key)!=-1){a.value.listen(this)}},this)}});var HedgeCalculator=Class.create({interestRisks:$H({"0":0.001,"31":0.0015,"61":0.0025,"91":0.0035,"121":0.005,"151":0.0075,"181":0.0105,"271":0.014,"366":0.0175}),fields:null,currencyPair:null,hedgePair:null,reportingCurrency:null,foreignCurrency:null,dataSource:null,initialize:function(e,g,a,c,f,b){this.dataSource=e;this.reportingCurrency=g;this.foreignCurrency=a;this.balance=c;this.days=f;this.currencyPair=this.dataSource.createPair(g,a);this.currencyPair.setDirection("LONG");this.currencyPair.setAmount(a,c);this.hedgePair=this.dataSource.createPair(a,g);this.hedgePair.setDirection("SHORT");this.hedgePair.setAmount(a,c);this.days=f;var d=b||{};this.volatility=d.volatility||0.0675;this.quotedForwardRate=d.forwardRate||1;this.balance=c;this.initFields();this.refreshGlobalFields();this.fields.values().invoke("addListeners");this.recalculate();return this},initFields:function(){this.fields=$H({todaysRate:new CalculationField("foreignAmount/reportingAmount",this,{abs:true,round:5}),totalCarryCost:new CalculationField("interestCost+homeHedgeCost",this),totalCost:new CalculationField("interestCost+homeHedgeCost+reportingAmount",this),estimatedCarryForwardRate:new CalculationField("balance/totalCost",this,{round:5}),estimatedForwardCosts:new CalculationField("interestCost+homeHedgeCost+estimatedForwardProfit+interestRiskCost",this),estimatedForwardTotalCost:new CalculationField("reportingAmount+(interestCost+homeHedgeCost+estimatedForwardProfit+interestRiskCost)",this),estimatedForwardRate:new CalculationField("balance/(totalCost+estimatedForwardProfit+interestRiskCost)",this,{round:5}),estimatedForwardRelativeCost:new CalculationField("estimatedForwardTotalCost-totalCost",this),estimatedForwardInterestChange:new CalculationField("(estimatedForwardRelativeCost*365)/(days*reportingAmount)",this,{abs:true,percent:true}),quotedForwardRateTotalCost:new CalculationField("balance/quotedForwardRate",this),quotedForwardRateProfit:new CalculationField("quotedForwardRateTotalCost-(interestCost+homeHedgeCost+reportingAmount+interestRiskCost)",this),quotedForwardRateRelativeCost:new CalculationField("quotedForwardRateTotalCost-totalCost",this),quotedForwardRateCosts:new CalculationField("interestCost+homeHedgeCost+quotedForwardRateProfit+interestRiskCost",this),quotedForwardInterestChange:new CalculationField("(quotedForwardRateRelativeCost*365)/(days*reportingAmount)",this,{abs:true,percent:true}),amountAtRisk:new CalculationField("reportingAmount*volatility",this,{abs:true}),potentialLoss:new CalculationField("(0-1)*(amountAtRisk+totalCarryCost)",this)})},updateInputs:function(a,b){this.balance=a.balance||this.balance;this.days=a.days||this.days;this.volatility=a.volatility||this.volatility;this.quotedForwardRate=a.quotedForwardRate||this.quotedForwardRate;this.reportingCurrency=a.reportingCurrency||this.reportingCurrency;this.foreignCurrency=a.foreignCurrency||this.foreignCurrency;this.recalculate(b)},recalculate:function(a){if(this.currencyPair.base.isoCode!=this.reportingCurrency||this.currencyPair.quote.isoCode!=this.foreignCurrency||a){this.currencyPair=this.dataSource.createPair(this.reportingCurrency,this.foreignCurrency);this.hedgePair=this.dataSource.createPair(this.foreignCurrency,this.reportingCurrency)}if(this.balance>0){this.currencyPair.setDirection("SHORT");this.hedgePair.setDirection("SHORT")}else{this.currencyPair.setDirection("LONG");this.hedgePair.setDirection("LONG")}this.hedgePair.setAmount(this.foreignCurrency,Math.abs(parseInt(this.balance,10)));this.currencyPair.setAmount(this.foreignCurrency,Math.abs(parseInt(this.balance,10)));this.refreshGlobalFields()},setGlobalField:function(c,a,b){if(this.fields.get(c)){this.fields.get(c).setValue(a)}else{this.fields.set(c,new Field(a,b))}},refreshGlobalFields:function(){this.setGlobalField("foreignAmount",this.hedgePair.base.amount*-1*this.balance/Math.abs(this.balance));this.setGlobalField("reportingAmount",this.hedgePair.quote.amount*this.balance/Math.abs(this.balance));this.setGlobalField("spread",this.currencyPair.getSpread(),{round:5});this.setGlobalField("foreignHedgeCost",Math.abs(this.currencyPair.getSpread()*this.currencyPair.base.amount));this.setGlobalField("homeHedgeCost",-1*Math.abs(this.currencyPair.getSpread()*this.currencyPair.base.amount/this.currencyPair.getSellRate()));this.setGlobalField("interestRiskRate",this.lookupInterestRisk(),{percent:true});this.setGlobalField("interestRiskCost",Math.abs(this.hedgePair.quote.amount*this.lookupInterestRisk()*this.days/365)*-1);this.setGlobalField("interestCost",this.calculateTotalInterest());this.setGlobalField("estimatedForwardProfit",-250);this.setGlobalField("sellRate",this.currencyPair.getSellRate(),{round:5});this.setGlobalField("balance",this.balance);this.setGlobalField("days",this.days,{round:0});this.setGlobalField("quotedForwardRate",this.quotedForwardRate,{round:5});this.setGlobalField("baseCurrency",this.currencyPair.base.isoCode);this.setGlobalField("quoteCurrency",this.currencyPair.quote.isoCode);this.setGlobalField("currencyPair",this.currencyPair.base.isoCode+"/"+this.currencyPair.quote.isoCode);this.setGlobalField("volatility",this.volatility,{percent:true,abs:true})},getInterestBreakdown:function(){var a=[];var b=function(c,h){var d=-1,g=c.borrowRate,f="Interest paid on sold";if(h=="lend"){d=1;g=c.lendRate;f="Interest received on purchased"}var i=this.dataSource.createPair(c.isoCode,this.currencyPair.base.isoCode);var e=[new Field(f),new Field(c.isoCode),new Field(g),new Field(c.amount*d),new Field(c.amount*d*g/100),new Field(i.getSellRate()),new Field(c.amount*d*g*i.getSellRate()/100),new Field((c.amount*d*g*i.getSellRate()*this.days)/(100*365))];return e}.bind(this);a=this.hedgePair.getLendRate().collect(function(c){return b(c.currency,"lend")});a=a.concat(this.hedgePair.getBorrowRate().map(function(c){return b(c.currency,"borrow")}));return a},calculateTotalInterest:function(){var a=this.hedgePair.getLendRate().map(function(c){return this.interestSummer(c.currency,"lend")},this);var b=this.hedgePair.getBorrowRate().map(function(c){return this.interestSummer(c.currency,"borrow")},this);return a.concat(b).inject(0,function(c,d){return c+d})},interestSummer:function(a,d){var b=-1,c=a.borrowRate;if(d=="lend"){b=1;c=a.lendRate}var e=this.dataSource.createPair(a.isoCode,this.currencyPair.base.isoCode);return(a.amount*b*c*e.getSellRate()/100)*((this.days)/365)},lookupInterestRisk:function(){var b=this.interestRisks.keys();for(var a=0;a<b.length;a++){if(this.days<parseInt(b[a],10)){return this.interestRisks.get(b[a-1])}}return this.interestRisks.get(b[b.length-1])},refreshData:function(a){this.dataSource.getNewData("/cgi-bin/tools/CurrencyBaseRates.fpl",function(b){this.dataSource=b;this.recalculate(true);a()}.bind(this))}});var HedgeCalculatorBaseUI={hc:null,updateRates:function(){$("updateButton").value="Refreshing Rates...";$("updateButton").disabled=true;this.hc.refreshData(this.finishUpdateRates.bind(this))},finishUpdateRates:function(){this.renderCalculator();$("updateButton").value="Refresh Rates";$("updateButton").disabled=false},renderCalculator:function(){},renderCalculationFields:function(){this.hc.fields.each(function(a){$$("."+a.key).invoke("update",a.value.getDisplayValue())},this)},renderFXTradesBreakdown:function(a){$(a).update();this.hc.hedgePair.getFXTradePairs().each(function(f){var b=f.direction=="LONG"?(new Field(f.getBuyRate(),{round:5}).getDisplayValue()):"&nbsp;";var c=f.direction=="SHORT"?(new Field(f.getSellRate(),{round:5}).getDisplayValue()):"&nbsp;";var e=f.direction=="LONG"?" (buy)":" (sell)";var d=new Element("tr").insert(new Element("td").insert(f.getName())).insert(new Element("td").insert(f.direction+e)).insert(new Element("td").insert(f.getUnits())).insert(new Element("td").insert(c)).insert(new Element("td").insert(b));$(a).insert(d)},this)},renderRateSummary:function(a){var b=function(g){var d=new Element("tr");var f="Direct Pair";if(g.composition.length>0){f="Synthetic Cross"}else{if(g.inverted){f="Inverted Rate"}}d.insert(new Element("td").insert(g.getName()+" ("+f+")"));var c=g.direction=="LONG"?(new Field(g.getBuyRate(),{round:5}).getDisplayValue()):"&nbsp;";var e=g.direction=="SHORT"?(new Field(g.getSellRate(),{round:5}).getDisplayValue()):"&nbsp;";d.insert(new Element("td").insert(e));d.insert(new Element("td").insert(c));return d};$(a).update("");$(a).insert(b(this.hc.currencyPair));$(a).insert(b(this.hc.currencyPair.reverse()));this.hc.currencyPair.reverse()},renderInterestBreakdown:function(a){$(a).update();this.hc.getInterestBreakdown().each(function(b,d){var c=new Element("tr");b.each(function(e){c.insert(new Element("td").insert(e.getDisplayValue()))},this);$(a).insert(c)},this);$(a).insert(new Element("tr").insert(new Element("td",{colspan:7}).insert("Total")).insert(new Element("td").addClassName("yellow").setStyle({borderLeft:"1px solid #5B818A"}).insert(this.hc.fields.get("interestCost").getDisplayValue())))},infoToggle:function(a,b){if(a.innerHTML.indexOf("Show")!=-1){a.innerHTML="Hide More Info";$(b).setStyle({display:"block"})}else{a.innerHTML="Show More Info";$(b).setStyle({display:"none"})}}};
// Combined /fileadmin/jslib/fxconsulting/tools/HedgeCalculatorUI.js
var HedgeCalculatorUI=Object.extend(HedgeCalculatorBaseUI,{initialize:function(g,c){var f=c.reportingCurrency||"USD";var d=c.foreignCurrency||"EUR";var b=c.balance||100000;var h=c.days||1;var e=new Date();e=new Date(e.getFullYear(),e.getMonth()-1,Utilities.getDaysInMonth(e.getMonth()-1,e.getFullYear()));var a=new Date(e.getFullYear(),e.getMonth()-1,Utilities.getDaysInMonth(e.getMonth()-1,e.getFullYear()));this.inputs={reportingCurrency:UI.createDropDown(g.getCurrencyCodes(),"reportingCurrency",f),foreignCurrency:UI.createDropDown(g.getCurrencyCodes(),"foreignCurrency",d),hedgeAmount:new Element("input",{value:50000,"class":"integer"})};this.balanceSheet={previousBalance:new Element("input",{value:500000,"class":"integer yellow"}).observe("change",this.previousBalanceInputsChange.bind(this)),previousDate:new Element("input",{value:Utilities.getFormattedDate(a),"class":"date optional yellow"}).observe("change",this.previousBalanceInputsChange.bind(this)),currentBalance:new Element("input",{value:450000,"class":"integer"}).observe("change",this.currentBalanceInputsChange.bind(this)),currentDate:new Element("input",{value:Utilities.getFormattedDate(e),"class":"date optional"}).observe("change",this.currentBalanceInputsChange.bind(this))};this.forexHedge={previousBalance:new Element("input",{value:-500000,"class":"integer yellow"}),previousDate:new Element("input",{value:Utilities.getFormattedDate(a),"class":"date optional yellow"}).observe("change",this.hedgeInputsChange.bind(this)),currentBalance:new Element("input",{value:-450000,"class":"integer"}),currentDate:new Element("input",{value:Utilities.getFormattedDate(e),"class":"date optional"}).observe("change",this.hedgeInputsChange.bind(this))};$H(this.inputs).values().invoke("observe","change",this.mainInputsChange.bind(this,true));$H(this.forexHedge).values().invoke("observe","change",this.hedgeInputsChange.bind(this));this.hc=new HedgeCalculator(g,f,d,b,h);this.interestCalc=new HedgeCalculator(g,f,d,-1*parseFloat(this.forexHedge.currentBalance.value),h);$("updateButton").observe("mousedown",this.updateRates.bind(this));this.renderInputs();ErrorHandler.addErrorHandlers();this.mainInputsChange()},mainInputsChange:function(d){var b={};if(!ErrorHandler.errorsPresent()){var c=d||false;this.forexHedge.currentBalance.value=parseFloat(this.inputs.hedgeAmount.value)+parseFloat(this.forexHedge.previousBalance.value);b.reportingCurrency=this.inputs.reportingCurrency.value;b.foreignCurrency=this.inputs.foreignCurrency.value;b.balance=-1*parseFloat(this.inputs.hedgeAmount.value);this.hc.updateInputs(b,c);var a=b;a.balance=-1*parseFloat(this.forexHedge.currentBalance.value);this.interestCalc.updateInputs(a);this.renderCalculator();this.calculateDisplayFields()}},hedgeInputsChange:function(){if(!ErrorHandler.errorsPresent()){this.inputs.hedgeAmount.value=parseFloat(this.forexHedge.currentBalance.value)-parseFloat(this.forexHedge.previousBalance.value);this.mainInputsChange()}},previousBalanceInputsChange:function(){if(!ErrorHandler.errorsPresent()){this.forexHedge.previousBalance.value=-1*this.balanceSheet.previousBalance.value;this.forexHedge.previousDate.value=this.balanceSheet.previousDate.value;this.forexHedge.currentDate.value=this.balanceSheet.currentDate.value;this.hedgeInputsChange()}},currentBalanceInputsChange:function(){if(!ErrorHandler.errorsPresent()){this.forexHedge.currentBalance.value=-1*this.balanceSheet.currentBalance.value;this.forexHedge.previousDate.value=this.balanceSheet.previousDate.value;this.forexHedge.currentDate.value=this.balanceSheet.currentDate.value;this.hedgeInputsChange()}},calculateDisplayFields:function(){var c=this.balanceSheet.previousDate.value.split("/");var d=this.balanceSheet.currentDate.value.split("/");var j=new Date(c[2],parseFloat(c[1])-1,parseFloat(c[0]));var l=new Date(d[2],parseFloat(d[1])-1,parseFloat(d[0]));var o=this.forexHedge.previousDate.value.split("/");var p=this.forexHedge.currentDate.value.split("/");var i=new Date(o[2],parseFloat(o[1])-1,parseFloat(o[0]));var f=new Date(p[2],parseFloat(p[1])-1,parseFloat(p[0]));var n=Math.floor((l.getTime()-j.getTime())/(1000*60*60*24));if(n<0||i.getTime()>=f.getTime()){alert("Please Enter a valid reporting period")}$("daysDiff").update("Over "+n+" Days");$("amountDiff").update(new Field(this.balanceSheet.currentBalance.value-this.balanceSheet.previousBalance.value,{round:0}).getDisplayValue());$("balance_currentDate").update(this.balanceSheet.currentDate.value);$("balance_currentBalance").update(new Field(parseFloat(this.balanceSheet.currentBalance.value),{round:0}).getDisplayValue());$("forex_currentDate").update(this.forexHedge.currentDate.value);$("forex_currentBalance").update(new Field(parseFloat(this.forexHedge.currentBalance.value),{round:0}).getDisplayValue());var e=(0-parseFloat(this.forexHedge.previousBalance.value))/parseFloat(this.balanceSheet.previousBalance.value);var m=(0-parseFloat(this.forexHedge.currentBalance.value))/parseFloat(this.balanceSheet.currentBalance.value);var k=parseFloat(this.balanceSheet.previousBalance.value)+parseFloat(this.forexHedge.previousBalance.value);var g=parseFloat(this.balanceSheet.currentBalance.value)+parseFloat(this.forexHedge.currentBalance.value);$("previousHedgingRatio").update(new Field(e,{percent:true}).getDisplayValue());$("currentHedgingRatio").update(new Field(m,{percent:true}).getDisplayValue());$("previousEndingExposure").update(new Field(k,{round:0}).getDisplayValue());$("currentEndingExposure").update(new Field(g,{round:0}).getDisplayValue());var a=new Field(parseFloat(this.forexHedge.currentBalance.value)+(parseFloat(this.balanceSheet.currentBalance.value)),{round:0});var b="";if(m<0){b="<strong>Hedge in wrong direction</strong>".fontcolor("red")}else{if(Math.abs(g)>Math.abs(parseFloat(this.balanceSheet.currentBalance.value))){b="Over Hedged"}else{b=Math.abs(m)==1?"":(Math.abs(m)>1?"Over-Hedged":"Under-Hedged")}}$("unhedgedAmountLabel").update(b);$("unhedgedAmount").update(a.getDisplayValue());$("unhedgedAmount2").update(a.getDisplayValue());var h={reportingCurrency:this.inputs.reportingCurrency.value,foreignCurrency:this.inputs.foreignCurrency.value,balance:a.value,days:n};if(!a.value){$("exposureLink").update("");$("exposureLink").href='javascript:alert("Your foreign exposure risk is fully hedged.");';$("exposureLink").target="_main"}else{$("exposureLink").update("Find out what's at risk if you don't hedge this amount");$("exposureLink").href="/tools/currency-risk-assessment-tool.shtml?"+Object.toQueryString(h);$("exposureLink").target="_blank"}h.days=1;h.balance=-1*parseFloat(this.forexHedge.currentBalance.value);$("hedgeCostLink").href="/tools/hedging-cost-comparison-tool.shtml?"+Object.toQueryString(h)+"#interestBreakdownSection"},renderInputs:function(){$H(this.inputs).each(function(a){$(a.key+"Display").update(a.value)});$H(this.balanceSheet).each(function(a){$("balancesheet_"+a.key+"Display").update(a.value)});$H(this.forexHedge).each(function(a){$("forexhedge_"+a.key+"Display").update(a.value)})},renderCalculator:function(){this.renderCalculationFields();this.renderFXTradesBreakdown("fxtrades");this.renderRateSummary("ratesummary");$("interestCost").update(this.interestCalc.fields.get("interestCost").getDisplayValue())}});Event.observe(window,"load",HedgeCalculatorUI.initialize.bind(HedgeCalculatorUI,currencyData,Utilities.getURLParameters()));
