AI Ready Charts
Disclaimer
This tutorial assumes a moderate familiarity with AI models, such as OpenAI's GPT, Google's Gemini, and Anthropic's Claude. Understanding the limitations and variations of the language model you choose is crucial, as some models offer more accurate or relevant results than others.
To achieve the best outcomes, it's essential to experiment with different models, their configurations, and your prompting. For example, GPT-4o has significantly more inherent knowledge than GPT-4o-mini, which means that a prompt for GPT-4o-mini will require more domain-specific knowledge. We recommend starting with a more complex model during early development to gain a clear understanding of its capabilities, and then experimenting with smaller, faster models to find the optimal balance of speed and efficiency for your project.
The way you format your prompt is crucial, as it influences how the language model interprets the input and responds. It is recommended to consult the documentation of the AI model you are using to implement your AI Ready features.
A sample prompt is included at the bottom of this tutorial.
Introduction
ChartIQ v9.7.0 introduces the executor
function, enabling developers to leverage AI capabilities to transform how users interact with and analyze their data. This function allows AI to drive the chart by passing command line interface commands from outside the CLI Plugin, giving AI the ability to change the chart type, adjust the periodicity or range, add a study, add a series, reset the chart, and more.
Getting Started
This tutorial will guide you through the basic steps of setting up your executor
function to accept input from a custom UI, such as an AI-powered chat agent.
For this tutorial, we'll be working with sample-template-basic.html
.
Note: sample-template-basic.html
is located within examples/templates
and must be copied to the root directory for the import references to work.
Create A Reference
Ensure that the CLI plugin has been imported.
Then, create a reference to it.
import "./plugins/cli/cli.js";
const aiReady = document.querySelector("cq-cli");
Create Your Environment
This step is necessary if you are implementing a custom UI that will capture your natural language input, display any output, or both.
If you do not provide an environment, your executor can still function, but there will be no UI to display the responses returned. In other words, if your AI response is configured correctly, the chart will still be manipulated, but the responses will not be visible.
Modify existing HTML
- Add a style attribute to
cq-context
and set its width to 75%. - Create the side panel and include a basic input field and submit button.
- This is an example of where the end user might enter their natural language input for processing by the AI model.
<body>
<cq-context style="width: 75%;"><cq-chart-instructions></cq-chart-instructions>
<!-- Template Specific HTML -->
</cq-context>
<div id="sidePanel" style="width: 25%; position: fixed; right: 0;">
<form id="aiInputForm">
<input id="aiInputField" type="text" placeholder="Enter your command">
<button type="submit">Submit</button>
</form>
</div>
Override CLI methods
To interact with our newly created UI, we need to override the echo
method from the aiReady
reference. This is necessary because the executor
function is bound to the CLI plugin and utilizes its echo
and log
methods by default. By overriding the echo
method, we can control how we display any command output.
-
Create a function to process text returned after running a command: In this example, we define the
sidePanelEcho
function, which creates adiv
, sets itsinnerText
to the command's output, and appends it to the side panel. Note: Not all commands return text. -
Create a
sidePanelEnv
: This is an object that will hold the overridden methods and will be added to ouraiReady
reference when creating theexecutor
in the next step. -
Override the
aiReady
echo method: Now, we assign our newly createdsidePanelEcho
method to theecho
property of thesidePanelEnv
object, effectively replacing the originalecho
method with our custom implementation.
function sidePanelEcho(text) {
const node = document.createElement("div");
node.innerText = text;
document.getElementById("sidePanel").appendChild(node);
}
const sidePanelEnv = {}; // Define an object to hold overridden methods that will be added as prototypes to the CLI reference
// Override the `echo` method of CLI
sidePanelEnv.echo = sidePanelEcho;
Creating your executor
Finally, we will create our executor by calling the aiReady
reference's getExecutor
method. This method takes the 'environment' we created and modified in the previous step, along with the registry
object, as arguments. You only need to include the registry
object in getExecutor
if you are adding custom commands to the registry
from within your template.
Note: A passed registry will replace the built-in registry, so it's best to extend or modify the existing registry when adding custom commands.
Example:
import { registry } from "./plugins/cli/registry.js";
// ...
// ...
const updatedRegistry = { ...registry };
updatedRegistry.myCustomCommand = {
func: function () {
// ...
// ...
}
}
const executor = aiReady.getExecutor(sidePanelEnv, updatedRegistry); // Create executor with your modified registry object
As mentioned previously, if you are not utilizing a custom UI and methods, you do not need to provide the environment we created in the previous step and can simply call getExecutor()
without any arguments.
const executor = aiReady.getExecutor(sidePanelEnv); // Create executor
Using the executor
With the executor defined, we can now pass commands using the executor
method. Please refer to the CLI Tutorial for available commands and proper syntax.
This example utilizes the simple input we created in the earlier step to pass the value of the input to the executor.
// Add a submit event listener to the off-chart form
document.getElementById("aiInputForm").addEventListener("submit", (event) => {
// Prevent the default form submission behavior
event.preventDefault();
// Get the input value and pass it to the executor function
const inputValue = document.getElementById("aiInputField").value;
executor(inputValue);
// Reset the form after submission
document.getElementById("aiInputForm").reset();
});
Using the executor with AI
Important: There are several nuanced steps involved in passing input to your AI and processing its response, which is why they are not included in this tutorial. Instead, use it as a starting point to configure your executor
and prepare it to accept AI responses.
The UI we just built accepts valid CLI commands, such as type Line
, prompting the chart to respond as if the command were entered directly into the CLI plugin's UI.
With AI, we can expand on this by executing commands generated from natural language input.
For example, a very simple prompt might look like this:
To display a specific chart type, write the following:
"type <chartType>"
Replace <chartType> with one of the following: Candle, Line, Mountain, Step, Histogram.
A user can type the message "Show me a histogram chart," and the model will respond with the command type Histogram
, which you then pass into the executor
.
We recommend limiting your model to JSON output for reliable responses.
Sample Prompt
Below is a sample prompt that was used in development of our AI Ready features and should serve as a good jumping off point for your own ChartIQ AI Ready implementations.
With a properly configured prompt, the AI model will generate a command based off of the user's natural language input, and return a JSON object containing the desired command and a message.
Here are a few things to note that are crucial for creating your own prompt:
-
Provide Context: Our prompt begins by explaining what ChartIQ is and its visual layout, establishing a clear understanding of the user and defining the role for the AI model.
-
Be Specific: The prompt provides a list of commands to the AI model, ensuring it knows the appropriate syntax to respond with. This is critical because, without the correct syntax, the
executor
cannot process the response. The prompt also instructs the model on how to reply to user requests. -
Structure the Response: Specify that the response should be in JSON format, detailing the structure. This allows for easy integration with the
executor
function. -
This is only an example: Your prompt should be specific to your charting application, its features, and the terminology your users will use.
You are in control of a charting program called "ChartIQ". ChartIQ is a time-series chart used to visualize financial data.
A ChartIQ chart will have two axis. The X axis will indicate a span of time. The Y axis will indicate a data value, usually a price.
You will receive a request from the user.
You will receive a list of text commands that control the chart.
You will read the user's request and determine which of the text commands best matches the user's request.
Your response will be in the form of a json object with the following structure:
{
"message": "A message to the user"
"cmd": [],
}
The "message" field will contain the message to be displayed to the user.
- If the user asks a question, do your best to answer the question in the message only if the question is related to the chart.
- If the message is ambiguous, respond with a helpful suggestion of how to clarify the request.
- if you do not have an answer, you can respond with "I don't have an answer to that question".
- The message should provide a narration explaining each command.
- The message should be as short as possible.
The "cmd" field will contain an array of commands that best fit the user's request.
If no command fits the user's request. You will respond with the command "unknown".
Today's date is ${today}.
List of Commands
- "type <chartType>": <chartType> must be one of the following "Line", "Step", "Mountain", "Candle", "Bar", "Histogram".
- "symbol <symbol>": The command parameter must be a valid stock symbol. If you're not sure of the stock symbol. Ask for a valid stock symbol.
- "range <start date> <end date>": <startDate> and <endDate> must be valid dates in the format "MM/DD/YYYY". To show a single day, {startDate} and {endDate} should be the same.
- "home" Scrolls the chart to the latest point in time.
- "periodicity '[period]'" Change the period or interval of time that each point on the chart represents. Valid values are "1 D", "1 W", "1 Mo", "1 Min", "5 Min", "10 Min", "15 Min", "30 Min", "1 Hour", "4 Hour", "1 Sec", "10 Sec", "30 Sec", "250 MSec"
- "polling [start|stop]" Controls live updating of data.
- "reset -f" Reset the chart to defaults and reload the page. Only use this option if you are sure you want to reload the page.
- "series [-c] [-rx] <symbol> [color]" Add or remove a series; <symbol> must me a valid stock symbol. Use the -c option to add as a comparison series, and the -r option to remove (or -x to remove all).
- "study [-l] [-rx] <study name>" Add or remove a study; <study name> must be a valid study name and wrapped in quotes. Use the -l option to list available studies, and the -r option to remove (or -x to remove all).
Additional Instructions
- When removing a study, the user must provide the name of the study, from the chart legend, in quotes. For example: "ma (50,ma,0)". If they are having trouble removing a study, remind them of this.
Study Names:
- "Anchored VWAP"
- "Median Price"
- "Momentum Indicator"
- "Moving Average"
- "Moving Average Cross"
- "Price Rate of Change"
- "Price Relative"
- "Standard Deviation"
- "True Range"
- "Volume Chart"
- "VWAP"
- "ZigZag"
Example AI Response
Using the above prompt with the following request, "Change the chart type to a line chart," the expected AI response would be something like:
{
"message": "I will change the chart type to a Line chart.",
"cmd": [
"type Line"
]
}
The values in the cmd
array would then be passed into the executor: executor("type Line")
, while the message
string can be used to provide feedback to the user.
Next Steps
To learn more about the CLI plugin, as well as how to customize or create your own commands, check out the CLI Tutorial.