/* * Loads symbol data from DB. Loaded data is stored in * the global Bar* g_symbol * * @return true if new data was loaded * * TODO: fix compare between old and new data and * only return true if new data was loaded */ bool PlotWidget::loadSymbolData() { Bars sym = _toolbarWidget->currentSymbol(); //Don't load new data unless symbol or barlength changed if(!(g_symbol->symbol() != sym.symbol() || g_symbol->barLength() != _toolbarWidget->length())) return false; if (! _plots.size()) return false; // load fresh symbol data if (! _toolbarWidget->count()) return false; IDBPlugin *qplug = dynamic_cast<IDBPlugin *>(((PluginFactory*)PluginFactory::getPluginFactory())->loadPlugin(QString("Database"))); if (! qplug) return false; g_symbol->clear(); g_symbol->setSymbol(sym.symbol()); g_symbol->setBarLength(_toolbarWidget->length()); g_symbol->setPlotRange(_controlWidget->getRange()); if (! qplug->getBars(g_symbol)) return false; return true; }
QList<Bars> Database::search (QString search) { QList<Bars> symbols; if (! init()) return symbols; QSqlQuery q(_db); // first find matching names QString s = "SELECT DISTINCT name FROM symbolIndex"; if (search.contains("%")) s.append(" WHERE name LIKE '" + search + "'"); else s.append(" WHERE name='" + search + "'"); s.append(" ORDER BY name ASC"); q.exec(s); if (q.lastError().isValid()) { qDebug() << "Database::search:" + q.lastError().text(); return symbols; } QStringList names; while (q.next()) names << q.value(0).toString(); // load names with data int loop = 0; for (; loop < names.size(); loop++) { Bars sym; sym.setSymbol(names.at(loop)); if (! getSymbol(&sym)) continue; symbols << sym; } return symbols; }
int DBStock::newTable (PluginData *pd) { if (! init()) return 0; if (! pd->bars) return 0; Bars *symbol = pd->bars; if (symbol->table().isEmpty()) { qDebug() << "DBStock::newTable: invalid table"; return 0; } QSqlQuery q(_db); // create new table QString s = "CREATE TABLE IF NOT EXISTS " + symbol->table() + " ("; s.append("date INT PRIMARY KEY UNIQUE"); s.append(", open REAL"); s.append(", high REAL"); s.append(", low REAL"); s.append(", close REAL"); s.append(", volume INT"); s.append(")"); q.exec(s); if (q.lastError().isValid()) { qDebug() << "DBStock::newTable:" + q.lastError().text(); return 0; } 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; }
void PlotWidget::refresh () { if (! _plots.size()) return; // load fresh symbol data if (! _cw->count()) return; PluginFactory fac; Plugin *qplug = fac.load(QString("DBSymbol")); if (! qplug) return; DataBase db(g_session); saveMarkers(db); Bars sym = _cw->currentSymbol(); g_symbol->clear(); g_symbol->setSymbol(sym.symbol()); g_symbol->setLength(_cw->length()); g_symbol->setRange(_cw->range()); PluginData pd; pd.command = QString("getBars"); pd.bars = g_symbol; if (! qplug->command(&pd)) return; else emit signalClear(); // refresh dates emit signalSetDates(); QHashIterator<QString, Plot *> it(_plots); while (it.hasNext()) { it.next(); Plot *plot = it.value(); Entity *e = _settings.value(it.key()); if (! e) continue; QVariant *plugin = e->get(QString("plugin")); if (! plugin) continue; Plugin *iplug = fac.load(plugin->toString()); if (! iplug) continue; PluginData tpd; tpd.command = QString("runIndicator"); tpd.settings = e; if (! iplug->command(&tpd)) continue; for (int tpos = 0; tpos < tpd.curves.size(); tpos++) plot->setCurve(tpd.curves.at(tpos)); for (int tpos = 0; tpos < tpd.markers.size(); tpos++) plot->setMarker(tpd.markers.at(tpos)); } loadMarkers(db); emit signalDraw(); setScrollBarSize(); QStringList tl; tl << "OTA" << "-" << sym.symbol() << "(" + sym.name() + ")" << _cw->lengthText() << _cw->rangeText(); emit signalTitle(tl.join(" ")); }
int DBStock::setBars (PluginData *pd) { if (! init()) return 0; if (! pd->bars) return 0; Bars *symbol = pd->bars; 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() << "DBStock::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() << "DBStock::setBars:" << q.lastError().text(); qDebug() << s; continue; } } 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; }
void PlotWidget::refresh () { qDebug() << "PlotWidget::refresh ()"; DataBase db(g_session); bool newData = loadSymbolData(); //Save all markers before clearing the plot saveMarkers(db); emit signalClear(); // refresh dates emit signalSetDates(); Bars sym = _toolbarWidget->currentSymbol(); //Plot all Indicators QHashIterator<QString, Plot *> it(_plots); while (it.hasNext()) { it.next(); Plot *plot = it.value(); Entity *pEntity = _settings.value(it.key()); if (! pEntity) continue; QVariant *plugin = pEntity->get(QString("plugin")); if (! plugin) continue; IIndicatorPlugin *pPlugin = dynamic_cast<IIndicatorPlugin*>(((PluginFactory*)PluginFactory::getPluginFactory())->loadPlugin(plugin->toString())); if (! pPlugin) continue; QList<Curve*> curves = pPlugin->runIndicator(pEntity); if(newData){ pPlugin->newDataLoaded(); } for (int tpos = 0; tpos < curves.size(); tpos++) plot->setCurve(curves.at(tpos)); // for (int tpos = 0; tpos < tpd.markers.size(); tpos++) // plot->setMarker(tpd.markers.at(tpos)); } //relaod all markers after plot have been updated loadMarkers(db); updateScrollBars(); emit signalDraw(); setPanScrollBarSize(); QStringList tl; tl << "QtTrader" << "-" << sym.symbol() << "(" + sym.name() + ")" << _toolbarWidget->lengthText(); emit signalTitle(tl.join(" ")); }