Data2d

The data2d data structure serves as a versatile solution for storing key-value pairs in Pine Script. Unlike the standard arrays in Pine Script, which are limited to storing single type values and do not offer key associations, data2d allows you to store multiple types of data and associate each value with a unique key. This unique feature enables more advanced data management and analysis within Pine Script's indicators, strategies and libraries.

Structure

To achieve the functionality of storing key-value pairs with multiple types of data, data2d relies on another custom object called kv (key-value). The kv object acts as a container for a single key with its corresponding value. By utilizing these kv objects within an array and pushing them onto a data2d object, we create a robust system for key-value storage.

Key Features

In addition to basic key-value pairing, the data2d object offers several powerful features:

  • Storing Alternate Values: Each key-value pair can store an alternate value, enabling the association of two values under one key. This key-value-alternate pairing proves particularly valuable when working with data that requires multiple associated values, such as storing both the current and last closing prices under the same key "close". It's important to note that the alternate value MUST be of the same data type as the original value. For added convenience, data2d provides numerous built-in comparison methods that work seamlessly with key-value-alternate pairs.
  • Comparison With Alternate: The ability to store alternate values brings with it the convenience of built-in comparison methods. You can perform multiple comparison operations to compare main values with their corresponding alternate values. Additionally, you can effortlessly obtain the change difference and change percentage between the main and alternate values.
  • Storing Unix Timestamps: The data2d object offers the capability to store Unix timestamps as a distinct data type. This feature greatly simplifies the handling of timestamp values. You can effortlessly store, retrieve, and display timestamps with the data2d object. By default, it presents Unix timestamp values in a human-readable format. You have the flexibility to customize this formatting according to your preferences. Additionally, the utility of alternate values can be fully leveraged for timestamps, as the data2d object includes built-in comparison methods specifically designed for timestamp comparisons.
  • Automatic Formatting: The data2d object automatically formats and stores the formatted version of each data entry, leveraging formatting options when available. This feature is especially useful when dealing with timestamps or other complex data types, simplifying data management and enhancing readability.
  • Sorting Capability: Similar to Pine Script's arrays, the data2d object supports data sorting. However, unlike standard arrays, it allows sorting for all data types, not limited to integers and floats. To ensure successful sorting, a single data2d object must hold values of only one data type. Attempting to sort a data2d object with mixed data types will result in an invalid operation.
  • Extended Array Functions: The data2d object extends some array functions, granting direct access to familiar array manipulations directly within the object. This streamlines data manipulation operations, making it easier and more intuitive to work with data2d objects.

Setup Keys And Values

To construct a single key-value pair, the recommended approach is to use the kv() method. This method accepts the following four parameters:

  • this: A string object, used as the key identifier.
  • val: The val parameter denotes the main value to be stored under the specified key.
  • altVal: The altVal parameter allows the inclusion of an alternate value for the same key. This proves useful when there is a need to associate two different values under one key.
  • format: The format parameter provides the option to set a custom format for the individual key. This custom format will take precedence over the global format set on the data2d object.

Creating kv objects

_open  = kv(this = 'open', val = open)
_high  = kv(this = 'high', val = high)
_low   = kv(this = 'low', val = low)
_close = kv(this = 'close', val = close)

Once you have your kv objects created, store them in an array. We will use this array on later examples when we initiate our data2d object.

Store kv objects in array

_kvs_ = array.from(_open, _high, _low, _close)

Exploring Data Types

One of the key strengths of the data2d data structure is its versatility in handling various data types. It provides the capability to store six different data types, and there is no restriction on selecting just one type at a time. Instead, you can combine multiple data types within a single data2d object. The supported data types for data2d are as follows:

  1. string: Represents string values.
  2. float: Represents floating-point numbers (decimals).
  3. int: Represents integers (whole numbers).
  4. bool: Represents boolean values (true or false).
  5. color: Represents color values.
  6. timestamp: Represents Unix-timestamp in milliseconds. Although timestamps are internally built using the int data type, data2d creates a clear distinction between integers and timestamps.

Let's explore some examples and variations that demonstrate working with multiple data types in data2d:

Multiple data type examples

string1 = kv('string1', 'Apple').alt('aapl')

Once you have created your kv objects, you can store them in an array. Since the kv objects handle the association of keys with their respective values, the data type of the underlying values is not an issue for Pine Script. For example, let's use the kv objects from the mixed types example above:

Store kv objects in array

_kvs_ = array.from(string1, float1, int1, bool1, color1, time1)

Create Data2d Object

To instantiate a data2d object, you will need to pass an array of kv objects to the recommended data2d() function. This function ensures that all keys are unique and performs essential internal functions to create the data2d object efficiently. The data2d() function accepts five parameters:

  • kvs: An array of kv objects containing key-value pairs. These pairs will form the basis of the data2d object.
  • sort: An optional boolean flag that indicates whether the data2d object should be sorted. If set to true, the data will be sorted; otherwise, it will retain its original order. Data2d containing mixed types cannot be sorted.
  • asc: An optional boolean flag that specifies the sorting order. When set to true, the data will be sorted in ascending order; when set to false, it will be sorted in descending order. This parameter is effective only when sort is set to true.
  • change: An optional boolean flag used in the context of sorting within the data2d object. When set to true, it indicates that the sorting should be based on the change percentage values. These change percentages are calculated using the main and alternate values. It's important to note that this functionality only works when alternate values are available.
  • format: An optional parameter that sets the global format for the entire data2d object. This format will be applied to all the values within the object. Individual keys with custom format will be ignored.
  • timezone: An optional parameter that specifies the timezone used for any timestamp related values within the data2d object. By default, it uses the chart's timezone.

Let's explore some examples and variations of creating a data2d object using the data2d() method:

Creating data2d object

d2d = data2d(
  kvs = _kvs_, // .................. Required. An array of kv objects.
  sort = true, // .................. Optional. Sort the data2d object.
  asc = false, // .................. Optional. False implies descending order.
  change = true, // ................ Optional. True implies sorting based on change percentages.
  format = '{0,number,currency}', // Optional. Use this format as default fallback.
  timezone = 'GMT+2') // ........... Optional. Use this timezone as default fallback.

Extended Array Functions

The data2d object extends some of the built-in array functions, providing convenient and familiar array manipulations directly within the data2d object. Here are the extended methods:

  • includes(): Use this method to search for a specific value within the data2d object. This method returns a boolean value indicating whether the searching value is present in any of the key-value pairs.
  • set(): This method allows you to modify an existing value in the data2d object. When using this method, the data type of the new value must match the data type of the original value associated with the specified key. Re-sorting of data will be triggered if data is sorted.
  • push(): This method is used to insert a new key and value pair at the end of the data2d object. Re-sorting of data will be triggered if data is sorted.
  • remove(): Use this method to remove a key and its associated value from the data2d object. You can also use this method to simply remove the alternate value. Re-sorting of data will be triggered if data is sorted.
  • sort(): Use this method to sort the data2d object.
  • format(): Use this method to set the default format for the data2d object. You can also use this method with kv objects to set custom formats for any key-value pair.

Extended functions

d2d.includes(123.45) // ........... Check within main values. Returns bool.
d2d.includes(123.45, alt = true) // Check within alternate values. Returns bool.

Fetch Keys

To obtain all the keys stored within the data2d object, you can use the keys() method. This method returns a
string-array containing all the keys, and it preserves the sort order if the data2d object is sorted.

Get Keys

d2d.keys() // returns a string array of all keys. Maintains sort order when sort is true.

Fetch all values

To retrieve the values from a data2d object, there are multiple methods available depending on your specific needs. If you only intend to display the data, you can use the values() method, which converts all values into strings, formats them if applicable, and returns them as a string-array.

However, if you require the original data type of the values, you should use the corresponding data type methods available for data2d. The available data type methods are as follows:

Please note that if the data2d object stores multiple types of data, calling any of these data type methods will only return values that match the specified data type, and na for the remaining types. All methods maintain the sort order if the object is sorted.

Get values

// ............................... For display purpose:
d2d.values() // .................. Returns string-array of main values.
d2d.values(alt = true) // ........ Returns string-array of alternate values.

// ............................... String:
d2d.stringValues() // ............ Returns string-array of main values.
d2d.stringValues(alt = true) // .. Returns string-array of alternate values.

// ............................... Float:
d2d.floatValues() // ............. Returns float-array of main values.
d2d.floatValues(alt = true) // ... Returns float-array of alternate values.


// ............................... Integer:
d2d.intValues() // ............... Returns int-array of main values.
d2d.intValues(alt = true) // ..... Returns int-array of alternate values.

// ............................... Boolean:
d2d.boolValues() // .............. Returns bool-array of main values.
d2d.boolValues(alt = true) // .... Returns bool-array of alternate values.

// ............................... Color:
d2d.colorValues() //  ............ Returns color-array of main values.
d2d.colorValues(alt = true) // ... Returns color-array of alternate values.

// ............................... Timestamp:
d2d.timestampValues() // ......... Returns int-array of main timestamp values.
d2d.timestampValues(alt = true) // Returns int-array of alternate timestamp values.

Fetch Single Value

To retrieve the value for a specific key from a data2d object, there are multiple methods available depending on your specific needs. If you only intend to display the value, you can use the get() method, which converts the data into a string, formats it if applicable and returns it.

However, if you require the original data type of the value, you should use the corresponding data type methods available for data2d. The available data type methods are as follows:

  • get(): Returns the value for the specified key as a string, formatted if applicable.
  • getString(): Returns the value for the specified key as a string.
  • getFloat(): Returns the value for the specified key as a float.
  • getInt(): Returns the value for the specified key as an integer
  • getBool(): Returns the value for the specified key as a boolean.
  • getColor(): Returns the value for the specified key as a color.
  • getTimestamp(): Returns the value for the specified key as a timestamp.

Please note that if the key you are requesting does not match the data type of the corresponding method, the method will return na, indicating that the requested data type is not available for the specified key.

Get value

// .......................................... For display purpose:
d2d.get(key = 'open') // .................... Returns main string value for key 'open'.
d2d.get(key = 'open', alt = true) // ........ Returns alternate string value for key 'open'.

// .......................................... String:
d2d.getString(key = 'open') // .............. Returns main string value for key 'open'.
d2d.getString(key = 'open', alt = true) // .. Returns alternate string value for key 'open'.

// .......................................... Float:
d2d.getFloat(key = 'open') // ............... Returns main float value for key 'open'.
d2d.getFloat(key = 'open', alt = true) // ... Returns alternate float value for key 'open'.

// .......................................... Integer:
d2d.getInt(key = 'open') // ................. Returns main integer value for key 'open'.
d2d.getInt(key = 'open', alt = true) // ..... Returns alternate integer value for key 'open'.

// .......................................... Boolean:
d2d.getBool(key = 'open') // ................ Returns main boolean value for key 'open'.
d2d.getBool(key = 'open', alt = true) // .... Returns alternate boolean value for key 'open'.

// .......................................... Color:
d2d.getColor(key = 'open') // ............... Returns main color value for key 'open'.
d2d.getColor(key = 'open', alt = true) // ... Returns alternate color value for key 'open'.

// .......................................... Timestamp:
d2d.getTimestamp(key = 'open') // ........... Returns main timestamp value for key 'open'.
d2d.getTimestamp(key = 'open', alt = true) // Returns alternate timestamp value for key 'open'.

Comparison

The power of alternate values becomes evident with the inclusion of built-in comparison methods in the data2d object. These methods enable effortless comparisons of each main value with its corresponding alternate value. All comparison methods maintain sorting order if applicable. By default, the methods return comparison for all keys. However, you can easily compare a single key data by specifying the key parameter. The following comparison methods are available:

  • et(): This method checks for equality, and the comparison operator used is main == alt.
  • gt(): This method checks for greater than, and the comparison operator used is main > alt.
  • gte(): This method checks for greater than or equal to, and the comparison operator used is main ≥ alt.
  • lt(): This method checks for less than, and the comparison operator used is main < alt.
  • lte(): This method checks for less than or equal to, and the comparison operator used is main ≤ alt.
  • change(): This method returns the difference between the main and the alternate value(s) by subtracting the alternate value from the main value. Additionally, you can request to return the percentage change by using the percent = true parameter.
  • changeF(): This method is identical to change() but returns the formatted value. You can provide a custom format as well.
  • timestampChange(): Similar to the changeF() method, timestampChange() targets only timestamp values. It enables you to compare the main vs. alternate timestamp values and return their time difference in segmented times, such as years, months, days, hours, minutes, and seconds as a formatted string.

Main vs alternate

// ..................... Check 'equality': main == alt. (preserves sort order)
d2d.et() // ............ Runs comparison for all keys. Returns a boolean array.
d2d.et(key = 'open') //  Runs comparison for a single key. Returns a boolean value.

// ..................... Check 'greater than': main > alt. (preserves sort order)
d2d.gt() // ............ Runs comparison for all keys. Returns a boolean array.
d2d.gt(key = 'open') //  Runs comparison for a single key. Returns a boolean value.

// ..................... Check 'greater than or equal to': main ≥ alt. (preserves sort order)
d2d.gte() // ........... Runs comparison for all keys. Returns a boolean array.
d2d.gte(key = 'open') // Runs comparison for a single key. Returns a boolean value.

// ..................... Check 'less than': main < alt. (preserves sort order.)
d2d.lt() // ............ Runs comparison for all keys. Returns a boolean array.
d2d.lt(key = 'open') //  Runs comparison for a single key. Returns a boolean value.

// ..................... Check 'less than or equal to': main ≤ alt. (preserves sort order)
d2d.lte() // ........... Runs comparison for all keys. Returns a boolean array.
d2d.lte(key = 'open') // Runs comparison for a single key. Returns a boolean value.

Print

You can now easily print any data2d object, directly on your chart, using the print() method from the tools library.

Print

// Replace the N with latest version number.
// import faiyaz7283/tools/N as tools

if barstate.islast
  printer = tools._printer.new()

  // Pass any data2d object.
  printer.print(d2d_obj) // Displays the objects keys and values.