So, let’s dream up and come up with our own robot, which may well be used for trading in a number of cases.
Let’s start with an idea, because everything great begins with an idea.
So, we would like our program to allow:
– work only inside the day;
– earn the income level we set per day;
– have a built-in loss limiter;
– work in two directions, both long and short;
– have different tracking strategies.
– display in a separate window all the current parameters of the algorithm with maximum detail. This will allow you to quickly understand what is happening in general, as well as make adjustments to the robot’s work.
So, it seems not bad. This is an idea, but is it possible to implement it? In fact, the perfect robot, of course, never turns out. But the beauty of programming is that in the course of testing your development, you will hone it to perfection by cutting off “bugs”. We do not pretend to give such an ideal program. Nevertheless, we will give a very interesting code that has sufficient complexity with the attraction of almost all the features of the ATF language to achieve the task.
We will also add one very popular function to our algorithm. The fact is that the robot can scribble deals at an unthinkable speed. And the more transactions, the higher the commission. When working with small amounts, the commission rule of 0.0375%, but not less than 41 rubles per transaction can quickly ruin us. When closing transactions on the market, it often turns out that instead of one transaction, we sometimes get up to 10 transactions, for example, we need to sell 100 lots, small applications for 3, 5, 10 lots are sitting in the glass. I.e. to get 100 lots, we need to collect all those who are sitting in a glass to a large one, who will finally swallow our remainder with one transaction. Well, that’s it. We will add a function that will look for a position in the glass where the big guy is sitting and we will immediately close the deal at a time! Brilliant idea, isn’t it? This dramatically adds value to our robot.
Please note that this robot is working (when checking the script, it will give “Ok”), but you should use it to earn money at your own risk, since the author cannot guarantee that there will be no losses when using this robot. We recommend that you first familiarize yourself with his work on small amounts and identify the features of his work. In the variables, I set a limit for the amount of no more than 1000 rubles. Of course, you can set the desired value.
Listing 2. Robot “MoneyTrain release 1” (author’s edition)
//Trade Robot MoneyTrain rel.1
#samewindow
#line 0 nodraw
//#line 0 dashed #C0C0C0
//#line 1 dashed #AAC0C0
//List of variables for managing the Money Train strategy
//Risk step in %
static procent_profit = 0.5;
//Duration of reaction to price change
extern time_shift_second = 5;
//Enable price tracking 1 disable 0
extern price_tracking = 1;
//Limit of the amount involved in trading in rubles
extern summ_limit = 1000;
//delay for determining the direction of market movement at the start
extern timer2_shift_second = 3;
//desired profit in % during the day (excluding taxes and broker fees)
static wish_profit_in_procent = 1.5;
//The allowed number of transactions, after reaching the program stops or earlier if the desired profit is received
extern orders_count_limit = 6;
// The number of cycles to monitor the level of losses. To disable it is 0.
extern loss_cycle = 0;
//difference when comparing loss growth
extern loss_procent = 0.25;
//a strategy for tracking market noises with adaptation to them
//use the tracking strategy
extern use_tracking_strategy = 1;
//the delay interval in hours
static tracking_interval_in_h = 0.5;
//allowed number of transactions per interval
static orders_count_for_tracking = 3;
//noise response coefficient. The risk step is multiplied/divided by this coefficient. during the current tracking interval
static noise_koeff = 1.33;
//Price for 1 transaction in rubles
static price_of_trade = 41;
//We will also need variables to access files.
var file;
var file1;
var file2;
//1 – regular application, 0 – stop application
var flow_order;
var stop_id;
static flow_price;
static timer1 = 0;
static timer2 = 0;
var timer2_price;
var book;
static start_balance = 0;
static stop_algoritm;
static orders_count = 0;
static price_at_start;
// loop control variables
static summ_timer = 0;
static orders_for_interval = 0;
static flow_profit;
static cycle_i = 0;
static cycle_start_value;
static cycle_end_value;
static cycle_direction = 0;
static step_book;
static n_lots;
// function for writing an event to a file.
function message_write(var mess)
{
if (file2.isopen())
{
file2.writeLn(mess);
}
}
// Actions when starting the ATF script. It is placed before all functions. The message_write function does not interfere with this rule.
function init()
{
//We are synchronizing time with the exchange server.
var exec_time = getSystemTime();
var dt = getFormattedDateTime(exec_time);
var nl;
// Creating a new file to store the messages generated by the program
file = new_object(“file”);
file.waopen(“mtrain_log.txt”);
file.writeLn(dt);
file2 = new_object(“file”);
file2.waopen(“mtrain_log_all.txt”);
// We issue a message to the message window and write it also to the message records file
signal::outputMultiple(“Init start”);
message_write(“Init start”);
// Stopping the second timer if it was activated
timer2_price = close;
signal::outputMultiple(“Close is ” + close+ “!”);
message_write(“Close is ” + close+ “!”);
signal::outputMultiple(“Init end”);
message_write(“Init end”);
// Creating a second timer
timer2 = setTimer(“onTimer2”, timer2_shift_second * 1000, TIMER_PERIODICALLY);
// Creating an object to access the glass
book = new_object(“book”);
book.subscribe();
stop_algoritm = false;
// we take into account the tax rate of 13 in profit%
wish_profit_in_procent = wish_profit_in_procent * 1.13;
step_book = 0;
}
// Let’s create a function to request the number of shares in the lot of the instrument, request the current balance on the account. We set a margin of 5% so as not to exceed the account balance
function get_number_of_lots(var act_price_lot)
{
var rl;
var sl;
var res;
var res1;
rl = getLotSize();
res1 = getMoneyBalance();
signal::outputMultiple(“Balance: ” + res1 + ” rub”);
message_write(“Balance: ” + res1 + ” rub”);
sl = summ_limit * 0.95;
if (res1 < summ_limit)
{
sl = res1;
}
res = int(sl/rl/act_price_lot);
signal::outputMultiple(“Number of lots ” + res + “!”);
message_write(“Number of lots ” + res + “!”);
return res;
}
// A function for processing and writing data about completed transactions to a file
function saveTrade(var order)
{
// Synchronize the system time with the server time
setSystemTime(getServerTime());
var exec_time = getSystemTime();
var dt = getFormattedDateTime(exec_time);
var sec_array = new_object(“array”);
var size_a;
var rl;
file.write(“Order: “);
file.write(” ” + order[“orderno”] + “; “);
if (order[“operation”] == OP_BUY) {
file.write(“BUY “);
}
else {
file.write(“SELL “);
}
file.write(dt + “; “);
file.write(getSecName() + “; “);
file.write(order[“quantity”]);
file.write(” lots at price “);
sec_array = getAllTradeIDsBySec();
size_a = sec_array.size();
size_a = getTrade(sec_array[size_a-1]);
if (order[“price”] == -1)
{
file.writeLn(size_a[“price”]);
}
else
{
file.writeLn(order[“price”]);
}
}
// writing the transaction ID produced by Timer2 to a file trnid.txt
function trnid_write(var tr_nid)
{
file1 = new_object(“file”);
file1.wopen(“trnid.txt”);
file1.seek(0);
file1.writeLn(tr_nid);
file1.close();
signal::outputMultiple(“TRNID was wrote”);
message_write(“TRNID was wrote”);
}
// reading the transaction ID produced by Timer2 from a file trnid.txt
function trnid_read()
{
var res;
file1 = new_object(“file”);
file1.ropen(“trnid.txt”);
if (file1.isopen()) {
res = file1.readLn();
file1.close();
signal::outputMultiple(“TRNID ” + res);
message_write(“TRNID ” + res);
return res;
}
}
// The function of issuing applications
function set_order(var order)
{
var stop = new_object(“hash”);
var act_price;
var rl = 0;
var order_quantity = 0;
var tr;
var sec_array = new_object(“array”);
var size_a;
signal::outputMultiple(“Set_Order is started”);
message_write(“Set_Order is started”);
if (isTradingAllowed()) {
signal::outputMultiple(“Order Op is ” + order[“orderno”]);
message_write(“Order Op is ” + order[“orderno”]);
sec_array = getAllTradeIDsBySec();
size_a = sec_array.size();
size_a = getTrade(sec_array[size_a-1]);
// Application for sale
if (order[“operation”] == OP_SELL) {
stop[“operation”] = OP_BUY;
if (order[“price”] == -1) {
act_price = size_a[“price”]*(1 + procent_profit/100);
}
else
{
act_price = order[“price”]*(1 + procent_profit/100);
}
signal::outputMultiple(“Order Op is ” + “SELL”);
message_write(“Order Op is ” + “SELL”);
}
// Purchase request
if (order[“operation”] == OP_BUY) {
stop[“operation”] = OP_SELL;
if (order[“price”] == -1) {
act_price = size_a[“price”]/(1 + procent_profit/100);
}
else
{
act_price = order[“price”]/(1 + procent_profit/100);
}
signal::outputMultiple(“Order Op is ” + “BUY”);
message_write(“Order Op is ” + “BUY”);
}
order_quantity = n_lots;
signal::outputMultiple(“Price is ” + act_price + “!”);
message_write(“Price is ” + act_price + “!”);
//Part of Stop Loss
stop[“sl_activationprice”] = act_price;
stop[“sl_quantity”] = order_quantity*2;
stop[“sl_usecredit”] = true;
// Placing a stop order on the market
//stop_id = trade_action::transactMultiple(stop);
// Processing of the timer of the algorithm for tracking the current price
if (price_tracking)
{
signal::outputMultiple(“Timer1 was checked “);
message_write(“Timer1 was checked “);
if (timer1)
{
delTimer(timer1);
timer1 = 0;
signal::outputMultiple(“Timer1 was killed “);
message_write(“Timer1 was killed “);
}
timer1 = setTimer(“onTimer1”, time_shift_second * 1000, TIMER_PERIODICALLY);
}
}
signal::outputMultiple(“Set_Order is end”);
message_write(“Set_Order is end”);
}
// The function of processing the application event
function onOrder(var id)
{
signal::outputMultiple(“OnOrder is activated”);
message_write(“OnOrder is activated”);
signal::outputMultiple(“OnOrder ID is ” + id);
message_write(“OnOrder ID is ” + id);
var order = getOrder(id);
signal::outputMultiple(“Order Number is ” + order[“orderno”]);
message_write(“Order Number is ” + order[“orderno”]);
signal::outputMultiple(“Order status is ” + order[“status”]);
message_write(“Order status is ” + order[“status”]);
if (order[“status”] == OS_MATCHED) {
if (timer1)
{
delTimer(timer1);
timer1 = 0;
signal::outputMultiple(“Timer1 was killed “);
message_write(“Timer1 was killed “);
}
if (price_at_start == 0)
{
price_at_start = order[“price”];
}
orders_count += 1;
signal::outputMultiple(“ORDERS_COUNT is now ” + orders_count);
message_write(“ORDERS_COUNT is now ” + orders_count);
if (orders_count >= orders_count_limit)
{
stop_algoritm = true;
}
trnid_write(id);
saveTrade(order);
if (stop_algoritm == true)
{
if (timer1)
{
delTimer(timer1);
timer1 = 0;
signal::outputMultiple(“Timer1 was killed “);
message_write(“Timer1 was killed “);
}
signal::alert(“Trade was stoped”);
message_write(“Trade was stoped”);
}
else
{
set_order(order);
}
}
}
// Transaction event processing function
function onTrade(var id)
{
orders_for_interval += 1;
}
// Function for stop request triggering events
function onStopOrder(var id)
{
signal::outputMultiple(“OnStopOrder is activated”);
message_write(“OnStopOrder is activated”);
var order = getStopOrder(id);
if (order[“status”] == OS_MATCHED) {
if (timer1)
{
delTimer(timer1);
signal::outputMultiple(“Timer1 was killed “);
message_write(“Timer1 was killed “);
}
trnid_write(id);
saveTrade(order);
signal::outputMultiple(“Start set_order “);
message_write(“Start set_order “);
set_order(order);
}
signal::outputMultiple(“OnStopOrder is end”);
message_write(“OnStopOrder is end”);
}
// Function for searching in the glass of applications with a sufficient number of lots
//need_OP = 0 to buy and 1 to sell
function get_book_position(var need_OP, var trade_quantity, var lot_mult)
{
var count_to_check;
var i;
var price_to_sell;
var vol_to_sell;
var price_to_buy;
var vol_to_buy;
var checker;
var act_price;
act_price = close;
book.load();
//need to buy
if (need_OP == 0)
{
count_to_check = book.getBidPosCount();
}
//need to sell
if (need_OP == 1)
{
count_to_check = book.getAskPosCount();
}
i = 1;
if (step_book > 0)
{
i = step_book;
}
signal::outputMultiple(“START calc. Num LOTS ” + trade_quantity * lot_mult);
message_write(“START calc. Num LOTS ” + trade_quantity * lot_mult);
while (i <= count_to_check-1) {
if (need_OP == 0)
{
price_to_sell = book.getAskPrice(i);
vol_to_sell = book.getAskVolume(i);
signal::outputMultiple(“PTS ” + price_to_sell);
message_write(“PTS ” + price_to_sell);
signal::outputMultiple(“VTS ” + vol_to_sell);
message_write(“VTS ” + vol_to_sell);
checker = (act_price <= price_to_sell) and (vol_to_sell>= trade_quantity * lot_mult);
signal::outputMultiple(“CHECKER ” + checker);
message_write(“CHECKER ” + checker);
if ((act_price <= price_to_sell) and (vol_to_sell >= trade_quantity * lot_mult))
{
signal::outputMultiple(“FIND solution ” + i);
message_write(“FIND solution ” + i);
i = count_to_check;
signal::outputMultiple(“END calc “);
message_write(“END calc “);
return price_to_sell;
}
else
{
i += 1;
}
}
if (need_OP == 1)
{
price_to_buy = book.getBidPrice(i);
vol_to_buy = book.getBidVolume(i);
signal::outputMultiple(“PTB ” + price_to_buy);
message_write(“PTB ” + price_to_buy);
signal::outputMultiple(“VTB ” + vol_to_buy);
message_write(“VTB ” + vol_to_buy);
checker = (act_price >= price_to_buy) and (vol_to_buy >= trade_quantity * lot_mult);
signal::outputMultiple(“CHECKER ” + checker);
message_write(“CHECKER ” + checker);
if ((act_price >= price_to_buy) and (vol_to_buy >= trade_quantity * lot_mult))
{
signal::outputMultiple(“FIND solution ” + i);
message_write(“FIND solution ” + i);
i = count_to_check;
signal::outputMultiple(“END calc “);
message_write(“END calc “);
return price_to_buy;
}
else
{
i += 1;
}
}
}
}
// The function is triggered on timer event 1, i.e. after each timer interval. The main function of our robot
function onTimer1()
{
signal::outputMultiple(“OnTimer1 is start”);
message_write(“OnTimer1 is start”);
var order = new_object(“array”);
var order_ = new_object(“hash”);
var size_o;
var trade_price;
var trade_quantity;
var trade_orderno;
var trade_operation;
var act_price;
var i;
var j;
var price_to_buy;
var price_to_sell;
var vol_to_buy;
var vol_to_sell;
var count_to_buy;
var count_to_sell;
var checker;
var rl;
var sl;
var nl;
var trnid;
var check_success;
var len_str;
var lot_mult = 2;
var flow_balance;
var check_status;
var client_data = getClientLimits(getClient());
if (price_tracking == 1)
{
// Tracking Strategy Processing
signal::outputMultiple(“Puse_tracking_strategy ” + use_tracking_strategy);
message_write(“Puse_tracking_strategy ” + use_tracking_strategy);
if (use_tracking_strategy == 1)
{
summ_timer += time_shift_second;
if ((summ_timer < (tracking_interval_in_h * 3600) ) and (orders_for_interval >= orders_count_for_tracking))
{
procent_profit = procent_profit * noise_koeff;
if (procent_profit > 1)
{
procent_profit = 1;
}
//summ_timer = 0;
orders_for_interval = 0;
}
if ((summ_timer == (tracking_interval_in_h * 3600) ) )
{
if ((orders_for_interval <= orders_count_for_tracking))
{
procent_profit = procent_profit / noise_koeff;
}
summ_timer = 0;
orders_for_interval = 0;
}
signal::outputMultiple(“orders_for_interval ” + orders_for_interval);
message_write(
“orders_for_interval ” + orders_for_interval);
signal::outputMultiple(“summ_timer ” + summ_timer);
message_write(“summ_timer ” + summ_timer);
signal::outputMultiple(“tracking_interval_in_h ” + tracking_interval_in_h * 3600);
message_write(“tracking_interval_in_h ” + tracking_interval_in_h * 3600);
signal::outputMultiple(“Procent_profit ” + procent_profit);
message_write(“Procent_profit ” + procent_profit);
}
order = getAllTradeIDsBySec();
size_o = order.size();
size_o = getTrade(order[size_o-1]);
trade_price = size_o[“price”];
//trade_quantity = size_o[“quantity”];
//trade_quantity = get_number_of_lots(close);
trade_quantity = n_lots;
rl = getLotSize();
trade_orderno = size_o[“orderno”];
trade_operation = size_o[“operation”];
signal::outputMultiple(“START_balance ” + start_balance);
message_write(“START_balance ” + start_balance);
signal::outputMultiple(“Trade_price ” + trade_price);
message_write(“Trade_price ” + trade_price);
if (size_o[“operation”] == OP_SELL)
{
flow_balance = getMoneyBalance() – trade_quantity * rl * close;
//flow_balance = getMoneyBalance();
}
else{
flow_balance = getMoneyBalance() + trade_quantity * rl * close;
}
signal::outputMultiple(“Trade quantity ” + trade_quantity);
message_write(“Trade quantity ” + trade_quantity);
signal::outputMultiple(“FLOW_balance ” + flow_balance);
message_write(“FLOW_balance ” + flow_balance);
sl = trade_quantity * rl * price_at_start;
signal::outputMultiple(“summ_in_trade ” + sl);
message_write(“summ_in_trade ” + sl);
signal::outputMultiple(“price_at_start ” + price_at_start);
message_write(“price_at_start ” + price_at_start);
flow_profit = (flow_balance – start_balance) / (sl) * 100;
signal::outputMultiple(“flow_balance ” + flow_balance);
message_write(“flow_balance ” + flow_balance);
signal::outputMultiple(“start_balance ” + start_balance);
message_write(“start_balance ” + start_balance);
signal::outputMultiple(“sl ” + sl);
message_write(“sl ” + sl);
//алгоритм проверки уровня убытка
if (cycle_i == 0)
{
cycle_start_value = flow_profit;
}
if (loss_cycle > 0)
{
cycle_i += 1;
}
if ((cycle_i == loss_cycle) and (loss_cycle > 0))
{
cycle_end_value = flow_profit;
// if the loss by more than 25% (loss_procent) is large, then we turn over
if (((abs(cycle_end_value / cycle_start_value – 1)) >= (loss_procent)) and (cycle_end_value < 0))
{
// initiating a coup
cycle_direction = 1;
signal::outputMultiple(“cycle_direction”);
message_write(“cycle_direction”);
}
cycle_i = 0;
}
signal::outputMultiple(“FLOW_profit ” + flow_profit);
message_write(“FLOW_profit ” + flow_profit);
if (flow_profit >= wish_profit_in_procent ) {
lot_mult = 1;
stop_algoritm = true;
signal::outputMultiple(“FLOW_profit is equal Wish _profit ” + flow_profit);
message_write(“FLOW_profit is equal Wish _profit ” + flow_profit);
}
// Order to sell
if (trade_operation == OP_SELL) {
signal::outputMultiple(“OP is SELL “);
message_write(“OP is SELL “);
signal::outputMultiple(“BEGIN flow_price ” + flow_price);
message_write(“BEGIN flow_price ” + flow_price);
if (flow_price > 0)
{
if (close < flow_price)
{
flow_price = close;
signal::outputMultiple(“New flow_price “);
message_write(“New flow_price “);
}
}
else
{
flow_price = trade_price;
signal::outputMultiple(“Trade flow_price “);
message_write(“Trade flow_price “);
}
signal::outputMultiple(“CLOSE ” + close);
message_write(“CLOSE ” + close);
i = flow_price*(1 + procent_profit/100);
signal::outputMultiple(“CLOSE-FLOW ” + i);
message_write(“CLOSE-FLOW ” + i);
if ((close > flow_price * (1 + procent_profit/100)) or (stop_algoritm) or (cycle_direction))
{
if (stop_algoritm)
{
signal::outputMultiple(“COND to sell. STOP is activated”);
message_write(“COND to sell. STOP is activated”);
}
else
{
signal::outputMultiple(“COND to sell”);
message_write(“COND to sell”);
}
// in case of a transaction processing failure
j = 0;
check_success = false;
while (check_success == false)
{
price_to_sell = get_book_position(0, trade_quantity, lot_mult);
signal::outputMultiple(“Trade quantity ” + trade_quantity);
message_write(“Trade quantity ” + trade_quantity);
signal::outputMultiple(“END calc “);
message_write(“END calc “);
if (orders_count + 1 == orders_count_limit)
{
lot_mult = 1;
}
order_[“operation”] = OP_BUY;
order_[“price”] = price_to_sell;
order_[“quantity”] = trade_quantity * lot_mult;
order_[“usecredit”] = true;
signal::outputMultiple(“Trade quantity * LOT_Mult ” + order_[“quantity”] );
message_write(“Trade quantity * LOT_Mult ” + order_[“quantity”] );
trade_action::cancelAllOrders();
if ((order_[“usecredit”]) or (lot_mult == 1))
{
signal::outputMultiple(“Usecredit is allowed “);
message_write(“Usecredit is allowed “);
trnid = trade_action::transactMultiple(order_);
signal::outputMultiple(“Trade is start TRNID ” + trnid);
message_write(“Trade is start TRNID ” + trnid);
}
else
{
order_[“quantity”] = trade_quantity;
signal::outputMultiple(“Usecredit is not allowed “);
message_write(“Usecredit is not allowed “);
trnid = trade_action::transactMultiple(order_);
trnid = trade_action::transactMultiple(order_);
signal::outputMultiple(“Trade is start TRNID ” + trnid);
message_write(“Trade is start TRNID ” + trnid);
}
signal::outputMultiple(“Trying nom. ” + j);
message_write(“Trying nom. ” + j);
j += 1;
len_str = as_number(trnid);
len_str = strlen(as_string(len_str));
if ((len_str > 0) or (j > 3))
{
check_success = true;
signal::outputMultiple(“LENGTH TRNID ” + len_str);
message_write(“LENGTH TRNID ” + len_str);
signal::outputMultiple(“check_success ” + check_success );
message_write(“check_success ” + check_success );
}
else
{
step_book = j + 1;
}
}
step_book = 0;
flow_price = 0;
signal::outputMultiple(“FIND to sell “);
message_write(“FIND to sell “);
signal::outputMultiple(“price_to_sell ” + price_to_sell);
message_write(“price_to_sell ” + price_to_sell);
signal::outputMultiple(“vol_to_sell ” + vol_to_sell);
message_write(“vol_to_sell ” + vol_to_sell);
}
}
if (trade_operation == OP_BUY) {
if (stop_algoritm)
{
signal::outputMultiple(“OP is BUY. STOP is activated”);
message_write(“OP is BUY. STOP is activated”);
}
else
{
signal::outputMultiple(“OP is BUY”);
message_write(“OP is BUY”);
}
signal::outputMultiple(“BEGIN flow_price ” + flow_price);
message_write(“BEGIN flow_price ” + flow_price);
if (flow_price > 0)
{
if (close > flow_price)
{
flow_price = close;
signal::outputMultiple(“New flow_price “);
message_write(“New flow_price “);
}
}
else
{
flow_price = trade_price;
signal::outputMultiple(“Trade flow_price “);
message_write(“Trade flow_price “);
}
signal::outputMultiple(“CLOSE ” + close);
message_write(“CLOSE ” + close);
i = flow_price/(1 + procent_profit/100);
signal::outputMultiple(“CLOSE-FLOW ” + i);
message_write(“CLOSE-FLOW ” + i);
if ((close < flow_price/(1 + procent_profit/100)) or (stop_algoritm) or (cycle_direction))
{
signal::outputMultiple(“COND to buy “);
message_write(“COND to buy “);
//на случай сбоя при обработке сделки
j = 0;
check_success = false;
while (check_success == false)
{
price_to_buy = get_book_position(1, trade_quantity, lot_mult);
if (orders_count + 1 == orders_count_limit)
{
lot_mult = 1;
}
order_[“operation”] = OP_SELL;
order_[“price”] = price_to_buy;
order_[“quantity”] = trade_quantity * lot_mult;
order_[“usecredit”] = true;
signal::outputMultiple(“Trade quantity * LOT_Mult ” + order_[“quantity”] );
message_write(“Trade quantity * LOT_Mult ” + order_[“quantity”]);
trade_action::cancelAllOrders();
if ((order_[“usecredit”]) or (lot_mult == 1))
{
signal::outputMultiple(“Usecredit is allowed “);
message_write(“Usecredit is allowed “);
trnid = trade_action::transactMultiple(order_);
signal::outputMultiple(“Trade is start TRNID ” + trnid);
message_write(“Trade is start TRNID ” + trnid);
}
else
{
order_[“quantity”] = trade_quantity;
signal::outputMultiple(“Usecredit is not allowed “);
message_write(“Usecredit is not allowed “);
trnid = trade_action::transactMultiple(order_);
trnid = trade_action::transactMultiple(order_);
signal::outputMultiple(“Trade is start TRNID ” + trnid);
message_write(“Trade is start TRNID ” + trnid);
}
signal::outputMultiple(“Trying nom. ” + j);
message_write(“Trying nom. ” + j);
j += 1;
len_str = as_number(trnid);
len_str = strlen(as_string(len_str));
if ((len_str > 0) or (j > 3))
{
check_success = true;
signal::outputMultiple(“LENGTH TRNID ” + len_str);
message_write(“LENGTH TRNID ” + len_str);
signal::outputMultiple(“check_success ” + check_success );
message_write(“check_success ” + check_success);
}
else
{
step_book = j + 1;
}
}
step_book = 0;
flow_price = 0;
//trade_action::sellMultiple(trade_quantity * lot_mult, ::lots, price_to_buy);
signal::outputMultiple(“FIND to buy “);
message_write(“FIND to buy “);
signal::outputMultiple(“price_to_buy ” + price_to_buy);
message_write(“price_to_buy ” + price_to_buy);
}
}
signal::outputMultiple(“FLOW_Price ” + flow_price);
message_write(“FLOW_Price ” + flow_price);
}
if (cycle_direction)
{
cycle_direction = 0;
}
signal::outputMultiple(“OnTimer1 is end”);
message_write(“OnTimer1 is end”);
}
// Second timer event handling function
function onTimer2()
{
var nl;
var n_active = 0;
var sec_array = new_object(“array”);
var order_array = new_object(“array”);
var order = new_object(“hash”);
var size_a;
var size_o;
var nom_order;
var trnid;
var rl;
var get_price;
var timer_cond = false;
if (isTradingAllowed())
{
signal::outputMultiple(“Timer2 start”);
message_write(“Timer2 start”);
n_active = getSecBalance();
n_lots = get_number_of_lots(close);
nl = n_lots;
if (n_active == 0)
{
start_balance = getMoneyBalance();
if ((close – timer2_price) >= 0)
{
get_price = get_book_position(0, nl, 1);
trnid = trade_action::buy(nl, ::lots, get_price);
}
else
{
get_price = get_book_position(1, nl, 1);
trnid = trade_action::sell(nl, ::lots, get_price);
}
signal::outputMultiple(“Get_Price ” + get_price);
message_write(“Get_Price ” + get_price);
signal::outputMultiple(“nl ” + nl);
message_write(“nl ” + nl);
signal::outputMultiple(“trnid ” + trnid);
message_write(“trnid ” + trnid);
delTimer(timer2);
timer2 = 0;
signal::outputMultiple(“Timer2 was killed “);
message_write(“Timer2 was killed “);
}
else
{
signal::outputMultiple(“SecBalance” + n_active);
message_write(“SecBalance” + n_active);
order_array = getAllOrderIDs();
size_o = order_array.size();
signal::outputMultiple(“OrderSize ” + size_o);
message_write(“OrderSize ” + size_o);
size_o = getOrder(order_array[size_o-1]);
nom_order = size_o[“orderno”];
signal::outputMultiple(“Order No” + nom_order);
message_write(“Order No” + nom_order);
delTimer(timer2);
timer2 = 0;
signal::outputMultiple(“Timer2 was killed “);
message_write(“Timer2 was killed “);
timer_cond = true;
sec_array = getAllTradeIDsBySec();
size_a = sec_array.size();
signal::outputMultiple(“SecSize ” + size_a);
message_write(“SecSize ” + size_a);
size_a = getTrade(sec_array[size_a-1]);
signal::outputMultiple(“Trade Nomber ” + size_a[“tradeno”]);
message_write(“Trade Nomber ” + size_a[“tradeno”]);
signal::outputMultiple(“Trade Price ” + size_a[“price”]);
message_write(“Trade Price ” + size_a[“price”]);
price_at_start = size_a[“price”];
if (start_balance == 0)
{
rl = getLotSize();
if (size_a[“operation”] == OP_SELL)
{
start_balance = getMoneyBalance() – nl * rl * price_at_start;
}
else{
start_balance = getMoneyBalance() + nl * rl * price_at_start;
}
}
timer1 = setTimer(“onTimer1”, time_shift_second * 1000, TIMER_PERIODICALLY);
}
signal::outputMultiple(“Start Balance ” + start_balance);
message_write(“Start Balance ” + start_balance);
}
}
// Let’s add a function to stop the robot when pressing the left SHIFT and the C key at the same time. It will work if a window with a graph is active in TRANSAQ, where our robot script is working
function onKeyDown(var key)
{
if (isKeyPressed(KEY_LSHIFT))
{
if (key == chr2num(“C”))
{
delTimer(timer1);
delTimer();
timer1 = 0;
signal::alert(“Program was stopped!”);
message_write(“Program was stopped!”);
}
}
}
// The function in our robot is not involved, although it is possible to output any information through it
function calc()
{
line[0] = 0;
}