Personal tools

Programming performance/JCAB Cpp

From HaskellWiki

Jump to: navigation, search
  • Language: C++
  • Skill: Advanced. I've been using C++ with all its features for many years.
  • Time: Approx 20 minutes.
  • Notes: I did this after doing the Haskell version, so that might have affected the time. I used Visual Studio 2003 for development. I needed two iterations (same as with Haskell, but different bugs!). I get 13754.97774 just like I did with Haskell.

Code

#include <stdio.h>
#include <ctype.h>
#include <list>


int main()
{
    std::list<double> closingCosts;
    FILE* f = fopen("C:\\JCAB\\ProgrammingPerformance\\gspc.txt", "rt");
    if (f) {
        while (!feof(f)) {
            char buf[4096];
            fgets(buf, sizeof(buf), f);
            buf[sizeof(buf)-1] = 0;

            if (buf[0] != '#') {
                char* p = buf;
                while (isspace(*p)) ++p;
                while (*p && !isspace(*p)) ++p;
                while (isspace(*p)) ++p;
                while (*p && !isspace(*p)) ++p;
                while (isspace(*p)) ++p;
                while (*p && !isspace(*p)) ++p;
                while (isspace(*p)) ++p;
                while (*p && !isspace(*p)) ++p;
                while (isspace(*p)) ++p;
                while (*p && !isspace(*p)) ++p;
                while (isspace(*p)) ++p;
                while (*p && !isspace(*p)) ++p;
                while (isspace(*p)) ++p;

                closingCosts.push_front(atof(p));
            }
        }
        fclose(f);
    }

    double cash = 10000.0;
    std::list<std::pair<double, double> > shares;

    std::list<double>::const_iterator it = closingCosts.begin();
    double lastClosing = *it;
    ++it;

    std::list<double>::const_iterator const closingCostsEnd = closingCosts.end();
    for (; it != closingCostsEnd; ++it) {
        double const currentClosing = *it;

        for (std::list<std::pair<double, double> >::iterator sIt = shares.begin(); sIt != shares.end();) {
            if (currentClosing - sIt->first >= 0.06 * sIt->first) {
                // Sell them.
                cash += sIt->second * currentClosing;
                sIt = shares.erase(sIt);
            } else {
                ++sIt;
            }
        }

        if (lastClosing - currentClosing > 0.03 * lastClosing) {
            // Buy some.
            shares.push_back(std::make_pair(currentClosing, cash * 0.10 / currentClosing));
            cash *= 0.90;
        }

        lastClosing = currentClosing;
    }

    // Sell all that's left.
    for (std::list<std::pair<double, double> >::iterator sIt = shares.begin(); sIt != shares.end(); ++sIt) {
        cash += sIt->second * lastClosing;
    }

    printf("%f\n", cash);

    return 0;
}