Login Page - Create Account

Support Board


Date/Time: Fri, 19 Apr 2024 17:55:15 +0000



[User Discussion] - [ACSIL] float conversions

View Count: 3222

[2013-12-18 01:24:31]
mainframer - Posts: 9
Folks, I'm trying draw a bar for every price tick between the highest high and lowest low on the chart. Is there an array of all the price ticks in the graph?

At first I tried incrementing the lowest low by the sc.TickSize, but the float data types lose their accuracy when I do anything to them.


//My original solution here fails because floats lose information when added.

float highestHigh = sc.BaseData[SC_HIGH][sc.Index];
float lowestLow = sc.BaseData[SC_LOW][sc.Index];

for(float price = lowestLow;
price <= highestHigh;
price += sc.TickSize)
{
//supposed to draw line for each tick, but 'price' float gets skewed.
myDrawFunction(price);
}

Date Time Of Last Edit: 2013-12-18 01:44:46
[2013-12-18 02:37:41]
vegasfoster - Posts: 444
How is it getting skewed, are all lines shifted or is the spacing between the lines not equal to the sc.Ticksize? Only thought is to try rounding to sc.Ticksize.
[2013-12-18 02:58:01]
mainframer - Posts: 9
The problem is that the binary representations of floating point numbers are actually imperfect representations.

0.01 is actually 0.0099999999776482582
3.21 is actually 3.2100000381469727

Therefore if I try to add the float representations of 0.01 and 3.21, I get an inaccurate result of 3.22000003812 instead of 3.22.

By that logic, the act of rounding would never produce an accurate result.

Date Time Of Last Edit: 2013-12-18 03:05:04
[2013-12-18 06:27:28]
ejtrader - Posts: 688
mainframer - Just a thought(haven't tested) - do you want to try this option instead and see?



//My original solution here fails because floats lose information when added.


float highestHigh = sc.BaseData[SC_HIGH][sc.Index];

float lowestLow = sc.BaseData[SC_LOW][sc.Index];

float price = lowestLow;

while ( price <= highestHigh )
{

//supposed to draw line for each tick, but 'price' float gets skewed.

myDrawFunction(price);
price += sc.TickSize;
}

Date Time Of Last Edit: 2013-12-18 06:29:09
[2013-12-18 11:47:30]
mainframer - Posts: 9
ejtrader: I appreciate your response, but your code is actually the same as mine.

The problem here is a fundamental rule of floating point computation which states that whenever you perform any mathematical change (add, subtract, multiply, etc.) on any float, you lose a small ammount of decimal information, and those small errors eventually add up.
[2013-12-18 15:46:14]
jackw - Posts: 57
You can eliminate the cumulative effect of the float inaccuracies by working with price in ticks.


int highestHigh = Round(sc.BaseData[SC_HIGH][sc.Index] / sc.TickSize);
int lowestLow = Round(sc.BaseData[SC_LOW][sc.Index] / sc.TickSize);

for(int price = lowestLow; price <= highestHigh; price++)
{
myDrawFunction((float)price * sc.TickSize);
}

[2013-12-19 16:32:25]
mainframer - Posts: 9
ejtrader: This won't work if I want to draw a bar at every price tick because converting floats to int's removes all of the decimal information.
Date Time Of Last Edit: 2013-12-19 16:33:03
[2013-12-27 17:55:59]
mainframer - Posts: 9
I found a reasonably accurate solution based on ejtrader's idea. It's rather complicated, so if anyone wants to know how I did it, feel free to PM me.
[2013-12-27 18:04:34]
ejtrader - Posts: 688
mainframer - I think the idea would be from "jackw" - just thought of correcting.

However interested in knowing the solution you came up with. in SC forum there is no PM option. Would you please see if you can post the solution here?

Thanks
[2013-12-30 19:11:05]
mainframer - Posts: 9
The key to my solution involves creating my own add and multiply functions for these floats. I provide below the necessary functions for this solution. For the sake of time, I have left out petty details like function parameters, so you will have to figure the rest out yourself. Ask questions if you are confused.

addFloat() The add function simply increments the price float by the sc.TickSize, then rounds that sum with sc.RoundToTickSize.

multiplyFloat() Multiplies a float by calling addFloat() 'x' number of times.

numberOfPrices() Calculates the number of prices in a range of prices 'x' and 'y'. To do this, you must convert x and y to int form and return x - y. The key is to convert x and y into integers while preserving their significant figures.
// Let's say x and y are at sc.TickSize == 0.01
int intX = (int) multiplyFloat(x, 100);
int intY = (int) multiplyFloat(y,100);
return intX - intY

buildPriceList() Determines the size of the set of prices between a provided range. First define an array of prices, then, for every element in that array, increment the price starting from the lowest in the range.
// Define array of prices.
int size = numberOfPrices();
float prices[size];

// Determine each price by incrementing with the tick price.
float currentPrice = 0; // You can start with another price.
for(int i=0; i < size; i++){
prices[i] = addFloat(currentPrice, sc.TickSize);
}

return prices;

To post a message in this thread, you need to log in with your Sierra Chart account:

Login

Login Page - Create Account