Custom Chart Software Thread

Discussion in 'Trading Software' started by EliteInterest, Mar 21, 2006.

  1. 1) The code comes out wrong here, some of the braces are not showing up. The forumla for the constant-volumebar formula has a small correction in the 'if (volumecount)' block - the date/time needs to be updated - its a new bar, so the new date/time is needed.

    2) I am in the process of re-vamping much of the base design. Firstly, I discovered the necessity of manually double-buffering certain widgets when implementing crosshairs. This is for performance reasons - if you redraw everything that is math-intensive every time the crosshairs move, the performance is pitiful and the crosshairs lag. The solution is to turn off double buffering, and write the complex chart drawing routine to a QPixmap (controlled by an 'isDirty' flag) and when the crosshairs are moving around, the dirty flag is false so only the buffered pixmap is drawn. Needless to say the performance is stellar now (in that respect). I implemented remote crosshairs to charts that are not in focus, which was kind of fun. The performance of the remote crosshairs is not up-to-snuff yet. It shouldn't be necessary to search through all displayed bars to find the date/time corresponding to the date/time of the position of the crosshair on the in-focus chart. This little quest has motivated me to rethink how to revamp the whole thing. Firstly, I am establishing a abstract base chart widget class which will be inherited by all chart widget classes. This will provide commonality, clean up the code and allow for better expansion. In particular, I am trying to design a 'generic' way to draw various routines on any given chart panel widget - so one could for instance have any number of studies on any panel - behind the candle/bar area, for instance. Plus I have to come up with a way to handle such things as custom studies or possibly a plug-in format. Nothing too complex - but most important is to design it for simple future expansion. This will require a bit of planning - so I am taking my time on this so it is done right.

    3) I thought this chart was somewhat interesting. It's really wide so the attachment hopefully will show up as a link instead of the picture being embedded within the body of this post.

    Russell 2000 weekly, longer term
     
    #11     Apr 4, 2006
  2. I implemented cross hairs extremely simply in Java by setting the Graphics object alternatively to paint and XOR modes. It is very fast - negligable CPU usage.

    Something like

    1. Paint cross hairs in PAINT mode.

    2. Mouse moved:

    A: Remove old crosshairs by painting in XOR mode. Automatically restores what was under the crosshairs.

    B: Paint new crosshair in PAINT mode.

    I don't know if QT supports this, but it is a very easy way to do it.
     
    #12     Apr 4, 2006
  3. I tried doing something similar to this manually before I had buffered the complex chart stuff (it was horribly slow) - something like this: QPainter lets you specify a simple or complex region to repaint, so I made one complex region using each of the previous and current crosshair locations (each of which was comprised of a combination of a 1-pixel wide rectangle for the horizontal and vertical components of the crosshairs). You then send this region to the update() or repaint() methods, and it will only redraw those. But now that I have buffered the complex chart code it might be faster. Nonetheless, it is quite fast the way it is now, but I'll certainly give it a try again, using your idea. The way it is now it just redraws the whole buffered shebang (overwriting the old crosshair location in the process) and the new crosshairs, but I can imagine how your way would improve it even more.

    In this regard I am more concerned with how to improve the performance of the external crosshair - it gets computationally expensive to seek out a date/time fed from the in-focus chart. The problem is varying timeframes - one might be a 60-minute chart or a tick chart that has a non-linear distribution of times, so it is not as simple as specifying an offset to directly seek out the bar position. Maybe there is a clever trick around this, something with mapping date/times to the bar locations, or maybe putting the external crosshairs on another thread (or each chart on its own thread?) Maybe there is a way to make the algorithm more efficient - e.g. I tried using the direction of the crosshair movement to tell the external chart in which direction to look for the date/time, and had some success with that, but it's not the best way. I'll have to think about it some more.

    edit: Now that i think about it, your XOR method sounds really efficient, however I fear there is no simple way to accomplish this, at least using built-in Qt methods. Creating the 'regions' to redraw over the old and new crosshair locations seems more computationally expensive than is necessary, rather than a simple XOR. I'll think about it some more, and ask around.
     
    #13     Apr 4, 2006
  4. Back to a few trendline charts for a quick minute:

    NQ 480 minute update to above, and ER2 60 minute extra wide with some basic divergence reversal and channel analysis:

    <img src="http://i2.photobucket.com/albums/y12/e647g9i/20060405-0723amEST-NQ-480min.png" border="0"</img><br>
    ER2 60 minute with divergences, very wide
     
    #14     Apr 5, 2006
  5. Needless to say,there is still plenty to be done. As can be seen on the attached chart, I have yet to coordinate symbols with digitcount&fp precision, etc. (i.e. NQ is ####.## - right column is set for ####.## but precision is off - still have to finish all persistent/loaded generic settings for the chart).. plus finishing the GRID to cover all permutations... plenty of work to do.

    Drawing tools (just simple line segments, for now) were somewhat tough, actually, believe it or not.

    <img src="http://i2.photobucket.com/albums/y12/e647g9i/20060407-NQ-480.png" border="0"></img><br>

    Something as seemingly simple as coordinating all mouse events, mouse icons, keyboard shortcuts, etc. was quite daunting, especially having never done it before. Of particular interest is the formula for determining relative proximity to a drawn line to enter 'edit' mode when left-clicking. The formula was adapted from a math-related website (I didn't remember the formula off the top of my head!):

    Code:
    QVector< QLineF >::const_iterator i;
    int x = event->pos().x();
    int y = event->pos().y();
    
    for (i = linestodraw.constBegin(); i != linestodraw.constEnd(); ++i){
    xx0 = -transformxorigin+(*i).x1();
    xx1 = -transformxorigin+(*i).x2();
    yy0 = (((float)height()/(mincandle-maxcandle))*(*i).y1())+(maxcandle*(float)height())/(maxcandle-mincandle);
    yy1 = (((float)height()/(mincandle-maxcandle))*(*i).y2())+(maxcandle*(float)height())/(maxcandle-mincandle);
    
    c1 = (xx1-xx0)*(x-xx0) + (yy1-yy0)*(y-yy0);
    c2 = (xx1-xx0)*(xx1-xx0) + (yy1-yy0)*(yy1-yy0);
    if (c1 <= 0)
       dist = sqrt( (x-xx0) * (x-xx0) + (y-yy0) * (y-yy0) );
    else if (c2 <= c1)
       dist = sqrt( (x-xx1) * (x-xx1) + (y-yy1) * (y-yy1) );
    else
       dist = ( ( (yy0-yy1)*x+(xx1-xx0)*y+(xx0*yy1-xx1*yy0) ) /
                 sqrt( (xx1-xx0)*(xx1-xx0)+(yy1-yy0)*(yy1-yy0) ) );
    ++lineindex;
    if (dist <= 3 && dist >= -3) {
      drawgrips = true;
      drawgripson = true;
      stayin = false;
      setCursor(editdrawmodecursor);
      ...
    }
    The astute observer may recognize that the formula is using dot products to determine if the point (grabbed by the mouse) forms acute or obtuse angles with the segment given by the two points on the line. This distance is compared, uising a tolerance of 3 units (pixels) away from the line, either from an end or the perpendicular distance, to determine whether to enter edit mode. Still have to go over everything - some minor kinks - but the meat and potatoes look pretty solid.

    I might wish to come back to create an 'enum' to properly organize the various modes of the chart. Right now there are numerous boolean flags flying around to set the modes and it is hard to follow. Maybe I can do something slick using bitwise operators to combine various states - otherwise each combination will have to get its own integer in the enum list.
     
    #15     Apr 7, 2006
  6. Hi EliteInterest,

    It seems that you are on the right path with Qt.
    In fact, about 5 years ago, I had a 100% home built system going using M$ development tools.
    Being 300% fed up with the M$ crap and having had intensive prior Unix experience, I decided it was time to junk M$ and move everything over to Linux.

    Like you, I opted for Qt as this enabled me to start work under windoz and migrate everything to Linux later on. In fact moving a major Qt app from windoz to Linux went truly painless.

    What I did differently from you is that I also opted for Python when starting of on Qt, in fact PyQt. Although I have a considerable experience with C/C++, I believe that for a complicated project like yours, the compactness of clutter-free Python code is of tremendous help. Forget about the Python 'slowness' whining - it's a non-problem. As to Java mentioned by some posters, it's only good for those having never heard about Qt.

    Further, the development of a charting package is a continuously evolving process. Even after these 4-5 years, I still come up with a charting need arising from a new insight. This would be impossible with any standard package. With your own package, there is always a solution. So be patient and keep on working on it. You also may come to believe one day that sharing such piece of work would be sheer foolishness.

    Good luck,
    nononsense :)
     
    #16     Apr 7, 2006