ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 엑셀함수 RATE()
    개발 2010. 10. 5. 00:13
    주식한번 만져본 적이 없는 나인데, 요즘은 주식과 보험에 관련된 프로젝트를 진행하고 있다.
    작업이 크게 어려운 것은 없지만, 프로젝트 완료일이 겹치는 것이 3개 정도가 되니 이것 때문에 요즘 통 잠을 잘 수가 없다.
    적당한 스트레스는 삶에 활력을 주지만, 이건 뭐 나의 에너지를 쪽쪽 빨어먹는 거머리 같다.

    프로그램 기능 중 일부는 현재가치와 미래가치, 기간등을 설정하여 이자율을 구하는 부분이 나온다.
    엑셀중에 RATE()함수를 구현해야 하는 것인데, 엑셀은 이 기본 함수의 소스를 공개하지 않는다.
    그래서 이와 유사한 함수를 만들어야 한다.
    하지만, 내가 동원할 수 있는 모든 소스 및 구글님의 도움을 빌어도 공식을 찾을 수 없었다.
    경제나 보험쪽에는 문외한이라 접근 방법이 잘못 된 것일지도 모른다.
    하지만 미래가치 공식은 쉽게 찾을 수 있었다.

    미래가치 = - 현재가치 * (1 + 이자율)^기간
    FV = -PV * Math.pow(1 + 이자율,  nper)

    문제는 위의 공식에서 역으로 이자율을 구하는 것인데, 이자율이 지수함수와 함께 있어 해를 구하기가 쉽지 않았다.
    (사실 지금도 구할줄 모른다.)
    고민을 2~3일 하다가 문득 이런 생각이 들었다.

    고등학교 2학년때 일이다.
    수능고사가 200점 만점에서 400점 만점으로 바뀐 시기인데,
    나는 수학을 좋아하고 재미있어 했는데 점수는 40점 만점중 20점을 넘은 적이 없었다.
    수학을 좋아하는 나로서는 참으로 이해하기 힘든 일이었다.
    나보다 조금더 수학을 잘하는 친구에게 물었다.(이친구도 공부를 잘하는 편은 아니었지만, 나보다는 수학을 잘했다.)
    친구가 대답해주기를 문제는 모두 객관식이니 각각의 항목을 대입해서 맞는 것을 찾으라는 것이었다.
    물론 모든 문제에 각각(한문제당 5항씩 있다.)의 항목을 대입하면 시간상 반절도 풀기가 어렵다.
    하지만 정확도는 2배정도 높아진다.
    그리하여 수학점수가 조금 높아지긴 했지만 그래도 절반을 넘을 수는 없었다. 지금 생각해보면 창피한 일이다.
    그런데 유일하게 23점인가를 맞은 적이 있었다. 바로 수능시험이었다.
    처음으로 절반이상 맞은 점수가 수능시험때 나오다니 나는 정말 운이 좋았다.

    각설하고...
    그래서 위의 공식은 풀기가 어렵고 대신에 유사 근사값을 이자율로 넣어서 구해진 미래가치의 값과 실제 미래가치를 비교해서, 적으면 이자율을 높히고 높으면 이자율을 낮추는 방법으로 방법을 찾기로 했다.

    /**
         * 이자율을 반환한다.
         * @param fv 미래가치
         * @param nper 기간
         * @param pv 현재가치
         * @return
         */
        public double rate(double fv, double nper, double pv){
            double rate = 0.1d;
            double amt = 0;
            char a = '+';
            double b = 1;
           
            for(int i=0; i<100; i++){
                amt = - pv * Math.pow(1 + rate, nper);
                amt = Math.floor(amt*100)/100d;
                if(i == 0){
                    a = amt < fv ? '+' : '-';
                }
                if(amt < fv){
                    if(a == '-'){
                        b *= 10;
                        a = '+';
                    }
                    rate += 0.01 / b;   
                }
                else if(amt > fv){
                    if(a == '+'){
                        b *= 10;
                        a = '-';
                    }
                    rate -= 0.01 / b;
                }
                else{
                    break;
                }
            }
            return Math.round(rate*10000)/100d;
        }


    방식은 간단하다.
    임의의 이자율을 대입해서 나온 결과치 미래가치가 실제 미래가치와 비교해서 다르면 이자율을 재조정하는 것이다.
    최대 100번까지 루프를 돌리고 구해진 미래가치가 실제 미래가치보다 커지거나 작아지면 소수자리수를 한자리 낮춰서 정확도를 높힌다. 그리고 구해진 미래가치와 실제 미래가치가 소수 둘째짜리까지 동일하면 이때의 이자율을 구한다.
    그리고 구해진 이자율도 소수 세번째 짜리에서 반올림하여 둘째자리까지 표시한다.
    여러차례 테스트를 해봤는데, 정확도가 꽤 일치한다.
    반응형

    '개발' 카테고리의 다른 글

    getOutputStream() has already been called for this response 오류  (1) 2010.11.02
    플리커 GPS 정보  (0) 2010.10.24
    open api 로 우편번호 검색하기  (8) 2010.08.31
    이미지에 워터마크 넣기  (0) 2010.08.30
    아이폰 웹개발시 팁  (0) 2010.07.29

    댓글

Designed by Tistory.