Home > SDK Trading

SDK Trading

Fintechee 2020-01-18

Fintechee provides SDK Trading which includes Algorithms for Trading. Automated Trading is based on SDK trading. Fintechee has RESTful API and JS API(running on the browser) which help traders monitor the market movements and trade Forex automatically.

Please use our WEB trader to implement your trading strategies.

More Materials

Constant Definition

var BROKER_NAME = {
	DEMO: "CC Demo"
}

var TIME_FRAME = {
	M1: "M1",
	M5: "M5",
	M15: "M15",
	M30: "M30",
	H1: "H1",
	H4: "H4",
	D: "D",
	W: "W",
	M: "M"
}

var ORDER_TYPE = {
	OP_BUY: "BUY",
	OP_SELL: "SELL",
	OP_BUYLIMIT: "BUY LIMIT",
	OP_SELLLIMIT: "SELL LIMIT",
	OP_BUYSTOP: "BUY STOP",
	OP_SELLSTOP: "SELL STOP"
}

var WHERE_TO_RENDER = {
	CHART_WINDOW: "CHART_WINDOW",
	SEPARATE_WINDOW: "SEPARATE_WINDOW"
}

var DATA_NAME = {
	TIME: "Time",
	OPEN: "Open",
	HIGH: "High",
	LOW: "Low",
	CLOSE: "Close",
	HL2: "HL2",
	HLC3: "HLC3",
	HLCC4: "HLCC4"
}

var RENDER_TYPE = {
	HISTOGRAM: "Histogram",
	LINE: "Line",
	ROUND: "Round",
	DASHARRAY: "Dasharray"
}

var PARAMETER_TYPE = {
	INTEGER: "Integer",
	NUMBER: "Number",
	BOOLEAN: "Boolean",
	STRING: "String"
}

Common Function

function sma (dataInput, dataOutput, calculatedLength, period) {
	var i = calculatedLength

	if (calculatedLength > 0) {
		i--
	} else {
		for (var j = 0; j < period - 1; j++) {
			dataOutput[j] = 0
		}

		i = period - 1
	}

	var sum = 0

	for (var j = i - period + 1; j < i; j++) {
		sum += dataInput[j]
	}

	for (var j = i; j < dataInput.length; j++) {
		sum += dataInput[j]
		dataOutput[j] = sum / period
		sum -= dataInput[j - period + 1]
	}
}

function ema (dataInput, dataOutput, calculatedLength, period) {
	var i = calculatedLength
	var smthFctr = 2.0 / (period + 1)

	if (i == 0) {
		dataOutput[0] = dataInput[0]
		i++
	} else if (i == 1) {
	} else {
		i--
	}

	while (i < dataInput.length) {
		dataOutput[i] = dataInput[i] * smthFctr + dataOutput[i - 1] * (1 - smthFctr)
		i++
	}
}

function smma (dataInput, dataOutput, calculatedLength, period) {
	var i = calculatedLength
	var sum = 0

	if (i > 0) {
		i--
	} else {
		i = period - 1

		for (var j = 1; j < period; j++) {
			dataOutput[i - j] = 0
			sum += dataInput[i - j]
		}

		sum += dataInput[i]
		dataOutput[i] = sum / period
		i++
	}

	while (i < dataInput.length) {
		sum = dataOutput[i - 1] * period - dataOutput[i - 1] + dataInput[i]
		dataOutput[i] = sum / period
		i++
	}
}

function lwma (dataInput, dataOutput, calculatedLength, period) {
	var i = calculatedLength

	if (i > 0) {
		i--
	} else {
		for (var j = 0; j < period - 1; j++) {
			dataOutput[j] = 0
		}

		i = period - 1
	}

	var sum = 0
	var diffsum = 0
	var weight = 0

	for (var j = 1; j < period; j++) {
		sum += dataInput[i - j] * (period - j)
		diffsum += dataInput[i - j]
		weight += j
	}
	weight += period

	while (i < dataInput.length) {
		sum += dataInput[i] * period
		dataOutput[i] = sum / weight
		diffsum += dataInput[i]
		sum -= diffsum
		diffsum -= dataInput[i - period + 1]
		i++
	}
}

Indicator Example

Simple moving average

registerIndicator("sma", "Simple moving average", function (context) {
	var dataInput = getDataInput(context, 0)
	var dataOutput = getDataOutput(context, "sma")
	var period = getIndiParameter(context, "period")
	var shift = getIndiParameter(context, "shift")

	var calculatedLength = getCalculatedLength(context)

	sma(dataInput, dataOutput, calculatedLength, period)

	if (shift != null && calculatedLength == 0) {
		setIndiShift(context, "sma", shift)
	}
},[{
	name: "period",
	value: 5,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "shift",
	value: 0,
	required: false,
	type: PARAMETER_TYPE.INTEGER,
	range: [-30, 30]
}],
[{
	name: DATA_NAME.CLOSE,
	index: 0
}],
[{
	name: "sma",
	visible: true,
	renderType: RENDER_TYPE.LINE,
	color: "steelblue"
}],
WHERE_TO_RENDER.CHART_WINDOW)

Exponential moving average

registerIndicator("ema", "Exponential moving average", function (context) {
	var dataInput = getDataInput(context, 0)
	var dataOutput = getDataOutput(context, "ema")
	var period = getIndiParameter(context, "period")
	var shift = getIndiParameter(context, "shift")

	var calculatedLength = getCalculatedLength(context)

	ema(dataInput, dataOutput, calculatedLength, period)

	if (shift != null && calculatedLength == 0) {
		setIndiShift(context, "ema", shift)
	}
},[{
	name: "period",
	value: 5,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "shift",
	value: 0,
	required: false,
	type: PARAMETER_TYPE.INTEGER,
	range: [-30, 30]
}],
[{
	name: DATA_NAME.CLOSE,
	index: 0
}],
[{
	name: "ema",
	visible: true,
	renderType: RENDER_TYPE.LINE,
	color: "steelblue"
}],
WHERE_TO_RENDER.CHART_WINDOW)

Smoothed moving average

registerIndicator("smma", "Smoothed moving average", function (context) {
	var dataInput = getDataInput(context, 0)
	var dataOutput = getDataOutput(context, "smma")
	var period = getIndiParameter(context, "period")
	var shift = getIndiParameter(context, "shift")

	var calculatedLength = getCalculatedLength(context)

	smma(dataInput, dataOutput, calculatedLength, period)

	if (shift != null && calculatedLength == 0) {
		setIndiShift(context, "smma", shift)
	}
},[{
	name: "period",
	value: 5,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "shift",
	value: 0,
	required: false,
	type: PARAMETER_TYPE.INTEGER,
	range: [-30, 30]
}],
[{
	name: DATA_NAME.CLOSE,
	index: 0
}],
[{
	name: "smma",
	visible: true,
	renderType: RENDER_TYPE.LINE,
	color: "steelblue"
}],
WHERE_TO_RENDER.CHART_WINDOW)

Linear weighted moving average

registerIndicator("lwma", "Linear weighted moving average", function (context) {
	var dataInput = getDataInput(context, 0)
	var dataOutput = getDataOutput(context, "lwma")
	var period = getIndiParameter(context, "period")
	var shift = getIndiParameter(context, "shift")

	var calculatedLength = getCalculatedLength(context)

	lwma(dataInput, dataOutput, calculatedLength, period)

	if (shift != null && calculatedLength == 0) {
		setIndiShift(context, "lwma", shift)
	}
},[{
	name: "period",
	value: 5,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "shift",
	value: 0,
	required: false,
	type: PARAMETER_TYPE.INTEGER,
	range: [-30, 30]
}],
[{
	name: DATA_NAME.CLOSE,
	index: 0
}],
[{
	name: "lwma",
	visible: true,
	renderType: RENDER_TYPE.LINE,
	color: "steelblue"
}],
WHERE_TO_RENDER.CHART_WINDOW)

MACD

registerIndicator("macd", "MACD", function (context) {
	var dataInput = getDataInput(context, 0)
	var dataFEMA = getDataOutput(context, "fastEMA")
	var dataSEMA = getDataOutput(context, "slowEMA")
	var dataOutputMain = getDataOutput(context, "main")
	var dataOutputSignal = getDataOutput(context, "signal")

	var fEMA = getIndiParameter(context, "fasteEMA")
	var sEMA = getIndiParameter(context, "slowEMA")
	var sgnlSMA = getIndiParameter(context, "signalSMA")

	var calculatedLength = getCalculatedLength(context)
	var i = calculatedLength

	if (i == 0) {
		dataFEMA[0] = dataInput[0]
		dataSEMA[0] = dataInput[0]
		dataOutputMain[0] = 0
		i++
	} else if (i == 1) {
	} else {
		i--
	}

	ema(dataInput, dataFEMA, calculatedLength, fEMA)
	ema(dataInput, dataSEMA, calculatedLength, sEMA)

	while (i < dataInput.length) {
		dataOutputMain[i] = dataFEMA[i] - dataSEMA[i]
		i++
	}

	sma(dataOutputMain, dataOutputSignal, calculatedLength, sgnlSMA)
},[{
	name: "fasteEMA",
	value: 12,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "slowEMA",
	value: 26,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "signalSMA",
	value: 9,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
}],
[{
	name: DATA_NAME.CLOSE,
	index: 0
}],
[{
	name: "fastEMA",
	visible: false
},{
	name: "slowEMA",
	visible: false
},{
    name: "main",
    visible: true,
    renderType: RENDER_TYPE.HISTOGRAM,
    color: "#4EC2B4"
},{
    name: "signal",
    visible: true,
    renderType: RENDER_TYPE.LINE,
    color: "#CCCCCC"
}],
WHERE_TO_RENDER.SEPARATE_WINDOW)

Relative strength index

registerIndicator("rsi", "Relative strength index", function (context) {
	var dataInput = getDataInput(context, 0)
	var dataOutput = getDataOutput(context, "rsi")
	var dataOutputHL = getDataOutput(context, "rsiHighLevel")
	var dataOutputLL = getDataOutput(context, "rsiLowLevel")
	var gainTmp = getDataOutput(context, "gainTmp")
	var lossTmp = getDataOutput(context, "lossTmp")

	var period = getIndiParameter(context, "period")
	var highLevel = getIndiParameter(context, "highLevel")
	var lowLevel = getIndiParameter(context, "lowLevel")

	var calculatedLength = getCalculatedLength(context)

	var ptr = null
	var ptr2 = null

	var diff = null
	var gain = null
	var loss = null
	var gainSum = 0
	var lossSum = 0

	if (calculatedLength > 0) {
		ptr = calculatedLength - 1
		ptr2 = calculatedLength - period
	} else {
		for (var i = 0; i < period; i++) {
			dataOutput[i] = 0
			dataOutputHL[i] = highLevel
			dataOutputLL[i] = lowLevel
		}

		ptr = period
		ptr2 = 1

		while (ptr2 <= ptr) {
			diff = dataInput[ptr2] - dataInput[ptr2 - 1]
			if (0 < diff) {
				gainSum += diff
			} else {
				lossSum -= diff
			}
			ptr2++
		}
		gain = gainSum / period
		loss = lossSum / period
		if (0 == (gain + loss)) {
			dataOutput[ptr] = 0
		} else {
			dataOutput[ptr] = 100 * gain / (gain + loss)
		}
		dataOutputHL[ptr] = highLevel
		dataOutputLL[ptr] = lowLevel
		gainTmp[ptr] = gain
		lossTmp[ptr] = loss
		ptr++
	}

	while (ptr < dataInput.length) {
		gain = gainTmp[ptr - 1] * (period - 1)
		loss = lossTmp[ptr - 1] * (period - 1)

		diff = dataInput[ptr] - dataInput[ptr - 1]
		if (0 < diff) {
			gain += diff
		} else {
			loss -= diff
		}
		gain = gain / period
		loss = loss / period

		if (0 == (gain + loss)) {
			dataOutput[ptr] = 0
		} else {
			dataOutput[ptr] = 100 * gain / (gain + loss)
		}
		dataOutputHL[ptr] = highLevel
		dataOutputLL[ptr] = lowLevel
		gainTmp[ptr] = gain
		lossTmp[ptr] = loss
		ptr++
	}
},[{
	name: "period",
	value: 14,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "highLevel",
	value: 70,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "lowLevel",
	value: 30,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
}],
[{
	name: DATA_NAME.CLOSE,
	index: 0
}],
[{
	name: "rsi",
	visible: true,
	renderType: RENDER_TYPE.LINE,
	color: "steelblue"
},{
	name: "rsiHighLevel",
	visible: true,
	renderType: RENDER_TYPE.DASHARRAY,
	color: "#AAAAAA"
},{
	name: "rsiLowLevel",
	visible: true,
	renderType: RENDER_TYPE.DASHARRAY,
	color: "#AAAAAA"
},{
	name: "gainTmp",
	visible: false
},{
	name: "lossTmp",
	visible: false
}],
WHERE_TO_RENDER.SEPARATE_WINDOW)

Average true range

registerIndicator("atr", "Average true range", function (context) {
	var dataInputClose = getDataInput(context, 0)
	var dataInputHigh = getDataInput(context, 1)
	var dataInputLow = getDataInput(context, 2)
	var tmpLine = getDataOutput(context, "tmp")
	var dataOutput = getDataOutput(context, "atr")

	var period = getIndiParameter(context, "period")

	var calculatedLength = getCalculatedLength(context)
	var i = calculatedLength
	var high = null
	var low = null
	var prevClose = null

	if (i > 0) {
		i--
	} else {
		tmpLine[i] = 0
		i = 1
	}

	while (i < dataInputClose.length) {
		high = dataInputHigh[i]
		low = dataInputLow[i]
		prevClose = dataInputClose[i - 1]

		tmpLine[i] = Math.max(high, prevClose) - Math.min(low, prevClose)

		i++
	}

	sma(tmpLine, dataOutput, calculatedLength, period)
},[{
	name: "period",
	value: 14,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
}],
[{
	name: DATA_NAME.CLOSE,
	index: 0
},{
	name: DATA_NAME.HIGH,
	index: 1
},{
	name: DATA_NAME.LOW,
	index: 2
}],
[{
    name: "tmp",
    visible: false
},{
    name: "atr",
    visible: true,
    renderType: RENDER_TYPE.LINE,
    color: "steelblue"
}],
WHERE_TO_RENDER.SEPARATE_WINDOW)

Average directional index

registerIndicator("adx", "Average directional index", function (context) {
	var dataInputClose = getDataInput(context, 0)
	var dataInputHigh = getDataInput(context, 1)
	var dataInputLow = getDataInput(context, 2)

	var tmpLine = getDataOutput(context, "tmp")
	var plusSdiTmp = getDataOutput(context, "plusSdiTmp")
	var minusSdiTmp = getDataOutput(context, "minusSdiTmp")

	var dataOutputAdx = getDataOutput(context, "adx")
	var dataOutputPlusDi = getDataOutput(context, "plusDi")
	var dataOutputMinusDi = getDataOutput(context, "minusDi")

	var period = getIndiParameter(context, "period")

	var calculatedLength = getCalculatedLength(context)
	var i = calculatedLength

	if (i > 0) {
		i--
	} else {
		plusSdiTmp[i] = 0
		minusSdiTmp[i] = 0
		i = 1
	}

	var plusDM = null
	var minusDM = null
	var trueRange = null
	var currH = null
	var currL = null
	var prevH = null
	var prevL = null
	var prevC = null

	while (i < dataInputClose.length) {
		currH = dataInputHigh[i]
		currL = dataInputLow[i]
		prevH = dataInputHigh[i - 1]
		prevL = dataInputLow[i - 1]
		prevC = dataInputClose[i - 1]

		plusDM = currH - prevH
		minusDM = prevL - currL
		if (0 > plusDM) {
			plusDM = 0
		}
		if (0 > minusDM) {
			minusDM = 0
		}
		if (plusDM == minusDM) {
			plusDM = 0
			minusDM = 0
		} else if (plusDM < minusDM) {
			plusDM = 0
		} else if (plusDM > minusDM) {
			minusDM = 0
		}

		trueRange = Math.max(Math.abs(currH - currL), Math.abs(currH - prevC))
		trueRange = Math.max(trueRange, Math.abs(currL - prevC))

		if (0 == trueRange) {
			plusSdiTmp[i] = 0
			minusSdiTmp[i] = 0
		}else{
			plusSdiTmp[i] = 100 * plusDM / trueRange
			minusSdiTmp[i] = 100 * minusDM / trueRange
		}

		i++
	}

	ema(plusSdiTmp, dataOutputPlusDi, calculatedLength, period)
	ema(minusSdiTmp, dataOutputMinusDi, calculatedLength, period)

	i = calculatedLength
	if (i > 0) {
		i--
	}

	while (i < dataInputClose.length) {
		var tmp = Math.abs(dataOutputPlusDi[i] + dataOutputMinusDi[i])

		if (0 == tmp) {
			tmpLine[i] = 0
		} else {
			tmpLine[i] = 100 * (Math.abs(dataOutputPlusDi[i] - dataOutputMinusDi[i]) / tmp)
		}

		i++
	}

	ema(tmpLine, dataOutputAdx, calculatedLength, period)
},[{
	name: "period",
	value: 14,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
}],
[{
	name: DATA_NAME.CLOSE,
	index: 0
},{
	name: DATA_NAME.HIGH,
	index: 1
},{
	name: DATA_NAME.LOW,
	index: 2
}],
[{
    name: "tmp",
    visible: false
},{
    name: "plusSdiTmp",
    visible: false
},{
    name: "minusSdiTmp",
    visible: false
},{
    name: "adx",
    visible: true,
    renderType: RENDER_TYPE.LINE,
    color: "#CCCCCC"
},{
    name: "plusDi",
    visible: true,
    renderType: RENDER_TYPE.DASHARRAY,
    color: "#4EC2B4"
},{
    name: "minusDi",
    visible: true,
    renderType: RENDER_TYPE.DASHARRAY,
    color: "#DE5029"
}],
WHERE_TO_RENDER.SEPARATE_WINDOW)

Parabolic SAR

registerIndicator("sar", "Parabolic SAR", function (context) {
	var dataInputHigh = getDataInput(context, 0)
	var dataInputLow = getDataInput(context, 1)

	var dataOutput = getDataOutput(context, "sar")

	var acceleration = getIndiParameter(context, "acceleration")
	var af = acceleration
	var afMax = getIndiParameter(context, "afMax")

	var calculatedLength = getCalculatedLength(context)
	var i = calculatedLength

	if (i > 0) {
		i--
	} else {
		dataOutput[i] = 0
		i = 1
	}

	var prevH = dataInputHigh[i - 1]
	var prevL = dataInputLow[i - 1]
	var currH = null
	var currL = null

	var isLong = true
	var ep = prevH
	var sar = prevL

	while (i < dataInputHigh.length) {
		currH = dataInputHigh[i]
		currL = dataInputLow[i]

		if (isLong) {
			if (currL <= sar) {
				isLong = false
				sar = Math.max(ep, currH, prevH)

				dataOutput[i] = sar

				af = acceleration
				ep = currL
				sar = sar + af * (ep - sar)
				sar = Math.max(sar, currH, prevH)
			} else {
				dataOutput[i] = sar

				if (currH > ep) {
					ep = currH
					af += acceleration
					if (af > afMax) {
						af = afMax
					}
				}
				sar = sar + af * (ep - sar)
				sar = Math.min(sar, currL, prevL)
			}
		} else {
			if (currH >= sar) {
				isLong = true
				sar = Math.min(ep, currL, prevL)

				dataOutput[i] = sar

				af = acceleration
				ep = currH
				sar = sar + af * (ep - sar)
				sar = Math.min(sar, currL, prevL)
			}else{
				dataOutput[i] = sar

				if (currL < ep) {
					ep = currL
					af += acceleration
					if (af > afMax) {
						af = afMax
					}
				}
				sar = sar + af * (ep - sar)
				sar = Math.max(sar, currH, prevH)
			}
		}
		i++

		prevH = currH
		prevL = currL
	}

},[{
	name: "acceleration",
	value: 0.02,
	required: true,
	type: PARAMETER_TYPE.NUMBER,
	range: [0.01, 0.1]
},{
	name: "afMax",
	value: 0.2,
	required: true,
	type: PARAMETER_TYPE.NUMBER,
	range: [0.1, 1]
}],
[{
	name: DATA_NAME.HIGH,
	index: 0
},{
	name: DATA_NAME.LOW,
	index: 1
}],
[{
	name: "sar",
	visible: true,
	renderType: RENDER_TYPE.ROUND,
	color: "steelblue"
}],
WHERE_TO_RENDER.CHART_WINDOW)

Stochastic oscillator

registerIndicator("stochastic", "Stochastic oscillator", function (context) {
	var dataInputClose = getDataInput(context, 0)
	var dataInputHigh = getDataInput(context, 1)
	var dataInputLow = getDataInput(context, 2)

	var highestTmp = getDataOutput(context, "highestTmp")
	var lowestTmp = getDataOutput(context, "lowestTmp")

	var dataOutputMain = getDataOutput(context, "main")
	var dataOutputSignal = getDataOutput(context, "signal")

	var kP = getIndiParameter(context, "KPeriod")
	var slowing = getIndiParameter(context, "slowing")
	var dP = getIndiParameter(context, "DPeriod")
	var method = getIndiParameter(context, "method")

	var calculatedLength = getCalculatedLength(context)
	var ptr = calculatedLength
	var maxParam = Math.max(kP + slowing - 1, dP)

	if (ptr > 0) {
		ptr--
	} else {
		ptr = maxParam - 1

		for (var i = 1; i <= maxParam - 1; i++) {
			dataOutputMain[ptr - i] = 0
			highestTmp[ptr - i] = 0
			lowestTmp[ptr - i] = 0
		}
	}

	while (ptr < dataInputClose.length) {
		var tmp = null
		var highest = Number.MIN_VALUE
		var lowest = Number.MAX_VALUE

		for (var ptr2 = (ptr - kP + 1); ptr2 <= ptr; ptr2++){
			tmp = dataInputHigh[ptr2]
			if (highest < tmp) {
				highest = tmp
			}

			tmp = dataInputLow[ptr2]
			if (lowest > tmp) {
				lowest = tmp
			}
		}

		highestTmp[ptr] = highest
		lowestTmp[ptr] = lowest

		ptr++
	}

	ptr = calculatedLength

	if (ptr > 0) {
		ptr--
	} else {
		ptr = maxParam - 1
	}

	while (ptr < dataInputClose.length) {
		var highestSum = 0
		var lowestSum = 0

		for (var ptr2 = ptr - slowing + 1; ptr2 <= ptr; ptr2++) {
			highestSum += highestTmp[ptr2] - lowestTmp[ptr2]
			lowestSum += dataInputClose[ptr2] - lowestTmp[ptr2]
		}

		if (0 == highestSum) {
			dataOutputMain[ptr] = 100
		}else{
			dataOutputMain[ptr] = lowestSum / highestSum * 100
		}

		ptr++
	}

	if ("sma" == method) {
		sma(dataOutputMain, dataOutputSignal, calculatedLength, dP)
	} else if ("ema" == method) {
		ema(dataOutputMain, dataOutputSignal, calculatedLength, dP)
	} else if ("smma" == method) {
		smma(dataOutputMain, dataOutputSignal, calculatedLength, dP)
	} else {
		lwma(dataOutputMain, dataOutputSignal, calculatedLength, dP)
	}
},[{
	name: "KPeriod",
	value: 5,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "slowing",
	value: 3,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "DPeriod",
	value: 3,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "method",
	value: "sma",
	required: true,
	type: PARAMETER_TYPE.STRING
}],
[{
	name: DATA_NAME.CLOSE,
	index: 0
},{
	name: DATA_NAME.HIGH,
	index: 1
},{
	name: DATA_NAME.LOW,
	index: 2
}],
[{
    name: "highestTmp",
    visible: false
},{
    name: "lowestTmp",
    visible: false
},{
    name: "main",
    visible: true,
    renderType: RENDER_TYPE.LINE,
    color: "#DE5029"
},{
    name: "signal",
    visible: true,
    renderType: RENDER_TYPE.DASHARRAY,
    color: "#4EC2B4"
}],
WHERE_TO_RENDER.SEPARATE_WINDOW)

Alligator

registerIndicator("alligator", "A series of Bill Williams' indicators", function (context) {
	var dataInput = getDataInput(context, 0)
	var dataOutputJaws = getDataOutput(context, "jaws")
	var dataOutputTeeth = getDataOutput(context, "teeth")
	var dataOutputLips = getDataOutput(context, "lips")

	var method = getIndiParameter(context, "method")
	var jawsPeriod = getIndiParameter(context, "jawsPeriod")
	var jawsShift = getIndiParameter(context, "jawsShift")
	var teethPeriod = getIndiParameter(context, "teethPeriod")
	var teethShift = getIndiParameter(context, "teethShift")
	var lipsPeriod = getIndiParameter(context, "lipsPeriod")
	var lipsShift = getIndiParameter(context, "lipsShift")

	var calculatedLength = getCalculatedLength(context)

	if ("smma" == method) {
		smma(dataInput, dataOutputJaws, calculatedLength, jawsPeriod)
		smma(dataInput, dataOutputTeeth, calculatedLength, teethPeriod)
		smma(dataInput, dataOutputLips, calculatedLength, lipsPeriod)
	} else if ("sma" == method) {
		sma(dataInput, dataOutputJaws, calculatedLength, jawsPeriod)
		sma(dataInput, dataOutputTeeth, calculatedLength, teethPeriod)
		sma(dataInput, dataOutputLips, calculatedLength, lipsPeriod)
	} else if("ema" == method) {
		ema(dataInput, dataOutputJaws, calculatedLength, jawsPeriod)
		ema(dataInput, dataOutputTeeth, calculatedLength, teethPeriod)
		ema(dataInput, dataOutputLips, calculatedLength, lipsPeriod)
	} else {
		lwma(dataInput, dataOutputJaws, calculatedLength, jawsPeriod)
		lwma(dataInput, dataOutputTeeth, calculatedLength, teethPeriod)
		lwma(dataInput, dataOutputLips, calculatedLength, lipsPeriod)
	}

	if (calculatedLength == 0) {
		setIndiShift(context, "jaws", jawsShift)
		setIndiShift(context, "teeth", teethShift)
		setIndiShift(context, "lips", lipsShift)
	}
},[{
	name: "jawsPeriod",
	value: 13,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "jawsShift",
	value: 8,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [0, 30]
},{
	name: "teethPeriod",
	value: 8,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "teethShift",
	value: 5,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [0, 30]
},{
	name: "lipsPeriod",
	value: 5,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "lipsShift",
	value: 3,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [0, 30]
},{
	name: "method",
	value: "smma",
	required: true,
	type: PARAMETER_TYPE.STRING
}],
[{
	name: DATA_NAME.HL2,
	index: 0
}],
[{
	name: "jaws",
	visible: true,
	renderType: RENDER_TYPE.LINE,
	color: "steelblue"
},{
	name: "teeth",
	visible: true,
	renderType: RENDER_TYPE.LINE,
	color: "#4EC2B4"
},{
	name: "lips",
	visible: true,
	renderType: RENDER_TYPE.LINE,
	color: "#DE5029"
}],
WHERE_TO_RENDER.CHART_WINDOW)

EA Example

A test EA based on SMA

registerEA(
"sample_using_sma",
"A test EA based on sma",
[{ // 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, "")
	}
})

Trading Arbitrage

registerEA(
"sample_trading_arbitrage",
"Two accounts signed up on the different servers are required to trade arbitrage. Additionally please make sure that you have signed in to both accounts and logged out from the accounts in investor mode.",
[],// parameters
function (context) { // Init()
	var account1 = getAccount(context, 0)
	var account2 = getAccount(context, 1)

	var acc1 = {
		brokerName: getBrokerNameOfAccount(account1),
		accountId: getAccountIdOfAccount(account1),
		symbolName: "EUR/USD"
	}
	var acc2 = {
		brokerName: getBrokerNameOfAccount(account2),
		accountId: getAccountIdOfAccount(account2),
		symbolName: "EUR/USD"
	}

	getQuotes (context, acc1.brokerName, acc1.accountId, acc1.symbolName)
	getQuotes (context, acc2.brokerName, acc2.accountId, acc2.symbolName)

	window.acc1 = acc1
	window.acc2 = acc2
},
function (context) { // Deinit()
	delete window.currTime
},
function (context) { // OnTick()
	var currTime = new Date().getTime()
	if (typeof window.currTime == "undefined") {
		window.currTime = currTime
	} else if (window.currTime <= currTime - 1000) {
		window.currTime = currTime
	} else {
		return
	}

	var acc1 = window.acc1
	var acc2 = window.acc2

	var ask1 = getAsk(context, acc1.brokerName, acc1.accountId, acc1.symbolName)
	var ask2 = getAsk(context, acc2.brokerName, acc2.accountId, acc2.symbolName)
	var bid1 = getBid(context, acc1.brokerName, acc1.accountId, acc1.symbolName)
	var bid2 = getBid(context, acc2.brokerName, acc2.accountId, acc2.symbolName)

	var volume = 0.01

	if (ask1 < bid2) {
		var tradeNum = getOpenTradesListLength(context)

		var acc1TradeId = null
		var acc2TradeId = null

		for (var i = tradeNum - 1; i >= 0; i--) {
			var trade = getOpenTrade(context, i)
			var brokerName = getBrokerName(trade)
			var accountId = getAccountId(trade)
			var tradeId = getTradeId(trade)
			var orderType = getOrderType(trade)
			if (brokerName == acc1.brokerName && accountId == acc1.accountId && orderType == ORDER_TYPE.OP_SELL) {
				acc1TradeId = tradeId
			}
			if (brokerName == acc2.brokerName && accountId == acc2.accountId && orderType == ORDER_TYPE.OP_BUY) {
				acc2TradeId = tradeId
			}
		}

		if (acc1TradeId == null) {
			sendOrder(acc1.brokerName, acc1.accountId, acc1.symbolName, ORDER_TYPE.OP_BUY, 0, 0, volume, 0, 0, "")
		} else {
			closeTrade(acc1.brokerName, acc1.accountId, acc1TradeId)
		}

		if (acc2TradeId == null) {
			sendOrder(acc2.brokerName, acc2.accountId, acc2.symbolName, ORDER_TYPE.OP_SELL, 0, 0, volume, 0, 0, "")
		} else {
			closeTrade(acc2.brokerName, acc2.accountId, acc2TradeId)
		}
	} else if (ask2 < bid1) {
		var tradeNum = getOpenTradesListLength(context)

		var acc1TradeId = null
		var acc2TradeId = null

		for (var i = tradeNum - 1; i >= 0; i--) {
			var trade = getOpenTrade(context, i)
			var brokerName = getBrokerName(trade)
			var accountId = getAccountId(trade)
			var tradeId = getTradeId(trade)
			var orderType = getOrderType(trade)
			if (brokerName == acc2.brokerName && accountId == acc2.accountId && orderType == ORDER_TYPE.OP_SELL) {
				acc2TradeId = tradeId
			}
			if (brokerName == acc1.brokerName && accountId == acc1.accountId && orderType == ORDER_TYPE.OP_BUY) {
				acc1TradeId = tradeId
			}
		}

		if (acc2TradeId == null) {
			sendOrder(acc2.brokerName, acc2.accountId, acc2.symbolName, ORDER_TYPE.OP_BUY, 0, 0, volume, 0, 0, "")
		} else {
			closeTrade(acc2.brokerName, acc2.accountId, acc2TradeId)
		}

		if (acc1TradeId == null) {
			sendOrder(acc1.brokerName, acc1.accountId, acc1.symbolName, ORDER_TYPE.OP_SELL, 0, 0, volume, 0, 0, "")
		} else {
			closeTrade(acc1.brokerName, acc1.accountId, acc1TradeId)
		}
	}
})

Neural Network

registerEA(
"sample_training_neuron_model",
"A test EA to train neuron model",
[{ // parameters
	name: "period",
	value: 20,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "inputNum",
	value: 20,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "hiddenNum",
	value: 50,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "diffPrice",
	value: 0.0001,
	required: true,
	type: PARAMETER_TYPE.NUMBER,
	range: [0, 10]
}],
function (context) { // Init()
	var account = getAccount(context, 0)
	var brokerName = getBrokerNameOfAccount(account)
	var accountId = getAccountIdOfAccount(account)
	var symbolName = "EUR/USD"

	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, "rsi", [{
		name: "period",
		value: period
	}])
},
function (context) { // Deinit()
	var period = getEAParameter(context, "period")
	var inputNum = getEAParameter(context, "inputNum")
	var hiddenNum = getEAParameter(context, "hiddenNum")
	var arrOpen = getData(context, window.chartHandle, DATA_NAME.OPEN)
	var arrClose = getData(context, window.chartHandle, DATA_NAME.CLOSE)
	var arrRsi = getData(context, window.indiHandle, "rsi")

	if (arrRsi.length <= period + 1) return
	if (inputNum + period - 1 > arrRsi.length) throw new Error("No enough data.")

	// extend the prototype chain
	Perceptron.prototype = new synaptic.Network()
	Perceptron.prototype.constructor = Perceptron

	var myPerceptron = new Perceptron(inputNum, hiddenNum, 1)
	var myTrainer = new synaptic.Trainer(myPerceptron)

	var diffPrice = getEAParameter(context, "diffPrice")
	var trainingSet = []
	var longCount = 0
	var shortCount = 0

	for (var i = period - 1; i < arrRsi.length - inputNum; i++) {
		if (arrClose[i * inputNum + inputNum] - arrOpen[i * inputNum + inputNum] > diffPrice) {
			var input = []

			for (var j = 0; j < inputNum; j++) {
				input.push(arrRsi[i * inputNum + j] / 100)
			}

			trainingSet.push({
				input: input,
				output: [0]
			})

			longCount++
		} else if (arrOpen[i * inputNum + inputNum] - arrClose[i * inputNum + inputNum] > diffPrice) {
			var input = []

			for (var j = 0; j < inputNum; j++) {
				input.push(arrRsi[i * inputNum + j] / 100)
			}

			trainingSet.push({
				input: input,
				output: [1]
			})

			shortCount++
		}
	}

	myTrainer.train(trainingSet)
	localStorage.sample_training_neuron_model = JSON.stringify(myPerceptron.toJSON())
	printMessage(longCount + ", " + shortCount)
	printMessage(JSON.stringify(trainingSet))
	printMessage(JSON.stringify(myPerceptron.toJSON()))
},
function (context) { // OnTick()
})

registerEA(
"sample_run_neuron_model",
"A test EA to run neuron model",
[{ // parameters
	name: "period",
	value: 20,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "inputNum",
	value: 20,
	required: true,
	type: PARAMETER_TYPE.INTEGER,
	range: [1, 100]
},{
	name: "threshold",
	value: 0.3,
	required: true,
	type: PARAMETER_TYPE.NUMBER,
	range: [0, 1]
},{
	name: "takeProfit",
	value: 0.0001,
	required: true,
	type: PARAMETER_TYPE.NUMBER,
	range: [0, 100]
}],
function (context) { // Init()
	if (typeof localStorage.sample_training_neuron_model == "undefined") return

	window.myPerceptron = synaptic.Network.fromJSON(JSON.parse(localStorage.sample_training_neuron_model))

	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, "rsi", [{
		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 period = getEAParameter(context, "period")
	var inputNum = getEAParameter(context, "inputNum")
	var threshold = getEAParameter(context, "threshold")
	var takeProfit = getEAParameter(context, "takeProfit")
	var arrRsi = getData(context, window.indiHandle, "rsi")

	if (inputNum + period - 1 > arrRsi.length) throw new Error("No enough data.")

	var input = []

	for (var i = arrRsi.length - inputNum - 1; i < arrRsi.length - 1; i++) {
		input.push(arrRsi[i] / 100)
	}

	var result = window.myPerceptron.activate(input)[0]
	printMessage(result)

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

	if (result < 0.5 - threshold) {
		sendOrder(brokerName, accountId, symbolName, ORDER_TYPE.OP_BUY, 0, 0, volume, ask+takeProfit, bid-3*takeProfit, "")
	} else if (result > 0.5 + threshold) {
		sendOrder(brokerName, accountId, symbolName, ORDER_TYPE.OP_SELL, 0, 0, volume, bid-takeProfit, ask+3*takeProfit, "")
	}
})
We are going IEO
2020-01-10 Bounty News
Brokerless.CC
Sponsored by Fintech Angel Investors Network