MQL4 - automated forex trading   /  

Статьи

Cтатьи  Трейдинг  Звуковые сигналы в индикаторах Авторизуйтесь или зарегистрируйтесь , чтобы добавить новую статью


Эта статья о возможностях
MetaTrader 4

Мобильный трейдинг!
Купите лицензию и торгуйте мобильно

Звуковые сигналы в индикаторах [ en ]


Вступление


Не смотря на возрастающую популярность автотрейдинга, многие трейдеры продолжают торговать вручную. И если эксперту для оценки текущей ситуации на рынке требуется несколько миллисекунд, то обычному человеку необходимо потратить много времени, усилий и, главное, внимания.

Как и несколько лет назад, многие трейдеры для анализа пользуются Техническими индикаторами - одним или несколькими сразу. А некоторые стратегии учитывают значения индикаторов одновременно на нескольких периодах.

Как не пропустить важный сигнал? Есть несколько вариантов:
  • Написать эксперта, который будет анализировать рынок и сообщать о важных событиях;
  • Сидеть возле монитора и, переключаясь между десятками графиков, пытаться сопоставить полученную информацию;
  • Добавить во все используемые индикаторы систему оповещения о торговых сигналах.
Первый вариант по моему мнению наиболее правильный, но требует либо навыков программиста либо денег на реализацию. Второй - очень трудоемкий, утомительный и нерациональный. А третий вариант - нечто среднее между первыми двумя. Для его реализации необходимо намного меньше времени и умений, но он значительно облегчит жизнь (работу) трейдеру, торгующему вручную.

Именно реализации третьего варианта и посвящена данная статья. После её прочтения каждый трейдер сможет добавлять в индикаторы удобные для себя сигналы.

Виды сигналов


Способов интерпретации индикаторов существует очень много. Даже стандартные индикаторы терминала MetaTrader 4 можно понимать по разному. О всевозможных пользовательских индикаторах я вообще молчу...

Кто-то покупает, когда главная линия MACD пересекает сигнальную, кто-то ждет пересечения с нулевой линией, а кто-то открывает длинную позицию, когда MACD меньше 0 и начинает движение вверх. Предусмотреть все возможные варианты интерпретации мне не представляется возможным, поэтому я вам расскажу принцип добавления сигнального блока, а вы, отталкиваясь от него, сможете добавить любой тип сигнала в большинство индикаторов.

Итак, какие виды сигналов у нас есть:
  • Пересечение двух линий индикатора (пример приведен выше - главная линия MACD и сигнальная линия);
  • Пересечение линией индикатора определенного уровня (главная линия MACD и нулевая линия, Stoсhastic и уровни 70 и 30, CCI и уровни -100 и 100);
  • Изменение направления движения (AC и AO, обычный MA);
  • Изменение расположения по отношению к цене (Parabolic SAR);
  • Появление стрелочки над или под ценой (Fractals).
Наверное, существуют ещё какие-то способы интерпретации, я просто о них забыл или не знал вообще, поэтому пока остановимся на этих пяти.

Способы оповещения


MetaTrader 4 и MQL 4 позволяют реализовать несколько способов как визуального, так и звукового оповещения:
  • Обычное сообщение на экран (функция Comment);
  • Текст в журнале (функция Print);
  • Окно с сообщением и звуковой сигнал (функция Alert);
  • Отдельный звуковой сигнал с выбором воспроизводимого файла (функция PlaySound).
Кроме того, есть функция отправки файла на FTP-сервер (функция SendFTP()), вывода диалогового окна с сообщением (MessageBox()) и отправки почтового сообщения (SendMail()). Функция SendFTP() вряд ли будет востребована обычным пользователем, MessageBox() не подходит для использования в индикаторе, так как останавливает его работу до закрытия окна сообщения, а SendMail(), хоть и удобна для отправки SMS-сообщений, достаточно "опасна" в использовании - оставив несколько индикаторов на графике, вы обеспечите себе нескончаемый и нерегулируемый поток сообщений. Функцию использовать можно, но лучше из советника, например, отправлять сообщение при появлении сигнала на нескольких индикаторах одновременно, уделив ей достаточно внимания.

В этой статье мы рассмотрим только способы звукового и визуального оповещения терминала MetaTrader 4.

Самый простой и удобный из них - функция Alert, так как содержит и текст и звук. Кроме того, терминал хранит историю Alert-ов и всегда можно посмотреть, какой сигнал был час назад.

Но, как известно, на вкус и цвет товарищей нет. Поэтому я сделаю заготовку для всех упомянутых способов (кроме SendFTP, MessageBox и SendMail), а вы выберете удобный для себя.

Фильтр на частоту сигналов


Если вы уже когда-нибудь пользовались сигналами в индикаторах, то наверняка сталкивались с их чрезмерной частотой, особенно, если речь идет о мелких таймфреймах. Решается эта проблема несколькими способами:
  • Сигналы определять на основании сформировавшихся баров. Это наиболее правильное решение;
  • Чередовать сигналы - после покупки только продажа, и наоборот (тоже очень логичный ход, его можно использовать одновременно с другими);
  • Делать паузу между сигналами (не очень хорошая идея);
  • Давать один сигнал на бар (тоже достаточно искусственное ограничение).
Использовать ли сигнал с нулевого, несформировавшегося, бара для торговли - личное дело каждого. Я, например, считаю что это неправильно. Но есть индикаторы требующие моментальной реакции - для них один бар это слишком много. Поэтому дадим пользователю выбор. Несколько сигналов на покупку подряд вряд ли имеют смысл, поэтому все сигналы будем чередовать. А искусственные паузы вводить, пожалуй, не будем. Если они действительно понадобятся, об этом напишут в комментариях к статье.

Итак, приступим к реализации.

Сигнал первый - пересечение двух индикаторных линий


Начнем с приводимого в примерах MACD.

Главная наша задача - определить в каких массивах хранятся линии индикатора. Для этого посмотрим в код:


//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 2
#property  indicator_color1  Silver
#property  indicator_color2  Red
#property  indicator_width1  2
//---- indicator parameters
extern int FastEMA = 12;
extern int SlowEMA = 26;
extern int SignalSMA = 9;
//---- indicator buffers
double MacdBuffer[];
double SignalBuffer[];

Обратите внимание на комментарий "indicator buffers" - это именно то, что мы искали. Такие массивы чаще всего имеют интуитивно понятное имя (MacdBuffer - буфер значения главной линии MACD, SignalBuffer - буфер сигнальной линии) и всегда располагаются вне функций init, deinit и start.

Если массивов много и сложно понять какой из них необходим, посмотрите в функцию init - все массивы, отображенные на графике, "привязываются" к определенному номеру с помощью функции SetIndexBuffer:

int init()
  {
//---- drawing settings
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexDrawBegin(1, SignalSMA);
   IndicatorDigits(Digits + 1);
//---- indicator buffers mapping
   SetIndexBuffer(0, MacdBuffer);
   SetIndexBuffer(1, SignalBuffer);
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("sMACD(" + FastEMA + "," + SlowEMA + "," + SignalSMA + ")");
   SetIndexLabel(0, "sMACD");
   SetIndexLabel(1, "sSignal");
//---- initialization done
   return(0);
  }

И именно в таком порядке (от 0 до 7) значения линий индикатора отображаются в окне DataWindow. Имена, которые вы увидите там же, назначаются функцией SetIndexLabel - это третий способ идентификации.

Теперь, когда мы знаем, где хранятся необходимые данные, можем переходить к реализации сигнального блока. Для этого перемещаемся в самый конец функции start - выше последнего оператора return:

   for(i = 0; i < limit; i++)
       SignalBuffer[i] = iMAOnArray(MacdBuffer, Bars,S ignalSMA, 0, MODE_SMA, i);
//---- done
 
// а сюда мы добавим наш код
 
   return(0);
  }
//+------------------------------------------------------------------+

Ни в коем случае нельзя добавлять сигнальный блок в цикл расчета индикатора - это замедлит его работу и не принесет никакой пользы.

Итак, начинаем сочинять:

    //---- Статические переменные, в которых хранятся
    //---- время последнего бара и направление последнего сигнала
    static int PrevSignal = 0, PrevTime = 0;
 
    //---- Если баром для анализа выбран не 0-й, нам нет смысла проверять сигнал
    //---- несколько раз. Если не начался новый бар, выходим.
    if(SIGNAL_BAR > 0 && Time[0] <= PrevTime ) 
        return(0);
    //---- Отмечаем, что этот бар проверен
    PrevTime = Time[0];

Каждый раз, когда будет выполняться функция start, будет выполняться наш код. Обычные переменные обнуляются после каждого выполнения функции. Поэтому для хранения последнего сигнала и номера просчитанного бара мы объявили две статические переменные.
Дальше находится простая проверка, начался ли новый бар (работает только, если SIGNAL_BAR больше 0).

Кстати, саму переменную SIGNAL_BAR мы объявили намного раньше, ещё до функции init:

double     SignalBuffer[];
 
//---- Номер бара, по которому будет искаться сигнал
#define SIGNAL_BAR 1
 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {

Обратите внимание на директиву #define - компилятор просто заменит во всем коде переменную SIGNAL_BAR указанным значением (1).

Теперь, собственно, код сигнала:

    //---- Если предыдущий сигнал был СЕЛЛ или это первый запуск (PrevSignal=0)
    if(PrevSignal <= 0)
      {
        //---- Проверяем, не пересеклись ли линии на прошлом баре:
        if(MacdBuffer[SIGNAL_BAR] - SignalBuffer[SIGNAL_BAR] > 0 && 
           SignalBuffer[SIGNAL_BAR+1] - MacdBuffer[SIGNAL_BAR+1] >= 0)
          {
            //---- Если пересеклись, отмечаем что последний сигнал - бай
            PrevSignal = 1;
            //---- и выводим информацию:
            Alert("sMACD (", Symbol(), ", ", Period(), ")  -  BUY!!!");
//            Print("sMACD (", Symbol(), ", ", Period(), ")  -  BUY!!!");
//            Comment("sMACD (", Symbol(), ", ", Period(), ")  -  BUY!!!");
//            PlaySound("Alert.wav");
          }
      }

Тут тоже все просто. Если предыдущий сигнал был на продажу, проверяем пересечение линий:
если  значение главной линии MACD на баре №1 больше, чем значение сигнальной линии на баре №1
    И
значение сигнальной линии на баре №2 больше, чем значение линии MACD на баре №2
    значит
линии пересеклись.

Дальше отмечаем, что последний сигнал был на покупку, и выводим сообщение. Обратите внимание на три закомментированные строки - это ещё три варианта оповещения. Вы можете разкомментировать или удалить любую из них или все сразу. По умолчанию я оставил только Alert, как самый удобный.
А в функции PlaySound можно указать, какой аудио файл проигрывать. Файл должен находиться в директории MetaTrader 4\sounds\ и иметь расширение wav. Например, сделать свой звук на сигнал бай и свой - на селл или разные звуки разным индикаторам.

Сигнал на продажу полностью аналогичен:

    //---- Полностью аналогично для сигнала СЕЛЛ
    if(PrevSignal >= 0)
      {
        if(SignalBuffer[SIGNAL_BAR] - MacdBuffer[SIGNAL_BAR] > 0 && 
           MacdBuffer[SIGNAL_BAR+1] - SignalBuffer[SIGNAL_BAR+1] >= 0)
          {
            PrevSignal = -1;
            Alert("sMACD (", Symbol(), ", ", Period(), ")  -  SELL!!!");
//            Print("sMACD (", Symbol(), ", ", Period(), ")  -  SELL!!!");
//            Comment("sMACD (", Symbol(), ", ", Period(), ")  -  SELL!!!");
//            PlaySound("Alert.wav");
          }
      }

Остальные сигналы


Теперь, когда мы освоились в коде индикатора, нам будет намного проще написать другие блоки оповещения. Меняться будет только "формула", остальной код будем просто копировать.

Сигнал на пересечение определенного уровня очень похож на пересечение линий. Я его добавил в Stochastic, но вы можете провести аналогию для любого другого индикатора:

    if(PrevSignal <= 0)
      {
        if(MainBuffer[SIGNAL_BAR] - 30.0 > 0 && 
           30.0 - MainBuffer[SIGNAL_BAR+1] >= 0)
          {
            PrevSignal = 1;
            Alert("sStochastic (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(70.0 - MainBuffer[SIGNAL_BAR] > 0 && 
           MainBuffer[SIGNAL_BAR+1] - 70.0 >= 0)
          {
            PrevSignal = -1;
            Alert("sStochastic (", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }

Как видите, при пересечении линией %K (MainBuffer) уровня 30 снизу вверх индикатор скажет "Buy", а при пересечении уровня 70 сверху вниз - "Sell".

Третий вид сигнала - изменение направления движения. Его мы рассмотрим на примере индикатора AC. Обратите внимание, в этом индикаторе используется пять буферов:

//---- indicator buffers
double     ExtBuffer0[];
double     ExtBuffer1[];
double     ExtBuffer2[];
double     ExtBuffer3[];
double     ExtBuffer4[];

ExtBuffer3 и ExtBuffer4 используются для промежуточных расчетов, ExtBuffer0 всегда хранит знчение индикатора, а ExtBuffer2 и ExtBuffer3 "разукрашивают" столбики в 2 цвета. Поскольку нам необходимо только значение индикатора, будем использовать ExtBuffer0:

    if(PrevSignal <= 0)
      {
        if(ExtBuffer0[SIGNAL_BAR] - ExtBuffer0[SIGNAL_BAR+1] > 0 &&
           ExtBuffer0[SIGNAL_BAR+2] - ExtBuffer0[SIGNAL_BAR+1] > 0)
          {
            PrevSignal = 1;
            Alert("sAC (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(ExtBuffer0[SIGNAL_BAR+1] - ExtBuffer0[SIGNAL_BAR] > 0 &&
           ExtBuffer0[SIGNAL_BAR+1] - ExtBuffer0[SIGNAL_BAR+2] > 0)
          {
            PrevSignal = -1;
            Alert("sAC (", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }

Если значение индикатора уменьшалось, а потом начало увеличиваться, даем сигнал на покупку, если наоборот - увеличивалось и начало уменьшаться - на продажу.

Четвертый вид сигнала - изменение расположения по отношению к цене - достаточно редкий.
Но все равно его можно встретить, например, в Parabolic-е. На его примере мы и напишем "формулу":

    if(PrevSignal <= 0)
      {
        if(Close[SIGNAL_BAR] - SarBuffer[SIGNAL_BAR] > 0)
          {
            PrevSignal = 1;
            Alert("sParabolic Sub (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(SarBuffer[SIGNAL_BAR] - Close[SIGNAL_BAR] > 0)
          {
            PrevSignal = -1;
            Alert("sParabolic Sub(", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }

Тут вообще все просто - сравниваем значение индикатора с ценой закрытия бара. Заметьте, если установить SIGNAL_BAR равным 0, каждое "прикосновение" цены к параболику будет сопровождаться сигналом.

И последний сигнал - появление стрелочки на графике. В стандартных индикаторах он встречается достаточно редко, зато очень распространен в пользовательских "определителях разворотов". Я рассмотрю этот вид сигналов на примере индикатора Fractals (исходный код на MQL 4 находится в Code Base: Fractals).

Общим для всех подобных индикаторов является то, что в тех местах, где они рисуются на графиках, они не равны 0 (или EMPTY_VALUE). На всех остальных барах их буферы пустые. То есть для определения сигнала достаточно сравнить значение буфера с 0:

    if(PrevSignal <= 0 )
      {
        if(ExtDownFractalsBuffer[SIGNAL_BAR] > 0)
          {
            PrevSignal = 1;
            Alert("sFractals (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(ExtUpFractalsBuffer[SIGNAL_BAR] > 0)
          {
            PrevSignal = -1;
            Alert("sFractals (", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }

Но если вы присоедините индикатор с таким кодом на график, вы никогда не дождетесь сигнала. У фракталов есть одна особенность - они используют 2 будущих бара для анализа, поэтому стрелочки появляются только на втором по номеру (или третьем по счету - 0-й, 1-й, 2-й) баре. Поэтому для того, чтоб сигналы заработали, надо установить SIGNAL_BAR равным 2:

//---- Номер бара, по которому будет искаться сигнал
#define SIGNAL_BAR 2

Всё, теперь сигналы будут работать!

Заключение


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

Среди видов сигналов были выделены и реализованы:
  • Пересечение двух линий индикатора;
  • Пересечение линией индикатора определенного уровня;
  • Изменение направления движения;
  • Изменение расположения по отношению к цене;
  • Появление стрелочки над или под ценой.
Для оповещения были выбраны функции:
  • Comment() - для обычного сообщения на экран;
  • Print() - для отображения сообщения в журнале;
  • Alert() - для отображения сообщения в специальном окне и звукового сигнала;
  • и PlaySound() - для воспроизведения любого звукового файла.
Для уменьшения частоты сигналов:
  • При определении сигнала использовались сформировавшиеся бары;
  • Все сигналы чередовались - после покупки только продажа, и наоборот.
На примере пяти индикаторов, соответствующих пяти видам сигналов, были рассмотрены их сигнальные блоки. Полученные индикаторы можно скачать - ссылки в конце статьи.

Я надеюсь, вы убедились, что ничего сложного в добавлении сигнального блока в индикаторы нет - это по силам каждому. Может быть, теперь на форумах будет меньше подобных просьб и мы сможем развиваться дальше.
Прикрепленные файлы:
sAccelerator.mq4 (4.4 Kb)
sFractals.mq4 (7.4 Kb)
sMACD.mq4 (4.2 Kb)
sParabolic Sub.mq4 (8.5 Kb)
sStochastic.mq4 (5.2 Kb)
Создана: 26.12.2006  Автор: Andrey Khatimlianskii
Предупреждение: все права на данные материалы принадлежат MetaQuotes Software Corp. Полная или частичная перепечатка запрещена.
Что такое мартингал?
Что такое мартингал?

Краткое описание различного рода иллюзий, возникающих при игре на мартингале, применении стратегии мартингала или при злоупотреблении спайкингом и родственными приемами.

Опрос: мобильный терминал глазами трейдеров
Опрос: мобильный терминал глазами трейдеров

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

21 комментарий: 1 2 3   Авторизуйтесь или зарегистрируйтесь
bor-ix писал(а):

может есть всетаки какие нибуть другие варианты?

Проигрывать звук не функцией PlaySound, а через какую-нибудь внешнюю программу или ф-цию, вызывая ее из кода.

Больше ничего в голову не приходит.

14.05.2009 22:59 komposter
komposter писал(а):
bor-ix писал(а):

кто подскажет?

а как сделать так чтоб последовательно друг за другом воспроизводились два (три т.д.) разных звуковых файла при достижении одного какого ни будь конкретного условия, допустим "звук1.wav" и сразуже после него "звук2.wav" ("звук3.wav" и т.д.)?

...
есть ли решение моей задаче?

Если бы из эксперта, можно было бы Sleep() вставить, а из индикатора - даже не знаю.

Как вариант - эксперт, проверяющий сигналы на нескольких графиках и сигнализирующих по-разному для каждого графика.

попробую сделать эксперта...

...хотя я думаю это неудобно т.к. придется его цеплять на специально открытый для него новый график пары в отличаи от индикатора который можно закинуть на любой график, занят он каким ни будь экспертом или нет...

...и в принципе можно и для каждой валютной пары свой звук зделать...

но это уже выходит за рамки унивирсальности и ограничения по вариантам используемых звуков - для каждой комбинации требуемого результата нужен отдельный файл, что за собой тянет прогрессию роста размера этих файлов их количества ну и как следствие общего объема требуемой базы звуков вообще...

может есть всетаки какие нибуть другие варианты?

14.05.2009 18:50 bor-ix
bor-ix писал(а):

кто подскажет?

а как сделать так чтоб последовательно друг за другом воспроизводились два (три т.д.) разных звуковых файла при достижении одного какого ни будь конкретного условия, допустим "звук1.wav" и сразуже после него "звук2.wav" ("звук3.wav" и т.д.)?

...
есть ли решение моей задаче?

Если бы из эксперта, можно было бы Sleep() вставить, а из индикатора - даже не знаю.

Как вариант - эксперт, проверяющий сигналы на нескольких графиках и сигнализирующих по-разному для каждого графика.

14.05.2009 11:44 komposter

кто подскажет?

а как сделать так чтоб последовательно друг за другом воспроизводились два (три т.д.) разных звуковых файла при достижении одного какого ни будь конкретного условия, допустим "звук1.wav" и сразуже после него "звук2.wav" ("звук3.wav" и т.д.)?

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

...под первым звуком будет звучать, к примеру, название основной валюты, под вторым - относительно какой валюте, под третим - на каком периоде (таймфрейме)...

...немогу это реализовать с помощь функции PlaySound - звучит только последний звук из нескольких...


есть ли решение моей задаче?

13.05.2009 21:37 bor-ix
tavrik писал(а):
А как бы эту замечательную вещь (сигналы) применить к Heiken Ashi? Заранее благодарен.

А как вы хотите их применить? ;)
Подавать при смене цвета? Это можно.

В качестве подсказки: цвет индикатора зависит от расположения буферов ExtMapBuffer1 и ExtMapBuffer2 (надо смотреть какой больше).

14.07.2008 17:01 komposter
А как бы эту замечательную вещь (сигналы) применить к Heiken Ashi? Заранее благодарен.
14.07.2008 14:55 tavrik
tavrik писал(а):
Подскажите пожалйста как в Стохастике сделать сигнал при пересечении линии индикатора с сигнальной
Почитайте статью еще раз, и обратите внимание на индикатор sMACD.mq4 - он аналогичен стохастику.
13.05.2008 12:59 komposter
Подскажите пожалйста как в Стохастике сделать сигнал при пересечении линии индикатора с сигнальной
13.05.2008 10:32 tavrik

Ура! Получилось. Правда код немного коряво написал... но аботает

Сначало с помощью Comment() нашел какие переменные хранят последние значения ЗигЗага High и Low - это lasthigh и lastlow. А дальше просто.

int    HighSound,  LowSound, Tik;
double HighZigZag, LowZigZag;
//-------------------------------------
int init()
  {.
   Tik = 0;
//-------------------------------------
int start()
   Tik = Tik + 1;
   
   if (Tik < 2)
    {
     HighZigZag = lasthigh;
     LowZigZag  =  lastlow;
     int SerchBars;  
     for ( SerchBars = 0; SerchBars <= 100; SerchBars++ )
      {
       if ( High[SerchBars] == lasthigh)
        {
         LowSound  = 1 ;
         HighSound = 0 ;
         break;
        }
       if ( Low[SerchBars] == lastlow)
        {
         LowSound  = 0 ;
         HighSound  = 1 ;
         break;
        }
      }
    }
//----------Sound----------------------------------- 
     if (HighSound == 1 && HighZigZag != lasthigh )
      {
       PlaySound ( "lv_elvis.wav" ) ;
       LowSound  = 1 ;
       HighSound = 0 ;
      }
  
     if (LowSound == 1 && LowZigZag != lastlow )
      {
       PlaySound ( "lv_elvis.wav" ) ;
       LowSound  = 0 ;
       HighSound = 1 ;
      }
 
       HighZigZag = lasthigh;
       LowZigZag  =  lastlow;
//------------------------------------------------------------------- 
20.03.2008 13:02 MAXHO
MAXHO писал(а):

Спасибо Вы мне помогли.

Удачи в работе с ЗигЗагом. Вас ожидает еще не один сюрприз! ;)
19.03.2008 18:02 komposter
21 комментарий: 1 2 3