int RSI::getMA (QString inKey, QString outKey, int type, int period) { if (! g_symbol) return 0; TA_RetCode rc = TA_Initialize(); if (rc != TA_SUCCESS) qDebug() << "RSI::getMA: error on TA_Initialize"; QList<int> keys = g_symbol->keys(); TA_Real input[MAX_SIZE]; TA_Real out[MAX_SIZE]; TA_Integer outBeg; TA_Integer outNb; int dpos = 0; for (int kpos = 0; kpos < keys.size(); kpos++) { CBar *bar = g_symbol->bar(keys.at(kpos)); double v; if (! bar->get(inKey, v)) continue; input[dpos++] = (TA_Real) v; } rc = TA_MA(0, dpos - 1, &input[0], period, (TA_MAType) type, &outBeg, &outNb, &out[0]); if (rc != TA_SUCCESS) { qDebug() << "RSI::getMA: TA-Lib error" << rc; return 0; } int keyLoop = keys.size() - 1; int outLoop = outNb - 1; while (keyLoop > -1 && outLoop > -1) { CBar *bar = g_symbol->bar(keys.at(keyLoop)); bar->set(outKey, out[outLoop]); keyLoop--; outLoop--; } return 1; }
int CurveOHLC::fill (PluginData *pd) { if (pd->key1.isEmpty() || pd->key2.isEmpty() || pd->key3.isEmpty() || pd->key4.isEmpty()) return 0; if (! g_symbol) { qDebug() << "CurveOHLC::fill: bars missing"; return 0; } if (! pd->data) return 0; Curve *curve = (Curve *) pd->data; QList<int> keys = g_symbol->keys(); for (int pos = 0; pos < keys.size(); pos++) { CBar *r = g_symbol->bar(keys.at(pos)); double o = 0; if (! r->get(pd->key1, o)) continue; double h = 0; if (! r->get(pd->key2, h)) continue; double l = 0; if (! r->get(pd->key3, l)) continue; double c = 0; if (! r->get(pd->key4, c)) continue; curve->setBar(keys.at(pos), new OHLCBar(pd->color, o, h, l, c)); } return 1; }
int Database::getBars (Bars *bd) { if (! bd) return 0; int length = bd->barLength(); if (length == -1) { qDebug() << "Database::getBars: invalid length"; return 0; } if (! getSymbol(bd)) return 0; if (! init()) return 0; // get last date in db QDateTime endDate = getMaxDate(bd); if (! endDate.isValid()) return 0; DateRange dr; //Don't bother to load less the all values into memory //All computers are bound to be able handle this in year 2012 //If ever porting to a mobile device, change at that point //bd->plotRange() QDateTime startDate = dr.interval(endDate, DateRange::_ALL); if (! startDate.isValid()) { qDebug() << "Database::getBars: invalid range"; return 0; } QSqlQuery q(_db); QString s = "SELECT date,open,high,low,close,volume"; s.append(" FROM " + bd->table()); s.append(" WHERE date >=" + startDate.toString("yyyyMMddHHmmss")); s.append(" AND date <=" + endDate.toString("yyyyMMddHHmmss")); s.append(" ORDER BY date ASC"); q.exec(s); if (q.lastError().isValid()) { qDebug() << "Database::getBars:" + q.lastError().text(); qDebug() << s; return 0; } BarType bt; BarLength bl; QDateTime isDate, ieDate; CBar *bar = 0; while (q.next()) { QDateTime lastDate = QDateTime::fromString(q.value(0).toString(), "yyyyMMddHHmmss"); // is date greater than current bar range? if (lastDate >= ieDate || ! bar) { // save old bar if (bar) bd->setBar(bd->bars(), bar); // create new bar bl.interval(lastDate, bd->barLength(), isDate, ieDate); bar = new CBar; bar->setDate(lastDate); bar->set(bt.indexToString(BarType::_OPEN), q.value(1).toDouble()); bar->set(bt.indexToString(BarType::_HIGH), q.value(2).toDouble()); bar->set(bt.indexToString(BarType::_LOW), q.value(3).toDouble()); bar->set(bt.indexToString(BarType::_CLOSE), q.value(4).toDouble()); bar->set(bt.indexToString(BarType::_VOLUME), q.value(5).toDouble()); } else { double v = q.value(2).toDouble(); double v2; bar->get(bt.indexToString(BarType::_HIGH), v2); if (v > v2) bar->set(bt.indexToString(BarType::_HIGH), v); v = q.value(3).toDouble(); bar->get(bt.indexToString(BarType::_LOW), v2); if (v < v2) bar->set(bt.indexToString(BarType::_LOW), v); bar->set(bt.indexToString(BarType::_CLOSE), q.value(4).toDouble()); v = q.value(5).toDouble(); bar->get(bt.indexToString(BarType::_VOLUME), v2); v += v2; bar->set(bt.indexToString(BarType::_VOLUME), v); } } // save any left over bar if (bar) bd->setBar(bd->bars(), bar); return 1; }
int Database::setBars (Bars *symbol) { if (! symbol) return 0; if (! getSymbol(symbol)) { if (! newSymbol(symbol)) return 0; } else { // check if we need to save the name if (! symbol->name().isEmpty()) setName(symbol); } if (! init()) return 0; _db.transaction(); QSqlQuery q(_db); QList<int> keys = symbol->keys(); BarType bt; int loop = 0; for (; loop < keys.size(); loop++) { CBar *bar = symbol->bar(keys.at(loop)); QDateTime dt = bar->date(); QString date = dt.toString("yyyyMMddHHmmss"); // first check if record exists so we know to do an update or insert QString s = "SELECT date FROM " + symbol->table() + " WHERE date =" + date; q.exec(s); if (q.lastError().isValid()) { qDebug() << "Database::setBars:" << q.lastError().text(); qDebug() << s; continue; } if (q.next()) // record exists, use update { s = "UPDATE " + symbol->table() + " SET "; QStringList tl; double v = 0; if (bar->get(bt.indexToString(BarType::_OPEN), v)) tl << "open=" + QString::number(v); v = 0; if (bar->get(bt.indexToString(BarType::_HIGH), v)) tl << "high=" + QString::number(v); v = 0; if (bar->get(bt.indexToString(BarType::_LOW), v)) tl << "low=" + QString::number(v); v = 0; if (bar->get(bt.indexToString(BarType::_CLOSE), v)) tl << "close=" + QString::number(v); v = 0; if (bar->get(bt.indexToString(BarType::_VOLUME), v)) tl << "volume=" + QString::number(v); s.append(tl.join(",")); s.append(" WHERE date=" + date); } else // new record, use insert { QStringList tl; s = "INSERT INTO " + symbol->table() + " (date,open,high,low,close,volume) VALUES("; tl << date; double v = 0; bar->get(bt.indexToString(BarType::_OPEN), v); tl << QString::number(v); v = 0; bar->get(bt.indexToString(BarType::_HIGH), v); tl << QString::number(v); v = 0; bar->get(bt.indexToString(BarType::_LOW), v); tl << QString::number(v); v = 0; bar->get(bt.indexToString(BarType::_CLOSE), v); tl << QString::number(v); v = 0; bar->get(bt.indexToString(BarType::_VOLUME), v); tl << QString::number(v); s.append(tl.join(",")); s.append(")"); } q.exec(s); if (q.lastError().isValid()) { qDebug() << "Database::setBars:" << q.lastError().text(); qDebug() << s; continue; } } _db.commit(); return 1; }
void NetfondsHistoryDownload::parseHistory(QByteArray &ba, QString &symbol, QString &name) { //quote_date,paper,exch,open,high,low,close,volume,value //20121101,OMXS30,Stockholm,1050.03,1064.08,1047.28,1062.51,0,0 QString ts(ba); QStringList ll = ts.split('\n'); Bars sym; sym.setExchange(QString("NETFONDS")); sym.setTicker(symbol); sym.setName(name); sym.setSymbolType(QString("Stock")); BarType bt; int line = 0; int loop = 1; // skip past first line for (; loop < ll.size()-2; loop++) { line++; ts = ll[loop].remove('"'); ts = ts.trimmed(); if (! ts.length()){ QStringList mess; mess << symbol << tr("Error!!"); emit signalMessage(mess.join(" ")); return; } QStringList l = ts.split(","); if (l.size() != 9) { QStringList mess; mess << symbol << ":" << tr("invalid # of fields, record skipped"); emit signalMessage(mess.join(" ")); return; } CBar *bar = new CBar; QDateTime dt = QDateTime::fromString(l.at(0).trimmed(), "yyyyMMdd"); if (! dt.isValid()) { delete bar; QStringList mess; mess << symbol << ":" << tr("invalid date") << l.at(0); emit signalMessage(mess.join(" ")); return; } else bar->setDate(dt); // verify open int pos = 3; bool ok; double t = l.at(pos).trimmed().toDouble(&ok); if (! ok) { delete bar; QStringList mess; mess << tr("Error, invalid open") << l.at(pos); emit signalMessage(mess.join(" ")); return; } else bar->set(bt.indexToString(BarType::_OPEN), t); // verify high pos = 4; t = l.at(pos).trimmed().toDouble(&ok); if (! ok) { delete bar; QStringList mess; mess << tr("Error, invalid high") << l.at(pos); emit signalMessage(mess.join(" ")); return; } else bar->set(bt.indexToString(BarType::_HIGH), t); // verify low pos = 5; t = l.at(pos).trimmed().toDouble(&ok); if (! ok) { delete bar; QStringList mess; mess << tr("Error, invalid low") << l.at(pos); emit signalMessage(mess.join(" ")); return; } else bar->set(bt.indexToString(BarType::_LOW), t); // verify close pos = 6; t = l.at(pos).trimmed().toDouble(&ok); if (! ok) { delete bar; QStringList mess; mess << tr("Error, invalid close") << l.at(pos); emit signalMessage(mess.join(" ")); return; } else bar->set(bt.indexToString(BarType::_CLOSE), t); // verify volume pos = 7; t = l.at(pos).trimmed().toDouble(&ok); if (! ok) { delete bar; QStringList mess; mess << tr("Error, invalid volume") << l.at(pos); emit signalMessage(mess.join(" ")); return; } else bar->set(bt.indexToString(BarType::_VOLUME), t); sym.setBar(sym.bars(), bar); } IDBPlugin *plug = dynamic_cast<IDBPlugin*>(((PluginFactory*)PluginFactory::getPluginFactory())->loadPlugin(QString("Database"))); if (! plug) { QStringList mess; mess << tr("Error, Database plugin missing"); emit signalMessage(mess.join(" ")); return; } if (!plug->init()) return; if (!plug->setBars(&sym)) return; }
int AROON::getAROON (int period, QString ukey, QString dkey) { if (! g_symbol) return 0; TA_RetCode rc = TA_Initialize(); if (rc != TA_SUCCESS) qDebug() << "AROON::AROON: error on TA_Initialize"; QList<int> keys = g_symbol->keys(); TA_Real high[MAX_SIZE]; TA_Real low[MAX_SIZE]; TA_Real out[MAX_SIZE]; TA_Real out2[MAX_SIZE]; TA_Integer outBeg; TA_Integer outNb; BarType bt; QString highKey = bt.indexToString(BarType::_HIGH); QString lowKey = bt.indexToString(BarType::_LOW); int dpos = 0; for (int kpos = 0; kpos < keys.size(); kpos++) { CBar *bar = g_symbol->bar(keys.at(kpos)); double h; if (! bar->get(highKey, h)) continue; double l; if (! bar->get(lowKey, l)) continue; high[dpos] = (TA_Real) h; low[dpos] = (TA_Real) l; dpos++; } rc = TA_AROON(0, dpos - 1, &high[0], &low[0], period, &outBeg, &outNb, &out[0], &out2[0]); if (rc != TA_SUCCESS) { qDebug() << "AROON::getAROON: TA-Lib error" << rc; return 0; } int keyLoop = keys.size() - 1; int outLoop = outNb - 1; while (keyLoop > -1 && outLoop > -1) { CBar *bar = g_symbol->bar(keys.at(keyLoop)); bar->set(dkey, out[outLoop]); bar->set(ukey, out2[outLoop]); keyLoop--; outLoop--; } return 1; }
int Volume::run (PluginData *pd) { if (! g_symbol) return 0; QVariant *var = pd->settings->get(QString("upColor")); if (! var) return 0; QColor uc(var->toString()); var = pd->settings->get(QString("downColor")); if (! var) return 0; QColor dc(var->toString()); var = pd->settings->get(QString("neutralColor")); if (! var) return 0; QColor nc(var->toString()); QVariant *label = pd->settings->get(QString("label")); if (! label) return 0; Curve *vol = new Curve(QString("CurveHistogram")); vol->setStyle(CurveHistogramType::_BAR); vol->setLabel(label->toString()); BarType bt; QList<int> keys = g_symbol->keys(); vol->fill(bt.indexToString(BarType::_VOLUME), QString(), QString(), QString(), nc); for (int pos = 1; pos < keys.size(); pos++) { CBar *pbar = g_symbol->bar(keys.at(pos - 1)); CBar *bar = g_symbol->bar(keys.at(pos)); Bar *vbar = vol->bar(keys.at(pos)); double yc = 0; if (! pbar->get(bt.indexToString(BarType::_CLOSE), yc)) continue; double c = 0; if (! bar->get(bt.indexToString(BarType::_CLOSE), c)) continue; if (c > yc) vbar->setColor(uc); else { if (c < yc) vbar->setColor(dc); } } pd->curves << vol; Curve *ma = getMA(pd->settings); if (ma) pd->curves << ma; return 1; }
int DBStock::getBars (PluginData *pd) { if (! init()) return 0; if (! pd->bars) return 0; Bars *bd = pd->bars; // get last date in db QDateTime endDate = getMaxDate(bd); if (! endDate.isValid()) return 0; DateRange dr; QDateTime startDate = dr.interval(endDate, bd->range()); if (! startDate.isValid()) { qDebug() << "DBStock::getBars: invalid range"; return 0; } QSqlQuery q(_db); QString s = "SELECT date,open,high,low,close,volume"; s.append(" FROM " + bd->table()); s.append(" WHERE date >=" + startDate.toString("yyyyMMddHHmmss")); s.append(" AND date <=" + endDate.toString("yyyyMMddHHmmss")); s.append(" ORDER BY date ASC"); q.exec(s); if (q.lastError().isValid()) { qDebug() << "DBStock::getBars:" + q.lastError().text(); qDebug() << s; return 0; } BarType bt; BarLength bl; QDateTime isDate, ieDate; CBar *bar = 0; while (q.next()) { QDateTime lastDate = QDateTime::fromString(q.value(0).toString(), "yyyyMMddHHmmss"); // is date greater than current bar range? if (lastDate >= ieDate || ! bar) { // save old bar if (bar) bd->setBar(bd->bars(), bar); // create new bar bl.interval(lastDate, bd->length(), isDate, ieDate); bar = new CBar; bar->setDate(lastDate); bar->set(bt.indexToString(BarType::_OPEN), q.value(1).toDouble()); bar->set(bt.indexToString(BarType::_HIGH), q.value(2).toDouble()); bar->set(bt.indexToString(BarType::_LOW), q.value(3).toDouble()); bar->set(bt.indexToString(BarType::_CLOSE), q.value(4).toDouble()); bar->set(bt.indexToString(BarType::_VOLUME), q.value(5).toDouble()); } else { double v = q.value(2).toDouble(); double v2; bar->get(bt.indexToString(BarType::_HIGH), v2); if (v > v2) bar->set(bt.indexToString(BarType::_HIGH), v); v = q.value(3).toDouble(); bar->get(bt.indexToString(BarType::_LOW), v2); if (v < v2) bar->set(bt.indexToString(BarType::_LOW), v); bar->set(bt.indexToString(BarType::_CLOSE), q.value(4).toDouble()); v = q.value(5).toDouble(); bar->get(bt.indexToString(BarType::_VOLUME), v2); v += v2; bar->set(bt.indexToString(BarType::_VOLUME), v); } } // save any left over bar if (bar) bd->setBar(bd->bars(), bar); return 1; }
int DrawChart(CDataInterface *pData, CEnvParam *pEnv, Interaction *itt, string VO, string &ppOutStruct,CResult **ppRst) { AnaWord aw; aw.Import(VO); CTString szChartType = aw.GetAt(0);//调用的算法名字 if (szChartType == CHART_LINE) //直线图 { CLine line; (*ppRst) = line.OnChart(pData, VO); } else if (szChartType == CHART_BAR) //条状图 { CBar Bar; (*ppRst) = Bar.OnChart(pData, VO); } else if (szChartType == CHART_PIE) //饼图 { CPie Pie; (*ppRst) = Pie.OnChart(pData, VO); } else if (szChartType == CHART_AREA) //面积图 { CArea Area; (*ppRst) = Area.OnChart(pData, VO); } else if (szChartType == CHART_BOXPLOT) //盒状图 { CBox Box; (*ppRst) = Box.OnChart(pData, VO); } else if (szChartType == CHART_HISTOGRAM)//直方图 { CHistogram Histogram; (*ppRst) = Histogram.OnChart(pData, VO); } else if (szChartType == CHART_SCATTER) //散点图 { CScatter Scatter; (*ppRst) = Scatter.OnChart(pData, VO); } else if (szChartType == CHART_SELFCORRELATIONS) //自相关 { CSelfCorrelation SelfCorr; (*ppRst) = SelfCorr.OnChart(pData,VO); } else if (szChartType == CHART_CROSSCORRELATIONS) //互相关 { CCrossCorrelation CrossCorr; (*ppRst) = CrossCorr.OnChart(pData,VO); } else if (szChartType == CHART_EMP) { CEmp Emp; (*ppRst) = Emp.OnChart(pData,VO); } else { CResult *pResult = new CResult("图形接口算法调用错误"); CTString szWarning = "没有相应的图形接口,请与供应商联系!"; CRsltElementText *pWarningTextRslt = new CRsltElementText("错误!"); pWarningTextRslt->AddString(szWarning); pResult->Add(pWarningTextRslt); (*ppRst) = pResult; (*ppRst)->Print(); return 1; } if (ppRst == NULL) { CResult *pResult = new CResult("图形接口算法调用错误"); CTString szWarning = "您所选择的数据不适合相应的图形接口算法,请重新运行!"; CRsltElementText *pWarningTextRslt = new CRsltElementText( "错误!" ); pWarningTextRslt->AddString(szWarning); pResult->Add(pWarningTextRslt); (*ppRst) = pResult; (*ppRst)->Print(); return 1; } else { (*ppRst)->Print(); return 0; } }