Write Your Own EA(Trading Robot)

This tutorial is to guide you how to write your own EA in our trading platform.

Tutorial Video

Hello everybody, today let's talk about EA.

EA is trading robot to help us analyze the data and generated the signals to help us make some decision: to trade long or short. EA is necessary to the traders recently. And because the market movement is very fast, so we need to catch up with the movement by some trading robots. EA can be run automatically, so you don't need to sit in front of your PC 24 hours. Just by using your trading robot, everything is done.

Of course our trading platform is different from other trading platform. So the EA running environment is different as well. You need to rewrite your program your EA. Maybe you would think it takes time. But I think it's worth doing. Why? Because our trading platform is the unique trading environment to provide you with some functions to allow you to sign in to several different accounts at the same time. That means you can monitor different market data at the same time. EA can be run 24 hours. You can use your EA to monitor different quotes from different brokerages or liquidity providers.

So it's worth doing. And Our running environment is based on web, so you don't need to install, you don't need to download anything. Just open our website and you can use them. It's very convenient for the beginners.

Let's start learning how to write your own EA on our trading platform. We provided several sample EAs and you can refer to the source codes and learn. By just clicking this "Doctor cap" icon on the Left sidebar, you can see a list of the EAs. They are samples. You can click the "Edit" icon to see the source code and we provided them on our document page as well. So you can check the source code there as well. And you can use Github and check our source code.

EA

If you want to run your own EA, the first thing you need to do is to register that EA to the system. By using this API(registerEA), you can register your EA into the system, make the EA visible to the system. This API includes several parameters: name, description, parameters, and 3 callback functions.

registerEA(
"<EA's Name>",
"<Description>",
[{ // parameters
	name: "period",
	value: 20,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
}],
function (context) { // Init()
	var account = getAccount(context, 0)
	var brokerName = getBrokerNameOfAccount(account)
	var accountId = getAccountIdOfAccount(account)
	var symbolName = "EUR/USD"

	getQuotes (context, brokerName, accountId, symbolName)
	window.chartHandle = getChartHandle(context, brokerName, accountId, symbolName, TIME_FRAME.M1)
	var period = getEAParameter(context, "period")
	window.indiHandle = getIndicatorHandle(context, brokerName, accountId, symbolName, TIME_FRAME.M1, "sma", [{
		name: "period",
		value: period
	}])
},
function (context) { // Deinit()
	delete window.currTime
},
function (context) { // OnTick()
	var arrTime = getData(context, window.chartHandle, DATA_NAME.TIME)
	if (typeof window.currTime == "undefined") {
		window.currTime = arrTime[arrTime.length - 1]
	} else if (window.currTime != arrTime[arrTime.length - 1]) {
		window.currTime = arrTime[arrTime.length - 1]
	} else {
		return
	}

	var account = getAccount(context, 0)
	var brokerName = getBrokerNameOfAccount(account)
	var accountId = getAccountIdOfAccount(account)
	var symbolName = "EUR/USD"

	var arrClose = getData(context, window.chartHandle, DATA_NAME.CLOSE)
	var arrSma = getData(context, window.indiHandle, "sma")

	var ask = getAsk(context, brokerName, accountId, symbolName)
	var bid = getBid(context, brokerName, accountId, symbolName)
	var limitPrice = 0.0003
	var stopPrice = 0.0003
	var volume = 0.01

	if (arrClose[arrClose.length - 3] < arrSma[arrSma.length - 3] && arrClose[arrClose.length - 2] > arrSma[arrSma.length - 2]) {
		sendOrder(brokerName, accountId, symbolName, ORDER_TYPE.OP_BUYLIMIT, ask-limitPrice, 0, volume, ask+limitPrice, bid-3*stopPrice, "")
	} else if (arrClose[arrClose.length - 3] > arrSma[arrSma.length - 3] && arrClose[arrClose.length - 2] < arrSma[arrSma.length - 2]) {
		sendOrder(brokerName, accountId, symbolName, ORDER_TYPE.OP_SELLLIMIT, bid+limitPrice, 0, volume, bid-limitPrice, ask+3*stopPrice, "")
	}
})

The callback functions are similar to registerIndicator API. But they are different. We have "init" callback function, "deinit" callback function and "onTick" callback function.

"onTick" callback function is the main function and we will run program logic here. When we get streaming quote, this callback function will be triggered automatically. It will run very frequently. the "init" function will run before you start your EA and the "deinit" function will run after you stop your EA.

Please Note:

  • The important point is you need to know how to transfer information between the functions. Don't use global variables, because global variables can't help you to transfer information between the functions.
  • Please use window object to transfer information. You can set the window object's property to transfer information.
  • Of course if you don't want to share the information between the functions, you can use local variables. The local variables can't be shared by other callback functions.

"init" Function

In the "init" function we will do some initializing process. It's very important to understand what the "init" function does. It will help you to map information and set some initialized information into the property and pack them into the window object and transfer them to other functions.

We need to map for the information because you know we will use our EA to read some information, some output information from the indicators. So we need to specify which indicator we will use, which candlestick we will use, which instrument we need to use. We will specify them in the "init" function and map the handle to the the output information from indicators or candles.

function (context) { // Init()
	var account = getAccount(context, 0)
	var brokerName = getBrokerNameOfAccount(account)
	var accountId = getAccountIdOfAccount(account)
	var symbolName = "EUR/USD"

	getQuotes (context, brokerName, accountId, symbolName)
	window.chartHandle = getChartHandle(context, brokerName, accountId, symbolName, TIME_FRAME.M1)
	var period = getEAParameter(context, "period")
	window.indiHandle = getIndicatorHandle(context, brokerName, accountId, symbolName, TIME_FRAME.M1, "sma", [{
		name: "period",
		value: period
	}])
}

If you want to use candlestick and if the candlestick is M1 time frame, you can call this API to get the handle.

window.chartHandle = getChartHandle(context, brokerName, accountId, symbolName, TIME_FRAME.M1)

Because this handle will be set to getData(An API) as parameter. In "onTick" main callback function, we will use this information as well.

So we need to set chart handle into window object as one property and transfer handle to "onTick" function. We will use this information here(getData's parameter) to specify the data we want to use.

This function(getChartHandle API) is just used to get the handle and this function(getData API) will use the handle to get data. So they are different and we always get handle in "init" function.

var arrClose = getData(context, window.chartHandle, DATA_NAME.CLOSE)

Please Note:

  • Don't use getChartHandle API here(in the "onTick" function). Because the performance will be very low.
  • If you do so, you will map this handle to the information you want to get duplicately.
  • So it's not so good to do it. We recommend you to get handle just in "init" callback function and to get data in "onTick" callback function.

This kind of structure is similar to other trading platform. So, if you have this kind of concept by using other trading platform, I think it will be not so difficult to learn. We have two types of the handles. One type is chart handle that is used to map your candlestick and the other one is indicator handle you can specify your indicators and map them.

In this EA(example) we will use moving average as our input information. So we need to get moving average's handle and map them here("init" function). We will use M1 candlesticks' data, so we will map M1 candlestick's handle here("init" function).

We need to specify the period of the moving average, so we need to get the parameter here("onTick" function) and set the parameter here(registerEA's parameter array). We specify 20 as the input parameter. We need to specify broke name, account ID when we use the APIs.

window.indiHandle = getIndicatorHandle(context, brokerName, accountId, symbolName, TIME_FRAME.M1, "sma", [{
    name: "period",
    value: period
}])

Please Note:

  • The coding style is different from other trading platform, because we support signing in to different accounts at at the same time.
  • So when we want to use the chart, when we want to use the indicators, we need to specify which broker, which account's data. So we need these information.

It's very simple as well. We just need to get information from the "context" object and specify the default account as our account information.

"deinit" Function

"deinit" function will help us to deinitialize information when we finish running our EA. It("deinit" function) will remove some resources.

"onTick" Function

We will use some mechanism to avoid running "onTick" frequently.

Because you will get data quote a lot of times every second. So every second, this "onTick" callback function will be triggered a lot of times. So the performance is very low if you run this function frequently. You don't need to capture the information frequently, you don't need to analyze the data so frequently.

If you are a scalping trader, you may hope to run your EA every tick. But for me, I'm a swing trader, so we don't use the information so frequently. We will use them maybe just every minute, it's enough. So, here we will program some logic to avoid running our EA too frequently.

So we will use current time as some threshold to avoid running our EA too frequently.

var arrTime = getData(context, window.chartHandle, DATA_NAME.TIME)
if (typeof window.currTime == "undefined") {
    window.currTime = arrTime[arrTime.length - 1]
} else if (window.currTime != arrTime[arrTime.length - 1]) {
    window.currTime = arrTime[arrTime.length - 1]
} else {
    return
}

We will use "close" value of the candlestick and simple moving average value as our input data to analyze and to generate the signals. That means when the "close" value is beyond SMA(simple moving average's value) and the buy signal occurs. If the "close" value of the candlestick is below to SMA and the sell signal occurs. We will set the logic here("onTick" function).

if (arrClose[arrClose.length - 3] < arrSma[arrSma.length - 3] && arrClose[arrClose.length - 2] > arrSma[arrSma.length - 2]) {
    sendOrder(brokerName, accountId, symbolName, ORDER_TYPE.OP_BUYLIMIT, ask-limitPrice, 0, volume, ask+limitPrice, bid-3*stopPrice, "")
} else if (arrClose[arrClose.length - 3] > arrSma[arrSma.length - 3] && arrClose[arrClose.length - 2] < arrSma[arrSma.length - 2]) {
    sendOrder(brokerName, accountId, symbolName, ORDER_TYPE.OP_SELLLIMIT, bid+limitPrice, 0, volume, bid-limitPrice, ask+3*stopPrice, "")
}

The data type is array, so we need to specify which elements of the array to use.

Every tick has "bid" value and "ask" value, so we need to specify "ask" value or "bid" value here("onTick" function). These information("bid" or "ask") will be used when we send order. The "sendOrder" API is similar to other training platform.

We will send pending order in this example, not a market order, so we will set order type as "Buy Limit" or "Sell Limit".

sendOrder(brokerName, accountId, symbolName, ORDER_TYPE.OP_SELLLIMIT, bid+limitPrice, 0, volume, bid-limitPrice, ask+3*stopPrice, "")

You can refer to the APIs by this page. You can see them there and every API has very clear definition.

After you write your own EA, just copy the source code and paste the source code in the console dialog. And then run the source code you pasted. After you run it and it will be shown here(EA list) and you can run it.

For example if we want to run this EA, we just need to click the "play" icon and a dialogue will shown up. And then we can set the "period" parameter. If you want to stop it and just click the "stop" icon.

EA

Back Testing

Sometimes we don't know whether our trading strategy works, so we need to back test our EA. We provide back testing page here by clicking the "Game stick" icon to open it.

The back testing environment is different from the trading environment. The trading environment is live, it's real. But the back testing one is virtual. So you can do anything here to check whether your strategy works or not. It will not do harm to your account. Don't worry about losing money, because this environment is virtual environment, you will not lose any money.

So the first thing to do is to start your EA. If we want to test the EA using moving average, we can click "Play" icon to run it.

Just keep the parameter default and then launch this EA. And you can run several EAs at the same time. This operation is to just specify which EA you will use.

Back Testing

After this operation, you need to specify in which period you want to test this EA.

That means you need to set which period of historical data you want to use to test your strategy. After we click this "Play" icon on the Left sidebar, a dialogue shows up. And you can specify the period of your back testing. We will choose May 1st and regarding the time frame, I will use M1. Because we will take M1 data here(in the EA's logic), so when we test EA, this option should be subject to the logic of EA. Both of them should be M1. You can't use different time frame if you specify M1 in your logic. The initial deposit is depending on your condition. I will use just $500 to test EA. It's enough. And if we hope to see the whole progress, check this option("Visible") and make the progress visible.

Back Testing

Now, run it, it will download the historical data from the server. We just need to wait.

Now it's running. Let me introduce what the elements on the chart mean. The blue circle means "Buy" signal and the red circle means "Sell" signal. If you see a circle with a line attached, that means we sent a pending order. If we just see a circle without a line attached, that means it's market order. And it will be traded immediately. You can see some lines without circle attached. The blue line without circle attached means take profit line. And the red line without circle attached means stop loss line. The dash line means you set "take profit" or "stop loss" when you send pending order. And after the pending order is traded, the dashed line will become solid line. That means the "take profit" order or the "stop loss" order attached to a pending order is activated. The progress will take several minutes and during the back testing progress and you can check the report at the same time.

Back Testing

If you are not so patient with the testing progress, you can stop it and then run it under invisible mode. The invisible mode will speed up the testing speed. It's very simple. After you verify your strategy, you can run it on your real account by clicking the "Play" icon. This is today's topic: EA and hopefully you can get profit by using your own EA. Thank you for watching, see you next time.