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 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 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; }
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; }