RealCode Classes, Manual Looping Overview. (Volume Weighted Price Take 2)

Kuf | Manual Looping, RealCode Classes | Monday, July 14th, 2008

As requested by reader Paul Stiles this article will explore a RealCode Class that performs it’s own looping (instead of using the default AutoLoop property of RealCode).

As you know (you have read all the posts on my blog right?), RealCode performs a loop over the current symbol’s price history and calls your code once for each value that should plot on a chart (or pass for a condition).   Sometimes this will make your code perform the same calculation more than once (look-back calculations like max/min and moving averages).  While the speed of modern computers is so blazing fast that you probably won’t notice the difference, over multiple iterations (say in a scan or BackScan) you might be able to pick up some noticeable speed by performing your own looping.

Let me say, this is an intermediate to advanced programming topic (for the non-programmer. For a professional developer you should have no problem understanding this). You should be comfortable with arrays, loops and functions before attempting to understand the code here.

As before, lets start with a new RealCode indicator. Switch to the Class tab.    In the class body, add the following lines of code:

   1: Sub New
   2:     AutoLoop = false
   3: end Sub

This creates a new class constructor.  In the body of the constructor we tell the base class not to perform the autolooping functions.  Changing this one property changes the way your class is run in context of the calculation. Instead of calling Plot once for every bar on the chart, plot will be called once and it’s your job to fill in the dates and values that you want to display.

When you have AutoLoop disabled, you need to call one of two methods to return your output:

AddToOutput(date,value)

AddToOutput(date,Open,High,Low,Close)

The first AddToOutput call is used when you only want to return one value for each date (like a moving average).  The second one is to return bar data.

The other big change when AutoLoop is disabled is that you can no longer use the Price and Volume lookback notation (ala Price.High(10)).  The reason should be obvious, you’re not executing in the context of a “current” bar.  Instead, you need to access the raw data arrays in the Price and volume indicators.

Price data (and any referenced indicator from the chart) can be accessed using the Price.bar property. The data arrays are as follows:

Price.bar.OpenValue(index)

Price.bar.HighValue(index)

Price.bar.LowValue(index)

Price.bar.Value(index) - (same as close/last)

Price.bar.DateValue(index)

Price.bar.Count - (data length)

Volume has the following methods:

mVolume.Value(index)

mVolume.DateValue(index)

mVolume.Count(index) – should always match the Price.bar.Count variable

If you were to import and indicator via drag and drop like so:  ‘# CustomPlot = indicator.MyCustomCode.1. You would have the following available to you:

CustomPlot.IsBar

CustomPlot.Bar

CustomPlot.Line

CustomPlot.Bar will have the exact same calls as the Price.Bar class above and CustomPlot.Line would have the same as mVolume above.  You can call IsBar to determine if there is bar data available (Open,High,Low,Close) if you are not sure.

Now that the background is out of the way, lets post the converted code sample. Replace the Body of your new RealCode class with the code below.

   1:
   2:   ‘#period = userinput.integer = 20
   3:   sub New
   4:       AutoLoop = False
   5:   End Sub
   6:   Public Overrides Function Plot() As System.Single
   7:       Dim sum As Double = 0
   8:       Dim VolSum As Double = 0
   9:
  10:       For x As Integer = 0 To Period - 1
  11:           sum += Price.Bar.Value(x) * mVolume.Value(x)
  12:           volSum += mVolume.Value(x)
  13:       Next
  14:
  15:       AddToOutput(Price.bar.DateValue(Period -1),CSng(sum / volsum))
  16:
  17:       For x As Integer = Period To Price.Bar.Count - 1
  18:           Dim newVal As Double =  (Price.Bar.Value(x) * mVolume.Value(x))
  19:           Dim oldVal As Double = Price.Bar.Value(x - Period) * mVolume.Value(x - period)
  20:           Dim delta As Double = newval - oldval
  21:           Dim volDelta = mvolume.value(x) - mvolume.value(x - period)
  22:
  23:           sum += delta
  24:           volSum += volDelta
  25:
  26:           AddToOutput(Price.Bar.DateValue(x),CSng(sum / volSum))
  27:       Next
  28:   End Function

I have modified a few of the variable types from  the previous example. I’m using doubles when dealing with the Price and volume calculations to hold larger values due to the “lop off” averaging method. Because of this there might be some minor rounding differences from the previous example.

Volume Weighted Price using a RealCode Class

Kuf | RealCode Classes | Sunday, July 13th, 2008

Today I’m going to walk you through creating the volume weighted price indicator using a RealCode Class. There is nothing special about this indicator that requires it to be a class, but it is a simple enough example that lends itself to a class demonstration.

Lets start by creating a new RealCode indicator, (Click - RealCode Editor, Indicator). Name it VolumeWeightedPrice.  When the RealCode editor is displayed, click on the Class tab at the top. Your editor will have some code already stubbed out for you:

image

You can see from the screenshot above that we have a Public Partial Class VolumeWeightedPrice and that it’s inheriting a base class named VolumeWeightedPrice_base. Yo do not ever want to change the first 3 lines of a RealCode class (if you do, it will break horribly and life as we know it will cease to exist).  The last line of code (line 12 in the screenshot above) is the End Class statement. You also do not want to remove this line (you know, end of existence and all) but it can and will change line numbers as you add more code to your class.  Line 5 declares a Public Overrides Function Plot as System.Single. This statement is the method that is called in your class to return a value. It will be called once per plot on the chart.  We do not want to remove this line either (though it can change line numbers without causing a catastrophe)   Line 10 is also needed as the End Function statement to define the code that is contained in the Plot method (though it too can change line numbers).

Everything between line 3 and line 12 above is the “class body”. As long as your class contains the required overridden function  you can edit the class body however you see fit.  When publishing class code (say on a blog or a forum) You should only post the class body and not the class definition itself.   All code examples from Worden and this blog will post only the class body.

Now that we understand what the default code is (you do understand what the default code is right?) we can modify the class to include our own user function.

We’re going to add a function which performs the actual calculation for the current bar. There is no special reason why we’re using a function for this calculation, other than to demonstrate how to write one. After the End Function and before the End Class (on line 11)  write (or copy/paste) the code below:

   1: Private Function AvgForPeriod(calcPeriod As Integer) As Single
   2:         dim pricesum As Single
   3:       Dim VolSum As Single
   4:       For i As Integer = 0 To calcPeriod
   5:          pricesum += price.Close(i) * volume(i)
   6:          volsum += volume(i)
   7:       Next
   8:
   9:       Return pricesum / volsum
  10:
  11: end function

The above code performs the volume weighting on price for the specified period .   This function will perform a loop from the current price index (0) to the calcPeriod.  It will sum up the price times the volume along with the sum of the volume itself. After the For loop it will perform the average by dividing the pricesum by the volume sum.

To finish this class, we need declare a user input directive and then simply call our function. The user input directive is simple and be anywhere in your class code. For readability, I recommend them near the top of your class (before the Plot function).

   1: ‘    #Period = userinput.integer = 20

By default this will perform a 20 period Volume Weighted price but the period can be edited from QuickEdit.  Now all we need to do is call our function, passing in the period and return the results. Simply add the line of code below to the body of the Plot function:

   1: Public Overrides Function Plot() As System.Single
   2:      return Me.AvgForPeriod(period)
   3: end function

This calls our AvgForPeriod function and passes in the current user-defined period.  AvgForPeriod returns a numeric value, so we simply return that for our Plot call.

Below is the full VolumeWeightedPrice code that you insert into the class body:

   1: ‘    #Period = userinput.integer = 20
   2:
   3:     Public Overrides Function Plot() As System.Single
   4:          plot = Me.AvgForPeriod(period)
   5:     end function
   6:
   7:     Private Function AvgForPeriod(calcPeriod As Integer) As Single
   8:
   9:           Dim pricesum As Single
  10:           Dim VolSum As Single
  11:           For i As Integer = 0 To calcPeriod
  12:              pricesum += price.Close(i) * volume(i)
  13:              volsum += volume(i)
  14:           Next
  15:           Return pricesum / volsum
  16: End Function

Introduction to RealCode Classes

Kuf | RealCode Classes | Monday, June 30th, 2008

 

Version 3.1 Build 15 of Blocks introduces the RealCode Class programming model.   Instead of writing the body of a method you can write an entire class to encapsulate all your logic and data.  Classes are at the core of all object oriented languages.   VB.Net and C# are both built with classes.

In earlier versions, we were writing the class for you behind the scenes, but now we have opened up the class code to you, the developer.   This allows you to use standard member variables (instead of static variables) to store data as well as the ability to write your own functions within your class.

Writing your own functions can make the logic in your code easier to create, manage and edit. It allows you to encapsulate calculations into logic parts.

One of the other additions that goes hand in hand with the RealCode classes is the ability for you to enumerate the price data with your own loop. By default, the RealCode engine calls your method (or the method in your class)  once for every data point in the price history. This default behavior is called AutoLoop and it is set by default for all RealCode items. Sometimes you might want to loop through the price history yourself, either for performance reasons or for simplicity sake. (you might need to do some complicated look-back logic that AutoLooping would make slow and hard to manage/read/edit). You can now do this in build 15 with the AutoLoop = false property.

Along with the AutoLoop = False we have given you direct array access to the Price data. This allows you to enumerate the data in a more traditional array index structure (0 is the first element in the array) as opposed to the look-back indexing of the built in Price object (0 is the current bar). You can access these raw data arrays with the Price.Bar or Price.Line objects.  They can also be used on any imported indicator.

An overview of RealCode classes has been included in the updated RealCode programmers reference.  The next few blog entries will be dedicated to writing indicators and conditions with RealCode Classes.

Blocks version 3.1 build 15 Now available

Kuf | Uncategorized | Sunday, June 29th, 2008

I’m excited to announce 3.1 build 15 is now available. Included in this build are some exciting additions to the RealCode programming language. We have added support for vb.net class authoring.  Some of the benefits of using classes for your RealCode include:

  • User functions. You can write functions in your class to perform the same calculation more than once
  • Inheritance – your class can inherit another class that contains existing reusable logic
  • Custom Looping – You can override the default RealCode behavior and enumerate the price data using your own custom loop.
  • Custom Timeframing – while this was possible without classes, it’s much easier with the custom looping.
  • Class level member variables – you can define class level member variables instead of static variables.
  • Private Classes – you can write your own classes to encapsulate a custom data set in your calculation.

An updated RealCode programmers reference is currently being edited and should be published this week.  In addition, I will be making a bunch of new posts on using the new functions in RealCode as well as how to use RealCode classes.

Cumulative Indicators

Kuf | Uncategorized | Wednesday, June 4th, 2008

We patched up version 3.1 build 12 this week.  There were some core RealCode changes that really have no effect on the end user (yet) but have set the groundwork for future RealCode development.

One of the key changes in build 12 was the support for the ‘#Cumulative directive. Adding ‘#Cumulative to your RealCode will instruct the compiler to mark your calculation as a cumulative indicator. Cumulative indicators are indicators who’s value changes depending on the start date.  An example would be an advance decline line or an exponential average. Generally, one does not care about the actual value in a cumulative indicator because the starting value can be so arbitrary.

If you have written a cumulative indicator and you are trying to include it in a WatchList column, you will need to add the ‘#Cumulative directive. When an indicator is added to a WatchList column, Blocks attempts to use the least amount of data possible to perform the calculation.  Because the calculation needs to be performed on every symbol in the WatchList, using the least amount of data ensures the fastest sorts, scans and filters. Cumulative data, however, needs all of the data available to match the values on the chart. This means that a cumulative indicator is considerably slower when used in scan, sort or filter, so be careful when writing cumulative indicators and make sure you actually need to use the entire history to perform your calculation. Many times there are alternative ways to get the same results without needing to evaluate the entire data (for instance instead of using exponential averages you can use simple or front weighted).

If you absolutely need to have a cumulative indicator and you plan on scanning, sorting or filtering on it, then you MUST add the ‘#Cumulative directive to your code or it will not match the chart.

RealCode, Blocks 3.2 and Webinars

Kuf | Uncategorized | Friday, May 23rd, 2008

 

I’ve been so busy working on the next release of Blocks I haven’t found any free time to update the blog. We have some exciting enhancements to RealCode coming down the line.  While I can’t discuss the specific changes, they make my 3rd installment of “RealCode is a Method”  null and void.   Needless to say (but I’m saying it anyway) there will not be “RealCode is a Method part 3″.

Our first Webinar exceeded our expectations and the feedback we received was excellent (thanks for sending them in!). We thought it went so well that we’ve scheduled more, this time with more focused topics.  You can view the list and register for the up and coming events.

Send Worden some suggestions on topics you would like to see in a future Webinar at the Worden discussion forums.

Have a good holiday weekend! Cheers!

InteropServices.COMException Visual Studio 2008

Kuf | Visual Studio | Monday, May 19th, 2008

image

I got this big nasty error message when opening a project in VS2008 that was saved in Visual Studio 2003.  A search of the Internet did not find a solution. I was able to fix it myself by editing the vbproj file and changing this line:

<ProjectExtensions>
   <VisualStudio>
     <FlavorProperties GUID=”{349c5851-65df-11da-9384-00065b846f21}”>
       <WebProjectProperties>
            <UseIIS>TRUE</UseIIS>

Change the UseIIS to FALSE, save and reload the project. Apparently if you don’t have IIS installed on your dev box, you will get the above COMException.   Nice and friendly. Hopefully someone else will find this blog entry and save themselves the headache.

Blocks Trader 3.1 Webinar

Kuf | Uncategorized | Friday, May 16th, 2008

Blocks is hosting it’s first Webinar on Monday May 19th.  We at Worden and The Blocks Company are excited to use the WebEx technology for interactive learning on the Blocks Trader Platform. 

via www.blocks.com:

Join Worden’s Training Director, Craig Shipman, for an hour-long walking tour of the latest version of Blocks. Learn the new Condition Palette and the healthy handful of new condition-related features that reside inside.
Q&A time will be provided.

Pre-Register

BuzzNet Tags: ,

RealCode is a Method Part 2

Kuf | Blocks Trader 3.1, RealCode Fundamentals | Thursday, May 15th, 2008

In part one, I described how RealCode is a method call inside a class. The class and method Blocks Trader generates for you, and you provide the “guts” of the method call. As you know everything in Blocks Trader 3.1 runs in a diagram (you have read the manual right?). In this part 2 I’m going to show you how to create global variables to preserve values between calls to your code.

Because your code is running in a method, all of your variables will “fall out of scope” at the end of your code and will be reset to their default values. If you want to preserve a variable’s value between iterations of the loop you will need to define them with the static keyword. This allows you to perform cumulative calculations, or other data caching to perform a more complex calculation. It is essentially your only way in Blocks Trader 3.1 of defining a global variable for your code. There is a caveat of defining a variable as static. You need to re-initialize the value at the start or end of the calculation context (the start or end of the loop for the current symbol). Because you don’t know when the symbol changes, the easiest way to do this is to check for isFirstBar = true. Because your RealCode is executed in the context of a stock price history, you can check to see if this is the first bar of a calculation and reset your variables to their starting values. Below is a RealCode indicator to count the number of bars in a row a stock is moving up (net change > 0).

static upCount as integer 

      if isFirstBar = true then
         upCount = 0
      else
         if Price.Close > Price.Close(1) then
           upCount += 1
         else
           upCount = 0
         end if
      end if

      Plot = upCount

Line 1 defines our variable upCount as static and types it as an Integer (32 bit signed). One line 3 we check to see if this is the first bar of the calculation (the first time we’re being called for the selected symbol). Line 4 we initialize our upCount back to 0.

Line 5, if we’re not on the first bar we do everything between line 5 and line 11.

Line 6: check for the close price of the stock on the current bar to the close price 1 bar ago (Price.Close(1)) The reason we enclose this block of code between the else statement of isFirstBar is because we cannot check for the price.close(1) until we’re on bar number 2 or higher. Line 7 increases our count variable by 1 if the stock is up from the previous bar. line 9 resets our counter back to 0 because the stock is not up. Line 13 will execute every call and will return our current upCount value. This is the value that will plot for the current bar.

The key points in the code above are defining the variable static to preserve it’s value, and resetting this value to 0 on the first bar of execution.

Now that we understand how to define our own variables that will remember their value between calls, and that our code is running as a method inside a loop we can do some really cool calculations. In part 3 I’ll show you some more advanced code using static variables and how we can cheat the compiler to let us write our own functions. Cheers!

RealCode is a Method

Kuf | Blocks Trader 3.1 | Tuesday, May 13th, 2008

What is RealCode?

I’m having a hard time summarizing for you, the end user and programmer, what exactly RealCode is. At it’s core, it’s nothing more than a function call (method). Blocks executes the code you provide to produce a value. It calls your code in the context of a stock’s price history. Behind the scenes there is so much more, but for this post RealCode is a Method.

When you create a RealCode item and hit the apply button on the Editor, we take the your code and insert it into a function inside a class. We then wrap your code with our own loop. This loop starts at the earliest price history point for the "selected symbol" and then asks your code for a value (indicator: a single floating point number, condition: boolean value, paintbrush: color). This means that your code will be called for each plot on the chart. If you return a value, it will add your value, and the date of the current bar to the chart. If you return an empty value (Single.NaN or color.empty) it will simply skip the date and continue on.

Code speaks louder than words, so lets examine some pseudo code for what happens behind the scenes. I write this to give you enlightenment and understanding as to the context in which your code runs. Once you understand what is happening you can manipulate this to change how your RealCode item is calculated.

Dim userValue as single 

For each priceBar in currentSymbolPriceHistory 

    userValue = RealCode.CallUserProvidedCode 

    if userValue <> Single.NaN then 

        Plot (userValue,priceBar.CurrentDate) 

    end if 

Next

There’s a whole lot more going on besides the pseudo code above. we provide you hooks to indicators and conditions on the chart, as well as your own user defined inputs. We also interpolate every input to ensure that there’s always a value every time your code is called. The fundamental things to understand though is that we call you once for every bar on the chart and if you return something other than Single.NaN, we will plot that value for the same date as the current bar. This model presumes you want to plot a value for every bar on the chart.

Now that we have this foundation, I can show you how to modify this default behavior to produce your own custom plots. Alas, that will have to wait for another post.

Next Page »

Powered by WordPress | Theme by Roy Tanck