Trade From Chart

Introduction

The Trade From Chart (TFC) module enables chart users to place trades directly from their charts. Users manipulate graphical tools with their mouse or, on touch devices, their fingers. Tools are available for placing market orders, limit and stop orders, and multi-leg orders. Unlike traditional ticket‑based online trading, TFC enables users to set price levels graphically and interactively in the context of the security — a quicker and more natural approach to trading.

The Trade from Chart plug-in is supported on multiple charts on the same web page. The plug-in is included in the sample-template-multi-charts.html template to create a ready-made, multiple-chart trading application.

Note: This module runs as a plug-in to the technical-analysis-chart.html, sample-template-multi-charts.html, and sample-template-active-trader.html templates, not as a stand-alone module.

Implementation

To enable the TFC plug-in, include the following import statement in your applications:

import "./plugins/tfc/tfc-loader.js"

You must also provide a custom CIQ.Account for the plug-in. The tfc-demo.js file in the plugins/tfc folder creates a sample custom account, CIQ.Account.Demo. You can include the demo account in your applications by importing tfc-demo.js as follows:

import "./plugins/tfc/tfc-demo.js";

Templates

Uncomment the following lines in technical-analysis-chart.html and sample-template-multi-charts.html to enable the Trade From Chart plug-in along with the sample account:

//import "./plugins/tfc/tfc-loader.js";
//import "./plugins/tfc/tfc-demo.js"; /* if using demo account class */

sample-template-active-trader.html

The sample-template-active-trader.html template takes care of everything for you. The template implements the Trade from Chart plug‑in by default; and so, includes the following statement:

import "./plugins/tfc/tfc-demo.js";

The TFC plug-in is loaded in the activetrader.js file (in the plugins/activetrader folder) by the following import:

import "../../plugins/tfc/tfc-loader.js";

Configuration

Add your own custom CIQ.Account by setting the account as the value of the account property of the tfc plug‑in referenced by the configuration object returned from defaultConfiguration.js, for example:

import "./plugins/tfc/tfc-loader.js";
import getDefaultConfig from "./js/defaultConfiguration.js";

const config = getDefaultConfig({
	markerSample: marker.MarkersSample,
	scrollStyle: PerfectScrollbar,
	quoteFeed: quotefeed,
	forecastQuoteFeed: forecastfeed
});

config.plugins.tfc.account = YourCustomCIQAccount; // Can also be a reference to a constructor that creates a custom account.

Multi-chart support

The Trade From Chart (TFC) plug-in works on multiple charts displayed on the same web page. The CIQ.Account#getPoller function returns a poller that synchronizes account positions, account value, and open orders on all TFC instances on the page.

The CIQ.Account constructor function assigns the return value of getPoller to the Poller property of CIQ.Account instances. Because CIQ.Account provides the prototype object of derived custom account objects, you can reference the poller returned by getPoller as follows:

CIQ.Account.MyAccount.prototype.Poller.intervals = {...};

User interface

  • Market Order Widget - This widget provides a quick interface for users to enter market orders. A "buy" and "sell" button are available. This widget can be repositioned vertically by the user by grabbing and dragging it.

  • Buy/Sell/Short/Cover - This is the same widget in different configurations. Buy/Short will be available options if the user has no position in the security. If the user has a position then either Short/Cover or Sell/Buy will be available options, each of which will either increase or decrease the user's current position. Users drag the widget vertically to indicate the desired price to initiate the order. They may optionally add stop loss and/or take profit protections and position these graphically as well.

  • Spreads/Straddles/Brackets - These widgets automatically provide upper and lower bounds that the user can manipulate for creating these trading strategies.

    • Spread - A user can catch a momentum breakout in either direction.
    • Straddle - A user can catch sideways bounces off of support and resistance.
    • Bracket - A user can set "stop loss"/"take profit" levels on an existing open position

Open orders will appear on the screen as small arrows. These can be clicked or tapped to expose a cancel/modify dialog. Users can cancel an order simply by clicking the "cancel" button. They can modify the order simply by moving the graphical elements to new price levels.

Note: Many of these dependent order types require the availability of One Triggers the Other (OTO) and One Cancels the Other (OCO) order types in your firm's order management system (OMS). If your OMS cannot support OTO or OCO orders, you can disable these order types with a simple configuration setting. See the Account configuration section below.

Integration

To integrate TFC into your back end you should create a new class that is derived from the CIQ.Account base object (found in tfc.js).

The tfc-demo.js file contains a 'Demo' instance of the CIQ.Account object called CIQ.Account.Demo. This demo object provides an example of a derived class that can be used as reference but should not be completely copied as it fictionally emulates order executions and automatically updates and open orders locally instead of taking new information from the back office.

You should derive your own class with interfaces to your server for the following functions:

Each time the TFC side-bar is opened, a new account is enabled, the positions view is changed, an order is placed, an order is cancelled, or the chart symbol is changed, CIQ.TFC#updateData will be called to refresh the account information on the screen.

Note that the default implementation will also pull data by calling all the fetch*(cb) methods using CIQ.Account#Poller. But this can be easily be modified to a pushing/streaming method if needed.

To do this:

  • Have the fetch function only call the cb() method as follows:
CIQ.Account.Demo.prototype.fetchOpenOrders = function(cb){
	cb();
};
  • Load your data into he pertinent object and update the screen as follows:
stxx.tfc.account.openOrders = //your open orders updated object here;
stxx.tfc.​updateData(); //force the data to display

Accounts can be enabled by calling CIQ.TFC#enableAccount, which is automatically done when the TFC widget is constructed.

See CIQ.TFC and CIQ.Account for more details.

The following is a simple example of the required data format for the TFC Account object:

this.currency = "USD";
this.balances = {
	liquidity: 100000,
	unsettledCash: 0,
	cash: 100000,
	profitLoss: 0,
	buyingPower: 200000
};

this.positions = {
	IBM: { quantity: 1000, basis: 126.13, price: 129.13, prevClose: 123.13, currency: "USD" },
	GE: { quantity: 100, basis: 26.11, price: 24.11, prevClose: 26.11, currency: "USD" },
	SPY: { quantity: -1000, basis: 187.11, price: 187.11, prevClose: 190.11, currency: "USD" },
	MSFT: { quantity: -100, basis: 230, price: 186, prevClose: 240, currency: "USD" }
};

this.openOrders = {
	IBM: [
		{ id: "1", action: "sell", quantity: 500, limit: 197, tif: "GTC", currency: "USD" },
		{ id: "2", action: "sell", quantity: 500, limit: 196, tif: "GTC", currency: "USD" }
	],
	TSLA: [{ id: "3", action: "buy", quantity: 10, limit: 170, tif: "DAY", currency: "USD" }],
	GE: [
		{
			id: "4",
			action: "sell",
			quantity: 100,
			limit: 30,
			tif: "GTC",
			currency: "USD",
			oco: "5"
		},
		{ id: "5", action: "sell", quantity: 100, stop: 25, tif: "GTC", currency: "USD", oco: "4" }
	],
	MSFT: [
		{
			id: "6",
			action: "buy",
			quantity: 100,
			limit: 112,
			tif: "DAY",
			currency: "USD",
			oto: [
				{
					id: "7",
					action: "sell",
					quantity: 100,
					limit: 130,
					tif: "GTC",
					currency: "USD",
					oco: "8"
				},
				{
					id: "8",
					action: "sell",
					quantity: 100,
					stop: 110,
					tif: "GTC",
					currency: "USD",
					oco: "7"
				}
			]
		}
	]
};

this.config = {
	oto: true,
	oco: true,
	disableModifyOrderQuantity: false
};

The following is an example of a fully functional balance fetch request using Ajax/JSON. Similar code can be derived to fetch all other Account components and place orders.

CIQ.Account.YourFeed.prototype.fetchBalances = function(cb) {
	// make your server call here and in the request callback set balances and call cb();
	var self = this;
	CIQ.postAjax("https://jsfiddle.chartiq.com/sample_tfc_balances.js", null, function(
		status,
		myserverResponseData
	) {
		if (status != 200) {
			// something went wrong
			cb();
			return;
		}
		self.balances = JSON.parse(myserverResponseData);
		cb();
	});
};

Once your Account class is created and all fetching and order placing functions are fully functional, the TFC object should be constructed and associated with an CIQ.ChartEngine (stx) object. It should also be passed your Account class which can be used for querying and placing orders. The TFC object creates and manages a number of DOM elements which are located in tfc.html.

First, include the TFC loader in your template (as it is in sample-template-advanced.html):

<script src="plugins/tfc/tfc-loader.js"></script>

Then create your TFC object:

//set account value to your custom account class, or leave as null to automatically load the Demo class (CIQ.Account.Demo)
new CIQ.TFC({ stx: stxx, account: CIQ.Account.MyFeed, context: UIContext });

TFC will request updated information whenever the stock symbol is changed on the chart. It is not necessary to filter for that security. Simply pass all of the information related to that account.

When placing an order, your class should wait for a response from your server and then update open orders, balances and positions. After doing so it should then call the callback function that was passed in so that TFC knows to update the graphical elements on the screen.

Customization

Trade from the Chart graphical components are plain HTML. As such, they can be modified as desired. The JavaScript code for TFC references these objects by class name and expects the components to exist; however, it makes no restriction on how they look. You can apply CSS selectors to override color or layout. You can also add or remove HTML componentry. For instance, if you require a disclaimer, simply add the disclaimer text to the HTML components.

Account configuration

CIQ.Account.Config is an object that defines the behavior of TFC. You can turn off OTO orders by setting config.oto=false in your CIQ.Account derived class. Likewise, set config.oco=false to disable OCO related functionality.

CIQ.Account.Demo = function() {
    this.currency = "EUR";
    this.config = {
        oto: false,
        oco: false,
        closeAll: true,
        tradeActions: true,
        vsp: "M"
    }
};

Tradability

Additional trading entitlements can be defined by modifying the CIQ.Account.Tradability function as needed.

The available flags are as:

  • tradable: true/false -- to enable or disable trading for the current symbol
  • shortable: true/false -- to enable or disable short trades for the current symbol
  • marketable: true/false -- to enable or disable market order for the current symbol

Localization will not translate the currency sign used to display money amounts, as this is not dependent on the location, but rather the currency of your data. All currencies are printed using the STX#money method, which can changed as needed based on the currency used at your back office.

Including additional js files

The TFC plug-in is dynamically loaded. If you wish to load additional custom JavaScript files to support TFC, you must load them before creating the TFC instance.

The best place to do this is by including the script files right after importing tfc-loader.js.

Programmatically opening and closing the side panel

Open:

document.querySelector("cq-side-panel").open({ className: "active", selector: ".stx-trade-panel" });

Close:

document.querySelector("cq-side-panel").close();

FAQ

Q: Does the TFC module support multiple portfolios ?

A: Yes. You can create a menu that switches between accounts as needed; either to support brokers that work with many accounts or single users that have many portfolios. As the user selects a new account from the drop down, you will create an CIQ.Account object and associate it with the chart as outlined in the 'Integration' section above . Note that only one account can be active for trading at any given time.

Q: Can the trading widget be forced to 'snap' to preset price intervals as it moves up and down the y axis?

A: Yes. By setting CIQ.ChartEngine.YAxis#minimumPriceTick, you can force the widget so skip certain price values and instead 'snap' to your desired intervals. This will guarantee that an order is only placed at the allowed price intervals for the security in question.

Q: Is there an interface for trading FOREX?

A: Yes. See the following tutorial: Trade From Chart - FOREX


Next Steps: