Ask the indicator assistant
Sends the chat history and the current editor state to the indicator assistant and returns its answer. When the answer contains a script, source is the complete Hyperprop Script to put in the editor (declarations plus compute), with pane and name set when the assistant wants them changed. Pass error to have a failing script fixed. Requests are limited to 40 per trader per hour; the response is typically 5–30 seconds because the whole script is generated in one pass. Timeout after 120 seconds.
curl --request POST \
--url https://api.hyperprop.com/platform/v1/indicator-builder/chat \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"messages": [
{
"role": "user",
"content": "Build an RSI with 30/70 guides."
}
],
"script": {
"pane": "separate",
"source": "const length = input.int('Length', 14, { min: 2, max: 100 });\nfunction compute(bars, inputs, hp) {\n const rsi = hp.rsi(bars.map(b => b.c), length);\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\n}",
"name": "RSI"
},
"error": null
}
EOFimport requests
url = "https://api.hyperprop.com/platform/v1/indicator-builder/chat"
payload = {
"messages": [
{
"role": "user",
"content": "Build an RSI with 30/70 guides."
}
],
"script": {
"pane": "separate",
"source": "const length = input.int('Length', 14, { min: 2, max: 100 });
function compute(bars, inputs, hp) {
const rsi = hp.rsi(bars.map(b => b.c), length);
return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };
}",
"name": "RSI"
},
"error": None
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
messages: [{role: 'user', content: 'Build an RSI with 30/70 guides.'}],
script: {
pane: 'separate',
source: 'const length = input.int(\'Length\', 14, { min: 2, max: 100 });\nfunction compute(bars, inputs, hp) {\n const rsi = hp.rsi(bars.map(b => b.c), length);\n return { plots: [{ title: \'RSI\', values: rsi, color: \'#ab47bc\' }], range: { min: 0, max: 100 }, guides: [30, 70] };\n}',
name: 'RSI'
},
error: null
})
};
fetch('https://api.hyperprop.com/platform/v1/indicator-builder/chat', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.hyperprop.com/platform/v1/indicator-builder/chat",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'messages' => [
[
'role' => 'user',
'content' => 'Build an RSI with 30/70 guides.'
]
],
'script' => [
'pane' => 'separate',
'source' => 'const length = input.int(\'Length\', 14, { min: 2, max: 100 });
function compute(bars, inputs, hp) {
const rsi = hp.rsi(bars.map(b => b.c), length);
return { plots: [{ title: \'RSI\', values: rsi, color: \'#ab47bc\' }], range: { min: 0, max: 100 }, guides: [30, 70] };
}',
'name' => 'RSI'
],
'error' => null
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.hyperprop.com/platform/v1/indicator-builder/chat"
payload := strings.NewReader("{\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Build an RSI with 30/70 guides.\"\n }\n ],\n \"script\": {\n \"pane\": \"separate\",\n \"source\": \"const length = input.int('Length', 14, { min: 2, max: 100 });\\nfunction compute(bars, inputs, hp) {\\n const rsi = hp.rsi(bars.map(b => b.c), length);\\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\\n}\",\n \"name\": \"RSI\"\n },\n \"error\": null\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.hyperprop.com/platform/v1/indicator-builder/chat")
.header("Content-Type", "application/json")
.body("{\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Build an RSI with 30/70 guides.\"\n }\n ],\n \"script\": {\n \"pane\": \"separate\",\n \"source\": \"const length = input.int('Length', 14, { min: 2, max: 100 });\\nfunction compute(bars, inputs, hp) {\\n const rsi = hp.rsi(bars.map(b => b.c), length);\\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\\n}\",\n \"name\": \"RSI\"\n },\n \"error\": null\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hyperprop.com/platform/v1/indicator-builder/chat")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Build an RSI with 30/70 guides.\"\n }\n ],\n \"script\": {\n \"pane\": \"separate\",\n \"source\": \"const length = input.int('Length', 14, { min: 2, max: 100 });\\nfunction compute(bars, inputs, hp) {\\n const rsi = hp.rsi(bars.map(b => b.c), length);\\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\\n}\",\n \"name\": \"RSI\"\n },\n \"error\": null\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"message": "A 14-period RSI in its own pane with 30/70 guides.",
"source": "const length = input.int('Length', 14, { min: 2, max: 100 });\nfunction compute(bars, inputs, hp) {\n const rsi = hp.rsi(bars.map(b => b.c), length);\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\n}",
"pane": "separate",
"name": "RSI"
}
}{
"success": false,
"statusCode": 400,
"error": "Bad Request",
"message": "Validation failed",
"code": "VALIDATION_ERROR"
}{
"success": false,
"statusCode": 401,
"error": "Unauthorized",
"message": "Authentication required",
"code": "UNAUTHORIZED"
}{
"success": false,
"statusCode": 429,
"error": "Too Many Requests",
"message": "You have reached the indicator builder limit for this hour. Try again later.",
"code": "RATE_LIMITED"
}{
"success": false,
"statusCode": 502,
"error": "Error",
"message": "The indicator assistant returned an error.",
"code": "MODEL_ERROR"
}{
"success": false,
"statusCode": 503,
"error": "Error",
"message": "The indicator assistant is not configured on this server.",
"code": "MODEL_UNAVAILABLE"
}{
"success": false,
"statusCode": 504,
"error": "Error",
"message": "The indicator assistant took too long to answer. Try a simpler request.",
"code": "MODEL_TIMEOUT"
}Body
Chat history, oldest first. The last message must be from the user. Each message is capped at 24,000 characters — enough for a full Pine Script paste.
1 - 40 elementsShow child attributes
Show child attributes
[
{
"role": "user",
"content": "Build an RSI with 30/70 guides."
}
]
What is currently in the editor. The reply replaces it wholesale when it contains code.
Show child attributes
Show child attributes
Compile or runtime error the chart reported for the current script, if any.
2000null
The sample series the builder chart is showing, so the model can reason about scale and bar count.
Show child attributes
Show child attributes
Related topics
Ask the indicator assistant (streaming)Indicator assistant availabilityHyperprop Script: build indicators (agent recipe)ChangelogGet all order books (best bid/ask)curl --request POST \
--url https://api.hyperprop.com/platform/v1/indicator-builder/chat \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"messages": [
{
"role": "user",
"content": "Build an RSI with 30/70 guides."
}
],
"script": {
"pane": "separate",
"source": "const length = input.int('Length', 14, { min: 2, max: 100 });\nfunction compute(bars, inputs, hp) {\n const rsi = hp.rsi(bars.map(b => b.c), length);\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\n}",
"name": "RSI"
},
"error": null
}
EOFimport requests
url = "https://api.hyperprop.com/platform/v1/indicator-builder/chat"
payload = {
"messages": [
{
"role": "user",
"content": "Build an RSI with 30/70 guides."
}
],
"script": {
"pane": "separate",
"source": "const length = input.int('Length', 14, { min: 2, max: 100 });
function compute(bars, inputs, hp) {
const rsi = hp.rsi(bars.map(b => b.c), length);
return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };
}",
"name": "RSI"
},
"error": None
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
messages: [{role: 'user', content: 'Build an RSI with 30/70 guides.'}],
script: {
pane: 'separate',
source: 'const length = input.int(\'Length\', 14, { min: 2, max: 100 });\nfunction compute(bars, inputs, hp) {\n const rsi = hp.rsi(bars.map(b => b.c), length);\n return { plots: [{ title: \'RSI\', values: rsi, color: \'#ab47bc\' }], range: { min: 0, max: 100 }, guides: [30, 70] };\n}',
name: 'RSI'
},
error: null
})
};
fetch('https://api.hyperprop.com/platform/v1/indicator-builder/chat', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.hyperprop.com/platform/v1/indicator-builder/chat",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'messages' => [
[
'role' => 'user',
'content' => 'Build an RSI with 30/70 guides.'
]
],
'script' => [
'pane' => 'separate',
'source' => 'const length = input.int(\'Length\', 14, { min: 2, max: 100 });
function compute(bars, inputs, hp) {
const rsi = hp.rsi(bars.map(b => b.c), length);
return { plots: [{ title: \'RSI\', values: rsi, color: \'#ab47bc\' }], range: { min: 0, max: 100 }, guides: [30, 70] };
}',
'name' => 'RSI'
],
'error' => null
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.hyperprop.com/platform/v1/indicator-builder/chat"
payload := strings.NewReader("{\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Build an RSI with 30/70 guides.\"\n }\n ],\n \"script\": {\n \"pane\": \"separate\",\n \"source\": \"const length = input.int('Length', 14, { min: 2, max: 100 });\\nfunction compute(bars, inputs, hp) {\\n const rsi = hp.rsi(bars.map(b => b.c), length);\\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\\n}\",\n \"name\": \"RSI\"\n },\n \"error\": null\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.hyperprop.com/platform/v1/indicator-builder/chat")
.header("Content-Type", "application/json")
.body("{\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Build an RSI with 30/70 guides.\"\n }\n ],\n \"script\": {\n \"pane\": \"separate\",\n \"source\": \"const length = input.int('Length', 14, { min: 2, max: 100 });\\nfunction compute(bars, inputs, hp) {\\n const rsi = hp.rsi(bars.map(b => b.c), length);\\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\\n}\",\n \"name\": \"RSI\"\n },\n \"error\": null\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hyperprop.com/platform/v1/indicator-builder/chat")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Build an RSI with 30/70 guides.\"\n }\n ],\n \"script\": {\n \"pane\": \"separate\",\n \"source\": \"const length = input.int('Length', 14, { min: 2, max: 100 });\\nfunction compute(bars, inputs, hp) {\\n const rsi = hp.rsi(bars.map(b => b.c), length);\\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\\n}\",\n \"name\": \"RSI\"\n },\n \"error\": null\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"message": "A 14-period RSI in its own pane with 30/70 guides.",
"source": "const length = input.int('Length', 14, { min: 2, max: 100 });\nfunction compute(bars, inputs, hp) {\n const rsi = hp.rsi(bars.map(b => b.c), length);\n return { plots: [{ title: 'RSI', values: rsi, color: '#ab47bc' }], range: { min: 0, max: 100 }, guides: [30, 70] };\n}",
"pane": "separate",
"name": "RSI"
}
}{
"success": false,
"statusCode": 400,
"error": "Bad Request",
"message": "Validation failed",
"code": "VALIDATION_ERROR"
}{
"success": false,
"statusCode": 401,
"error": "Unauthorized",
"message": "Authentication required",
"code": "UNAUTHORIZED"
}{
"success": false,
"statusCode": 429,
"error": "Too Many Requests",
"message": "You have reached the indicator builder limit for this hour. Try again later.",
"code": "RATE_LIMITED"
}{
"success": false,
"statusCode": 502,
"error": "Error",
"message": "The indicator assistant returned an error.",
"code": "MODEL_ERROR"
}{
"success": false,
"statusCode": 503,
"error": "Error",
"message": "The indicator assistant is not configured on this server.",
"code": "MODEL_UNAVAILABLE"
}{
"success": false,
"statusCode": 504,
"error": "Error",
"message": "The indicator assistant took too long to answer. Try a simpler request.",
"code": "MODEL_TIMEOUT"
}