МТС – взгляд дилетанта. Часть 2 – Стопы.

Продолжаем.

Что имеем:

  1. можем получать сигналы,
  2. можем делать сделки,
  3. записываем нашу сделку в файл,
  4. записываем наш результат в файл.

Сегодня кое что поменяем и добавим стопы.

На самом деле стопы в ATF Transaq делаются своим способом формирования заявки. Об этом нужно читать в документации и на форуме (есть примеры). Что меня не устроило во всем этом. Да в общем-то только одно: в количестве нужно указывать % а не кол-во контрактов (на FORTS) что пока не совсем.. или точнее, совсем не удобно.

МЕНЯЕМ CODE#

Добавим переменные для стоп сигналов

12
13
static loss;		// кол-во в пунктах (расчетный)
static stopLoss = 0.5;	// кол-во в процентах

Далее немного изменим функцию:

35
36
// РОБОТ СДЕЛАЛ СДЕЛКУ
function onATFTrade(var id) {

В документации есть подробное описание всех функций по работе с заявками. Мы использовали здесь проверку на возможность самого получения статуса (иначе говоря, есть ли связь с биржей) а потом проверку статуса заявки, и если она исполнена — обнуляем переменную.
Нас сейчас интересует эта функция.
Что мы делали? Мы записывали в файл новую сделку при положительном балансе (точнее если он не равен 0) и мы затирали файл профита вместе с балансом, если баланс был равен нулю.

Так вот затирать файл профита нужно всегда при любой сделке. Оно и понятно, и так пишем (обновим) этот код:

	// стираем файл профита
	file = new_object("file");
	file.wopen("./!DATA/T01/profit.txt"); // открыли на запись
	file.writeLn(0);
	file.close(); // закрыли

На выходе получаем:

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// РОБОТ СДЕЛАЛ СДЕЛКУ
function onATFTrade(var id) {
	timer = getFormattedTime(getServerTime());
	file = new_object("file");
	// чтение баланса из файла
	file.ropen("./!DATA/T01/balance.txt"); // открыли на чтение
	balance = file.readLn();
	file.close(); // закрыли
 
	var operation;
	var newBalance;	// новый баланс после сделки
	var trade = getTrade(id);
	if (trade["operation"] == -1){
		operation = "SELL ";
		newBalance = (balance)-trade["quantity"];}
	if (trade["operation"] == 1) {
		operation = "BUY ";
		newBalance = (balance)+trade["quantity"];}
	signal::outputMultiple (name + operation + trade["quantity"] + "шт. по " + trade["price"] + " | " + timer);
 
if (newBalance!=0) { // если мы в позиции
	// запись баланса после сделки
	file.wopen("./!DATA/T01/balance.txt"); // открыли на запись
	file.writeLn(newBalance);
	file.writeLn(trade["price"]);
	file.writeLn("время: " + timer);
	file.close(); // закрыли
 	// стираем файл профита
	file = new_object("file");
	file.wopen("./!DATA/T01/profit.txt"); // открыли на запись
	file.writeLn(0);
	file.close(); // закрыли
	}
 
if (newBalance==0) { // если закрыли позицию
	// стираем файл баланса
	file = new_object("file");
	file.wopen("./!DATA/T01/balance.txt"); // открыли на запись
	file.writeLn(0);
	file.writeLn();
	file.writeLn();
	file.close(); // закрыли
	// стираем файл профита
	file = new_object("file");
	file.wopen("./!DATA/T01/profit.txt"); // открыли на запись
	file.writeLn(0);
	file.close(); // закрыли
	}
}

Перед подачей заявок, у нас был код — снятие возможных заявок, которые не исполнились.
Добавим проверку:

103
104
105
106
107
108
109
110
// ПРОВЕРКА СТАТУСА ЗАЯВОК
var order = getOrder(order_id);
var status = order["status"];
if (status!= OS_INACTIVE){ // если связь с биржей есть и статус заявки понятен
	if (status == OS_MATCHED) { // если заявка исполнена
		order_id = 0;
	}
}

STOP LOSS

Далее ведем расчет условий исполнения стопа. Вообще все расчеты связанные с закрытием позиций, надо вести если на балансе что-то есть. Так что это и будет нашим основным условием. (в прошлый раз мы придерживались именно этой логики. Осталось вписать расчеты).

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
loss = close/100*stopLoss; 	// расчет stopLoss в пунктах
if (result <= -loss) { 		// убыток! Ставим СТОП LOSS
	if (balance > 0) {
		// снимаем предыдущую (стоп) заявку
		if (order_id != 0) {trade_action::cancelOrder(order_id); order_id = 0;}
		trade_action::sell(abs(balance), ::lots,close-slip);
		signal::output (name + " закрыл лонг по стопу | " + timer);
		}
	if (balance < 0) {
		// снимаем предыдущую (стоп) заявку
		if (order_id != 0) {trade_action::cancelOrder(order_id); order_id = 0;}
		trade_action::buy(abs(balance), ::lots,close+slip);
		signal::output (name + " закрыл шорт по стопу | " + timer);
		}
	}

По тому же принципу мы можем ставить Take Profit, а так же ставить следящий стоп.

Но думаю для следящего стопа нужен пример, так что в следующий раз опишу расчет Trail Stop.

В ATF он так же имеется, НО как я говорил выше — все стопы на FORTS пока ставятся в % а не в кол-ве контрактов. Когда это исправят, можно переписать код, но с другой стороны надо ли?

По мне так лучше я оставлю такой расчет. Единственный минус во всем в этом — постоянное подключение к сети. Если вдруг случилось непредвиденное, а стопа на бирже нет — тут уже ничего не поделаешь. Но я решил этот вопрос надежным каналом связи.

МТС – взгляд дилетанта. Часть 2 – Стопы.: 4 комментария

  1. Уважаемый автор скрипта !
    Вопросы новичка-непрофессионала(тяжело освоить прогр-ие без базового образования,приходится начать с того, искать коды,сравнивать,»склеевать» и тд.)
    1.Как выгледить Ваш код полностью(у меня когда фрагменты »склеел»показывает ошибки или фаил не открывается)
    2.Применим ли Ваш код на ММВБ.
    3.Как избавиться от множества типвых сигналов и заявок т.е.предусмотрен ли отдельная функция регулирующее заявки,допустим купил остальные сигналы или заявки на покупку игнорируется.

    1. Сергей привет
      Этот робот довольно пожилой. Возможно функции для Транзака уже стали лучше и бодрее, поэтому лучше смотреть в настоящее чем в прошлое. Код робота конечно где-то есть, но Транзак не очень то и люблю. В основном работаю на Quik. Для меня это сейчас лучший и главное понятный вариант

Добавить комментарий