В этом разделе я буду выкладывать совершенно бесплатно все торговые роботы (СОВЕТНИКИ) и скрипты для терминала ТРАНЗАК (TRANSAQ) для торговли на Московской бирже, FORTS.
Поэтому, уважаемые трейдеры, скачиваем, тестируем, наслаждаемся торговлей!

Все для терминала Транзак (Transaq)
Скрипты
Скачать робота помощника Автоматический STOP & PROFIT для Transaq
В Чем прелесть робота- помощника:
— Если программа видит сделку, она выставляет Stop Loss и Take Profit с заданными параметрами;
— Если сделка закрыта вручную полностью или частично, снимает/корректирует Стоп-заявки.
ВСЕ МАТЕРИАЛЫ предоставлены для ознакомления, скачивание материала с целью дальнейшей продажи или распространения запрещено.
ВСЕ МАТЕРИАЛЫ НА ДАННОЙ СТРАНИЦЕ САЙТА БЫЛИ НАЙДЕНЫ НА ПРОСТОРАХ ИНТЕРНЕТА И НАХОДИЛИСЬ В СВОБОДНОМ ДОСТУПЕ.
Список примеров ATF по категориям
Индикаторы
%R
extern period = 27;
function init() {
setInitCandles(period - 1);
setBounds(0, period - 1, 0);
}
function calc() {
var p = 1 - period;
var hi = high[p, 0];
line[0] = -100 * (hi - close) / (hi - low[p, 0]);
}
A/D
function init()
{
setInitCandles(1);
if (high == low) {
line[0] = 0;
}
else {
line[0] = (2 * close - high - low) * volume / (high - low);
}
}
function calc()
{
if (high == low) {
line[0] = line[0][-1];
}
else {
line[0] = line[0][-1] +
(2 * close - high - low) * volume / (high - low);
}
}
ADX
function init()
{
setInitCandles(1);
setBounds(0, 1, 0);
}
function calc()
{
var pdi = IndRef("pdimdi", 27)[0];
var mdi = IndRef("pdimdi", 27)[1];
if (pdi and mdi) {
line[0] = 100*abs(pdi-mdi)/(pdi+mdi);
}
}
Alligator
#samewindow
#line 0 solid blue
#line 1 solid red
#line 2 solid green
extern period1 = 13;
extern period2 = 8;
extern period3 = 5;
extern lag1 = 8;
extern lag2 = 5;
extern lag3 = 2;
function init()
{
setBounds(0, lag1, lag1);
setBounds(1, lag2, lag2);
setBounds(2, lag3, lag3);
}
function calc()
{
line[0][lag1] = MovAvg(ind_smma, period1, pt_med);
line[1][lag2] = MovAvg(ind_smma, period2, pt_med);
line[2][lag3] = MovAvg(ind_smma, period3, pt_med);
}
AO
#line 0 colored_hist
extern period1 = 5;
extern period2 = 34;
function init()
{
var max = period1;
if (period2 > max) {max = period2;}
setBounds(0, max - 1, 0);
}
function calc()
{
line[0] = MovAvg(ind_sma, period1, pt_med) -
MovAvg(ind_sma, period2, pt_med);
}
ATR
extern period = 27;
function init()
{
setInitCandles(2);
setBounds(0, 1, 0);
var tr = high[1] - low[1];
if (tr < high[1] - close) {tr = high[1] - close;}
if (tr < close - low[1]) {tr = close - low[1];}
line[0][1] = tr;
}
function calc()
{
var tr = high - low;
if (tr < high - close[-1]) {tr = high - close[-1];}
if (tr < close[-1] - low) {tr = close[-1] - low;}
var alpha = 2 / (period + 1);
line[0] = alpha * tr + (1 - alpha) * line[0][-1];
}
Bollinger Bands
#samewindow
#line 0 solid #00C000
#line 1 solid #006000
#line 2 solid #006000
extern ma_period = 20;
extern sd_period = 20;
extern k = 2;
function init()
{
var m = ma_period;
if (m < sd_period) {m = sd_period;}
setInitCandles(m);
setBounds(0, m, 0);
setBounds(1, m, 0);
setBounds(2, m, 0);
}
function calc()
{
var sd = StdDev(stddev_abs, sd_period, pt_close);
var v = MovAvg(ind_sma, ma_period, pt_close);
line[0] = v;
line[1] = v + k * sd;
line[2] = v - k * sd;
}
CCI
extern period = 20;
extern var_period = 20;
extern k = 0.015;
function init()
{
var m = period;
if (m < var_period) {m = var_period;}
setInitCandles(m);
setBounds(0, m, 0);
}
function calc()
{
var m = 0;
var md = 0;
var i = 0;
while (i < var_period) {
m += typical[-i] / var_period;
i += 1;
}
i = 0;
while (i < var_period) {
md += abs(typical[-i] - m) / var_period;
i += 1;
}
line[0] = (typical - MovAvg(ind_sma, period, pt_typical)) / (k * md);
}
CMO
extern period = 27;
function init()
{
setInitCandles(period);
setBounds(0, period, 0);
}
function calc()
{
var sumUp = 0;
var sumDown = 0;
var i = 0;
while (i < period) {
var d = close[-i] - close[-i - 1];
if (d > 0) {sumUp += d / period;}
else {sumDown += -d / period;}
i += 1;
}
line[0] = 100 * (sumUp - sumDown) / (sumUp + sumDown);
}
DeMarker
#line 0 nodraw
#line 1 nodraw
extern period = 17;
function init()
{
setInitCandles(1);
setBounds(2, period, 0);
}
function calc()
{
if (high > high[-1]) {line[0] = high - high[-1];}
if (low < low[-1]) {line[1] = low[-1] - low;}
var sma_demax = MovAvg(ind_sma, period, line[0]);
var sma_demin = MovAvg(ind_sma, period, line[1]);
var d = sma_demin + sma_demax;
if (d > 0) {
line[2] = sma_demax / (sma_demin + sma_demax);
}
}
Chaikin Volatility
extern period = 10;
var emaold;
var emacur;
function init()
{
setInitCandles(period);
emaold = high - low;
emacur = high[period] - low[period];
line[0] = 100 * (emacur - emaold) / emaold;
setBounds(0, period, 0);
}
function calc()
{
var alpha = 2 / (period + 1);
emaold = alpha * (high[-period] - low[-period]) +
(1 - alpha) * emaold;
emacur = alpha * (high - low) + (1 - alpha) * emacur;
line[0] = 100 * (emacur - emaold) / emaold;
}
EFI
extern period = 13;
function init()
{
setInitCandles(2);
setBounds(0, 1, 0);
line[0][1] = (close[1] - close) * volume[1];
}
function calc()
{
var alpha = 2 / (period + 1);
line[0] = alpha * volume * (close - close[-1]) +
(1 - alpha) * line[0][-1];
}
Elder-rays
extern period = 10;
function calc()
{
var ema = MovAvg(ind_ema, period, pt_close);
line[0] = high - ema;
line[1] = low - ema;
}
Ichimoku Kinko Hyo
#samewindow
extern n1 = 9;
extern n2 = 26;
extern n3 = 52;
function init()
{
setInitCandles(n3);
setBounds(0, n3, 0);
setBounds(1, n3, 0);
setBounds(2, n3, -n2);
setBounds(3, n3, -n2);
setBounds(4, n3 * 2, n2);
}
function calc()
{
line[0] = (high[-n1, 0] + low[-n1, 0]) / 2;
line[1] = (high[-n2, 0] + low[-n2, 0]) / 2;
line[2][-n2] = (line[0] + line[1]) / 2;
line[3][-n2] = (high[-n3, 0] + low[-n3, 0]) / 2;
line[4][n2] = close;
}
Impulse system (A. Elder)
#line 0 nodraw
#line 1 nodraw
#line 2 hist
extern ma_period = 13;
extern macd1 = 12;
extern macd2 = 26;
extern macd_signal = 9;
function init()
{
setInitCandles(1);
setBounds(2, 1, 0);
}
function calc()
{
line[0] = MovAvg(ind_ema, ma_period, pt_close);
line[1] = IndRef("macdhistogram", macd1, macd2, macd_signal,
ind_ema, ind_ema, ind_ema, pt_close)[0];
if (line[0] > line[0][-1] && line[1] > line[1][-1]) {
line[2] = 1;
}
if (line[0] < line[0][-1] && line[1] < line[1][-1]) {
line[2] = -1;
}
}
MA Envelope
#samewindow
#line 0 solid #00c000
#line 1 solid #00c000
extern period = 14;
extern k = 2;
function calc()
{
var ma = MovAvg(ind_ema, period, pt_close);
line[0] = ma * (1 + k/1000);
line[1] = ma * (1 - k/1000);
}
ParabolicSAR
#samewindow
#line 0 dot maroon
extern step = 0.02;
extern init_step = 0.02;
extern max_step = 0.20;
var ac;
var trend;
var ep;
function init()
{
setInitCandles(1);
if (low < low[1]) {
trend = 1;
ep = high[0, 1];
line[0] = low;
}
else {
trend = -1;
ep = low[0, 1];
line[0] = high;
}
ac = init_step;
}
function calc()
{
if (trend == 1) {
if (high > ep) {
ep = high;
ac += step;
if (ac > max_step) {ac = max_step;}
}
line[0] = line[0][-1] + ac * (ep - line[0][-1]);
if (low < line[0]) {
trend = -1;
line[0] = ep;
ep = low;
ac = init_step;
}
}
else {
if (low < ep) {
ep = low;
ac += step;
if (ac > max_step) {ac = max_step;}
}
line[0] = line[0][-1] + ac * (ep - line[0][-1]);
if (high > line[0]) {
trend = 1;
line[0] = ep;
ep = high;
ac = init_step;
}
}
}
PDI, MDI
extern period = 27;
var alpha;
var pdm;
var mdm;
var tr;
function init()
{
alpha = 2/(period+1);
setInitCandles(1);
setCurrentPosition(1);
pdm = high - high[-1];
mdm = low[-1] - low;
if (pdm<0) {pdm = 0;}
if (mdm<0) {mdm = 0;}
if (pdm < mdm) {pdm = 0;}
else {mdm = 0;}
tr = high - low;
if (tr < high - close[-1]) {tr = high - close[-1];}
if (tr < close[-1] - low) {tr = close[-1] - low;}
if (tr) {
line[0] = pdm/tr;
line[1] = mdm/tr;
}
}
function calc()
{
var pdmt = high - high[-1];
var mdmt = low[-1] - low;
if (pdmt<0) {pdmt = 0;}
if (mdmt<0) {mdmt = 0;}
if (pdmt < mdmt) {pdmt = 0;}
else {mdmt = 0;}
var trt = high - low;
if (trt < high - close[-1]) {trt = high - close[-1];}
if (trt < close[-1] - low) {trt = close[-1] - low;}
pdmt = (1 - alpha) * pdm + alpha * pdmt;
mdmt = (1 - alpha) * mdm + alpha * mdmt;
tr = (1 - alpha) * tr + alpha * trt;
if (trt) {
line[0] = pdmt/tr;
line[1] = mdmt/tr;
}
else {
line[0] = line[0][-1];
line[1] = line[1][-1];
}
pdm = pdmt;
mdm = mdmt;
}
RAVI
extern period1 = 7;
extern period2 = 65;
function init()
{
setInitCandles(period2);
setBounds(0, period2, 0);
}
function calc()
{
var m1 = MovAvg(ind_sma, period1, pt_close);
var m2 = MovAvg(ind_sma, period2, pt_close);
line[0] = abs(100 * (m1 - m2) / m2);
}
RSI (EMA based)
extern period = 14;
var up;
var down;
function init()
{
up = 0;
down = 0;
setInitCandles(period - 1);
setBounds(0, period - 1, 0);
var i = 1;
while (i <= period) {
var delta = close[i] - close[i - 1];
if (delta > 0) {up += delta;}
else {down -= delta;}
i += 1;
}
up /= period - 1;
down /= period - 1;
line[0][period] = 100 - 100 / (1 + up / down);
}
function calc()
{
var delta = close - close[-1];
var u = 0;
var d = 0;
if (delta > 0) {u = delta;}
else {d = -delta;}
up = (up*(period - 1) + u) / period;
down = (down*(period - 1) + d) / period;
line[0] = 100 - 100 / (1 + up / down);
}
RVI
#line 2 nodraw
#line 3 nodraw
function init()
{
setInitCandles(4);
setBounds(0, 8, 0);
setBounds(1, 12, 0);
}
function calc()
{
line[2] = (close - open) + 2*(close[-1] - open[-1])
+ 2*(close[-2] - open[-2]) + (close[-3] - open[-3]);
line[3] = (high - low) + 2*(high[-1] - low[-1])
+ 2*(high[-2] - low[-2]) + (high[-3] - low[-3]);
if (noCandle() < 7) {return;}
line[0] = sumLine(2, -4) / sumLine(3, -4);
if (noCandle() < 11) {return;}
line[1] = (line[0] + 2*line[0][-1] + 2*line[0][-2] + line[0][-3]) / 6;
}
ZigZag
#samewindow
#line 0 solid red
extern rate = 1;
var trend = 1;
var last;
var last_n;
var last_extr;
var last_extr_n = 0;
var r;
function init() {
last = close;
line[0] = close;
last_extr = close;
last_extr_n = 0;
last_n = 0;
r = rate / 100;
}
function getCandleLag(var n, var curr)
{
return -(curr - n);
}
function approxLinear(var x1, var y1, var x2, var y2)
{
var n = x2 - x1;
if (!n) {
line[0][getCandleLag(x1, noCandle())] = y1;
return;
}
var k = (y2 - y1) / n;
var i = 0;
while (i <= n) {
line[0][getCandleLag(x1 + i, noCandle())] = y1 + k*i;
i += 1;
}
}
function myFindMax(var from, var to)
{
var m = high[getCandleLag(from, noCandle())];
var n = from;
var i = from + 1;
while (i <= to) {
var x = high[getCandleLag(from, noCandle())];
if (x > m) {
m = x;
n = i;
}
i += 1;
}
return n;
}
function myFindMin(var from, var to)
{
var m = low[getCandleLag(from, noCandle())];
var n = from;
var i = from + 1;
while (i <= to) {
var x = low[getCandleLag(from, noCandle())];
if (x < m) {
m = x;
n = i;
}
i += 1;
}
return n;
}
function calc()
{
if (trend == 1) {
if (close > last_extr) {
last_extr = high;
last_extr_n = noCandle();
approxLinear(last_n, last, noCandle(), high);
}
else {
approxLinear(last_extr_n, last_extr, noCandle(), low);
}
}
if (trend == -1) {
if (close < last_extr) {
last_extr = low;
last_extr_n = noCandle();
approxLinear(last_n, last, noCandle(), low);
}
else {
approxLinear(last_extr_n, last_extr, noCandle(), high);
}
}
if (abs(close - last_extr) / last_extr > r) {
var old_n = last_n;
var old = last;
last_n = last_extr_n;
last = last_extr;
if (trend > 0) {
trend = -1;
last_extr_n = myFindMin(last_n, noCandle());
last_extr = low[getCandleLag(last_extr_n, noCandle())];
}
else {
trend = 1;
last_extr_n = myFindMax(last_n, noCandle());
last_extr = high[getCandleLag(last_extr_n, noCandle())];
}
approxLinear(old_n, old, last_n, last);
approxLinear(last_n, last, noCandle(), close);
}
}
Pivot points
#samewindow
#line 0 solid blue
#line 1 dashed green
#line 2 dashed red
#line 3 dot green
#line 4 dot red
var day; // current day
var nday; // number of day in chart
var ph; // high of yesterday
var pl; // low of yesterday
var pc; // close of yesterday
var cl; // today's low
var ch; // today's high
function init()
{
nday = 1;
day = getDay(getCandleTime());
}
function drawLines()
{
line[0] = (ph + pl + pc) / 3; // Pivot point
line[1] = 2*line[0] - ph; // Support 1
line[2] = 2*line[0] - pl; // Resistance 1
line[3] = line[0] - (line[2] - line[1]); // Resistance 2
line[4] = line[0] + (line[2] - line[1]); // Support 2
}
function calc()
{
if (nday == 1) {
if (getDay(getCandleTime()) != day) {
nday = 2;
day = getDay(getCandleTime());
ph = high;
pl = low;
}
}
else if (nday == 2) {
if (getDay(getCandleTime()) != day) {
nday = 3;
day = getDay(getCandleTime());
cl = low;
ch = high;
pc = close[-1];
drawLines();
setBounds(0, noCandle(), 0);
setBounds(1, noCandle(), 0);
setBounds(2, noCandle(), 0);
setBounds(3, noCandle(), 0);
setBounds(4, noCandle(), 0);
}
else {
if (high > ph) {ph = high;}
if (low < pl) {pl = low;}
}
}
else {
if (getDay(getCandleTime()) != day) {
nday += 1;
day = getDay(getCandleTime());
ph = ch;
pl = cl;
pc = close[-1];
cl = low;
ch = high;
}
else {
if (high > ch) {ch = high;}
if (low < cl) {cl = low;}
}
drawLines();
}
}
Stochastic Momentum Index
#line 0 nodraw
#line 1 nodraw
#line 2 nodraw
#line 3 nodraw
#line 4 nodraw
#line 5 nodraw
#line 7 solid red
extern lp = 13;
extern sm = 25;
extern dsmp = 2;
extern sig = 3;
function init()
{
if (countCandles() < lp) {
lackHistory();
}
setInitCandles(lp);
setBounds(0, lp, 0);
}
function calc()
{
line[0] = close - .5 * high[-lp,0] + low[-lp,0];
line[1] = MovAvg(ind_ema, sm, line[0]);
line[2] = MovAvg(ind_ema, dsmp, line[1]);
line[3] = high[-lp, 0] - low[-lp, 0];
line[4] = MovAvg(ind_ema, sm, line[3]);
line[5] = 0.5*MovAvg(ind_ema, dsmp, line[4]);
line[6] = 100 * line[2] / line[5];
line[7] = MovAvg(ind_ema, sig, line[6]);
}
Ultimate Oscillator
// Данный индикатор может быть существенно оптимизирован
// с точки зрения скорости расчета. Улучшенный пример
// будет приведен позже
#line 0 nodraw
#line 1 nodraw
extern period = 7;
function init()
{
if (countCandles() < period * 4 + 1) {
lackHistory();
}
setInitCandles(1);
setBounds(0, period*4 + 1, 0);
}
function sumLine1(var n)
{
var i = 0;
var s = 0;
while (i < n) {
s += line[0][-i];
i += 1;
}
return s;
}
function sumLine2(var n)
{
var i = 0;
var s = 0;
while (i < n) {
s += line[1][-i];
i += 1;
}
return s;
}
function avg(var n)
{
return sumLine1(n) / sumLine2(n);
}
function calc()
{
if (low < close[-1]) {
line[0] = close - low;
}
else {
line[0] = close - close[-1];
}
var h;
var l;
if (high > close[-1]) {h = high;}
else {h = close[-1];}
if (low < close[-1]) {l = low;}
else {l = close[-1];}
line[1] = h - l;
if (noCandle() > period*4 + 1) {
line[2] = 100 * (4*avg(period) + 2*avg(period*2) + avg(period*4)) / 7;
}
}
Медианный фильтр
#samewindow
extern period = 15;
var window;
static lastvalue;
function init()
{
window = new_object("array");
setBounds(0, period + 1, 0);
setInitCandles(period + 1);
}
function findMed()
{
window.clear();
var i = 1;
while (i <= period) {
window.push(close[-i]);
i += 1;
}
i = 0;
while (i <= period / 2) {
var min_n = i;
var j = min_n + 1;
while (j < window.size()) {
if (window[min_n] > window[j]) {
min_n = j;
}
j += 1;
}
if (min_n > i) {
var tmp = window[min_n];
window[min_n] = window[i];
window[i] = tmp;
}
i += 1;
}
lastvalue = window[i - 1];
return lastvalue;
}
function onNewCandle()
{
findMed();
}
function calc()
{
if (!isHistoryCalculated()) {
findMed();
}
line[0] = lastvalue;
}
Сигналы
Пересечение ценой скользящей средней
#samewindow
#line 0 solid red
extern period = 9;
var trend = 0;
function init()
{
setInitCandles(1);
}
function calc()
{
line[0] = MovAvg(ind_ema, period, pt_close);
if (trend == 1 and close < line[0]) {
signal::alert("Продажа: " + getSecName() +
" пересекла сверху вниз скользящую среднюю.");
}
if (trend == -1 and close > line[0]) {
signal::alert("Покупка: " + getSecName() +
" пересекла снизу вверх скользящую вреднюю.");
}
if (close > line[0]) {trend = 1;}
else if (close < line[0]) {trend = -1;}
}
Пересечение двух скользящих средних
#samewindow
#line 0 solid red
extern fast = 9;
extern slow = 14;
var trend = 0;
function init()
{
setInitCandles(1);
}
function calc()
{
line[0] = MovAvg(ind_ema, fast, pt_close);
line[1] = MovAvg(ind_ema, slow, pt_close);
if (trend == 1 and line[0] < line[1]) {
signal::alert("Продажа: по " + getSecName() +
" быстрая MA пересекла медленную сверху вниз.");
}
if (trend == -1 and line[0] > line[1]) {
signal::alert("Покупка: по " + getSecName() +
" медленная MA пересекла быструю снизу вверх.");
}
if (line[1] < line[0]) {trend = 1;}
else if (line[1] > line[0]) {trend = -1;}
}
Примеры технических функций
Сохранение данных в файл
// Данный код не несет полезной функии,
// а лишь демонстрирует работу с файлами.
// Подробности смотрите в руководстве.
static c1 = 0;
static c2 = 0;
var file;
function init()
{
file = new_object("file");
file.ropen("data.txt");
if (file.isopen()) {
c1 = file.readLn();
c2 = file.readLn();
file.close();
}
file.wopen("data.txt");
}
function onNewCandle()
{
c2 += 1;
file.seek(0);
file.writeLn(c1);
file.writeLn(c2);
}
function calc()
{
if (isHistoryCalculated()) {
c1 += 1;
}
line[0] = 0;
}
Сохранение информации о сделках в файл
// Данный код не несет полезной функии,
// а лишь демонстрирует работу с файлами.
// Подробности смотрите в руководстве.
var file;
function init()
{
file = new_object("file");
file.waopen("data.txt");
}
function saveTrade(var id)
{
var trade = getTrade(id);
if (trade["operation"] == OP_BUY) {
file.write("BUY ");
}
else {
file.write("SELL ");
}
file.write(trade["quantity"]);
file.write(" lots at price ");
file.writeLn(trade["price"]);
}
function onClientTrade(var id)
{
file.write("Client order: ");
saveTrade(id);
}
function onATFTrade(var id)
{
file.write("ATF order: ");
saveTrade(id);
}
function calc()
{
line[0] = 0;
}
Регулярная синхронизация времени клиента со временем сервера
extern interval = 15;
function synchronize()
{
setSystemTime(getServerTime());
}
function init()
{
synchronize();
setTimer("synchronize", interval * 60, TIMER_PERIODICALLY);
}
Данный скрипт не содержит в себе каких-либо линий, поэтому может использоваться лишь в совокупности с каким-либо индикатором или роботом ATF.
Торговые роботы
Простая стратегия "Лесенка"
// Данная демонстрационна стратегия продает
// при любом движении цены вверх на step_percent
// процентов и покупает при движении цены вниз
// на step_percent процентов в ожидании коррекции.
// При этом используются лимитированные заявки,
// постоянно выставлено пять-шесть лимитированных
// заявок на одинаковом расстоянии. Смотрите
// результаты тестировщика ATF для более наглядного
// представления.
extern step_percent = 0.2;
extern num = 5;
extern amount = 1;
var step;
static buy_count = 0;
static sell_count = 0;
function init()
{
step = step_percent / 100;
}
function buy(var price)
{
trade_action::buyMultiple(amount, ::lots, price);
buy_count += 1;
}
function sell(var price)
{
trade_action::sellMultiple(amount, ::lots, price);
sell_count += 1;
}
function setOrders()
{
var i = 1;
while (i <= num) {
buy(close * (1 - i*step));
sell(close * (1 + i*step));
i += 1;
}
}
function onHistoryCalculated()
{
setOrders();
}
function onATFOrder(var id)
{
var order = getOrder(id);
if (order["status"] == OS_MATCHED) {
if (order["operation"] == OP_BUY) {
buy_count -= 1;
var newprice = order["price"] * (1 - step * num);
var oldprice = order["price"] * (1 + step);
if (buy_count < num) {buy(newprice);}
sell(oldprice);
}
else {
sell_count -= 1;
var newprice = order["price"] * (1 + step * num);
var oldprice = order["price"] * (1 - step);
if (sell_count < num) {sell(newprice);}
buy(oldprice);
}
}
}
Пример программирования торговых функций привязанных к клавиатуре
/*
При добавлении данного скрипта в торговое окно, в данном окне
становится возможно использовать дополнительные торговые функции.
Торговая команда набирается на клавиатуре с зажатой клавишей
shift и имеет двухбуквенное название. Доступны следующие команды:
BS - выставить одновременно заявки на покупку и продажу
CA - снять все заявки
CM - снять последние две заявки
UP - сдвинуть заявки вверх
DN - сдвинуть заявки вниз
CL - сдвинуть заявки ближе друг к другу
OP - расширить диапазон между заявками
FG - "забыть" старую выставленную позицию
При добавлении данного скрипта на график доступны для настройки
следующие параметры:
eps - начальное расстояние между выставляемыми заявками
move_eps - шаг сдвига заявок
range_eps - относительное изменение расстояния между заявками
quantity - объем заявок
Данный скрипт вряд ли имеет действительно полезный смысл, но
наглядно демонстрирует каким образом вы можете писать собственные
сложные торговые функции, управляемые с клавиатуры.
*/
#samewindow
#line 0 nodraw
extern eps = 0.005;
extern move_eps = 0.0005;
extern range_eps = 0.00025;
extern quantity = 1;
static prevKey = 0;
static buyord = 0;
static sellord = 0;
function cancelAll()
{
trade_action::cancelAllOrders();
buyord = 0;
sellord = 0;
}
function onOrder(var id)
{
var error;
if (id != buyord and id != sellord) {
return;
}
var order = getOrder(id);
if (order["status"] != OS_ACTIVE) {
cancelAll();
}
}
function buy(var price)
{
if (buyord) {trade_action::cancelOrder(buyord);}
buyord = trade_action::buyMultiple(quantity, ::lots, price);
if (not buyord) {
signal::outputMultiple(getLastErrorMessage());
}
}
function sell(var price)
{
if (sellord) {trade_action::cancelOrder(sellord);}
sellord = trade_action::sellMultiple(quantity, ::lots, price);
if (not sellord) {
signal::outputMultiple(getLastErrorMessage());
}
}
function moveDown()
{
if (not buyord or not sellord) {return;}
var b = getOrder(buyord);
var s = getOrder(sellord);
buy(b["price"] * (1 - move_eps));
sell(s["price"] * (1 - move_eps));
}
function moveUp()
{
if (not buyord or not sellord) {return;}
var b = getOrder(buyord);
var s = getOrder(sellord);
buy(b["price"] * (1 + move_eps));
sell(s["price"] * (1 + move_eps));
}
function makeCloser()
{
if (not buyord or not sellord) {return;}
var b = getOrder(buyord);
var s = getOrder(sellord);
buy(b["price"] * (1 + range_eps));
sell(s["price"] * (1 - range_eps));
}
function makeWider()
{
if (not buyord or not sellord) {return;}
var b = getOrder(buyord);
var s = getOrder(sellord);
buy(b["price"] * (1 - range_eps));
sell(s["price"] * (1 + range_eps));
}
function buysell()
{
if (buyord or sellord) {return;}
buy(close*(1-eps));
sell(close*(1+eps));
}
function forget()
{
buyord = 0;
sellord = 0;
}
function cancelMine()
{
if (buyord) {
trade_action::cancelOrder(buyord);
buyord = 0;
}
if (sellord) {
trade_action::cancelOrder(sellord);
sellord = 0;
}
}
function onKeyDown(var key)
{
if (isKeyPressed(KEY_LSHIFT)) {
if (prevKey == chr2num("B") and key == chr2num("S")) {
buysell();
}
if (prevKey == chr2num("C") and key == chr2num("A")) {
cancelAll();
}
if (prevKey == chr2num("C") and key == chr2num("M")) {
cancelMine();
}
if (prevKey == chr2num("U") and key == chr2num("P")) {
moveUp();
}
if (prevKey == chr2num("D") and key == chr2num("N")) {
moveDown();
}
if (prevKey == chr2num("C") and key == chr2num("L")) {
makeCloser();
}
if (prevKey == chr2num("O") and key == chr2num("P")) {
makeWider();
}
if (prevKey == chr2num("F") and key == chr2num("G")) {
forget();
}
prevKey = key;
}
}
Равномерное совершение сделок (ATF 1.19)
#samewindow
#line 0 nodraw
// За какое время продать/купить всё
extern time;
// Как часто совершать сделки
extern frequency;
// Сколько всего лотов купить/продать
// Если >0, то покупка, если <0 - продажа
extern quantity;
// Погрешность частоты совершения сделок
extern freq_eps;
// Погрешность объема в отдельной сделке
extern quantity_eps;
static time_to;
static time_elapsed;
static quantity_elapsed;
static ready = 0;
static x_rand = 1;
function makeTrade(var q)
{
var trnid;
if (quantity > 0) {
signal::outputMultiple("Покупаю " + q + " лотов.");
trnid = trade_action::buyMultiple(q, ::lots);
}
else {
signal::outputMultiple("Продаю " + q + " лотов.");
trnid = trade_action::sellMultiple(q, ::lots);
}
if (not trnid) {
signal::outputMultiple(getLastErrorMessage());
}
}
function printStats()
{
signal::outputMultiple("-----");
if (quantity > 0) {
signal::outputMultiple("Осталось купить " + quantity_elapsed +
" бумаг за " + time_elapsed + " секунд.");
}
else {
signal::outputMultiple("Осталось продать " + quantity_elapsed +
" бумаг за " + time_elapsed + " секунд.");
}
}
function arrangeNewTransaction()
{
if (not isTradingAllowed() or not ready) {return;}
time_elapsed = time_to - getSystemTime();
var t = rand_uniform(frequency - freq_eps, frequency + freq_eps);
if (t + getSystemTime() > time_to) {
t = time_to - getSystemTime();
}
signal::outputMultiple("Следующая сделка через " + round(t) + " секунд.");
setTimer("trade", t*1000, TIMER_AFTERDELAY);
}
function onStopRobot()
{
if (quantity_elapsed) {
time_elapsed = time_to - getSystemTime();
printStats();
}
else {
signal::outputMultiple("Задание выполнено.");
ready = 0;
}
}
function trade()
{
time_elapsed = time_to - getSystemTime();
if (not isTradingAllowed() or not ready) {return;}
if (time_elapsed < frequency) {
makeTrade(quantity_elapsed);
signal::outputMultiple("Все бумаги проданы!");
}
else {
var q = quantity_elapsed / (time_elapsed / frequency);
q = round(rand_uniform(q - quantity_eps, q + quantity_eps));
if (q > quantity_elapsed) {q = quantity_elapsed;}
if (q > 0) {
makeTrade(q);
quantity_elapsed -= q;
printStats();
}
else {
signal::outputMultiple("Решил отложить сделку.");
printStats();
}
if (quantity_elapsed) {arrangeNewTransaction();}
else {onStopRobot();}
}
}
function init()
{
time_elapsed = time;
time_to = getSystemTime() + time;
quantity_elapsed = abs(quantity);
}
function onStartRobot()
{
if (quantity != 0 and frequency > 0 and time > 0) {
ready = 1;
printStats();
arrangeNewTransaction();
}
else {
signal::output("Заданы некорректные параметры для торговли; выполнение скрипта отменено.");
ready = 0;
}
}
Максимум/минимум в конкретный интервал времени
// Функции getHigh и getLow вычисляют значения
// high и low в заданный промежуток времени
// В качестве примера сам скрипт вычисляет значения
// high и low за время с 9 до 11 и отрисовывает две
// две линии, соответствующие этим уровням
static H;
static L;
function getHigh(var from, var to)
{
var n = getCandleByTime(from);
setCurrentPosition(n);
if (getCandleTime() != from) {
from = n + 1;
}
else {
from = n;
}
setCurrentPosition(0);
to = getCandleByTime(to);
var h = high[from, to];
restoreCurrentPosition();
return h;
}
function getLow(var from, var to)
{
var n = getCandleByTime(from);
setCurrentPosition(n);
if (getCandleTime() != from) {
from = n + 1;
}
else {
from = n;
}
setCurrentPosition(0);
to = getCandleByTime(to);
var h = low[from, to];
restoreCurrentPosition();
return h;
}
function init()
{
var from = getTimeObject(9, 0);
var to = getTimeObject(11, 0);
H = getHigh(from, to);
L = getLow(from, to);
}
function calc()
{
line[0] = H;
line[1] = L;
}


















