How to design and organize a project?

Software design

  • QUESTION: Hi, I am building this program that gathers stock market data(open, high, low, close, volume). My question is: should I build this as a vector of objects (each object containing the previously mentioned members) or should I build just one object containing 5 vectors of those items. I have already build a working program using the first approach but before I am getting too far in this project and having to re-start from the beginning, I was wondering if one approach would be more efficient than the other. Thanks very much for you input with this. Warm regards, E. ANSWER: Hello Eric. I believe that your first approach is more correct. The 5 data elements all refer to a single stock for a single day and so it is logical to group them together instead of spreading them apart into 5 vectors. You will have an easier time dealing with the 5 elements as a unit with your first approach. If spread across 5 vectors, then the only thing connecting them together is their position in the vectors. I don't believe there is an issue with efficiency. ---------- FOLLOW-UP ---------- QUESTION: Thanks very much for this Zlatko. I was not sure because I am trying to build technical indicators for these series. Many indicators only use the close so I have to extract the data before I can use it. However, some indicators need all components and working with them as an object will certainly be easier. Do you have any suggestion for good software design book(s)(with c++ preferably). I have data structure books and also one on design but the book on design is probably oriented to software engineers. I am just doing this as a hobby (I gave myself a pretty tough assignment!!!). If it exists, I would like a beginner's book with real life examples (i.e. something like: this solution could do but a bit later we realize that this is not so good because of... So, instead we should have done this... and this allows us to then upgrade with this...) Thanks for your time. Eric. ANSWER: Hello Eric. If you are writing your own analysis functions, you can certainly have them each accept a vector of the struct, and use only the pertinent elements of the struct. If you are calling analysis functions written by someone else, then you will need to present the data in the format required by the function. I don't think that it will be a big performance penalty. Most likely, the analysis itself will take the majority of the time. In any case, how to organize the data will depend on the focus of the program and it's difficult for me to say with conviction at this point. As for good software design books, I can recommend Head First Design Patterns and Head First Object Oriented Analysis and Design. These books are Java based, but really for this subject, the language is not important. You really want to learn concepts about organizing your program. A class in Java looks much like a class in C++. Those books come to mind because they match your description "(i.e. something like: this solution could do but a bit later we realize that this is not so good because of... So, instead we should have done this... and this allows us to then upgrade with this...)" You can see previews on google books. Don't be put off by the light style. Unfortunately, the C++ specific books that I know of are really old. I've read "Clouds to Code" by Jessie Liberty and "Designing Object Oriented Applications using the Booch Method" by Robert C. Martin. They're good if you can find them. Good luck on your project. ---------- FOLLOW-UP ---------- QUESTION: Hi Zlatko, Thanks again for this - I ordered a few of your suggested books. I have two more questions; one on design one on operator overloading. First one on design: I have a class which contain a vector of StockData objects (open, high low, etc) which I call DataCollection. To calculate the indicators, I extract the data I need from the vectors inside the DataCollection class and do the calculations. So far, the indicators are only basic regular functions (i.e. not part of the class). Because of this, the functions do not have access to private members so I had to build setters and getters (apparently poor design). I have tried to built this using containment but this way each indicators would have to be a method of the class and adding new ones requires modifying the class. I am wondering if private inheritance would not be better as it seems that adding indicators would be easier in the future (just making them a derived class of DataCollection) or alternatively keeping it as it is as outside functions. Also, if I keep the indicators as outside functions (and keep the getters and setters) I am having the problem related to question 2: I want the result of the indicators to also return a DataCollection object - this way I can build compounded indicators (i.e. the MACD is a difference of two EMA(exponential moving averages). This is fine but I have to define a few operators (certainly +, - and /). Let's say for example I want the relative price of a stock. I would then have to take the close of the stock divided by the close of an index. This is easily done with a valarray object(which I had up until I decided to return a DataCollection object). The close is part of the StockData class and this is an object inside the vector of the DataCollection class. I was thinking of overloading the / operator so that DataCollection& dc1 / DataCollection& dc2 would be accepted as a valid operator. I have started on this but I am at a loss as to how to iterate through the whole vector and access each members of the DataStock object. Hopefully the way I ask this question made it somehow understandable. Again a big thanks for your help. Eric.

  • Answer:

    Hello Eric. I don't know if I am helping you or not with this response. First I think you should not try to over-engineer the problem. To much analysis leads to paralysis. I think you should expect that you will learn something from this hobby and in the end, no matter what, you will have ideas about what you should have done differently. That's all part of the process. I've tried to address your questions based on assumptions of what I think your program looks like so far. I've put in some sample code below, and some comments. Maybe it will be a starting point for more discussion, or maybe you'll just get fed up with me ;). using namespace std; /* Is DataCollection a time series of data for one symbol ? What other responsibilities does it have ? If DataCollection is just that, a collection of data associated with a symbol, there is probably nothing wrong with directly accessing the data. It is when objects become more complex, and maintain internal state, that you want to have public and private sections. There is no difference between an accessor function, and accessing the data directly unless you have some added processing or checking in the accessor. class DataCollection { public: class StockData { float open; float close; float high; float low; float volume; }; string symbol; vector data; }; /* I think there is nothing wrong with having stand alone functions operating on the data I don't think private inheritance will gain you anything. /* EMA function. Would this calculate EMA for each element in StockData ? Indicator functions should probably return pointers to dynamically allocated memory. Returning a DataCollection, instead of a pointer to DataCollection, would be inefficient because a copy of the result would be made on the return. if result is quite large, and the function is called often, you may notice a program slow down. If efficiency is not a big concern, then it is certainly easier to not deal with dynamic memory. DataCollection* EMA(const DataCollection& data, int timePeriod) { DataCollection* result = new DataCollection; result->symbol = data.symbol; // TODO do the calculation. Access the data directly, or use an STL iterator return result; } /* Overloading operators outside of any class can be done in the way shown below. I think overloading a built in operator would only make sense if the operator is being applied to each element in StockData. For calculations like relative price, it would not make sense to use an overloaded division operator. You should stick with a relativePrice function. An alternative is to go with separate vectors of open, close, etc. Then only the relevant vector can be passed to the overloaded operator. So far, I don't see the StockData structure being treated as unit of related data. Perhaps separate vectors would be appropriate. The operator overloading gives you some syntactic sugar, and allows you to chain calculations like this a-b-c, but there is a price to pay. In the worst case, an operation like a-b will produce an object for result, and then another copy of result will be made for the return, and after assignment to the recipient of the result, the two objects will be destroyed. Again, if your data set is huge, this can slow your program down. There is a way of passing "pointers" to the overloaded operator, and avoiding all the copying, but it requires the use of an auto_ptr, which is yet another concept to learn. However, it would mesh well with the idea of returning pointers from indicator functions like EMA above. vector operator-(const vector & op1, const vector & op2) { vector result; // TODO do the calculation return result; } DataCollection* MACD(DataCollection& ema12day, DataCollection& ema26day) { DataCollection* dc = new DataCollection; dc->symbol = ema12day.symbol; dc->data = ema12day.data - ema26day.data; return dc; }

Miningco.com Visit the source

Was this solution helpful to you?

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.