Matlab Engine from C++


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.

No comments:

Post a Comment

would you like it. :)