示例#1
0
time_t
DateRangeDaily::secIn( const DateRange & dateTwo ) const
{
  return( UnionOfDur( getTimeT(), dur,
		      dateTwo.getSecOfDay(), dateTwo.getDur(),
		      getFrequency() ) );
}
示例#2
0
void
GUIWidget::downloadHistory ()
{
  _log->clear();
  setEnabled(FALSE);
  _okButton->setEnabled(FALSE);
  _cancelButton->setEnabled(TRUE);
  
  DateRange dr;
  QDateTime ed = QDateTime::currentDateTime();
  QDateTime sd = dr.interval(ed, _range->currentIndex());
  
  _timer->start(100);
  
  YahooHistoryDownload function(this);
  connect(&function, SIGNAL(signalMessage(QString)), _log, SLOT(append(const QString &)));
  connect(_cancelButton, SIGNAL(clicked()), &function, SLOT(stop()));
  function.download(_symbolButton->files(), sd, ed);
  
  _timer->stop();

  setEnabled(TRUE);
  _okButton->setEnabled(TRUE);
  _cancelButton->setEnabled(FALSE);
}
示例#3
0
int
DateRangeDaily::compare( const DateRange & two ) const
{
  int diff = ::compare( getStart(), two.getSecOfDay() );
  if( diff )
    return( diff );
  else
    return( ::compare( getDur(), two.getDur() ) );
}
示例#4
0
time_t
DateRange::secIn( const DateRange & dateTwo ) const
{
  time_t   secs = 0;

  return( UnionOfDur( getTimeT(), dur,
		      dateTwo.getTimeT(), dateTwo.getDur() ) );
  
  return( secs );
}
示例#5
0
/** @todo this method implementation is not generic enough and not extendible by subclasses. */
PyObject* ResourceSkill::create(PyTypeObject* pytype, PyObject* args, PyObject* kwds)
{
  try
  {
    // Pick up the skill
    PyObject* skill = PyDict_GetItemString(kwds,"skill");
    if (!PyObject_TypeCheck(skill, Skill::metadata->pythonClass))
      throw DataException("resourceskill skill must be of type skill");

    // Pick up the resource
    PyObject* res = PyDict_GetItemString(kwds,"resource");
    if (!PyObject_TypeCheck(res, Resource::metadata->pythonClass))
      throw DataException("resourceskill resource must be of type resource");

    // Pick up the priority
    PyObject* q1 = PyDict_GetItemString(kwds,"priority");
    int q2 = q1 ? PythonObject(q1).getInt() : 1;

    // Pick up the effective dates
    DateRange eff;
    PyObject* eff_start = PyDict_GetItemString(kwds,"effective_start");
    if (eff_start)
    {
      PythonObject d(eff_start);
      eff.setStart(d.getDate());
    }
    PyObject* eff_end = PyDict_GetItemString(kwds,"effective_end");
    if (eff_end)
    {
      PythonObject d(eff_end);
      eff.setEnd(d.getDate());
    }

    // Create the load
    ResourceSkill *l = new ResourceSkill(
      static_cast<Skill*>(skill),
      static_cast<Resource*>(res),
      q2, eff
    );

    // Return the object
    Py_INCREF(l);
    return static_cast<PyObject*>(l);
  }
  catch (...)
  {
    PythonType::evalException();
    return NULL;
  }
}
示例#6
0
DateRange DateRange::intersect(DateRange const& other) const
{
   if (isNull() || other.isNull())
   {
      return DateRange();
   }

   QDate startDate = std::max(m_startDate, other.startDate());
   QDate endDate = std::min(this->endDate(), other.endDate());
   if (startDate <= endDate)
   {
      return DateRange(startDate, endDate);
   }
   else
   {
      return DateRange();
   }
}
示例#7
0
void GUIWidget::downloadHistory ()
{
  _log->clear();
  setEnabled(FALSE);
  _okButton->setEnabled(FALSE);

  DateRange dr;
  QDateTime ed = QDateTime::currentDateTime();
  QDateTime sd = dr.interval(ed, DateRange::_YEAR5);

  _timer->start(100);

  NetfondsHistoryDownload function(this);
  connect(&function, SIGNAL(signalMessage(QString)), _log, SLOT(append(const QString &)));
  function.download(getTickers()); //, sd, ed);
  _timer->stop();

  setEnabled(TRUE);
  _okButton->setEnabled(TRUE);
}
示例#8
0
time_t
DateRange::startsIn( const DateRange & dateTwo ) const
{
  time_t  secs = 0;

  if( dateTwo.getTimeT() >= getTimeT() &&
      dateTwo.getTimeT() <= (getTimeT() + dur ) )
    {
      secs = secIn( dateTwo );
    }
  return( secs );
}
示例#9
0
time_t
DateRangeDaily::startsIn( const DateRange & dateTwo ) const
{
  time_t  secs = 0;
  
  if( dateTwo.getSecOfDay() >= getTimeT() &&
      dateTwo.getSecOfDay() <= getTimeT() + dur )
    {
      secs = secIn( dateTwo );
    }
  return( secs );
}
示例#10
0
Currency RoutineAllocator::allocate(DateRange const& period, Currency available)
{
   DateRange range;
   if (m_history.isEmpty())
   {
      range = DateRange();
   }
   else
   {
      Q_ASSERT(m_history.lastKey() < period.startDate());
      range = DateRange(m_history.firstKey(), period.startDate().addDays(-1));
   }
   DateRange firstDay(range.startDate(), range.startDate());

   foreach (Currency const& total, m_historyTotals)
   {
      Currency amount = total.amortize(range, firstDay) * period.days();
      m_allocation -= amount;
      available += amount;
   }
示例#11
0
文件: flow.cpp 项目: Rona111/frePPLe
PyObject* Flow::create(PyTypeObject* pytype, PyObject* args, PyObject* kwds)
{
  try
  {
    // Pick up the operation
    PyObject* oper = PyDict_GetItemString(kwds, "operation");
    if (!oper)
      throw DataException("missing operation on Flow");
    if (!PyObject_TypeCheck(oper, Operation::metadata->pythonClass))
      throw DataException("flow operation must be of type operation");

    // Pick up the buffer
    PyObject* buf = PyDict_GetItemString(kwds, "buffer");
    if (!buf)
      throw DataException("missing buffer on Flow");
    if (!PyObject_TypeCheck(buf, Buffer::metadata->pythonClass))
      throw DataException("flow buffer must be of type buffer");

    // Pick up the quantity
    PyObject* q1 = PyDict_GetItemString(kwds, "quantity");
    double q2 = q1 ? PythonData(q1).getDouble() : 1.0;

    // Pick up the effectivity dates
    DateRange eff;
    PyObject* eff_start = PyDict_GetItemString(kwds, "effective_start");
    if (eff_start)
    {
      PythonData d(eff_start);
      eff.setStart(d.getDate());
    }
    PyObject* eff_end = PyDict_GetItemString(kwds, "effective_end");
    if (eff_end)
    {
      PythonData d(eff_end);
      eff.setEnd(d.getDate());
    }

    // Pick up the type and create the flow
    Flow *l;
    PyObject* t = PyDict_GetItemString(kwds, "type");
    if (t)
    {
      PythonData d(t);
      if (d.getString() == "flow_end")
        l = new FlowEnd(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
      else if (d.getString() == "flow_fixed_end")
        l = new FlowFixedEnd(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
      else if (d.getString() == "flow_fixed_start")
        l = new FlowFixedStart(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
      else
        l = new FlowStart(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
    }
    else
      l = new FlowStart(
        static_cast<Operation*>(oper),
        static_cast<Buffer*>(buf),
        q2
      );

    // Iterate over extra keywords, and set attributes.   @todo move this responsibility to the readers...
    if (l)
    {
      l->setEffective(eff);
      PyObject *key, *value;
      Py_ssize_t pos = 0;
      while (PyDict_Next(kwds, &pos, &key, &value))
      {
        PythonData field(value);
        PyObject* key_utf8 = PyUnicode_AsUTF8String(key);
        DataKeyword attr(PyBytes_AsString(key_utf8));
        Py_DECREF(key_utf8);
        if (!attr.isA(Tags::effective_end) && !attr.isA(Tags::effective_start)
          && !attr.isA(Tags::operation) && !attr.isA(Tags::buffer)
          && !attr.isA(Tags::quantity) && !attr.isA(Tags::type)
          && !attr.isA(Tags::action))
        {
          const MetaFieldBase* fmeta = l->getType().findField(attr.getHash());
          if (!fmeta && l->getType().category)
            fmeta = l->getType().category->findField(attr.getHash());
          if (fmeta)
            // Update the attribute
            fmeta->setField(l, field);
          else
            PyErr_Format(PyExc_AttributeError,
                "attribute '%S' on '%s' can't be updated",
                key, Py_TYPE(l)->tp_name);
        }
      };
    }

    // Return the object
    Py_INCREF(l);
    return static_cast<PyObject*>(l);
  }
  catch (...)
  {
    PythonType::evalException();
    return NULL;
  }
}
示例#12
0
void
GUIWidget::createGUI ()
{
  _timer = new QTimer(this);
  connect(_timer, SIGNAL(timeout()), this, SLOT(updateGUI()));

  QVBoxLayout *vbox = new QVBoxLayout;
  vbox->setSpacing(2);
  vbox->setMargin(5);
  setLayout(vbox);
  
  QFormLayout *form = new QFormLayout;
  form->setSpacing(2);
  form->setMargin(0);
  vbox->addLayout(form);
  
  // templates
  _templates = new QComboBox;
  form->addRow (tr("Templates"), _templates);
  
  // range
  DateRange dr;
  _range = new QComboBox;
  _range->addItems(dr.list());
  _range->setCurrentIndex(5);
  form->addRow (tr("Range"), _range);
  
  // symbol file
  _symbolButton = new FileButton(0);
  connect(_symbolButton, SIGNAL(signalSelectionChanged(QStringList)), this, SLOT(buttonStatus()));
  _symbolButton->setFiles(QStringList() << "/tmp/yahoo_symbols");
  form->addRow (tr("Symbol File"), _symbolButton);
  
  // log
  QGroupBox *gbox = new QGroupBox;
  gbox->setTitle(tr("Log"));
  vbox->addWidget(gbox);

  QVBoxLayout *tvbox = new QVBoxLayout;
  gbox->setLayout(tvbox);
  
  _log = new QTextEdit;
  _log->setReadOnly(TRUE);
  tvbox->addWidget(_log);

  // buttonbox
  QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Help);
  vbox->addWidget(bb);

  // ok button
  _okButton = bb->addButton(QDialogButtonBox::Ok);
  _okButton->setText(tr("&OK"));
  connect(_okButton, SIGNAL(clicked()), this, SLOT(downloadHistory()));

  // cancel button
  _cancelButton = bb->addButton(QDialogButtonBox::Cancel);
  _cancelButton->setText(tr("&Cancel"));
  _cancelButton->setDefault(TRUE);
  _cancelButton->setFocus();
  _cancelButton->setEnabled(FALSE);

  // help button
  QPushButton *b = bb->button(QDialogButtonBox::Help);
  b->setText(tr("&Help"));
  connect(b, SIGNAL(clicked()), this, SIGNAL(signalHelp()));
}
示例#13
0
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;
}
示例#14
0
文件: flow.cpp 项目: frePPLe/frePPLe
PyObject* Flow::create(PyTypeObject* pytype, PyObject* args, PyObject* kwds)
{
  try
  {
    // Pick up the operation
    PyObject* oper = PyDict_GetItemString(kwds, "operation");
    if (!oper)
      throw DataException("missing operation on Flow");
    if (!PyObject_TypeCheck(oper, Operation::metadata->pythonClass))
      throw DataException("flow operation must be of type operation");
    else if (!static_cast<Operation*>(oper)->getLocation())
      throw DataException("operation location is unspecified");

    // Pick up the item
    PyObject* item = PyDict_GetItemString(kwds, "item");
    if (!item)
      throw DataException("missing item on Flow");
    if (!PyObject_TypeCheck(item, Item::metadata->pythonClass))
      throw DataException("flow item must be of type item");

    // Pick up the quantity
    PyObject* q1 = PyDict_GetItemString(kwds, "quantity");
    double q2 = q1 ? PythonData(q1).getDouble() : 1.0;

    // Pick up the effectivity dates
    DateRange eff;
    PyObject* eff_start = PyDict_GetItemString(kwds, "effective_start");
    if (eff_start)
    {
      PythonData d(eff_start);
      eff.setStart(d.getDate());
    }
    PyObject* eff_end = PyDict_GetItemString(kwds, "effective_end");
    if (eff_end)
    {
      PythonData d(eff_end);
      eff.setEnd(d.getDate());
    }

    // Find or create a buffer for the item at the operation location
    Buffer* buf = Buffer::findOrCreate(
      static_cast<Item*>(item),
      static_cast<Operation*>(oper)->getLocation()
      );

    // Pick up the type and create the flow
    Flow *l;
    PyObject* t = PyDict_GetItemString(kwds, "type");
    if (t)
    {
      PythonData d(t);
      if (d.getString() == "flow_end")
        l = new FlowEnd(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
      else if (d.getString() == "flow_transfer_batch")
        l = new FlowTransferBatch(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
      else
        l = new FlowStart(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
    }
    else
      l = new FlowStart(
        static_cast<Operation*>(oper),
        static_cast<Buffer*>(buf),
        q2
      );

    // Iterate over extra keywords, and set attributes.   @todo move this responsibility to the readers...
    if (l)
    {
      l->setEffective(eff);
      PyObject *key, *value;
      Py_ssize_t pos = 0;
      while (PyDict_Next(kwds, &pos, &key, &value))
      {
        PythonData field(value);
        PyObject* key_utf8 = PyUnicode_AsUTF8String(key);
        DataKeyword attr(PyBytes_AsString(key_utf8));
        Py_DECREF(key_utf8);
        if (!attr.isA(Tags::effective_end) && !attr.isA(Tags::effective_start)
          && !attr.isA(Tags::operation) && !attr.isA(Tags::buffer)
          && !attr.isA(Tags::quantity) && !attr.isA(Tags::type)
          && !attr.isA(Tags::action))
        {
          const MetaFieldBase* fmeta = l->getType().findField(attr.getHash());
          if (!fmeta && l->getType().category)
            fmeta = l->getType().category->findField(attr.getHash());
          if (fmeta)
            // Update the attribute
            fmeta->setField(l, field);
          else
            l->setProperty(attr.getName(), value);
        }
      };
    }

    // Return the object
    Py_INCREF(l);
    return static_cast<PyObject*>(l);
  }
  catch (...)
  {
    PythonType::evalException();
    return nullptr;
  }
}
示例#15
0
文件: load.cpp 项目: DwBu/frePPLe
PyObject* Load::create(PyTypeObject* pytype, PyObject* args, PyObject* kwds)
{
  try
  {
    // Pick up the operation
    PyObject* oper = PyDict_GetItemString(kwds,"operation");
    if (!oper)
      throw DataException("missing operation on Load");
    if (!PyObject_TypeCheck(oper, Operation::metadata->pythonClass))
      throw DataException("load operation must be of type operation");

    // Pick up the resource
    PyObject* res = PyDict_GetItemString(kwds,"resource");
    if (!res)
      throw DataException("missing resource on Load");
    if (!PyObject_TypeCheck(res, Resource::metadata->pythonClass))
      throw DataException("load resource must be of type resource");

    // Pick up the quantity
    PyObject* q1 = PyDict_GetItemString(kwds,"quantity");
    double q2 = q1 ? PythonData(q1).getDouble() : 1.0;

    // Pick up the effective dates
    DateRange eff;
    PyObject* eff_start = PyDict_GetItemString(kwds,"effective_start");
    if (eff_start)
    {
      PythonData d(eff_start);
      eff.setStart(d.getDate());
    }
    PyObject* eff_end = PyDict_GetItemString(kwds,"effective_end");
    if (eff_end)
    {
      PythonData d(eff_end);
      eff.setEnd(d.getDate());
    }

    // Create the load
    Load *l = new LoadDefault(
      static_cast<Operation*>(oper),
      static_cast<Resource*>(res),
      q2, eff
    );

    // Iterate over extra keywords, and set attributes.   @todo move this responsibility to the readers...
    if (l)
    {
      PyObject *key, *value;
      Py_ssize_t pos = 0;
      while (PyDict_Next(kwds, &pos, &key, &value))
      {
        PythonData field(value);
        PyObject* key_utf8 = PyUnicode_AsUTF8String(key);
        DataKeyword attr(PyBytes_AsString(key_utf8));
        Py_DECREF(key_utf8);
        if (!attr.isA(Tags::effective_end) && !attr.isA(Tags::effective_start)
          && !attr.isA(Tags::operation) && !attr.isA(Tags::resource)
          && !attr.isA(Tags::quantity) && !attr.isA(Tags::type)
          && !attr.isA(Tags::action))
        {
          const MetaFieldBase* fmeta = l->getType().findField(attr.getHash());
          if (!fmeta && l->getType().category)
            fmeta = l->getType().category->findField(attr.getHash());
          if (fmeta)
            // Update the attribute
            fmeta->setField(l, field);
          else
            l->setProperty(attr.getName(), value);;
        }
      };
    }

    // Return the object
    Py_INCREF(l);
    return static_cast<PyObject*>(l);
  }
  catch (...)
  {
    PythonType::evalException();
    return NULL;
  }
}
示例#16
0
bool DateRange::operator==(DateRange const& other) const
{
   return m_startDate == other.m_startDate && endDate() == other.endDate();
}
示例#17
0
PyObject* ItemSupplier::create(PyTypeObject* pytype, PyObject* args, PyObject* kwds)
{
  try
  {
    // Pick up the supplier
    PyObject* sup = PyDict_GetItemString(kwds,"supplier");
    if (!sup)
      throw DataException("missing supplier on ItemSupplier");
    if (!PyObject_TypeCheck(sup, Supplier::metadata->pythonClass))
      throw DataException("ItemSupplier supplier must be of type supplier");

    // Pick up the item
    PyObject* it = PyDict_GetItemString(kwds,"item");
    if (!it)
      throw DataException("missing item on ItemSupplier");
    if (!PyObject_TypeCheck(it, Item::metadata->pythonClass))
      throw DataException("ItemSupplier item must be of type item");

    // Pick up the priority
    PyObject* q1 = PyDict_GetItemString(kwds,"priority");
    int q2 = q1 ? PythonData(q1).getInt() : 1;

    // Pick up the effective dates
    DateRange eff;
    PyObject* eff_start = PyDict_GetItemString(kwds,"effective_start");
    if (eff_start)
    {
      PythonData d(eff_start);
      eff.setStart(d.getDate());
    }
    PyObject* eff_end = PyDict_GetItemString(kwds,"effective_end");
    if (eff_end)
    {
      PythonData d(eff_end);
      eff.setEnd(d.getDate());
    }

    // Create the ItemSupplier
    ItemSupplier *l = new ItemSupplier(
      static_cast<Supplier*>(sup),
      static_cast<Item*>(it),
      q2, eff
    );

    // Iterate over extra keywords, and set attributes.   @todo move this responsibility to the readers...
    if (l)
    {
      PyObject *key, *value;
      Py_ssize_t pos = 0;
      while (PyDict_Next(kwds, &pos, &key, &value))
      {
        PythonData field(value);
        PyObject* key_utf8 = PyUnicode_AsUTF8String(key);
        DataKeyword attr(PyBytes_AsString(key_utf8));
        Py_DECREF(key_utf8);
        if (!attr.isA(Tags::effective_end) && !attr.isA(Tags::effective_start)
          && !attr.isA(Tags::supplier) && !attr.isA(Tags::item)
          && !attr.isA(Tags::type) && !attr.isA(Tags::priority) && !attr.isA(Tags::action))
        {
          const MetaFieldBase* fmeta = l->getType().findField(attr.getHash());
          if (!fmeta && l->getType().category)
            fmeta = l->getType().category->findField(attr.getHash());
          if (fmeta)
            // Update the attribute
            fmeta->setField(l, field);
          else
            l->setProperty(attr.getName(), value);
        }
      };
    }

    // Return the object
    Py_INCREF(l);
    return static_cast<PyObject*>(l);
  }
  catch (...)
  {
    PythonType::evalException();
    return nullptr;
  }
}
示例#18
0
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;
}