Germany | Finland | Saint Petersburg | Drive

Как сделать робота на AmiSharp? Часть 1.

Опубликовано в AmiSharp

В этой статье я попробую проиллюстрировать процесс создания простейшего робота на связке QUIK-AmiSharp-AmiBroker. Пример боевого фреймворка описан здесь.

Подразумеваю, что у Вас установлен терминал QUIK, программа технического анализа Amibroker и Вы понимаете язык AFL (ну или хотя бы С, достаточно). Некоторый объём информации по этим вопросам Вы найдёте на этом сайте. Также предполагаю, что экспорт котировок из терминала QUIK в Амиброкер у Вас уже настроен и работает (если нет - Настройка экспорта котировок в Amibroker), а также где-нибудь на жестком диске имеется AmiSharp

 

Итак, формулируем наш алгоритм.  Сделаем робота, работающего по простейшим классическим правилам:

  • Если предыдущая свеча закрылась выше простой скользящей средней, то покупаем по рынку;
  • Если предыдущая свеча закрылась ниже простой скользящей средней, то продаём по рынку;
  • Для простоты работаем только в лонг.
 

 

Первое, что делаем - создаём AFL формулу для расчета точек входа-выхода. Создаем новый чарт, копируем в него стандартные графики Price и Simple Moving Average. Автоматически создаётся AFL формула:


_SECTION_BEGIN("Price");

SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorBlack ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_END();

_SECTION_BEGIN("MA");
P = ParamField("Price field",-1);
Periods = Param("Periods", 15, 2, 300, 1, 10 );
Plot( MA( P, Periods ), _DEFAULT_NAME(), ParamColor( "Color", colorCycle ), ParamStyle("Style") );
_SECTION_END();

 

Процедура заняла секунд 10. Теперь добавляем правила входов и выходов из позиций и выводим метки на график. Дописываем 4 строчки:

 

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorBlack ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
_SECTION_END();

_SECTION_BEGIN("MA");
P = ParamField("Price field",-1);
Periods = Param("Periods", 15, 2, 300, 1, 10 );
MovingAverage = MA( P, Periods );
Plot(MovingAverage , _DEFAULT_NAME(), ParamColor( "Color", colorCycle ), ParamStyle("Style") ); 
_SECTION_END();

Buy = Cross(C, MovingAverage);
Sell = Cross(MovingAverage,C);


PlotShapes(Buy * shapeUpArrow,colorGreen);
PlotShapes(Sell * shapeDownArrow,colorGreen);

 


 

На графике появится что-типа такого:

Amisharp урок 1

 

Теперь добавляем выставление заявок через AmiSharp. Используем готовую процедуру из статьи Выставление заявок из AmiBroker:


 

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorBlack ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_END();

_SECTION_BEGIN("MA");
P = ParamField("Price field",-1);
Periods = Param("Periods", 15, 2, 300, 1, 10 );
MovingAverage = MA( P, Periods );
Plot(MovingAverage , _DEFAULT_NAME(), ParamColor( "Color", colorCycle ), ParamStyle("Style") );
_SECTION_END();

// Даем возможность пользователю менять параметры для торговли
_SECTION_BEGIN("Trade");
Seccode = ParamStr("SecCode","");
Classcode = ParamStr("ClassCode","");
Account = ParamStr("Account","");
ClientCode = ParamStr("Client code","");
Size = Param("Size",1,1,100);
QUIK_Path = ParamStr("QUIK_Path","e:\quik");
_SECTION_END();

// Включаем AmiSharp
amisharp = CreateStaticObject("AmiSharp.Mutant");

// ================== ТРАНЗАКЦИИ ======================

function SetTransParameter(ParameterString,ParameterName,ParameterValue)
{
return ParameterString + ParameterName + "=" + ParameterValue + ";" ;
}

//======================== Выставляем заявку ==================

function Make_Order(ClassCode,SecCode,TransactionOper,TransactionSize)
{ local result,trans_result,str;

  str = SetTransParameter("", "ACTION", "NEW_ORDER");
  str = SetTransParameter(str,"TRANS_ID", amisharp.Generate_TransID());
  str = SetTransParameter(str,"SECCODE", Seccode);
//str = SetTransParameter(str,"PRICE",0);
  str = SetTransParameter(str,"QUANTITY", TransactionSize);
  str = SetTransParameter(str,"OPERATION", StrToUpper(StrLeft(TransactionOper,1)));
  str = SetTransParameter(str,"CLASSCODE", ClassCode);
  str = SetTransParameter(str,"ACCOUNT", Account);
  if (ClientCode != "")
     str = SetTransParameter(str,"CLIENT_CODE", ClientCode);
  str = SetTransParameter(str,"TYPE", "M");

  amisharp.QuikConnect(QUIK_Path);
  trans_result = amisharp.QuikSendSyncTransaction(str);
  amisharp.QuikDisconnect();

  return StrExtract( trans_result,1);
}

Buy = Cross(C, MovingAverage);
Sell = Cross(MovingAverage,C);


PlotShapes(Buy * shapeUpArrow,colorGreen);
PlotShapes(Sell * shapeDownArrow,colorGreen);

// Смотрим текущую позицию и отрабатываем сигналы. CurrentPosition хранит 0, если позиции нет и размер позиции, если она есть
CurrentPosition = StrToNum(StaticVarGetText("POSITION"));
if (CurrentPosition == 0)
   {  if (LastValue(Buy))
      { Make_Order(ClassCode,SecCode,"Buy",Size);
        StaticVarSetText("POSITION","" + Size);
      }
   }
else
   {  if (LastValue(Sell))
      { Make_Order(ClassCode,SecCode,"Sell",CurrentPosition);
         StaticVarSetText("POSITION","0");
      }
   }

Я взял готовый кусок и слегка его подправил. Написать с нуля этот фрагмент можно за 10-15 минут.

Запускаем терминал QUIK, разрешаем ему отрабатывать внешние транзакции (Торговля-Внешние транзакции), указываем скрипту параметры (номер аккаунта, размер позиции и остальные) и наливаем кофе. Итого, максимум полчаса и

все.

Оно работает. Наблюдаем, как амиброкер щелкает заявками. Конечно, это не тот робот, который можно использовать для зарабатывания денег, исключительно иллюстрация механизма. Тем не менее, можно понаблюдать, как расчетные метки Buy и Sell Амиброкера сопровождаются заявками и сделками в таблицах QUIK и дублируются на его графике.

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

При желании можно запустить несколько копий робота в одном амиброкере параллельно. Например, можно торговать одной бумагой на 5-минутках, другой на часовиках, а третьей на таймфрейме 7 минут (можно и такПодмигиваю). Все они будут замечательно трудиться на одном счете или на разных, взависимости от того, какой торговый счет указать в настройках каждого скрипта. Но текст робота придется слегка подправить (изменить 3 строки), чтобы роботы не мешали друг другу - оставляю это Читателю.

Пока ничего необычного нет: рисует, выставляет транзакции... Написан робот быстро и, надеюсь, получился совсем несложным (все-таки язык ANSI C понятен любому, кто знаком с программированием). Очевидно, что в робот нужно много чего добавить - контроль успешности выставления/исполнения заявок, контроль наличия соединения с брокером и т.д., но всё это в демонстрационном варианте для ясности опустим.

Подобный робот можно сделать   на qpile/S#/Excel, однако эти способы гораздо сложнее (я писал роботов с использованием всех этих вариантов, но Вы можете воспользоваться правом не согласиться со мной Подмигиваю).

 

Этот робот пока только посылает транзакции в терминал, не используя никакие возможности обратной связи. В следующих статьях проиллюстрирую, каким образом можно получать внутренние таблицы терминала QUIK и приведу примеры, демонстрирующие преимущества подхода с использованием AmiSharp.

Продолжение: Как сделать робота на AmiSharp? Часть 2.

См. также

 


P.S. Возникающие вопросы , пожалуйста, на форум.

 

Комментарии   
# Viktor 06.02.2013 12:58
Красиво. В своё время пробовал делать роботов на MQL4 и StockSharp. S# конечно круто, но пока реализуешь простейший алгоритм пальцы отвалятся - много рутины, ну и конечно глючность :( А тут легко и главное наглядно!
Ответить | Ответить с цитатой | Цитировать
Добавить комментарий