Saving and Loading Charts
Table of contents
- Overview
- Saving of chart layouts and study templates
- Predefined REST API
- API handlers
- Low-level API
- Additional use cases
Overview
From this article you will know how to save users' chart layouts and study templates, and restore them when users get back.
What is a chart layout
A chart layout is a group of charts (in Trading Terminal) or a single chart (in Advanced Charts). Chart layout content includes drawings, indicators and chart settings like colors, styles etc.
What is a study template
A study template is a set of applied indicators and their settings (inputs and styles).
By design, all settings are saved except for Precision
; for most indicators the optimal precision depends on the precision of the symbol and it's inherited from the symbol.
Therefore it does not make sense to save a setting that might not be relevant depending on the symbol it's used on.
What is a chart template
A chart template is a set of colors used for the main series. For example candle up/down colors, wick colors, line color, background colors, etc.
Saving of chart layouts and study templates
Usually, if your use cases assume the use of drawings, you'll need to think about storing users' chart layouts. Enabling study templates on the chart requires implementing a storage. It is recommended to store chart layouts on a server, unless you want the users to have the only one chart layout. In the case of one possible chart layout you can consider using LocalStorage. Otherwise, you shouldn't use LocalStorage, because its size is limited.
To simplify development of a storage for chart layouts and study templates, the library includes 3 layers:
- Predefined REST API and a sample server-side storage in case you want to save chart layouts and study templates on a server and you don't have a general purpose storage that can be used for this
- API handlers allows you to add custom processing of save/load commands coming from GUI
- Low-level API to get/set current chart layout / study templates content
Predefined REST API
The library supports a predefined REST API to save chart layouts and study templates (but not chart templates) on your server. It sends requests in a certain format that is described below. We provide an example of server-side storage that is a good point to start from.
Example of a storage
We created a tiny storage sample with Python and PostgreSQL that can be found in our GitHub. You can use it and run on your own server so that you'll be able to have control over all your users' saved data.
Here are a few steps for those who want to have their own chart storage:
- Clone our repository to your host
- Run the data service or use our demo service. Here is a short to-do list for anyone who is not familiar with Django.
- Install Python 3.x and Pip.
- Install PostgreSQL or some other Django-friendly database engine.
- Go to you chart storage folder and run
pip install -r requirements.txt
- Go to charting_library_charts folder and set up your database connection in settings.py (see
DATABASES
@ line #12). Please remember to create the appropriate database in your PostgreSQL. - Run
python manage.py migrate
. This will create the database schema without any data. - Run
python manage.py runserver
to run a TEST instance of your database. Don't use the command above in the production environment. Use some other program (i.e., Gunicorn).
- Set up your page: set
charts_storage_url = url-of-your-charts-storage
, also setclient_id
anduser_id
(see details below) in the widget constructor. - Enjoy!
Remark: Manual database filling/editing is not the intended usage. Please avoid doing this as you may hurt the Django infrastructure.
Remark: This example doesn't support an authorization so we do not recommend to use it without adding this layout of security in production.
Developing your own backend
If you decided to develop your own storage that accepts predefined REST API requests, here is the description of the end-points that you'll need to implement.
- The library sends HTTP/HTTPS commands to
charts_storage_url/charts_storage_api_version/charts?client=client_id&user=user_id
for charts andcharts_storage_url/charts_storage_api_version/study_templates?client=client_id&user=user_id
for study templates.charts_storage_url
,charts_storage_api_version
,client_id
anduser_id
are the arguments of the widget constructor. - You should implement the processing of 4 requests: save / load / delete / list.
LIST CHARTS
GET REQUEST: charts_storage_url/charts_storage_api_version/charts?client=client_id&user=user_id
RESPONSE: JSON Object
status
:ok
orerror
data
: Array of Objectstimestamp
: UNIX time when the chart was saved (example,1449084321
)symbol
: base symbol of the chart (example,AA
)resolution
: resolution of the chart (example,1D
)id
: unique integer identifier of the chart (example,9163
)name
: chart name (example,Test
)
SAVE CHART
POST REQUEST: charts_storage_url/charts_storage_api_version/charts?client=client_id&user=user_id
name
: name of the chartcontent
: content of the chartsymbol
: chart symbol (example,AA
)resolution
: chart resolution (example,1D
)
RESPONSE: JSON Object
status
:ok
orerror
id
: unique string identifier of the chart (example,9163
)
SAVE AS CHART
POST REQUEST: charts_storage_url/charts_storage_api_version/charts?client=client_id&user=user_id&chart=chart_id
name
: name of the chartcontent
: content of the chartsymbol
: chart symbol (example,AA
)resolution
: chart resolution (example,1D
)
RESPONSE: JSON Object
status
:ok
orerror
LOAD CHART
GET REQUEST: charts_storage_url/charts_storage_api_version/charts?client=client_id&user=user_id&chart=chart_id
RESPONSE: JSON Object
status
:ok
orerror
data
: Objectcontent
: saved content of the charttimestamp
: UNIX time when the chart was saved (example,1449084321
)id
: unique integer identifier of the chart (example,9163
)name
: name of the chart
DELETE CHART
DELETE REQUEST: charts_storage_url/charts_storage_api_version/charts?client=client_id&user=user_id&chart=chart_id
RESPONSE: JSON Object
status
:ok
orerror
LIST STUDY TEMPLATES
GET REQUEST: charts_storage_url/charts_storage_api_version/study_templates?client=client_id&user=user_id
RESPONSE: JSON Object
status
:ok
orerror
data
: Array of Objectsname
: template name (example,Test
)
SAVE STUDY TEMPLATE
POST REQUEST: charts_storage_url/charts_storage_api_version/study_templates?client=client_id&user=user_id
name
: name of the templatecontent
: content of the template
RESPONSE: JSON Object
status
:ok
orerror
LOAD STUDY TEMPLATE
GET REQUEST: charts_storage_url/charts_storage_api_version/study_templates?client=client_id&user=user_id&chart=chart_id&template=name
name
: name of the template
RESPONSE: JSON Object
status
:ok
orerror
data
: Objectname
: name of the templatecontent
: saved content of the template
DELETE STUDY TEMPLATES
DELETE REQUEST: charts_storage_url/charts_storage_api_version/study_templates?client=client_id&user=user_id&template=name
name
: name of the template
RESPONSE: JSON Object
status
:ok
orerror
Using Demo Charts and Study Templates Storage
We're running a demo chart storage service to let you save/load charts as soon as you build your application. Here is the link http://saveload.tradingview.com. Note that it's provided as-is since it's a demo.
We do not guarantee its stability. Also, note that we delete the data in the storage on a regular basis.
Managing Access to Saved Charts
You are responsible for the charts that your users are able to see and load.
A user can see/load charts that have the same client_id
and user_id
that the user has.
client_id
is an identifier of the user's group.
The intended use is when you have a few groups of users or when you have a few sites that use the same chart storage.
So the common practice is to set client_id = your-site's-URL
. It's up to you to decide.
user_id
is a unique identifier of a user. Users ID belongs to a particular client_id
group.
You can either set it for each user individually (private storage for each user) or set it for all users or user groups (public storage).
Here are a few examples:
client_id | user_id | Effect |
---|---|---|
Your site URL or other link | Unique user ID | Each user has a private chart storage that other users can't see. |
Your site URL or other link | The same value for all users | Each user can see and load any saved chart. |
Your site URL or other link | Unique user ID for registered users along with a separate setting for anonymous users | Each registered user has a private chart storage that other users can't see. All anonymous users share a single storage. |
API handlers
Prefer using the API handlers if you have your own back-end service that you can use for storing chart layouts and study templates. save_load_adapter is an object containing the save/load API handlers. Using of the API handlers prevents the library from sending the REST requests. These functions are called by the library when users click on save/load UI elements.
In-memory save/load adapter example
You can use this in-memory example for testing purposes.
Low-level API
Content of charts and study templates can be directly accessed using widget's save() / load() methods and createStudyTemplate() / applyStudyTemplate() methods.
You are able to save the JSONs where you wish. For example, you may embed them to your saved pages or user's working area etc.
Commonly you might want to hide the save/load GUI elements if you use the Low-level API. You can disable header_saveload featureset to hide the save/load GUI elements from the header toolbar.
Additional use cases
Saving charts automatically
You might want to automatically save chart layouts. Here are the steps to implement it:
- Set a threshold delay in seconds that is used to reduce the number of onAutoSaveNeeded calls.
- Subscribe to onAutoSaveNeeded.
- Call the saveChartToServer method.
Restoring last saved chart
Usually users open an empty chart and load their chart layouts using the "Load Chart Layout..." dialog. But you may want to open the last saved chart layout on start. If you use the Low-level API, you can set the chart layout content to the saved_data field in the widget constructor. Otherwise, it is enough to assign true
to the load_last_chart field.