Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Уважаемые!
Ответьте пожалуйста на вопрос.
Как и где в коде нужно обозначить внешние переменные?
Из приведенного примера это не понятно.
//================================================================================== 4 == double AT[33]; // Массив для внешних переменных bool New_Parametr = false; // Обновления параметров пока не было for (int i=0; i<=32; i++) // Поищем обновлённый параметр { // Если какой-то параметр обновлён.. if(NormalizeDouble(AT[i], 8) != NormalizeDouble(Instrument[0][0][i][0],8)) { New_Parametr = true; // .. запоминаем этот факт.. for (i=0; i<=32; i++) // .. то присвоим новые значения всем AT[i] = Instrument[0][0][i][0]; // Для удобства пользования break; // .. и выходим из цикла перебора } } //================================================================================== 5 == int Strategy = NormalizeDouble(AT[0],0); switch(Strategy) {Как сделать, чтобы внешние переменные в настройках приложения были не обезличены АТ_1...АТ_32, а то ведь не запомнишь что за каждым номером значится?
Значения внешних переменных для стратегий указываются (как и любые значения внешних переменных) в настройках эксперта.
Названия внешних переменных в эксперте Вы изменить не сможете, т.к. они зашиты в код эксперта AG_exp.ex4.
Внешние переменные из эксперта передаются в присоединяемый файл стратегии через массив Instrument.
Названия локальных переменных в стратегии, соответствующие внешним переменным в эксперте, можно изменить в стратегии.
В этом примере так и сделано:
Вы по своему усмотрению можете задать свои названия.
Например, вместо АТ[i] указать Alfa, Beta и т.д.
Массив Instrument [][][][]: http://autograf.dp.ua/Pages/2/26/267/2676.htm
Стратегии в функции AG_AT(): http://autograf.dp.ua/Pages/2/26/267/26711/26711_1.htm
Присоединяемые стратегии: http://autograf.dp.ua/Pages/2/26/267/26711/26711_2.htm
Примеры кодирования стратегий:
http://autograf.dp.ua/Pages/2/26/267/26712/26712_1.htm
и http://autograf.dp.ua/Pages/2/26/267/26712/26712_2.htm
Вот теперь понятно. А то без опыта программирования сразу не доходит ещё. Спасибо.
Если программно, то можно воспользоваться функцией ObjectDelete() или ObjectsDeleteAll().
А куда её в моей стратегии прописывать? Или объекты будут создаваться и удаляться при каждом обращении к пользовательской функции?
Вот теперь понятно. А то без опыта программирования сразу не доходит ещё. Спасибо.
А куда её в моей стратегии прописывать? Или объекты будут создаваться и удаляться при каждом обращении к пользовательской функции?
Её не нужно прописывать в пользовательскую функцию или в стратегию.
Сделайте простой отдельный скрипт. После выключения стратегии набросите его в окно, он всё лишнее и удалит.
(придётся в AG 5 сделать некое подобие deinit в стретегии; но решение будет зависеть от возможностей MQL 5)
Спасибо за дельный совет. Только Вы меня переоцениваете. Со скриптами я еще не разбирался, но пойду в этом направлении. Если возможно дайте ссылку на какой-нибудь аналог.
Я пока только с индикатором познакомился.
Взял за аналог TD_Points&Line_mgtd1.1.mq4 Vladislav Goshkov (VG), дабавил log.mq4 Copyright © 2006, komposter для создания отчетов и получил более 2 000 строк своего индикатора.
Сделал его схему. Получилось около 500 строк. Можно наверно еще порезать, но пока так.
Значком
// --- // ---обозначены вырезанные места.
Пока что в голове держится структура, хочется достичь желаемой функциональности. Потом все причесывать по правилам (цена качества в геометрической прогрессии затрат).
Ну вот, в SRC не вставить 521 строку: "текст больше допустимого размера". Придется крепить файл
На этом этапе Вам нужно познакомиться со специальными функциями и видами прикладных программ.
Для этого лучше всего взять учебник по MQL4 и читать с начала, последовательно. Будут вопросы - выкладывайте, постараюсь ответить.
На этом этапе Вам нужно познакомиться со специальными функциями и видами прикладных программ.
Для этого лучше всего взять учебник по MQL4 и читать с начала, последовательно. Будут вопросы - выкладывайте, постараюсь ответить.
Ваш учебник - моя настольная книга. С него все и началось. Скачал, распечатал и постоянно пользуюсь.
Вопросы возникают если не понимаю сути прочитанного или не раскрыты какие-то вопросы.
Вот есть там два примера с записью данных во внешний файл или чтение из файла новостей, так это за одно обращение к функции Start(). Больше месяца ковырялся пока у Andrey Khatimlianskii (komposter) не нашёл пример из которого сделал то что мне нужно. А именно: init() – формирование шапки таблицы отчета (порядка 30 столбцов), start() – формирование строки с параметрами каждой сделки за сессию, deinit() – формирование итогов сессии. Причем сделал три вида отчетов (таблица с параметрами по каждой сделке, столбец с итогами сессии, таблица с итогами сессии) и можно их лепить сколько хочешь в разных конфигурациях, чтобы потом обрабатывать в Excel. К слову, в deinit() ObjectsDeleteAll(). Но это было потом, а с начала наворочал кучу графики чтобы в тестере и реале все оставалось на графиках и все видеть и анализировать. Это очень помогает при программировании, ведь в MQL-4 нет отладчика, а так на графике видно какие линии (условия открытия и закрытия, цели, линии сделок) строит программа и как она это делает. Но это все в рамках индикатора, а он не торгует реально. Поэтому есть необходимость прикрепиться к эксперту, чтобы получить возможность не виртуальной торговли, плюс возможность использования данных отчета тестера с возможностью автоматической оптимизации. И все это без потери имеющейся функциональность реализуемой пока в индикаторе.
К сожалению в рамках 495 стр. учебника, 180 стр. справочника, 370 стр. описания AutoGraf-4, справок по MetaEditor, MT, все не изложишь, а форум прочитать – жизни не хватит. Но это так, все лирика.
А вот конкретно сделал я схему кода функции стратегии (на основе алгоритма индикатора) и не знаю, куда и как туда воткнуть скрипт для ObjectsDeleteAll()? Правильно ли воткнул торговые функции(они выделены “жжжжжж”? Посмотрите пожалуйста это хозяйство:
Схема кода функции стратегии (на основе алгоритма индикатора)
//+------------------------------------------------------------------+ //| Shema_3_TD_BLS_21_1.mq4 | //| Copyright © 2009, Leonid Belskiy | //| leonid.belskiy@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright © 2009, Leonid Belskiy" #property link "leonid.belskiy@gmail.com" //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж #property library //ж //ж #import "AG_Lib.ex4" //ж int AG_Magic_Number(); // Вычисление MN //ж int AG_Message(string & Message[], string _Text); // Запись сообщений в массив Message[] //ж // Запись управляющих воздействий ф-ии АТ в массив Manager[][]: //ж int AG_Set_Instr(double & Manager[][], int ii, double v1, double v2, double v3, //ж double v4, double v5, double v6, int io , int ih); //ж int AG_Delete_Instr(double&Manager[][], int ii, int io,int ih); //Удаление инструментов //ж #import //ж //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //ж int TD_BLS_21_2(int Parol_S, double Order[][], string Object[], //ж double Instrument[][][][], int Ddraw_Object[][], //ж double& Tuning[], double& Manager[][], string& Message[]) //ж { //ж static int Count = 0; // Счётчик посещений этого блока //ж //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //ж double Lot= NormalizeDouble(Tuning[1],2); // Значение лотов //ж int Per = NormalizeDouble(Tuning[2],0); // Значение % (целое) //ж int Slip = NormalizeDouble(Tuning[3],0); // Проскальзывание (пунктов) //ж int SL = NormalizeDouble(Tuning[4],0); // StopLoss (пунктов) //ж int TP = NormalizeDouble(Tuning[5],0); // TakeProfit (пунктов) //ж int Ds = NormalizeDouble(Tuning[6],0); // Дистанция (пунктов) //ж int St = NormalizeDouble(Tuning[7],0); // Шаг модификации (пунктов) //ж //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //ж if (Count==0) // Это можно делать один раз в начале //ж { // Пример сообщения (максимум 62 симв): //ж AG_Message(Message, "Разработчик J.Smith, http://company.com"); //ж Count++; // Количество посещений этого блока //ж //ж Lot = 0.1; // Если количество лотов Lot (Tuning[1]) больше нуля, .. //ж Per = 0; // .. независимо от значения переменной Per (Tuning[2]). //ж // Lot = 0.0; // 0.0 означает, что колич лотов высчитывается в AutoGraf //ж // Per = 7; // .. на основе значения % (здесь 7%) суммы баланса //ж Slip = 1; //ж SL = 25; //ж TP = 100; //ж // Ds = 20; //ж // St = 3; //ж Tuning[1] = Lot; // Значение лотов //ж Tuning[2] = Per; // Значение % (целое) //ж Tuning[3] = Slip; // Проскальзывание (пунктов) //ж Tuning[4] = SL; // StopLoss (пунктов) //ж Tuning[5] = TP; // TakeProfit (пунктов) //ж Tuning[6] = Ds; // Дистанция (пунктов) //ж Tuning[7] = St; // Шаг модификации (пунктов) //ж AG_Message(Message,"Изменение настроек из АТ."); // Пример сообщения (макс.62 симв.) //ж return(1); // Выход после перенастроек параметров //ж } //ж //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //ж int MN; // MagicNumber в ф-ии AG_Magic_Number() //ж string Comm = "AG_AT"; // Комментарий (рекомендуется "AG_AT") //ж static int Ticket; // Номер ордера //ж int _Ord_Ticket = 0; // Номер ордера //ж double _Ord_Lots = 0; // Полное закрытие //ж //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //ж double AT[33]; // Массив для внешних переменных //ж bool New_Parametr = false; // Обновления параметров пока не было //ж for (int i=0; i<=32; i++) // Поищем обновлённый параметр //ж { // Если какой-то параметр обновлён.. //ж AT[1]=11; //ж //ж if(NormalizeDouble(AT[i], 8) != NormalizeDouble(Instrument[0][0][i][0],8)) //ж { //ж New_Parametr = true; // .. запоминаем этот факт.. //ж for (i=0; i<=32; i++) // .. то присвоим новые значения всем //ж AT[i] = Instrument[0][0][i][0]; // Для удобства пользования //ж break; // .. и выходим из цикла перебора //ж } //ж } //ж //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж if((nTime!=Time[0])||(CurPeriod!=Period())) // На новом баре или изменении таймфрейма все пересчитываем { // Period Возвращает значение числа минут периода для текущего графика. //================================================= //******** Поиск опорных точек предложения ******** //================================================= for(i=2+StepBack,D=2,NP=0; (NP<D)&&(i<Bars); i++) // Перебираем бары влево начиная со 2-го бара от текущего { // Begin // --- // --- } // End; //================================================= //********** Поиск опорных точек спроса *********** //================================================= for(i=2+StepBack,D=2,NP=0; (NP<D)&&(i<Bars); i++) // Перебираем бары влево начиная со 2-го бара от текущего { // Begin // --- // --- } // End; //================================================= //**** Рисуем TD-линии **** //================================================= // --- // --- CurPeriod=Period(); // Соответствие минут графика с минутами системы nTime=Time[0]; // Соответствие время текущего и бара программы } //================================================= //**** Формирование сигналов для сделок **** //================================================= Fun_New_Bar(); // Определение нового бара //================================================= //**** Формирование сигналов на покупку **** //================================================= if((Close[i]>UpP[0]+UpV*(UpB[0]-i)+Puncture*Point) && (High[i+1]<=UpP[0]+UpV*(UpB[0]-(i+1)))) // Сигнал на покупку { // --- // --- Нахождение баров для расчета проекторов // --- // --- Расчет цен проекторов // --- // --- Расчет размеров проекторов if(NoQw ... ) // Определение квалификаторов прорыва { // --- // --- Формирование массива цен уровней целей // --- // --- Создаем и рисуем сигнал на покупку кружок (красный) if(Flag_Up==true) { // --- // --- Создаем и рисуем линию на покупку (красный) // --- // --- Создаем и рисуем линии целей //================================================ //**** Открываем сделку Buy **** //================================================ if(MiB_Up[1]==0 && Flag_Up_CD_Start==false && Flag_Up_Start==false && Flag_Dn_Start==false) { MiB_Up[1]=i; // Массив номеров баров точек Up сделки MiB_Up[1]-левая, MiB_Up[0]-правая MiP_Up[1]=Close[i]; // Массив цен точек Up сделки MiP_Up[1]-левая, MiP_Up[0]-правая MiBT_Up[1]=TimeCurrent(); // Количество секунд в момент открытия сделки Flag_Up_CD_Start=true; // Флаг рисования линий сделок на покупку - покупки запрещены Flag_Up_CD_End=false; // до закрытия сделки и образования нового бара Flag_Dn_Start=true; // Запрещено открывать противоположную Dn сделку // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж AG_Message(Message, "АТ: сработал критерий открытия Buy."); // Сообщение(макс.62симв) ж MN = AG_Magic_Number(); // Вычисление MagicNumber (рекомендуется)ж OrderSend( Symbol(), OP_BUY, Lot, Ask, 2, Bid-SL*Point, Bid+TP*Point, Comm, MN); // Открытие ордера Buy: ж // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж } bay++; // Счетчик нарисованных линий целей на покупку Flag_Up=false; // Линии нарисовали - флаг опустили до образования нового бара } } } //================================================= //**** Закрываем сделку Buy **** //================================================= if(Flag_Up_CD_Start==true && Flag_Up_CD_End==false) // Флаг конца рисования линий сделок на покупку - закрытие сделки { // Пока сделка открыта, пересчитываем точку [0] и перерисовываем линию // --- // --- // Расчет времени слелки (статистика отчета) // --- // --- // Расчет результата слелки (статистика отчета) // --- // --- // Рисуем линию сделки Up //-------жжжжжжжжжжжжжжжжжжжжжжжжж Выбор условий закрытия слелки Up if(CD_TrSL && Close[i]<iP_Up-TrStopLoss*Point) // (TrStopLoss==TrSL) Если цена пересекла TrStopLoss { // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж if (NormalizeDouble(Order[1][6],0) == 0.0) // Если тип ордера Buy ж { ж _Ord_Ticket = NormalizeDouble(Order[1][4],0); // Номер ордера ж _Ord_Lots = NormalizeDouble(Order[1][5],2); // Полное закрытие ж OrderClose(_Ord_Ticket, _Ord_Lots, Bid, 2); // Закрыть ордер Buy ж } ж // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // --- // --- // Расчет времени по всем Up сделкам (статистика отчета) // --- // --- // Расчет времени по всем сделкам (статистика отчета) // --- // --- // Расчет баланса и результатов Up сделок (статистика отчета) // --- // --- // Формируем строку отчета (статистика отчета) } WindowRedraw(); } //================================================= //**** Формирование сигналов на продажу **** //================================================= if((Close[i]<DownP[0]+DownV*(DownB[0]-i)-Puncture*Point) && (Low[i+1]>=DownP[0]+DownV*(DownB[0]-(i+1)))) // Сигнал на продажу { // --- // --- Нахождение баров для расчета проекторов // --- // --- Расчет цен проекторов // --- // --- Расчет размеров проекторов if(NoQw ... ) // Определение квалификаторов прорыва { // --- // --- Формирование массива цен уровней целей // --- // --- Создаем и рисуем сигнал на продажу кружок (синий) if(Flag_Dn==true) { // --- // --- Создаем и рисуем линию на продажу (синий) // --- // --- Создаем и рисуем линии целей //================================================= //**** Открываем сделку Sell **** //================================================= if(MiB_Dn[1]==0 && Flag_Dn_CD_Start==false && Flag_Dn_Start==false && Flag_Up_Start==false) { MiB_Dn[1]=i; // Массив номеров баров точек Dn сделки iB_Up[1]-левая, iB_Dn[0]-правая MiP_Dn[1]=Close[i]; // Массив цен точек Dn сделки iP_Dn[1]-левая, iP_Dn[0]-правая MiBT_Dn[1]=TimeCurrent(); // Массив времени баров содержащих точки Dn сделки iBT_Dn[1]-левая, iBT_Dn[0]-правая Flag_Dn_CD_Start=true; // Флаг начала рисования линий сделок на продажу Flag_Dn_CD_End=false; // Флаг конца рисования линий сделок на продажу Flag_Up_Start=true; // Запрещено открывать противоположную Up сделку // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж AG_Message(Message, "АТ: сработал критерий открытия Sell."); //Сообщение(макс62симв) ж MN = AG_Magic_Number(); // Вычисление MagicNumber (рекомендуется)ж OrderSend( Symbol(), OP_SELL, Lot, Bid, 2, Ask+SL*Point, Ask-TP*Point, Comm, MN); // Открытие ордера Sell: ж // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж } sell++; // Счетчик нарисованных линий целей на продажу Flag_Dn=false; // Линии нарисовали - флаг опустили до образования нового бара } } } //================================================= //**** Закрываем сделку Sell **** //================================================= i=0; if(Flag_Dn_CD_Start==true && Flag_Dn_CD_End==false) // Флаг конца рисования линий сделок на продажу - закрытие сделки { // Пока сделка открыта, пересчитываем точку [0] и перерисовываем линию // --- // --- // Расчет времени слелки (статистика отчета) // --- // --- // Расчет результата слелки (статистика отчета) // --- // --- // Рисуем линию сделки Dn // --- // --- //-------жжжжжжжжжжжжжжжжжжжжжжжжж Выбор условий закрытия слелки Dn if(CD_TrSL && Close[i]>iP_Dn+TrStopLoss*Point) // (TrStopLoss==TrSL) Если цена пересекла TrStopLoss { // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж if (NormalizeDouble(Order[1][6],0) == 1.0) // Если тип ордера Sell ж { ж _Ord_Ticket = NormalizeDouble(Order[1][4],0); // Номер ордера ж _Ord_Lots = NormalizeDouble(Order[1][5],2); // Будем закр.ордер полностью ж OrderClose(_Ord_Ticket, _Ord_Lots, Ask, 2); // Закрыть ордер Sell ж } ж // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // --- // --- // Расчет времени по всем Dn сделкам (статистика отчета) // --- // --- // Расчет времени по всем сделкам (статистика отчета) // --- // --- // Расчет баланса и результатов Dn сделок (статистика отчета) // --- // --- // Формируем строку отчета (статистика отчета) } WindowRedraw(); } } // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж return(1); // Нормальный выход ж } ж // жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Fun_New_Bar() // Функция определения образования нового бара // --- // ---А вот конкретно сделал я схему кода функции стратегии (на основе алгоритма индикатора) и не знаю, куда и как туда воткнуть скрипт для ObjectsDeleteAll()? Правильно ли воткнул торговые функции(они выделены “жжжжжж”? Посмотрите пожалуйста это хозяйство:
Думаю, что Вы сильно забегаете вперёд в своей деятельности.
В программировании нельзя действовать наощупь.
В собственном коде недопустимо использование чего-либо такого, что программист не вполне понимает или не понимает вовсе.
Так ничего не выйдет.
Программирование, возможно, как никакая другая деятельность, по воей сути требует полной ясности и полного самоотчёта.
Начните с написания элементарных кодов. Переходите к более сложным только тогода, когда полностью сможете объяснить каждую букву в Вашем коде.
--
Примеры простого и обычного экспертов есть в учебнике.
Раньше, во введении в программирование, даётся классификация прикладных программ (признаки и отличия экспертов, скриптов и индикаторов).
Скрипт нельзя "воткнуть" в эксперт. Это - отдельная самостоятельная программа.
Навскидку про Ваш код можно сказать, что он составлен небрежно с точки зрения форматирования.
Кроме того, бОльшую часть блоков можно оформить в виде функций. Так было бы наглядней (иначе через пару месяцев Вы не сможете прочесть собственный код)
Вы совершенно правы. Согласен с Вами по всем позициям. Спасибо что нашли время на конструктивную критику!
Под “воткнуть” имелось ввиду прописать код, связывающий работу скрипта с функцией AG_AT() или прикрепленной к ней функцией, реализующей стратегию.
В учебнике, в примере простого эксперта присутствует start(), а в обычном, все специальные функции. Проблем нет, но как говориться, “апетит приходит во время еды”.
Вопрос-то в том, чтобы пользоваться всеми замечательными возможностями AutoGraf-4. Как тут быть?