This is just for my fun, don't take seriously. I was writing a small stock screening utility for personal use, which was based on
NSE(Indian stock exchange) Bhavcopy data. First I plan to write each and everything in own way, I have written half of my matrices operations in my library, then i figure out, it will took very long time to write all kind of operation and stock indicators. I also want to graph plotting with data, which I already used one tool
gnuplot.
Finally I found
matlab, which supports both things for me. It will do calculation and graph plotting.
Here i found they have given example code in C style format and i used to with C++ class-object re-usability, you can say, mad for writing code in OOP(oops) formats, a very bad habit. I written a small class using something called singleton design pattern[which i don't know, once somebody told me this is not singleton, but it's working perfect for me or my requirement].
First I will show you how i used my class which created above graph.
.............................. when my application startup -------------------------
MLEngine* me = MLEngine::getMLEngine();
void stockprice::drapgraph() // This is my sample class for playing with stock data.
std::vector<double> close(close());
std::vector<double> open(open());
std::vector<double> rsi;
std::stringstream ss;
ss<<"x = 1:1:"<<ticklist.size();
std::string strcmd1=ss.str();
me->sendCommand(strcmd1.c_str());
me->sendDoubleVector(close,"close");
me->sendDoubleVector(open,"open");
double rsival,sma5val,ema5val;
me->sendCommand("rsi=rsindex(close);"); //calcualte rsi from matlab enginee
me->getDoubleVector(rsi,"rsi"); // getting calculated rsi from matlab in vector
rsival = rsi[rsi.size()-1];
me->sendCommand("sma5=tsmovavg(close, \'s\', 5,1);"); //calcualte simple moving average
me->getDoubleVector(rsi,"sma5");
sma5val = rsi[rsi.size()-1];
me->sendCommand("ema5=tsmovavg(close, \'e\', 5,1);"); //calcualte simple moving average
me->getDoubleVector(rsi,"ema5");
ema5val = rsi[rsi.size()-1];
me->sendCommand("sh(1)=subplot(3,1,1);"); // for multiploting and linking axis
me->sendCommand("plot(x,close,x,open);");
me->sendCommand("legend(\'close\',\'open\');");
me->sendCommand("grid on;");
me->sendCommand("sh(2)=subplot(3,1,2);");
me->sendCommand("plot(x,rsi);");
me->sendCommand("legend(\'rsi\');");
me->sendCommand("grid on;");
me->sendCommand("sh(3)=subplot(3,1,3);");
me->sendCommand("plot(x,ema5,x,sma5);");
me->sendCommand("legend(\'ema5\',\'sma5\');");
me->sendCommand("grid on;");
me->sendCommand("linkaxes(sh,\'x\');");
//// for multiploting and linking axis
.............................. when my application exit -------------------------
MLEngine::releaseMLEngine();
Now have look of this class.
#include<engine.h>
#include<vector>
class MLEngine
{
public:
static MLEngine*
getMLEngine();
static void releaseMLEngine();
void
sendCommand(const char* _cmd);
void
sendDoubleVector(const std::vector<double> & _vecdouble,const char* _name);
void sendLongVector(const std::vector<long> & _veclong,const char* _name);
void
getDoubleVector(std::vector<double> & _vecdbl,const char* _var_name);
private:
static MLEngine* m_pMLEngine;
Engine *m_pEngine;
MLEngine(void);
MLEngine(const MLEngine&){}
MLEngine& operator=(MLEngine&){}
virtual ~MLEngine(void);
};
Now we will look implementation of some of important attribute and behavior of this class.
getMLEngine : this will give you handle of matlab engine, which we are releasing in releaseMEEngine.
MLEngine* MLEngine::m_pMLEngine =NULL;
MLEngine* MLEngine::getMLEngine()
{
if(!m_pMLEngine)
m_pMLEngine = new MLEngine();
return m_pMLEngine;
}
void MLEngine::releaseMLEngine()
{
delete m_pMLEngine;
m_pMLEngine = NULL;
}
sendCommand : this used for sending command from C++ application to matlab engine.
void MLEngine::sendCommand(const char* _cmd)
{
if(!m_pEngine) return;
engEvalString(m_pEngine, _cmd);
}
sendDoubleVector : This use to send vector data to matlab engine and create matlab variable with given name. This name can use in next command to refer this data.
void MLEngine::sendDoubleVector(const std::vector<double> & _vecdouble,const char* _name)
{
if(!m_pEngine) return;
mxArray * mx1 = mxCreateDoubleMatrix(_vecdouble.size(),1, mxREAL);
std::copy(_vecdouble.begin(), _vecdouble.end(), mxGetPr(mx1));
engPutVariable(m_pEngine, _name, mx1);
}
getDoubleVector : This used to get the data from matlab engine with given name.
void MLEngine::getDoubleVector(std::vector<double> & _vecdbl,const char* _var_name)
{
if(!m_pEngine) return;
mxArray* pMx = engGetVariable(m_pEngine, _var_name);
if(pMx==NULL)
return;
int size = mxGetNumberOfElements(pMx);
_vecdbl.clear();
_vecdbl.resize(size);
double *data=reinterpret_cast<double*>(mxGetData(pMx));
for(int i=0; i<size; ++i){
_vecdbl[i]= data[i];
}
mxDestroyArray(pMx);
}
Now go and enjoy matlab engine and C++ but take care of linking part, which I haven't added here.