Altius Community

Altius Consulting Community
Welcome to Altius Community Sign in | Join | Help
in Search

Jake Smillie

August 2009 - Posts

  • Importance of Unrealised FX Gain and Loss

    Many businesses want to see measures across multiple currencies, for example: sales for all countries or customer balances for all account currency types. Typically when dealing with multiple currencies a ‘base’ currency to report on is chosen to make life easier (you can’t simply add Euro sale values to Sterling sale values and get the correct total sales answer). This means data needs to be converted to base currency so we can accurately see how we are doing.

    Currency exchange rates are by no means static, so movement in exchange rates can influence your measures.

    For example, if you wanted to see total balances across months you might see something like this:

    image

    Looking at this we can see that May 2009 was a great month!…. Or was it?

    Well lets look at the raw data that makes this chart.

    image

    You can see in May 2009 we actually lost €100,000. The above report paints a very different picture to what actually happened! The reason why the chart shows such a large jump is that Sterling became a lot stronger against the Euro giving the illusion of a good month, when really it wasn’t.

    This means we have to track Unrealised FX Gain and Loss to understand the numbers better.

    Depending on whether you are using ‘End of Day’ or ‘Start of Day’ exchange rates this is done differently.

    End of Day Rate

    To calculate unrealised FX using end of day rates use this formula:

    (Today’s Measure @ Today’s Exchange Rate) - (Today’s Measure @ Previous Exchange Rate)

     

    Start of Day Rate

    To calculate unrealised FX using start of day rates use this formula (rates should be in direct quotation e.g. local ccy value * rate = base ccy value)

    (Today’s Measure - (measure delta)) * (exchange rate delta)

     

    Once unrealised FX is calculated we can show a slightly different report:

    image

    We will use the Balance £ – Unrealised FX Accumulation to display in our report, which gives us:

     

    image

    This shows something quite different from the report above, but it shows a more accurate visualisation of the numbers. It shows that May 2009 was actually a bad month.

     

    Now that you understand the importance of tracking Unrealised FX you need to decide at what granularity to track it. I would recommend tracking it at the lowest level possible so that you can see it at any aggregation level. This makes your design a little more tricky but gets you the most flexibility.

  • Multi Level Hierarchy Dimension Design Tip

    When building a dimensional modelling solution, somewhere along the line you will almost certainly have at least one multi level hierarchy within one or more dimensions. A good example of this is a Product hierarchy, which might go:

    Department->Sub Department->Type->Product

    Typically for each level member you will have an ID (be it numeric or alpha numeric) and a Description. In the Adventure Works database there is a product hierarchy that goes: Department->Sub Department->Model->Product, so this seems like a nice example to share this tip.

    Lets have a look at how you might store this data in your conformed dimension:

    image

    So here, Product 709 rolls into Mountain Bike Socks, Socks and Clothing.

    Building this in a cube is simple, but sometimes not all reports are suited to cube and are better delivered using SQL.

    Lets consider a requirement whereby the user wants a dump of all sales between dates and wants to filter by any level in the Product hierarchy (e.g. any Clothing, or just Socks).

    There are many ways to provide this solution but there is 1 way I like.

    Assuming that you would do this in a stored procedure, you might pass in each level ID for Category, Subcategory, Model and Product as a parameter and then determine what to filter on based on their selection (e.g. If they selection ‘All’ for Subcategory do not filter on this and so on. Doing this is complicated and gives me a headache, you might use 4 different almost identical SQL statements and have IF (SubcategoryIDSelection = ‘All’) then run this query, otherwise run another query. Confused? I am. You may use dynamic SQL to build up the query (which is a nightmare to maintain / understand what is going on).

    The way I like to do achieve this is to store a unique hierarchy key as a string for each product. So for Product 709 we would have: ‘0003_0023_000013_000709’ as the ProductHierarchyKey (we pad the keys to make them sortable). This makes filtering on any level of the hierarchy very easy. For example if the user requests to see all sales for Clothing_Socks we pass into the procedure ‘0003_0023’ as the value we can then do a select and filter like this:

       1: SELECT
       2:     p.*
       3: FROM dbo.D_Product p
       4: WHERE
       5:     p.ProductHierarchyCode like '0003_0023%'

    Which will bring back products 709 and 710. As you can see, it doesn’t matter what level you pass into the procedure, it will always be the same query (no need to build any funky logic or use dynamic SQL). It also makes it easier to filter on multiple selections, e.g. the user might want to see sales for ‘Socks’ and ‘Road Frames’ together. So we would pass in ‘0003_0023,0002_0014’ then split the parameter by ‘,’ into a table variable (I will let you decide how to do this as there are many techniques) and then execute SQL similar to:

       1: SELECT
       2:     p.*
       3: FROM dbo.D_Product p
       4: INNER JOIN @SelectedProducts sel
       5: ON
       6:     p.ProductHierarchyCode like sel.Value + '%'

    This approach, for me, is far simpler and easier to understand.

    Hope it helps.