Главная страница
Навигация по странице:

  • Факультет информационных технологий РУБЕЖНЫЙ КОНТРОЛЬ 3 по дисциплине «Интеллектуальные информационные системы»

  • ФИО студента Рунов Александр Александрович Направление подготовки

  • Группа ИВТ-Б-01-Д-2019-1 Москва – 2021 г. Оглавление

  • Введение

  • Пример использования

  • Список использованных источников

  • ртеун. кст. Пример построения индикатора с использованием Fuzzy Logic


    Скачать 347.76 Kb.
    НазваниеПример построения индикатора с использованием Fuzzy Logic
    Анкорртеун
    Дата01.06.2021
    Размер347.76 Kb.
    Формат файлаdocx
    Имя файлакст.docx
    ТипДокументы
    #212585




    Российский государственный социальный университет
    Факультет информационных технологий



    РУБЕЖНЫЙ КОНТРОЛЬ 3

    по дисциплине «Интеллектуальные информационные системы»
    тема «Пример построения индикатора с использованием Fuzzy Logic»


    ФИО студента

    Рунов Александр Александрович

    Направление подготовки

    Информатика и вычислительная техника

    Группа

    ИВТ-Б-01-Д-2019-1


    Москва – 2021 г.

    Оглавление


    Введение 3

    Пример использования 3

    Функция принадлежности 4

    Составляем программный код 6

    Список использованных источников: 18


    Введение


    Математическая теория нечётких множеств позволяет описывать нечёткие понятия и знания, оперируя этими знаниями, и делать нечёткие выводы.

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

    Математическая теория нечетких множеств и нечёткая логика является обобщением классической теории множеств и формальной логики. Данные понятия были предложены американским учёным З. Лотфи в 1965 году. Основной причиной появления новой теории стоило наличие нечётких и приближённых рассуждений при описании человеком процессов, систем, объектов.

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

    Нечёткая логика обеспечивает эффективные средства отображения, неопределённостей и неточностей реального мира.

    Пример использования


    Опишем функцию принадлежности для высказывания "горячий кофе": температуру кофе следует рассматривать в диапазоне от 0 до 100 градусов Цельсия по той простой причине, что при температуре меньше 0 градусов это будет лед, а выше 100 градусов - пар. Очевидно, что чашка кофе с температурой 20 градусов никак не может быть названа горячей, то есть функция принадлежности кофе к категории "горячий" равна 0, а вот чашка кофе с температурой 70 градусов уже однозначно принадлежит к категории "горячий" и соответственно значение функции в этом случае равно 1.

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

    Тем не менее примерный вид функции принадлежности мы можем себе представить: она "монотонно возрастающая":



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

    Таким образом, функция может быть задана следующим аналитическим выражением:



    Функции подобного вида мы и будем использовать для нашего индикатора.

    Функция принадлежности


    В задачу любого технического индикатора, в той или иной мере, входит определение состояния рынка на данный момент (Флет, Тренд вверх, Тренд вниз), а также генерация сигналов на заключение сделки и выход из нее. Как это можно осуществить при помощи функций принадлежности? Достаточно просто.
    Для начала нам нужно определиться с граничными условиями. Путь граничным условием для определения «100% Тренд вверх» будет пересечение EMA с периодом 2, построенной по типичной цене (H+L+C)/3, с верхней границей конверта Envelopes  с параметрами 8, 0.08, SMA, Close., а «100% тренд вниз» с нижней границей. Все, что между ними, будем считать флетом.  Для  пущей важности добавим еще один конверт с параметрами 32, 0.15, SMA, Close. 

    В итоге мы должны получить две идентичные функции принадлежности.  Сигналом к покупке будет ситуация, когда обе функции будут равны  1, к продаже соответственно -1.  Т.к. графики функции удобно строить в диапазоне от -1 до 1,  результирующий график получим путем среднего арифметического результатов двух функций F(x)= (f1(x)+f2(x))/2.

    Вот так это выглядит на чарте:



    В таком случае функция принадлежности примет следующее графическое отображение:



    Аналитически его можно записать в следующем виде:

    ,

    где a и b верхняя и нижняя линии конверта соответственно, а х - значение EMA(2).

    С функцией определились, теперь переходим к написанию кода индикатора.



    Составляем программный код


    Сначала определимся с тем, что и как будем рисовать.

    Результаты вычислений функции принадлежности будем выводить линией - красной и синей соответственно.

    Среднее арифметическое будем рисовать гистограммой от нулевой линии и раскрашивать в зависимости от значения результирующей функции в пять цветов:



    Для этого будем использовать стиль рисования DRAW_COLOR_HISTOGRAM.

    Для выдачи сигналов на покупку и продажу нарисуем прямоугольники синего и красного цветов над теми полосками гистограммы, значение которых равно 1 или -1.

    Запускаем MetaEditor и приступаем. Создать->Пользовательский индикатор->Далее... Заполняем окошко "параметры":



     Создаем буферы:



    Жмем кнопку "Готово", получаем исходный код и начинаем его дорабатывать.

    Во-первых, определимся с количеством буферов. Семь у нас уже создал мастер (5 для данных, 2 для цвета). Нам понадобится еще 5.

    #property indicator_minimum -1.4 // Ставим дробные значения

    #property indicator_maximum 1.4  // мастер экспертов почему-то игнорирует дробные части

    #property indicator_buffers 12   // Меняем значение с 7 на 12 (добавилось еще 5 буферов)

    Редактируем входные параметры:

    input string txt1="----------";

    input int                  Period_Fast=8;

    input ENUM_MA_METHOD        Method_Fast = MODE_SMA; /*Метод усреднения*/ //метод усреднения скользящей

    input ENUM_APPLIED_PRICE    Price_Fast  = PRICE_CLOSE;

    input double               Dev_Fast=0.08;

    input string txt2="----------";

    input int                  Period_Slow=32;

    input ENUM_MA_METHOD        Method_Slow = MODE_SMA;

    input ENUM_APPLIED_PRICE    Price_Slow  = PRICE_CLOSE;

    input double               Dev_Slow=0.15;  /*Параметр отклонения*/

    input string txt3="----------";

    input int                  Period_Signal=2;

    input ENUM_MA_METHOD        Method_Signal = MODE_EMA;

    input ENUM_APPLIED_PRICE    Price_Signal  = PRICE_TYPICAL;

    input string txt4="----------";

    Очень удобным нововведением является комментарий, стоящий за объявленной переменной, его текст вставляется в окошко параметров индикатора.

    Также очень радует возможность создания списков:



    Резервируем переменные под хендлы индикаторов и индикаторные буферы:

    int Envelopes_Fast;     // Быстрый конверт

    int Envelopes_Slow;     // Медленный конверт

    int MA_Signal;          // Сигнальная линия

    double Env_Fast_Up[];   // Верхняя граница быстрого конверта

    double Env_Fast_Dn[];   // Нижняя граница быстрого конверта

    double Env_Slow_Up[];   // Верхняя граница медленного конверта

    double Env_Slow_Dn[];   // Нижняя граница медленного конверта

    double Mov_Sign[];      // Сигнальная линия

    Теперь переходим в функцию OnInit().

    Наведем немного красоты: зададим имя индикатору и уберем лишние десятичные нули:

    IndicatorSetInteger(INDICATOR_DIGITS,1); // зададим точность отображения, большая нам не нужна

    string name;    // имя индикатора

    StringConcatenate(name, "FLE ( ", Period_Fast, " , ", Dev_Fast, " | ", Period_Slow, " , ", Dev_Slow, " | ", Period_Signal, " )");

    IndicatorSetString(INDICATOR_SHORTNAME,name);

    и добавим недостающие буферы:

    SetIndexBuffer(7,Env_Fast_Up,INDICATOR_CALCULATIONS);

    SetIndexBuffer(8,Env_Fast_Dn,INDICATOR_CALCULATIONS);

    SetIndexBuffer(9,Env_Slow_Up,INDICATOR_CALCULATIONS);

    SetIndexBuffer(10,Env_Slow_Dn,INDICATOR_CALCULATIONS);

    SetIndexBuffer(11,Mov_Sign,INDICATOR_CALCULATIONS);

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

    Обратите внимание на то, как обьявляются индикаторы с буфером цвета:

    SetIndexBuffer(4,SignalBuffer1,INDICATOR_DATA);     // Сперва все буферы индикатора

    SetIndexBuffer(5,SignalBuffer2,INDICATOR_DATA);     // т.к это Color Histogram2 то у него 2 буфера данных

    SetIndexBuffer(6,SignalColors,INDICATOR_COLOR_INDEX);// а потом идет буфер цвета.

    заполняем хендлы:

    Envelopes_Fast = iEnvelopes(NULL,0,Period_Fast,0,Method_Fast,Price_Fast,Dev_Fast);

    Envelopes_Slow = iEnvelopes(NULL,0,Period_Slow,0,Method_Slow,Price_Slow,Dev_Slow);

    MA_Signal      = iMA(NULL,0,Period_Signal,0,Method_Signal,Price_Signal);

    С функцией OnInit() все.

    Теперь создадим функцию, которая будет рассчитывать значение функции принадлежности:

    double Fuzzy(double x,double a, double c)

    {

    double F;

         if (a
    else if (x<=a && x>=c)  F=(1-2*(a-x)/(a-c));// Флет

    else if (x
    return (F);

    }

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

    Приступаем непосредственно к основной функции OnCalculate().

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

    CopyBuffer(Envelopes_Fast,  // Хендл индикатора

               UPPER_LINE,      // Буфер индикатора

               0,              // Откуда начинаем 0 - с самого начала

               rates_total,    // Сколько копируем - Все

               Env_Fast_Up);   // Буфер в который записываются значения

    // - остальные по аналогии

    CopyBuffer(Envelopes_Fast,LOWER_LINE,0,rates_total,Env_Fast_Dn);

    CopyBuffer(Envelopes_Slow,UPPER_LINE,0,rates_total,Env_Slow_Up);

    CopyBuffer(Envelopes_Slow,LOWER_LINE,0,rates_total,Env_Slow_Dn);

    CopyBuffer(MA_Signal,0,0,rates_total,Mov_Sign);

     Здесь необходимо добавить код для оптимизации вычислений (пересчет только последнего бара)

    // объявляем переменную start, в ней будет храниться индекс бара с которого будет осуществляться

    // пересчет индикаторных буферов.

    int start;              

    if (prev_calculated==0)  // если ни один бар не просчитан

        {

        start = Period_Slow; // до этого значения не все индикаторы просчитаны поэтому исполнять код не имеет смысла

        }

    else start=prev_calculated-1;

    for (int i=start;i
          {

          // Здесь будет записан весь оставшийся код

          }

    Кода осталось совсем чуть-чуть.

    Задаем параметры x, a, b, производим расчет значения функции принадлежности и записываем его в соответствующий буфер:

    double x = Mov_Sign[i]; // Сигнал

    // Зададим параметры первой функции принадлежности:

    double a1 = Env_Fast_Up[i]; // Верхняя граница

    double b1 = Env_Fast_Dn[i];

    // вычислим значение первой функции принадлежности и запишем ее в буфер

    Rule1Buffer[i] = Fuzzy(x,a1,b1);

    // Зададим параметры второй функции принадлежности:

    double a2 = Env_Slow_Up[i]; // Верхняя граница

    double b2 = Env_Slow_Dn[i];

    // вычислим значение второй функции принадлежности и запишем ее в буфер

    Rule2Buffer[i] = Fuzzy(x,a2,b2);

    Две индикаторные линии построены.

    Теперь рассчитаем результирующее значение.

    ResultBuffer[i] = (Rule1Buffer[i]+Rule2Buffer[i])/2;

    Далее раскрасим полоски гистограммы соответствующими цветами: т.к. цветов пять, то ResultColors[i] может принимать значение от 0 до 4.

    Вообще цветов может быть до 64, так что это невероятная возможность для полета фантазии.

    for (int ColorIndex=0;ColorIndex<=4;ColorIndex++)

        {

        if (MathAbs(ResultBuffer[i])>0.2*ColorIndex && MathAbs(ResultBuffer[i])<=0.2*(ColorIndex+1))

            {

            ResultColors[i] = ColorIndex;

            break;

            }

        }

    Далее нарисуем сигнальные прямоугольники, нам понадобится стиль рисования DRAW_COLOR_HISTOGRAM2.

    У него два буфера данных, между которыми строится полоска гистограммы и один буфер цвета.

    Значения буферов данных всегда будут постоянными: 1.1 и 1.3 для сигнала на покупку, -1.1 и -1.3 для сигнала на продажу соответственно.

    Значение EMPTY_VALUE будет соответствовать отсутствию сигнала.

          if (ResultBuffer[i]==1)

            {

            SignalBuffer1[i]=1.1;

            SignalBuffer2[i]=1.3;

            SignalColors[i]=1;

            }

          else if (ResultBuffer[i]==-1)

            {

            SignalBuffer1[i]=-1.1;

            SignalBuffer2[i]=-1.3;

            SignalColors[i]=0;

            }

          else

            {

            SignalBuffer1[i]=EMPTY_VALUE;

            SignalBuffer2[i]=EMPTY_VALUE;

            SignalColors[i]=EMPTY_VALUE;

            }

    Жмем "Компилировать" и вуаля!




    Список использованных источников:


    1. https://www.netkom.by/docs/N31-Nechetkaya-logika.pdf

    2. Fuzzy-технология: математические основы. Практика моделирования в экономике (Автор: Бочарников Виктор Павлович)

    3. Александр Леоненков Нечеткое моделирование в среде MATLAB и fuzzyTECH / Александр Леоненков. - М.: БХВ-Петербург, 2005

    4. https://www.mql5.com/ru/articles/178


    написать администратору сайта