РЕФЕРАТ
Пояснительная записка к дипломному проекту содержит страниц
-139 , таблиц - 29 , рисунков - 19 .
Объект исследования - программная система для оптимизации
портфеля ценных бумаг с использованием генетического алгоритма.
Цель работы - увеличение эффективности процесса управления портфелем
ценных бумаг путем повышения оперативности принятия решений, а также снижение
рисков инвестиций в ценные бумаги.
Работа посвящена проектированию программного обеспечения,
предназначенного для автоматизации процесса оптимизации портфеля ценных бумаг.
Результатом работы является программа для автоматизации
процесса оптимизации портфеля ценных бумаг, которая обеспечивает:
¾
возможность
импорта котировок акций из текстового файла;
¾
возможность
графически представлять курсы акций компаний;
¾
возможность
самостоятельно устанавливать пользователю основные параметры генетического
алгоритма;
¾
визуализацию
результатов работы генетического алгоритма в виде таблицы;
¾
возможность
выбора пользователем акций для портфеля ценных бумаг, который оптимизируется;
Реализованная программная система обеспечивает все
перечисленные функции по оптимизации портфеля ценных бумаг.
ГЕНЕТИЧЕСКИЙ АЛГОРИТМ, МУТАЦИЯ, СКРЕЩИВАНИЕ, ЭЛИТИЗМ, .NET .
C#, ОПТИМИЗАЦИЯ, ЦЕННЫЕ БУМАГИ
ПЕРЕЧЕНЬ УСЛОВНЫХ ОБОЗНАЧЕНИЙ И
СОКРАЩЕНИЙ
ГА - Генетический алгоритм
ЭВМ - Электронная вычислительная машина
ПО - Программное обеспечение
ПС - Программная система
DLL - Dynamic Link Library
RTL - Run- Time Library
UML - Universal Modeling Language
XML - Extensible Markup Language
HTML - HyperText Markup Language
СОДЕРЖАНИЕ
Вступление 7
1. АНАЛИЗ ПРЕДМЕТНОЙ
ОБЛАСТИ И ПОСТАНОВКА ЗАДАЧИ 9
1.1
Актуальность оптимизационного моделирования портфеля ценных бумаг с
использованием генетических алгоритмов 9
1.2
Использование генетических алгоритмов в задачах оптимизации портфеля
ценных бумаг 14
1.3
Обзор существующих программных продуктов 17
1.3.1
Программная среда Genetic Algorithm and Direct Search Toolbox 1.0.2 17
1.3.2 Программная среда GeneHunter 20
1.3.3 Программная среда TransGA 25
1.4 Постановка
задачи на разработку программной системы 28
2 РАЗРАБОТКА
МОДЕЛИ И ПРОЕКТИРОВАНИЕ ПРОГРАММНОЙ СИСТЕМЫ 30
2.1
Разработка модели программной системы 30
2.1
Проектирование структуры программной системы 32
2.2 Проектирование UML-Диаграмм работы и
взаимодействия блоков программы 33
3 РАЗРАБОТКА
ПРОГРАММНОЙ СИСТЕМЫ 37
3.1
Разработка алгоритмов работы программной системы 37
3.2 Разработка интерфейса программы 42
4 РАЗРАБОТКА
ПРОГРАММНОЙ СИСТЕМЫ 52
4.1
Обоснование средств реализации 52
4.2 Реализация программного комплекса 56
5 ТЕСТИРОВАНИЕ
ПРОГРАММНОЙ СИСТЕМЫ 73
Выводы
78
Перечень
ссылок
79
Приложение А Листинг программы
81
Приложение Б Руководство пользователя 118
Приложение В Экранные формы 126
Приложение Д Перечень замечаний к
дипломному проекту 131
ВВЕДЕНИЕ
Сегодня банки, брокерские
компании, частные инвесторы, интернет-трейдеры активизировали работу в области
формирования и управления инвестиционным портфелем. Количество
непрофессиональных участников рынка ценных бумаг стремительно растет и у них
возникает необходимость использовать профессиональные знания об использовании методов
анализа рынка ценных бумаг, которые могли бы помочь ориентироваться в сложных
процессах рынка. Данное обстоятельство вызывает необходимость проведения более
полного системного анализа портфельных теорий и ставит задачу разработки
методического обеспечения процесса управления портфелем ценных бумаг,
основанного на стратегии оптимизации портфеля ценных бумаг.
Оптимизационные
стратегии основаны на
построении экономико-математических моделей портфеля. Выбор наилучшей структуры
портфеля осуществляется путем варьирования критериев оптимизации и проведения
многовариантных имитационных расчетов. Использование методов оптимизации
позволяет определить конфигурацию портфеля, наиболее точно отвечающую
индивидуальным требованиям инвестора с точки зрения сбалансированного сочетания
риска, доходности и ликвидности вложений. В качестве классических примеров
обычно приводятся оптимизационные модели Марковитца, Шарпа, Тобина[6]. Одна из
проблем заключается в том, что процесс выбора инвестиционной стратегии далеко
не всегда можно адекватно формализовать, иногда более существенное значение
имеют не количественные, а качественные показатели. Поэтому в настоящее время
помимо традиционных методов оптимизации (например, линейного или динамического
программирования) менеджеры и аналитики используют методы, основанные на
генетических алгоритмах, нечеткой логике, а также экспертные системы, нейронные
сети.
В первом разделе работы
сделан анализ предметной области, обзор и сравнительный анализ существующего
программного обеспечения в этой сфере. В конце сделана постановка задачи на
разработку программного обеспечения для оптимизационного моделирования
динамических систем с использованием генетических алгоритмов.
Второй раздел посвящен
проектированию структуры системы, UML- диаграмм работы и взаимодействия
программной системы.
В третьем разделе
выполняется разработка алгоритмов работы системы. Приведена общая структура
программы, блок схемы реализации операций. Также здесь детально описывается
интерфейс создаваемой программы
В четвертом разделе
выполняется реализация программной системы. Сначала выбираются инструменты, с
помощью которых будет разрабатываться система, затем описываются разработанные
классы и функции в программной системе.
Пятый раздел посвящен
тестированию разработанной программной системы. Описаны результаты, которые
получились при изменении тех или иных параметров.
1.
АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ И
ПОСТАНОВКА ЗАДАЧИ
1.1
Актуальность оптимизационного моделирования портфеля
ценных бумаг с использованием генетических алгоритмов
Рынок ценных бумаг
играет важную роль в экономике любой страны. Возможности рынка ценных бумаг
привлекают все больше и больше инвестиций в эту сферу рыночной экономики. В
связи с этим актуальным становится анализ и прогнозирование возможной прибыли и
рисков, понесенных инвестором при управлении им портфелем ценных бумаг.
Сущность
портфельного инвестирования подразумевает распределение инвестиционного
потенциала между различными группами активов, так как невозможно найти ценную
бумагу, которая была бы одновременно высокодоходной и высоконадежной. В
зависимости от того, какие цели и задачи изначально стоят при формировании того
или иного портфеля, выбирается определенное процентное соотношение между
различными типами активов, составляющими портфель инвестора.
Проведя анализ рынка
ценных бумаг, инвестор может выбрать актив и инвестировать в него свои
средства, но вкладывая весь свой капитал только в одну ценную бумагу, инвестор
обрекает себя либо на заведомо низкую доходность, либо на заведомо высокий
риск. Следствием второго вывода является необходимость диверсификации капитала
между различными активами. Распределение средств по различным ценным бумагам
приводит к формированию портфеля ценных бумаг, и за счет этого инвестор может достичь
приемлемого уровня доходности и риска инвестиций. В этом состоит главное
преимущество портфельного инвестирования по сравнению с инвестициями в
отдельные ценные бумаги.
В дипломной работе
рассматривается выбор оптимального портфеля ценных бумаг на основе подхода
«доходность-риск». Выбор портфеля ценных бумаг на основе его ожидаемой
доходности и риска известен как подход «доходность-риск», который был впервые
сформулирован Г. Марковицем[3]. В рамках данного подхода предполагается, что
инвестор стремится максимизировать ожидаемую доходность портфеля при заданном
уровне риска, либо минимизировать риск при заданном уровне ожидаемой доходности
по средствам диверсификации вложений.
Теория
эффективных портфелей направлена на решение практической задача о рассредоточении
капитала по различным видам ценных бумаг в условиях неопределенности. Основные
положении этой теории были разработаны американским математиком Г. Марковицем при
подготовке его докторской диссертации в 1950 - 1951 годах. Практическое значение
теории эффективных портфелей, которая является математической теорией для
рассредоточения вкладов, увеличения прибыли и снижения риска очень велико. Использование этой теории
вызвало революцию на фондовом рынке.
Традиционный подход в
инвестировании, преобладавший до появления современной теории портфельных
инвестиций, имел два существенных недостатка. Во-первых, в нем основное
внимание уделялось анализу поведения отдельных активов (акций, облигаций).
Во-вторых, основной характеристикой активов в нем была исключительно
доходность, тогда как другой фактор - риск - не получал четкой оценки при
инвестиционных решениях. Нынешний уровень разработки теории портфельных
инвестиций преодолевает эти недостатки.
Результаты исследований,
полученные Г. Марковицем, сразу позволили перевести задачу выбора оптимальной
инвестиционной стратегии на точный математический язык. Именно он первым
привлек внимание к общепринятой практике диверсификации портфеля и точно
показал, как инвесторы могут уменьшить стандартное отклонение его доходности,
выбирая акции, цены на которые изменяются по-разному. С математической точки
зрения, полученная оптимизационная стратегия относится к классу задач
квадратичной оптимизации при линейных ограничениях. До сих пор, вместе с
задачами линейного программирования, это один из наиболее изученных классов
оптимизационных задач, для которых разработано большое количество достаточно
эффективных алгоритмов.
Основные выводы теории
портфельных инвестиций, можно сформулировать так[4]:
- эффективное множество содержат те
портфели, которые одновременно обеспечивают и максимальную ожидаемую доходность
при фиксированном уровне риска, и минимальный риск при заданном уровне
ожидаемой доходности;
- предполагается, что инвестор
выбирает оптимальный портфель из портфелей, составляющих эффективное множество;
- оптимальный портфель инвестора
идентифицируется с точкой касания кривых равнодушия инвестора с эффективным
множеством;
- как правило, диверсификация влечет
за собой уменьшение риска, поскольку в общем случае стандартное отклонение
доходности портфеля будет меньше, чем средневзвешенные стандартные отклонения
доходности ценных бумаг, которые составляют этот портфель;
- соотношение доходности ценной
бумаги и доходности на индекс рынка известно как рыночная модель;
- доходность на индекс рынка не
отражает доходности ценной бумаги полностью; необъясненные элементы включаются
в случайную погрешность рыночной модели;
- в соответствии с рыночной моделью,
общий риск ценной бумаги состоит из рыночного риска и собственного риска;
- диверсификация приводит к
усреднению рыночного риска;
- диверсификация может значительно
снизить собственный риск.
Центральной проблемой в
теории портфельных инвестиций является выбор оптимального портфеля, то есть
определение набора активов с наивысшим уровнем доходности при наименьшем или
заданном уровне инвестиционного риска. Такой подход является
"многомерным" как по количеству привлеченных в анализ активов, так и
по учтенным характеристикам.
Задача оптимизации
портфеля ценных бумаг относится к оптимизационным задачам.
В типичной задаче
оптимизации существует набор переменных, влияющих на процесс, и формула или
алгоритм, который использует эти переменные, чтобы построить полную модель
этого процесса. При этом задача заключается в том, чтобы найти такие значения
переменных, которые некоторым образом оптимизируют модель. Если моделью
является формула, то обычно ищут максимум или минимум функции, которую данная
формула представляет. Существует много математических методов, которые решают
(и очень быстро) задачи оптимизации в том случае, если это задачи с
"хорошим поведением". Однако традиционные методы часто терпят крах,
если задача "ведет себя" недостаточно хорошо.
К сожалению, классические
методики оказываются малоэффективными во многих практических задачах. Это
связано с тем, что невозможно достаточно полно описать реальность с помощью
небольшого числа параметров модели, либо расчет модели требует слишком много
времени и вычислительных ресурсов.
В частности, рассмотрим проблемы, возникающие при решении задачи
оптимизации портфеля ценных бумаг.
В реальной задаче ни одна
из функций не известна точно - известны лишь приблизительные или ожидаемые
значения прибыли. Для того чтобы избавиться от неопределенности, мы вынуждены
зафиксировать функции, теряя при этом в точности описания задачи.
Детерминированный
алгоритм для поиска оптимального решения (симплекс-метод) применим только в том
случае, если все данные функции линейны. В реальных задачах бизнеса это условие
не выполняется. Хотя данные функции можно аппроксимировать линейными[7],
решение в этом случае будет далеким от оптимального.
Если одна из функций
нелинейна, то симплекс-метод неприменим, и остается два традиционных пути
решения этой задачи.
Первый путь -
использовать метод градиентного спуска[15] для поиска максимума прибыли. При решении задачи методом
градиентного спуска вначале выбираются некоторые случайные значения параметров,
а затем эти значения постепенно изменяют, добиваясь наибольшей скорости роста
целевой функции. Достигнув локального максимума, такой алгоритм
останавливается, поэтому для поиска глобального оптимума потребуются
дополнительные усилия. Градиентные методы работают очень быстро, но не
гарантируют оптимальности найденного решения. Они идеальны для применения в так
называемых унимодальных
задачах, где целевая функция имеет единственный локальный максимум (он же -
глобальный). Типичная практическая задача, как правило, мультимодальна и многомерна, то есть содержит
много параметров. Для таких задач не существует ни одного универсального
метода, который позволял бы достаточно быстро найти абсолютно точное решение. В данном случае область определения
функции прибыли имеет сложную форму, а сама функция - несколько локальных
максимумов, поэтому градиентный метод может привести к неоптимальному решению.
Второй путь - провести полный перебор вариантов инвестирования, что
означает, что для определения наилучшей перебираются все возможные комбинации.
Этот подход обеспечивает очень точный результат : в конечном итоге обязательно
найдется наилучшая комбинация. Однако, это очень неэффективный подход,
поскольку полный перебор всех комбинаций параметров в большинстве случаев
требует недопустимо много времени. Пользователи оптимизаторов с полным
перебором вынуждены ограничивать число используемых переменных и количество
значений, которые эти переменные могут принимать.
Вероятностные
технологии также обладают существенными недостатками при решении практических
задач. Также нужно отметить, что статистические методы хорошо развиты только
для одномерных случайных величин. Если же необходимо учитывать для
прогнозирования курса акций несколько взаимосвязанных факторов (например, объем
сделок, курс доллара и т.д.), то придется обратиться к построению многомерной
статистической модели. Однако такие модели либо предполагают гауссовское
распределение наблюдений (что не выполняется на практике), либо не обоснованы
теоретически.
В дипломной работе
задача оптимизации портфеля ценных бумаг будет решена с использованием
генетического алгоритмах [9]. Генетические алгоритмы - это специальная
технология для поиска оптимальных решений, которая успешно применяется в
различных областях науки и бизнеса. В этих алгоритмах используется идея
естественного отбора среди живых организмов в природе, поэтому они называются
генетическими. Генетические алгоритмы часто применяются совместно с нейронными
сетями, позволяя создавать предельно гибкие, быстрые и эффективные инструменты
анализа данных.
Генетический алгоритм не пробует каждую возможную комбинацию и не
ограничивает пространство поиска. Вместо этого он пытается подбираться все
ближе и ближе к лучшему решению, используя механизмы естественного отбора,
аналогичные имеющим место в живой природе. Как следствие этого, можно
использовать гораздо больше переменных, и можно позволить поиск среди всех
значений каждой из переменных. Если дать генетическому алгоритму слишком много
переменных, оптимизация все же может занять достаточно большое время, но за это
время будет проделано гораздо больше работы. В дополнение следует отметить, что
благодаря эволюционному механизму генетические алгоритмы гораздо менее
подвержены "застреванию" в локальных минимумах, чем другие алгоритмы
оптимизации, отличные от полного перебора.
Первый шаг при построении
генетических алгоритмов — это кодировка исходных логических закономерностей в
базе данных, которые именуют хромосомами, а весь набор таких закономерностей
называют популяцией хромосом. Далее для реализации концепции отбора вводится
способ сопоставления различных хромосом.
Стандартные операторы для
всех типов генетических алгоритмов это:
- селекция
- скрещивание
-мутация.
Оператор селекции
(reproduction, selection) осуществляет отбор хромосом в соответствии со
значениями их функции приспособленности. Существуют как минимум два популярных
типа оператора селекции: рулетка и турнир.
-Метод рулетки (roulette-wheel selection) -
отбирает особей с помощью n "запусков" рулетки. Колесо рулетки
содержит по одному сектору для каждого члена популяции. Размер i-ого
сектора пропорционален соответствующей величине Psel(i)
вычисляемой по формуле:
(1.1)
При таком отборе члены популяции с
более высокой приспособленностью с большей вероятностью будут чаще выбираться,
чем особи с низкой приспособленностью.
-Турнирный отбор (tournament selection) реализует n
турниров, чтобы выбрать n особей. Каждый турнир построен на выборке k
элементов из популяции, и выбора лучшей особи среди них. Наиболее распространен
турнирный отбор с k=2.
-Оператор скрещивание
(crossover) осуществляет обмен частями хромосом между двумя (может быть и
больше) хромосомами в популяции. Может быть одноточечным или многоточечным.
Одноточечный кроссовер работает следующим образом. Сначала, случайным образом
выбирается одна из l-1 точек разрыва. Точка разрыва - участок между
соседними битами в строке. Обе родительские структуры разрываются на два
сегмента по этой точке. Затем, соответствующие сегменты различных родителей
склеиваются и получаются два генотипа потомков.
-Мутация (mutation) -
стохастическое изменение части хромосом. Каждый ген строки, которая подвергается
мутации, с вероятностью Pmut (обычно очень маленькой) меняется на
другой ген.
Генетические алгоритмы удобны тем, что их легко
распараллеливать. Например, можно разбить поколение на несколько групп и работать
с каждой из них независимо обмениваясь время от времени несколькими
хромосомами. Существуют также и другие методы распараллеливания генетических
алгоритмов.
Генетические алгоритмы
имеют ряд недостатков. Критерий отбора хромосом и используемые процедуры
являются эвристическими и далеко не гарантируют нахождения “лучшего” решения.
Как и в реальной жизни, эволюцию может “заклинить” на какой-либо непродуктивной
ветви. И, наоборот, можно привести примеры, как два неперспективных родителя,
которые будут исключены из эволюции генетическим алгоритмом, оказываются
способными произвести высокоэффективного потомка. Это особенно становится
заметно при решении высокоразмерных задач со сложными внутренними связями.
1.3
Обзор существующих программных продуктов
Прежде всего,
необходимо провести обзор существующих программных продуктов для решения задач
с использованием генетических алгоритмов. На сегодняшний момент на рынке
программного обеспечения можно найти достаточно программ, которые используют
генетические алгоритмы. Проведем обзор и сравнительный анализ существующего
программного обеспечения, которое использует в своей работе генетические
алгоритмы.
Программа Genetic
Algorithm and Direct Search Toolbox предназначена для решения задач оптимизации
при использовании генетического алгоритма и алгоритма прямого поиска. В этой
программе содержатся новые возможности по применению известных алгоритмов
оптимизации для такого класса задач, который представляет определенные
трудности при решении обычными методами оптимизации, то есть такого класса
задач, который представляет определенную трудность в математической
формулировке. Основные особенности программы:
- Графический интерфейс
пользователя и функции командной строки являются удобными средствами для
постановки задачи; установки соответствующих опций алгоритма и мониторинга
выполнения задачи.
- Генетический алгоритм
дополнен инструментами для разработки, масштабирования, отбора, перехода от
одной задачи к другой и изменения хода выполнения программы.
- Наличие функциональной
связи между программами Optimization Toolbox и MATLAB и генетическим алгоритмом
и методом прямого поиска.
- Поддержка
автоматической генерации М-кодов.
-Имеются соответствующие
инструментарии для управления процессом оптимизации и контроля эффективности
выполнения и ввода критериев останова выполнения программы.
Рисунок 1.1 - Внешний вид программы Genetic Algorithm
and Direct Search Toolbox
Программа поддерживает
выполнение таких функций:
1. Функций для
отображения результатов оптимизации. Подобная визуализация дает возможность
установить динамическую обратную связь с процессом оптимизации и проводить
необходимые модификации во время выполнения программ. Специализированные
графические функции имеются как для генетического алгоритма, так и для метода
прямого поиска. В набор специализированных графических функций входят:
-графики для отображения
значений функции;
-гистограмма оценки эффективности;
-генеалогический график;
-показатель соответствия;
-расчетные значения
функций;
Кроме того, есть
возможность совмещения графиков, выделение отдельных графиков для более
тщательного анализа и введение собственных графических отображений пользователя.
2. Функции для вывода
результатов
-запись результатов в
файл,
-формирование собственных
критериев останова,
-создание
собственных графических интерфейсов для управления программами решателей в
данном тулбоксе.
Компьютер должен отвечать следующим
системным требованиям:
Операционная система: XP (Service Pack 1 or 2), 2000 (Service Pack 3 or 4), NT 4.0
(Service Pack 5 или 6a);
Процессор: Pentium III, IV, Xeon, Pentium M,
AMD Athlon, Athlon XP, Athlon MP;
Пространство на диске: 340 MB и выше;
Оперативная память: 256 MB,512 MB
(рекомендуется);
GeneHunter представляет собой
комплекс мощных программных средств для решения оптимизационных задач с помощью
генетических алгоритмов.
Пакет состоит из трех частей:
1. Надстройка для Microsoft Excel. Надстройка дает возможность решать
оптимизационные задачи прямо в Excel.
-Решение оптимизационных задач из рабочих листов Excel;
-Автоматический поиск ячеек Вашего рабочего листа, которые используются
при решени задачи;
-Задание параметров генетического алгоритма и списка ограничений,
которым должно удовлетворять решение;
-Доступность для пользователей, не владеющих программированием;
2. Динамическая библиотека функций. Библиотека функций генетических
алгоритмов GALIB, которую можно использовать при программировании своих
собственных систем.
3. Комплект примеров. Комплект примеров использования пакета для решения
разнообразных задач, который содержит множество полезных идей. В комплект
входят готовые документы Excel, на примере которых можно легко научиться
использовать надстройку для Excel, а также исходные коды на Delphi, Borland C,
Visual Basic и Visual C, демонстрирующие использование программного интерфейса
библиотеки GALIB.
Рисунок 1.2 –
Внешний вид среды GeneHunter
Рисунок
1.3 Диалоговое окно среды GeneHunter
Рисунок
1.4 Окно для ввода параметров GeneHunter
Диалоговое окно
GeneHunter — Ячейка целевой функции.
Окно “Целевая функция” передает в GeneHunter сообщение о положении
ячейки с формулой, по которой определяется, насколько хорошее решение задачи
нашел GeneHunter. Формула может быть создана с помощью любой функции Excel,
доступной из меню "Вставка", например "СРЗНАЧ". Для
создания формул можно также использовать макросы Excel или функции Excel
Visual Basic, которые позволяют решать очень сложные задачи. Для расчета
целевой функции можно использовать нейросети.
Диалоговое окно “GeneHunter — хромосомы”. Хромосомы
представляют собой переменные, значения которых надо подобрать для того, чтобы
решить задачу. Их значения в конечном итоге определяют величину целевой функции.
GeneHunter использует два типа хромосом:
- Непрерывные хромосомы используются в том случае, когда подбираемый
параметр может принимать значения из некоторой непрерывной области, например,
значение 1,5 внутри диапазона от 0 до 2. Непрерывные хромосомы могут также быть
целыми числами.
- Перечислимые хромосомы используются в задачах поиска оптимальных
комбинаций типа выбора маршрута, составления расписания занятий или
последовательности процессов и т.п.
Диалоговое окно GeneHunter — диапазоны, ограничения и
дополнительные целевые функции. Нижняя часть диалогового окна GeneHunter позволяет
сделать следующее:
- Указать диапазоны значений каждой хромосомы, в которых GeneHunter будет искать решение.
- Добавить к первоначальной целевой
функции дополнительные условия. Такие условия называются ограничениями.
GeneHunter будет пытаться искать решения, которые удовлетворяют ограничениям,
но и одновременно оптимизируют целевую функцию.
- Указать ячейки дополнительных целевых функций, значения которых
будут оптимизироваться одновременно со значением главной целевой функции,
определенной выше.
Многие пользователи хотят
использовать мощь генетических алгоритмов в своих приложениях, однако
предпочитают разработать собственный интерфейс или сократить время вычислений
сложной целевой функции по сравнению со временем, которое эта процедура
занимает в Excel. Для удовлетворения этих потребностей в состав GeneHunter
включена полная динамическая библиотека функций генетических алгоритмов -
GALIB.DLL.
В библиотеку входят функции создания популяции, определения
параметров эволюции (таких как вероятности скрещивания, мутации, разнообразия),
определения значений целевой функции индивидуумов, обновления популяции и
перехода в следующее поколение. Пользователь имеет возможность создавать
индивидуумов с непрерывными или перечислимыми хромосомами.
Библиотека GALIB.DLL позволяет программисту использовать следующие
генетические операторы:
1. Оператор скрещивания представляет собой процесс, в ходе
которого GeneHunter выбирает двух подходящих индивидуумов и скрещивает их. При
этом потомство получит некоторые черты от обоих родителей.
2. Оператор мутации также служит для продолжения эволюции.
Однако, вместо комбинирования родительских качеств, мутация вносит изменение в
одного индивидуума путем случайного изменения одной из хромосом.
3. Оператор разнообразия также вносит изменения в отдельного
индивидуума, но это очень небольшие изменения в каждой хромосоме, а не сильное
изменение одной хромосомы, как происходит при мутации.
4. Оператор вымирания позволяет уничтожить всю популяцию за
исключением элиты. Подобно чуме, он уничтожает большую часть популяции и
освежает генетический материал, пополняя популяцию большим количеством новых
членов.
Руководство пользователя GeneHunter содержит подробное разъяснение по
каждой функции, включая описание аргументов, примеры вызова функции и список
функций, имеющих отношение к данной. Динамическая библиотека GALIB.DLL
позволяет создавать приложения, в которых могут развиваться одновременно до 128
популяций. Функция MakeChromosomePool дает возможность быстро создавать
множество схожих между собой хромосом, что бывает удобно, например, для таких
приложений, как оптимизация весов нейронной сети. GeneHunter позволяет
использовать даже смесь непрерывных и перечислимых хромосом в одной популяции.
Требования к компьютеру:
IBM® PC или совместимый компьютер с процессором не ниже Pentium 120 MHz, не
менее 128Mb ОЗУ и 1.5 Mbсвободного места на жестком диске.
Рекомендуется использовать процессоры обладающие высокой производительностью
при операциях с плавающей точкой. Например, Athlon 64 3000+, Pentium 4 3,2 GHz.
К недостаткам программы
GeneHunter фирмы Ward Systems Group можно отнести ее стоимость — около $1000,
а также большие требования к системным ресурсам.
TransGA является приложением
Windows, поэтому для выполнения приложений и открытия документов могут применяться
стандартные методы Windows.
TransGA получает
динамическую модель процесса путем установки динамических данных в процессе
экспериментально измерены. Эксперимент состоит в изменении входных данных
процесса и измерении результатов.
-Данные могут быть
занесены непосредственно в таблицу, расположенную в главном окне программе.
Добавление новой строки производится нажатием на кнопку “Добавить”, а удаление
строки нажатием на кнопку “Удалить”;
-Данные могут быть
скопированы из таблицы Excel;
- Данные могут быть
загружены из текстового файла с помощью команды меню "Файл".
Параметры алгоритма могут
быть адаптированы к конкретной проблеме. Эти параметры могут быть изменены в
диалоговом окне "Настройки", которое открывается с помощью команды
"Свойства обозревателя" в меню, или при нажатии на соответствующую
кнопку на панели инструментов.
Параметрами алгоритма
являются:
-численность
популяции;
-количество поколений;
-тип и вероятность
размножения;
-вероятность мутации;
-элитизм.
Рисунок
1.5 - Окно для ввода параметров TransGA
После введения
экспериментальных данных и настройки параметров алгоритма, алгоритм может быть
выполнен с помощью команды "Выполнить" меню алгоритма, либо при
нажатии на соответствующую кнопку на панели инструментов.
После выполнения алгоритма, полученные результаты будут показаны в главном
окне.(Рис 1.6)
Рисунок
1.6 - Окно TransGA
Эти результаты также
хранятся в текстовом файле с именем NameFile_Report.txt.
Отчет содержит следующие параметры:
- Параметры генетического
алгоритма;
-Изменение некоторых
параметров в ходе эволюции.
Эти параметры включают:
среднее значение и стандартное отклонение фитнес функции, количество мутаций и
репродукции, и генотип c лучшим решением,
фенотип и целевая функция.
-Резюме результатов,
полученных по алгоритму;
Рисунок
1.7 - Окно с результатами работы среды TransGA
Недостатком всех
программ этого класса считают требование к специальной подготовке пользователя.
Также нужно отметить, что мощные современные статистические пакеты являются
слишком "тяжеловесными" для массового применения в финансах и
бизнесе. К тому же часто эти системы весьма дороги — от $1000 до $15000.
1.4 Постановка задачи на разработку программной системы
Современная теория
портфельных инвестиций первоначально предложенная Марковицем, как было сказано
выше, основана на разумном обмене между средним ожидаемым доходом по всем
инвестициям и риском. Эта задача оптимизации может быть решена квадратичным
программированием. Но задача поиска оптимального портфеля ценных бумаг может
быть так же решена с использованием генетического алгоритма. Так как это -
типичная модель оптимизации, генетический алгоритм является подходящим для
этой задачи.
Пусть на рынке действуют
различные ценные бумаги с доходностями Mi и эффективностями Ri
, i=1...n, где Ri является случайной величиной,
распределенной по нормальному закону, а Mi есть
математическое ожидание случайной величины. Инвестор формирует портфель ценных
бумаг, покупая ценные бумаги всех видов, причем на i-ый вид ценных бумаг
тратится xi доля капитала.
2
РАЗРАБОТКА МОДЕЛИ И ПРОЕКТИРОВАНИЕ ПРОГРАММНОЙ СИСТЕМЫ
По определению портфель ценных бумаг
будет иметь следующий вид:
(2.1)
Доходность портфеля ценных
бумаг вычисляется следующей формулой: (2.2)
Эффективность портфеля соответственно
будет исчисляться следующим образом:
(2.3)
(2.4)
(2.5)
Где, где Rit – доходность
ценной бумаги i за время t, SCPit - цена на момент
закрытия биржи ценных бумаг на ценную бумагу i в момент времени t,
n - число периодов времени для доступных данных.
Риск портфеля рассчитывается по
формуле:
(2.6)
(2.7)
Обозначим параметры
модели, описывающей оптимальный портфель ценных бумаг:
- Входными параметрами
модели будут являться:
S={s1,s2…sn}
- множество всевозможных состояний рынка, где i - общее количество
состояний;
P(Si) –
вероятность возникновения состояния si причем
(2.8)
N={n1.n2…nj}–
акции (альтернативы), отобранные для включения в портфель, где j- общее
количество акций;
R={r1,1.r1,2…rij}–
матрица возможных значений доходности j-ой акции для i-го
состояния;
Выходными параметрами
модели будут являться:
M={M1.M2…Mj}–
– среднеожидаемая доходность акций, где j - общее количество акций;
B=||cov(ri,rj)||-
ковариационная матрица, где диагональные элементы задают риск активов.
Целевые функции могут
быть определены следующим образом:
(2.9)
(2.10)
(2.11)
Целевая функция может
быть выбрана пользователем.
Так же при разработке программного
продукта по оптимизации портфеля ценных бумаг с помощью генетических алгоритмов
необходимо, чтобы в программе присутствовали следующие функции:
- Импорт котировок акций
из текстового файла заданного формата;
- Возможность
представления информации в виде графиков;
- Возможность
редактировать, удалять добавлять котировки акций;
- Возможность печати
результатов работы программы и графиков;
- Возможность экспорта
данных из программы в Microsoft Office;
- Легкий и интуитивно
понятный интерфейс пользователя;
- Возможность отбора
акций, которые будут включатся в портфель;
- Возможность задавать
параметры для генетического алгоритма, таких как: количество индивидуумов в
популяции, вероятности кроссинговера и мутации, количество итераций работы
генетического алгоритма без изменения значения его фитнесс - функции.
2.1
Проектирование
структуры программной системы
Программа для оптимизации
портфеля ценных бумаг состоит из нескольких блоков, которые дополняют друг
друга.
Блок архива котировок -
в этом блоке пользователю дается возможность импортировать котировки акций из
текстового файла определенного формата. В этом же блоке пользователь может
редактировать, удалять, добавлять значения котировок акций. Акции представлены
в виде дерева. Пользователь имеет возможность загрузить котировки акций за
разный период. Например, за день, неделю, месяц, год.
Блок отбора акций тех
компаний, акции которых будут включаться в портфель для оптимизации.
Блок вывода результатов
работы алгоритма - как известно , генетический алгоритм выдает множество
вариантов решений поставленной задачи . В данном случае , варианты решений
располагаются по горизонтали. Первые столбцы – это доли в каждую ценную бумагу ,
по которым инвестор должен распределить свой капитал . Предпоследний и
последний столбцы задают риск и доходность портфеля соответственно в процентах.
Блок задания параметров
для работы генетического алгоритма – здесь пользователь может ввести количество
индивидуумов в популяции, вероятности кроссинговера и мутации, количество
итераций работы генетического алгоритма без изменения значения его
фитнесс-функции, что повышает гибкость программы.
Блок вывода графика курса
акций - предназначен для визуального просмотра курса акции за определенный
период. График курса акции позволяет помочь инвестору принять правильное
решение при выборе акции для портфеля ценных бумаг.
Блок печати полученных
результатов на принтер - позволяет вывести нужную информацию, а так же
графики из программы на принтер.
Блок экспорта полученных
результатов работы программы в Excel – данная возможность позволяет конечному
пользователю в среде, независимой от программы генерации оптимального портфеля
ценных бумаг(в данном случае в Excel), просмотреть конечный результат работы
программы, отредактировать и распечатать в удобном для него виде.
Блок справочной
информации – в этом блоке находится инструкция по использованию программы.
2.2 Проектирование UML-Диаграмм работы и взаимодействия блоков
программы
Язык UML представляет
собой общецелевой язык визуального моделирования, который разработан для
спецификации, визуализации, проектирования и документирования компонентов
программного обеспечения, бизнес-процессов и других систем. Язык UML одновременно
является простым и мощным средством моделирования, который может быть
эффективно использован для построения концептуальных, логических и графических
моделей сложных систем самого различного целевого назначения. Этот язык вобрал
в себя наилучшие качества методов программной инженерии, которые с успехом
использовались на протяжении последних лет при моделировании больших и сложных
систем.
Язык UML основан на
некотором числе базовых понятий, которые могут быть изучены и применены
большинством программистов и разработчиков, знакомых с методами
объектно-ориентированного анализа и проектирования. При этом базовые понятия
могут комбинироваться и расширяться таким образом, что специалисты объектного
моделирования получают возможность самостоятельно разрабатывать модели больших
и сложных систем в самых различных областях приложений.
Конструктивное
использование языка UML основывается на понимании общих принципов моделирования
сложных систем и особенностей процесса объектно-ориентированного анализа и проектирования
в частности. Выбор выразительных средств для построения моделей сложных систем
предопределяет те задачи, которые могут быть решены с использованием данных
моделей. При этом одним из основных принципов построения моделей сложных систем
является принцип абстрагирования, который предписывает включать в модель только
те аспекты проектируемой системы, которые имеют непосредственное отношение к
выполнению системой своих функций или своего целевого предназначения. При этом
все второстепенные детали опускаются, чтобы чрезмерно не усложнять процесс
анализа и исследования полученной модели.
В рамках языка UML все
представления о модели сложной системы фиксируются в виде специальных
графических конструкций, получивших название диаграмм. В терминах языка UML
определены следующие виды диаграмм:
− Диаграмма вариантов использования
(use case diagram)
− Диаграмма классов (class diagram)
− Диаграммы обращения (behavior
diagrams)
− Диаграмма состояний (statechart
diagram)
− Диаграмма деятельности (activity
diagram)
− Диаграммы взаимодействия (interaction
diagrams)
− Диаграмма последовательности
(sequence diagram)
− Диаграмма кооперации (collaboration
diagram)
− Диаграммы реализации (implementation
diagrams)
− Диаграмма компонентов (component
diagram)
− Диаграмма развертывания (deployment
diagram)
Каждая из этих диаграмм
детализирует и конкретизирует различные представления о модели сложной системы
в терминах языка UML. При этом диаграмма вариантов использования представляет
собой наиболее общую концептуальную модель сложной системы, которая является
исходной для построения всех остальных диаграмм. Диаграмма классов является, по
своей сути, логической моделью, отражающей статические аспекты структурного
построения сложной системы.
Центральное место в ООАП
занимает разработка логической модели системы в виде диаграммы классов. Нотация
классов в языке UML проста и интуитивно понятна всем, кто когда-либо имел опыт
работы с CASE-инструментариями. Схожая нотация применяется и для объектов —
экземпляров класса, с тем различием, что к имени класса добавляется имя объекта
и вся надпись подчеркивается.
Класс (class) в языке UML
служит для обозначения множества объектов, которые обладают одинаковой
структурой, поведением и отношениями с объектами из других классов. Графически
класс изображается в виде прямоугольника, который дополнительно может быть
разделен горизонтальными линиями на разделы или секции (рис. 2.1). В этих
разделах могут указываться имя класса, атрибуты (переменные) и операции
(методы).
Рисунок 2.1 - Диаграмма классов
3
РАЗРАБОТКА ПРОГРАММНОЙ СИСТЕМЫ
3.1
Разработка
алгоритмов работы программной системы
Процесс разработки любой
программы делится на несколько этапов, один из которых - разработка алгоритма
работы программы, когда определяются действия программы во время тех или иных
событий. Существует много способов разработки алгоритмов - графические
алгоритмы (блок схемы), алгоритмические языки и т.д. Центральное место в работе
программы занимает работа генетического алгоритма. Разработаем блок схему
генетического алгоритма. На первом этапе случайным образом генерируется
исходная популяция хромосом.
С помощью математической
модели определяется индекс приспособленности каждого решения и в зависимости от
его величины упорядочивается популяция. Далее вычисляется средняя по популяции
приспособленность. Опираясь на нее, назначается вероятность, с какой каждая
особь, обладающая приспособленностью выше среднего уровня, может стать
родителем. Для каждого родителя есть две возможности - либо просто быть
скопированным в следующее поколение, либо подвергнутся воздействию генетических
операторов в процессе генерирования хромосомы потомка.
Далее оценивается
приспособленность потомка, и, действуя аналогичным образом, постепенно
заполняется популяция следующего поколения. Через М шагов новое поколение будет
сформировано. Ясно, что поскольку оно получено от лучших родителей, то его
приспособленность должна быть также высокой. Не вызывает сомнений, что,
блокировка слабо приспособленным особям возможности стать родителем и дать потомство,
увеличивает или, по крайней мере, не уменьшает среднюю по популяции
приспособленность.
Работа алгоритма
прекращается при достижении популяцией состояния адаптации. То есть когда
величина фитнесс- функции максимальна или установленное количество эпох
закончилось. Кроссовер как механизм изменчивости теряет в таких условиях свою
силу - при скрещивании идентичных родителей потомок ничем не будет отличается
ни от одного из них.
Рисунок 3.1 - Работа
генетического алгоритма
К сожалению, почти никогда
(за исключением аналитически сконструированных тестовых задач) нельзя с
уверенностью утверждать, что найденное решение представляет собой глобальный
экстремум. Фенотипическое и генотипическое вырождение популяции является
необходимым, но не достаточным признаком успешности поиска. Оно только
свидетельствует, что какой-то экстремум найден, но ничего не говорит о том,
каков его характер, Тем не менее, не остается ничего другого, как
довольствоваться достигнутым результатом. В противном случае лучше повторно
запустить задачу в надежде на более благоприятное развитие событий, чем ждать
чуда от популяции. Эволюция неповторима и при новом сочетании случайных
факторов решение может оказаться более привлекательным.
Генерация популяции
хромосом проводится случайным образом. Хромосома задается вектором размера N ,
каждый элемент которой -десятичное целое число от 0 до 1. Каждый элемент в
хромосоме представляет собой удельный вес i - ценной бумаги в общем
портфеле ценных бумаг. Поскольку общей удельный вес ценных бумаг должен быть
равен 1, после инициализации хромосомы, используя формулу необходимо
нормализовать удельный вес ценных бумаг(таблица 3.1).
(3.1)
Таблица 3.1 - Удельный вес
ценной бумаги к и после нормализации
№ ценной бумаги
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
Хромосома vi(t)
|
0.52
|
0.35
|
0.44
|
0.68
|
0.56
|
0.23
|
0.11
|
0.19
|
Удельный вес ЦБ после нормализации
|
0.17
|
0.11
|
0.14
|
0.22
|
0.18
|
0.07
|
0.04
|
0.06
|
В работе применяются
стандартные генетические операции – отбор,
мутация и скрещивание. Операция
отбора организована таким образом, что
особи сортируются по убыванию
приспособленности, а затем выбираются
пропорционально полученному после
сортировки номеру.
Оператор мутации
выполняется методом вставки. Случайно выбранный ген, с малой вероятностью,
которая задается, меняется местами с другим геном.(Таблица 3.2,3.3)
Таблица 3.2 Вид хромосомы до
мутации
0.45
|
0.32
|
0.21
|
0.49
|
0.88
|
0.12
|
0.03
|
0.38
|
Таблица 3.3 Вид хромосомы
после мутации
0.45
|
0.32
|
0.21
|
0.88
|
0.12
|
0.03
|
0.49
|
0.38
|
Оператор скрещивание
(crossover) выполняется методом одноточечного скрещивания. Одноточечный
кроссовер работает следующим образом. Сначала, случайным образом выбирается
одна из l-1 точек разрыва. Точка разрыва - участок между соседними
битами в строке. Обе родительские структуры разрываются на два сегмента по этой
точке. Затем, соответствующие сегменты различных родителей склеиваются и
получаются два генотипа потомков.
Рисунок 3.2 - Пример
одноточечного кроссовера
3.2 Разработка интерфейса программы
Современные
Windows-приложения создаются с помощью 32-разрядного интерфейса прикладного
программирования Win32, который содержит библиотеку классов, необходимых для
создания Windows-приложения. Windows-приложения поддерживают многозадачность и
многопоточность.
Наиболее важным
свойством Windows-приложений является то, что все они используют стандартный
графический пользовательский интерфейс. Этот интерфейс поддерживается
операционной системой Windows.
Графический пользовательский
интерфейс - это интерфейс, поддерживающий операции с использованием мыши, окна,
пиктограммы, меню, кнопок и так далее. До появления Win32 API программисту приходилось не
только создавать каждый элемент интерфейса, но и писать тысячи строк кода для определения
действий, выполняемых с помощью этих элементов, в зависимости от контекста их
использования. С появленим Win32 API все изменилось. Окна, меню, диалоговые
окна, кнопки и другие элементы теперь легко могут быть добавлены в новое
приложение. Win32 API автоматически генерирует большую часть кода для
выполнения стандартних операций. Еще одним преимуществом использования Win32
API является сокращение сроков создания приложений.
Обычный интерфейс
Windows-приложения представляет собой окно, в котором размещены различные
элементы управления. В среде Visual Studio .NET это окно называют формой.
Формы Windows - это
основной компонент пользовательского интерфейса. Они предоставляют контейнер,
который содержит элементы управления и меню и позволяет отображать приложение в
уже привычной и единообразной модели. Элемент управления - это объект формы,
используемый для взаимодействия с пользователем. Элементы управления
применяются для получения входных данных от пользователя и вывода результатов.
Самыми распространенными элементами управления можно назвать текстовые окна,
кнопки, окна списков и переключатели. Для каждой формы могут быть определены
собственный стиль, формат, цвет и другие характеристики.
Интерфейс приложения
может состоять только из одной формы или из одной родительской (parent) формы
и нескольких дочерних (chield) форм. Первый вид интерфейса (с одной формой)
называют однодокументным интерфейсом (SDI-Single- Document Interface), а второй
многодокументным(MDI-Multiple Document Interface).
Приложение, которое использует несколько интерфейсов, является MDI-приложением.
Такое приложение имеет одну родительскую и несколько дочерних форм. Дочерние
формы отображаются в пределах родительской формы. MDI-приложения позволяют
пользователям одновременно работать с несколькими формами.
Рисунок 3.3 - Общая схема
интерфейса программы
При запуске программы открывается
главное окно программы. В верхней части главного окна расположено
горизонтальное меню. Меню создано с использованием элемента управления MenuStrip.
Первичное предназначение элемента MenuStrip заключается в отображении объектов
ToolStripItemMenu. Элемент управления MenuStrip предоставляет большое
количество свойств, влияющих на поведение элементов управления
ToolStripMenuItem. Объекты ToolStripMenuItem являються элементами управления,
обеспечивающими визуальное представление для элементов меню. Они могут
выглядеть в виде текста или изображения, а код, который содержится в
обработчиках события ToolStripMenuItem.Click , будет выполняться при щелчке мыши.
Рисунок 3.4 - Главное окно
программы
Главное меню программы состоит из
таких пунктов меню:
− Файл
− Сервис
− Оптимизация
− Справка
− Выход
Рассмотрим каждое меню
программы более подробно.
Меню “Файл” содержит два
подменю: “Новый график” и “Выход”. При нажатии на пункт меню “Новый график”
появляется выпадающее меню с перечнем доступных пользователю акций. При щелчке
на выбранной акции в главном окне выводится график, показывающий курс акции,
выбранной пользователем. Пункты меню с названиями доступных акций формируются
динамически, в зависимости от того, сколько текстовых файлов с курсами акций
сохранено в определенной папке на жестком диске.
.
Рисунок 3.5 - Вид пункта
меню “Новый график”
При нажатии на пункт меню
“Выход” происходит выход из программы.
Пункт меню “Сервис”
содержит два подпункта-Архив котировок и настройки.
Пункт меню “Архив
котировок” позволяет пользователю просматривать котировки выбранной акции, что
повышает удобство программы.
Пункт меню “Архив
котировок” позволяет пользователю загружать котировки акций из текстового
файла, редактировать котировки, удалять, экспортировать котировки в текстовый
файл.
Рисунок 3.6 - Внешний вид
окна “Архив котировок”
Окно “Архив котировок”
представляет собой форму, которая разделена на две части в левой части
пользователь может выбрать префикс акции, курсы которой он хочет просмотреть.
При щелчке мышью на префиксе акции открывается список доступных временных
интервалов. Нажав на нужный временной интервал в правой части окна,
пользователь может увидеть котировки выбранной акции за определенный период.
Для отображения перечня
акций в левой части окна используется элемент управления TreeView. Этот элемент
позволяет отображать список объектов иерархичным способом. Узлы, содержащие
дочерние узлы в элементе управления TreeView, можно сворачивать и
разворачивать.
В нижней части окна
расположен ряд кнопок. Кнопка “Загрузить” позволяет загрузить текстовый файл с
котировками акции.
Кнопка “Добавить”
позволяет добавить строку котировок на определенную дату. Кнопка “Правка”
переводит таблицу с котировками акций в режим редактирования. Кнопка “Удалить”
позволяет удалять строки, выбранные пользователем. Кнопка “Экспорт” позволяет
экспортировать котировки акций в текстовый формат. Кнопка “Закрыть” закрывает
окно архива котировок.
Следующий пункт главного
меню – “Оптимизация”. Пункт меню “Оптимизация” содержит два подменю – “Начать
оптимизацию” и “Параметры”.
При нажатии на пункт меню
“Начать оптимизацию” открывается мастер, который последовательно открывает ряд
окон.
Окно “Выбор акций для
портфеля ценных бумаг”. В этом окне происходит отбор акций тех компаний, акции
которых будут включаться в портфель. После того как пользователь выберет необходимое количество
акций он нажимает на кнопку и ОК и переходит к следующему окну.
Окно “Цены закрытия выбранных акций” - Это окно выводит в
таблице цены закрытия выбранных пользователем акций.
При нажатии на кнопку “Начать расчет” происходит запуск
генетического алгоритма.
Рисунок 3.7 - Окно выбора
акций
Рисунок 3.8 -
Внешний вид окна цены закрытия
Рисунок 3.9 - Внешний вид
окна с результатами работы программы
После
окончания работы генетического алгоритма открывается окно с результатами его
работы.
Как известно,
генетический алгоритм выдает множество вариантов решений поставленной задачи. В
данном случае, варианты решений располагаются по горизонтали. Первые несколько
столбцов – это доли в каждую ценную бумагу, по которым инвестор должен
распределить свой капитал. Последний столбец показывает значение фитнес
функции. Каждая строка таблицы показывает лучшее решение на данной итерации.
Внизу окна расположены кнопки “График”
и “Закрыть”.
При нажатии на кнопку “График”
открывается окно с круговым графиком, где в графическом виде представлен удельный
вес каждой из выбранных ценных бумаг в оптимизированном портфеле.
Нажатие кнопки “Закрыть” закрывает
окно.
Рисунок 3.10 - Результат
работы программы в графическом виде
Пункт меню “Параметры”. При нажатии
на этот пункт меню открывается окно, где пользователь может самостоятельно
изменить параметры работы генетического алгоритма.
Рисунок 3.11 -
Параметры генетического алгоритма
Пункт меню “Справка”. При нажатии на
этот пункт меню открывается окно “О программе”.
4
РАЗРАБОТКА ПРОГРАММНОЙ СИСТЕМЫ
4.1
Обоснование
средств реализации
C# является, согласно
определению Microsoft, “простым, современным, объективно-ориентированным языком
программирования, обеспечивающим безопасность типов и представляющим собой
логическое развитие языков С и С++”, Ориентированный на разработчиков
Web-приложений, для которых основным языком программирования считается Java ,
C# входит в состав Microsoft Visual Studio .NET.
C# разрабатывался
специально для платформы .NET – технологии Microsoft, которая позволяет Web-программистам
создавать сложные Internet-приложения. Платформа .NET содержит обширную
библиотеку классов, доступ к которой возможен не только для разработчиков,
использующих C#, но и для тех, кто предпочитает программировать на других
языках. По существу .NET – это общая платформа для разработчиков Web- и
Windows- приложений.
Создавая C#, Корпорация
Microsoft предприняла попытку объединить лучшие свойства доступных на
сегодняшний день языков программирования и инструментальных средств. Языки С,
С++ и Visual С обеспечивают достаточно эффективное управление и гибкость, но
ценой за это являются большие затраты времени на создание программы. C# лишен
этого недостатка.
Синтаксис C# похож на
синтаксис С++ и Java, только он еще проще. В C# отсутствуют некоторые слишком
сложные возможности С++, такие как указатели и непосредственный доступ к
памяти.
В C# не поддерживается
множественное наследование классов. Однако разработчики могут имитировать
возможности множественного наследования с помощью концепции интерфейсов.
Кроме того, в C#
добавлена возможность, которую называют автоматизированной сборкой мусора и
благодаря которой программисты освобождаются от утомительной обязанности
управлять памятью вручную. Некоторые из современных средств разработки и языков
программирования, например VB и С++, были созданы в то время, когда Web
находилась на раннем этапе развития. В большинстве из них отсутствует поддержка
передовых Web технологий. В C# этот недостаток устранен. Язык C# по сути можно
назвать Web-ориентированным. Платформа .NET, для которой и разработан C#,
содержит большое количество предопределенных классов, поддерживающих работу с
языками XML и HTML и протоколом SOAP.
XML становится все более
популярным стандартом для передачи данных по Internet. C# позволяет осуществлять
непосредственное преобразование XML-данных в тип struct. Таким образом,
облегчается возможность передачи небольшого объема данных по Internet. В C#
также встроена поддержка финансовых типов данных и специальных типов для
изменяющихся во времени данных. В качестве примеров встроенных типов можно
назвать decimal и math. Финансовые типы добавлены как долгожданные
нововведения, особенно актуальное в эру разработки приложений уровня
предприятий.
C# - идеальный язык
программирования для разработки особо сложных приложений масштаба предприятия.
Однако в настоящее время уже используется большое количество приложений,
созданных с помощью С/С++, и может потребоваться поддержка машинно-зависимого
кода этих приложений. Могут оказаться необходимыми и арифметические действия с
указателями, и управление памятью вручную. В C# реализована встроенная
поддержка для COM и ограниченное использование указателей. Более того,
программы на C# могут получать доступ к существующим COM-объектам, независимо
от того на каком языке они были созданы.
Значение, которое
оказывается поддержке Web в модели .NET и языке C#, может вызвать ошибочное
представление, что Microsoft перестала заниматься улучшением методов
программирования в среде Windows. На самом деле Microsoft затратила значительные
усилия, чтобы упростить разработку Windows-приложений с помощью технологии
Windows.Forms. Windows.Forms - это архитектура, построенная на базе управляемых
классов и являющаяся частью среды .NET.
С помощью Windows.Forms
программисты могут быстро создавать интерфейсы для своих приложений,
рассчитанных на использование Web. К методу перетаскивания элементов управления
Visual Basic, Windows.Forms добавляет преимущества среды .NET:общая структура
приложений, управляемая среда выполнения, встроенные методы обеспечения
безопасности и реализация принципов объектно-ориентированного программирования.
Кроме того, технология Windows.Forms обеспечивает полную поддержку быстрого
подключения к Web-службам и построения мощных, основанных на модели ADO.NET
приложений с возможностью доступа к базам данных. Приложения, созданные на
основе технологии Windows.Forms, могут быть написаны на любом из языков
программирования, которые поддерживаются .NET Framework, например VB.NET или
C#.
В качестве среды
разработки выбран Visual Studio .NET. Вот некоторые характеристики этого
редактора:
-Все программы .NET
создаются на базе исходных текстовых файлов. Программы на C# хранятся в файлах
cs. Visual Studio .NET-это инструмент, необходимый для разработчиков,
работающих на любых платформах. Его преимущества впечатляют.
-Автоматическое выявление
ошибок. Можно сэкономить многие часы, воспользовавшись возможностью Visual
Studio .NET выявлять ошибки и сообщать о них еще до исполнения приложений.
Потенциально проблемные отрывки кода подчеркиваются, что напоминает функцию
фоновой проверки правописания, имеющуюся во многих текстовых процессорах.
Visual Studio .NET может обнаруживать широкий спектр проблем, таких как ошибки
преобразования типов данных, отсутствие пространств присваиваемых имен и
классов, не определенные переменные. Ошибки обнаруживаются на стадии набора на
клавиатуре, подчеркиваются и для удобства добавляются в список ошибок.
-Конструктор Windows форм. Чтобы добавить элемент
управления Windows Forms, нужно только перетащить
его в нужное место, вручную изменить его размер и настроить свойства. Visual
Studio .NET делает все остальное: автоматически создает шаблонный файл с
необходимыми тегами и трибутами и добавляет управляющие переменные в файл с
кодом.
-Повышение продуктивности.
Visual Studio .NET делает процесс кодирования быстрым и эффективным,
обеспечивая сворачиваемое отображение кода(collapsible code display),
автоматическое завершение операторов и синтаксис с цветовым кодированием.
-Простое размещение. При
создании нового проекта в Visual Studio .NET все необходимые файлы генерируются
автоматически. При компиляции приложения, все классы приложения компилируются в
один файл DLL, что обеспечивает простое размещение.
-Полная расширяемость. В
редактор можно добавлять собственные расширения, элементы управления и
динамические средства справки, а также настраивать все детали его внешнего вида
и работы.
-Многоуровневая отладка.
В Visual Studio .NET сохранены широко известные инструменты отладки,
позволяющие просматривать результаты работы кода и следить за содержанием
переменных.
-Дизайн Web-страниц.
Можно без труда создавать привлекательное оформление Web-страниц, используя
интегрированные в Visual Studio .NET средства дизайна Web-форм.
-IntelliSense. Visual
Studio .NET осуществляет завершение выражений «на лету” для опознанных объектов
и автоматически заносит информацию, например параметры функции, в содержание
полезных всплывающих подсказок.
4.2
Реализация
программного комплекса
Windows Forms - это новая архитектура для создания и проектирования
графического пользовательского интерфейса Windows - приложений. Как и Win 32 API, Windows Forms предоставляет богатый набор классов и методов для
создания интерфейса приложения и управления его элементами. Но по сравнению с
Win 32 API новая архитектура имеет больше возможностей, элементов управления, и
специальных средств, значительно улучшающих качество интерфейса Windows-приложения, к тому же
поддерживаемого средой .NET Framework.
Windows Forms является частью среды .NET Framework. Поэтому эта
архитектура обладает преимуществами многих новых возможностей, реализованных в
.NET, например поддержкой общей интегрированной среды разработки приложений,
написанных на различных языках программирования, и среды выполнения, которая
полностью управляется операционной системой. Это позволяет программисту
использовать ранее недоступные службы автоматического управления памятью,
сборки мусора и обеспечения безопасности программного кода. Windows Forms является полностью объектно-ориентированным средством
и обеспечивает простое и удобное взаимодействие с Web-службами, основанными на
использовании протокола SOAP.
Windows Forms обеспечивает поддержку многих новых возможностей, что
выделяет эту архитектуру из существующих средств разработки интерфейсов. Среди
основных достоинств Windows
Forms можно назвать следующие:
-Новые средства. Windows Forms включает в себя многие новые средства построения
графического интерфейса, которые позволяют значительно улучшить его внешний
вид.
-Обработка событий. В Windows Forms для упрощения обработки событий используется
концепция делегатов.
-Единственный файл. Windows Forms позволяет выполнять разработку целого приложения в
одном файле вместо традиционного использования большого количества файлов.
Например, для создания окна понадобится заголовочный файл, файл ресурса и т.п.
При использовании Windows
Forms создается только один файл с
расширением .cs в котором сохраняется вся необходимая информация.
Архитектура Windows Forms построена на базе набора классов и интерфейсов,
которые содержат информацию, необходимую для создания и использования различных
компонентов интерфейса. Этот набор входит в пространство имен System.Windows.Forms.
От класса Form
пространства имен System.Windows.Forms наследуется большинство компонентов пользовательского
интерфейса Windows-приложения, то есть он является
базовым для этих объектов. Этот класс используется для создания форм,
диалоговых окон и окон сообщений. Можно сказать, что этот класс является
стержнем архитектуры Windows Forms. Остальные
элементы управления пользовательского интерфейса создаются с помощью класса
Control. Свойства класса Form применяются для определения внешнего вида
контейнерных объектов, отображаемых в интерфейсе. Действия пользователя при
работе с формой интерпретируются как события, которые должны быть обработаны.
Для создания формы
необходимо создать новый класс, производный от класса Form. Различают два вида
форм: модальные и немодальные.
Модальные формы требуют
ответа пользователя до предоставления ему возможности работы с другими формами.
Немодальные формы не требуют немедленного ответа пользователя - пользователь
может игнорировать появление формы и продолжить работу с приложением или другой
формой. Ответ на запрос немодальной формы может быть выполнен в любой удобный
момент.
Только что, создав Windows- приложение, пользователь будет
иметь дело с единственной формой под названием Form1. Впоследствии можно будет добавить
новые формы, щелкая правой кнопкой мыши на проекте в окне Solution Explorer и
выбирая пункт Add->New Item. Как видно
создать форму в В Visual Studio .NET очень просто.
Для каждого пункта меню
создается свой обработчик события. Windows Form Designer автоматически добавляет обработчик
событий , возникающих в результате щелчка на пункте меню.
Методы класса main.
main_Load - загрузка
данной формы. При обработке этого события происходит динамическое формирование
меню и перечнем акций. ArrayList stocs_list = f1.show(); Для этого создается
новый экземпляр класса load_file f1 и вызывается его метод Show(). Результатом работы этого метода
является возвращаемый объект типа ArrayList. В каждой строке списка stocs_list
содержится строка типа наименование акции; полный путь к акции.
Далее в цикле методом Split(';')
класса String строка разбивается на массив строк. Для каждой акции создается
свой пункт меню и создается событие нажатия на пункт меню..
this.akt =new
ToolStripMenuItem(a[0]);
this.akt.Click += new
System.EventHandler(this.a_Click);
a_Click - метод,
обрабатывающий событие нажатия на пунк меню с названием акции. В этом методе
вызывается метод Load_file(path), где в качестве параметра передается полный
путь к файлу с котировками акции, объекта класса load_file. Этот метод
возвращает объект типа DataTable. И далее вызывается метод DrawGraph().
Параметром которого выступает DataTable.
ts_exit_Click-метод,
обрабатывающий нажатие на пункт меню “Выход”. Приложение закрывается.
ts_arhiv_kotir_Click - метод
обрабатывающий нажатие на пункт меню “Архив котировок”.
Создается экземпляр класса arhiv_kotir и вызавается его метод Show().
Открывается окно “Архив котировок”.
ts_parameters_Click -
метод обрабатывающий нажатие на пункт меню “Параметры”.
Создается экземпляр класса GA_options и вызавается его метод Show().
Открывается окно установки параметров генетического алгоритма.
ts_start_optimization_Click-
метод обрабатывающий нажатие на пункт меню “Параметры”.
Создается экземпляр класса Select_stocs и вызавается его метод Show().
Открывается окно для выбора акций в портфель ценных бумаг.
DrawGraph()-метод для
рисования графика. В программе использован бесплатный компонент .NET zedGraph.
Эта библиотека позволяет легко рисовать графики различных видов. Бибилиотека
поставляется в виде Dll. В этой функции рисуется линейный график синего цвета.
В качестве значений для координат точек графика выступают значения цены
закрытия акции. Котировки акции передаются в качестве параметра функции
DrawGraph().
Таблица 4.1 - Элементы управления класса main
Название элемента
|
Тип
|
Модификатор доступа
|
menuStrip1
|
MenuStrip
|
private
|
ts_fail
|
ToolStripMenuItem
|
private
|
ts_new_chart
|
ToolStripMenuItem
|
private
|
ts_exit
|
ToolStripMenuItem
|
private
|
ts_servis
|
ToolStripMenuItem
|
private
|
ts_arhiv_kotir
|
ToolStripMenuItem
|
private
|
ts_nastroiki
|
ToolStripMenuItem
|
private
|
ts_optimization
|
ToolStripMenuItem
|
private
|
ts_start_optimization
|
ToolStripMenuItem
|
private
|
ts_parameters
|
ToolStripMenuItem
|
private
|
ts_spravka
|
ToolStripMenuItem
|
private
|
ts_about
|
ToolStripMenuItem
|
private
|
ts_exit1
|
ToolStripMenuItem
|
private
|
zedGraph
|
ZedGraphControl
|
private
|
Таблица 4.2 - Поля класса main
Название поля
|
Тип
|
Модификатор доступа
|
f1
|
load_file
|
public
|
akt
|
ToolStripMenuItem
|
private
|
table
|
DataTable
|
private
|
path
|
string
|
static
|
Таблица 4.3 - Методы класса main
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
main_Load
|
private
|
object sender, EventArgs e
|
void
|
a_Click
|
private
|
Object sender, EventArgs e
|
void
|
ts_exit_Click
|
private
|
object sender, EventArgs e
|
void
|
ts_arhiv_kotir_Click
|
private
|
object sender, EventArgs e
|
void
|
DrawGraph
|
private
|
DataTable table
|
void
|
ts_parameters_Click
|
private
|
object sender, EventArgs e
|
void
|
ts_start_optimization_Click
|
private
|
object sender, EventArgs e
|
void
|
Класс arhiv_kotir
предоставляет пользователю возможность просмотра выбранных котировок акций. При
нажатии на кнопку “Импорт” позволяет загрузить текстовый файл с котировками
акции.
Кнопка “Добавить”
позволяет добавить строку котировок на определенную дату. Кнопка “Правка”
переводит таблицу с котировками акций в режим редактирования. Кнопка “Удалить”
позволяет удалять строки, выбранные пользователем. Кнопка “Экспорт” позволяет
экспортировать котировки акций в текстовый формат. Кнопка “Закрыть” закрывает
окно архива котировок.
Рассмотрим методы,
которые используются во время работы программы.
arhiv_kotir_Load –загрузка формы
arhiv_kotir. При инициализации окна запускается также метод класса
FindFiles("D://dip_prog//kotirovki", "*.csv"), который
имеет два параметра-абсолютный путь к папке с котировками акций и шаблон файла
для поиска в директории. Здесь же происходит инициализация элемента управления
OpenFileDialog;
InitializeOpenFileDialog()-этот метод
отвечает за инициализацию элемента управления OpenFileDialog. В частности
задается шаблон для поиска файлов в директории.
btn_close_Click-метод обрабатывающий
событие нажатия на кнопку “Закрыть”. Закрывает окно arhiv_kotir.
FindFiles здесь происходит заполнение
узлов элемента управления значениями. Каждый узел это наименование акций.
Родительский узел содержит дочерние узлы. Щелчек на дочернем узле приводит к
загрузке котировок акций, того временного интервала, который выбрал
пользователь. Если процесс заполнения элемента управления TreeView закончился
неудачей, то обрабатывается исключение и выводится сообщение с описанием
ошибки.
tree_ak_AfterSelect-стандартный метод
для обработки события нажатия на узел элемента управления TreeView. Здесь
запускается функция dataGrid_bind(), где в качестве параметра выступает полный
путь к папке с котировками акций.
dataGrid_bind-с помощью этого метода
происходит связывания элемента управления DataGridView с источником данных. Для
этого создается объкт класса load_file и вызывается его метод Load_file(path)
где параметром выступает полный путь к папке с котировками акций. Значение
возвращаемое этой функцией присвается элементу управления DataTable.
btn_add_Click-метод, обрабатывающий
событие нажатия на кнопку Добавить. Добавляет строку с новыми котировками
акции.
btn_edit_Click- метод, обрабатывающий
событие нажатия на кнопку Изменить.Изменяет данные по котировкам акций.
Таблица 4.4 - Элементы управления класса arhiv_kotir
Название элемента
|
Тип
|
Модификатор доступа
|
btn_load
|
Button
|
private
|
btn_add
|
Button
|
private
|
btn_edit
|
Button
|
private
|
btn_delete
|
Button
|
private
|
btn_export
|
Button
|
private
|
btn_close
|
Button
|
private
|
label1
|
Label
|
private
|
label2
|
Label
|
private
|
tree_ak
|
Label
|
private
|
dg
|
Label
|
private
|
openFileDialog1
|
OpenFileDialog
|
private
|
btn_delete_Click- метод,
обрабатывающий событие нажатия на кнопку Удалить.Удаляет выделенную
пользователем строку.
Таблица 4.5 - Методы класса arhiv_kotir
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
arhiv_kotir_Load
|
private
|
object sender, EventArgs e
|
void
|
InitializeOpenFileDialog
|
private
|
|
void
|
btn_close_Click
|
private
|
object sender, EventArgs e
|
void
|
FindFiles
|
private
|
string dir, string pattern
|
void
|
btn_load_Click
|
private
|
object sender, EventArgs e
|
void
|
tree_ak_AfterSelect
|
private
|
object sender, TreeViewEventArgs e
|
void
|
dataGrid_bind
|
public
|
string path
|
void
|
btn_add_Click
|
private
|
object sender, EventArgs e
|
void
|
btn_edit_Click
|
private
|
object sender, EventArgs e
|
void
|
btn_delete_Click
|
private
|
object sender, EventArgs e
|
void
|
Класс Kotir_close
предназначен для вывода цен закрытия выбранных пользователем ценных бумаг для
оптимизации портфеля.
kotir_close_Load в этом методе элемент управления
DataGridView заполняется данными. Для этого из класса Select_stocs передается
объект DataSet. С помощью объекта DataSet происходит связывание данных с
элементом управления DataGridView.
btn_start_Click-в этом методе
происходит вызов окна result. Создается новый объект класса result. И
вызывается его метод Show().(См. таб. 4.7)
Таблица 4.6 - Элементы управления класса kotir_close
Название элемента
|
Тип
|
Модификатор доступа
|
dg_close
|
DataGridView
|
private
|
btn_start
|
Button
|
private
|
Таблица 4.7 - Методы класса arhiv_kotir
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
kotir_close_Load
|
private
|
object sender, EventArgs e
|
void
|
btn_start_Click
|
private
|
object sender, EventArgs e
|
void
|
Класс load_file
предназначен для загрузки данных котировок валют, выбранных пользователем из
текстового файла. В классе есть несколько полей и методов, которые используются
в процессе работы.( См. таб 4.8)
dir1 переменная типа DirectoryInfo в
которой хранится путь к директории, где находятся текстовые файлы с котировками
акций.
txt_file массив типа FileInfo в
котором содержатся имена файло, удовлетворяющих определенному шаблону.
table объект типа DataTable- в эту
таблицу добавляются данные, извлеченные из текстового файла.
mFile переменная типа
StreamReader-открытие потока для чтения текстового файла.
stocs_list-переменная типа ArrayList.
Это список для хранения наименования акции и полного пути к ней.
Метод show()-выделяет из имени
текстового файла название акции и формирует список из наименований акций.
Метод Load_file-открывает поток для
чтения текстового файла. Динамически формирует таблицу для записи данных из
текстового файла. Структуру текстового файла должна быть следуюшей:
-дата
-цена открытия
-макмимальная цена
-минимальная цена
-цена закрытия
-объем
В случае неудачи при чтении
текстового файла выводится сообщение с описанием ошибки.( См. таб 4.9)
Таблица 4.8 - Поля класса load_file
Название поля
|
Тип
|
Модификатор доступа
|
dir1
|
DirectoryInfo
|
static
|
txt_file
|
FileInfo
|
static
|
table
|
DataTable
|
static
|
mFile
|
StreamReader
|
public
|
stocs_list
|
ArrayList
|
public
|
Таблица 4.9 - Методы класса load_file
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
show
|
public
|
|
ArrayList
|
Load_file
|
public
|
string path
|
DataTable
|
Класс pie_chart
- рисует круговую диаграмму, по результатам работы генетического алгоритма. (См.
таб 4.10)
Метод pie_chart_Load-срабатывает при
загрузке окна. В этом методе вызывается функция CreateChart,
Метод CreateChart- собственно рисует
круговую диаграмму и выводит ее на экран.(См. таб. 4.11)
Таблица 4.10 - Элементы управления класса pie_chart
Название элемента
|
Тип
|
Модификатор доступа
|
ZedGraph
|
ZedGraphControl
|
private
|
Таблица 4.11 - Методы класса pie_chart
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
pie_chart_Load
|
private
|
object sender, EventArgs
|
void
|
CreateChart
|
public
|
|
void
|
Класс raschet - в этом классе рассчитываются
параметры для фитнес- функции. В частности доходность и риск портфеля ценных
бумаг.
В классе есть несколько полей и
методов, которые используются в процессе работы.
Obs-числовая переменная в которой
указывается количества периодов для анализа данных.
Kolvo-количество ценных бумаг,
которые выбрал пользователь для оптимизации портфеля.
Prirost-массив в котором хранятся
приросты цен ценных бумаг.
ER-массив в котором хранятся
доходности ценных бумаг.
Sredznach-среднее значение цены
ценной бумаги за анализируемый период
matrix_cov-матрица ковариации.
Stock-массив, состояций из массивов с
ценами закрытия всех выбранных пользоватем акций.
Raschet-конструктор класса в котором
инициализируются начальные значения.(См. таб. 4.12)
Метод returen-этот метод находит прирост
и среднее значение по каждой акции и рассчитывает доходность акции.
Метод matrix_covar-здесь расчитывает
матрица ковариации по всем ценным бумагам. Матрица ковариаци также является
показателем рисковости ценной бумаги. (См. таб. 4.13)
Таблица 4.12 - Поля класса raschet
Название поля
|
Тип
|
Модификатор доступа
|
obs
|
integer
|
public
|
kolvo
|
integer
|
public
|
prirost
|
double[][]
|
public
|
ER
|
double[]
|
public
|
sredznach
|
double
|
public
|
matrix_cov
|
double[,]
|
public
|
stock
|
double[][]
|
public
|
Таблица 4.13 - Методы класса raschet
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
returen
|
public
|
|
double[]
|
matrix_covar
|
public
|
|
double[,]
|
Класс result выводит
результаты работы генетического алгоритма в таблицу.
Метод result_Load - в этом методе
создается объект класса TestPopulation-Population. Затем вызывается метод
класса Population NextGeneration() который генерируют популяцию хромосом И
метод WriteNextGeneration(), который заподняет таблицу данными расчета.
В элементе управления DataGridView выводятся такие данные: первые
колонки удельный вес ценной бемаги в портфеле ценных бумаг. Последняя и
предпоследняя колонки это риск и доходность ценной бумаги. Каждоя строка – это
лучший вариант отбора в очередной генерации.
Метод bt_chart_Click- обрабатывает событие нажатие на кнопку
График. Создается объкт класса pie_chart и вызывается его метод Show.(См. таб.
4.14)
Таблица 4.14 - Методы класса raschet
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
result_Load
|
private
|
object sender, EventArgs e
|
void
|
bt_chart_Click
|
private
|
object sender, EventArgs e
|
void
|
Класс Select_stocs- предоставляет
пользователю возможность выбрать какие акции включить в портфель ценных бумаг
для оптимизации.
dataSet-переменная типа DataSet. Объкты
DataSet доступны в пространстве имен System.Data и используются в приложении
для кеширования данных в памяти.
Row-пременная типа DataRow. Это
строки, которые затем добавляются в таблицу.
Метод Select_stocs_Load-в этом методе
создается объект класса load_file и вызывается его метод Show. Результатом
работы этого метода будет список, который содержит наименование акций.
Программно создается DataGridView. Первая колонка содержит checkbox для выбора значений. Вторая колонка-префиксы акций.
Метод ok_Click-обрабатывает событие
нажатия на кнопку ОК. При нажатии на кнопку ОК анализируется какие
наименования выбрал пользователь и формируется таблица с выбранными значениями. Создается объект
класса kotir_close и вызывается его метод show.(См. таб. 4.16)
Таблица 4.15 - Поля класса Select_stocs
Название поля
|
Тип
|
Модификатор доступа
|
dataSet
|
Dataet
|
public
|
row
|
DataRow
|
public
|
f
|
load_file
|
private
|
Таблица 4.16 - Методы класса Select_stocs
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
Select_stocs_Load
|
private
|
object sender, EventArgs e
|
void
|
ok_Click
|
private
|
object sender, EventArgs e
|
void
|
Класс Population отвечает за
генерацию хромосом в текущей популяции.
Шаги алгоритма следующие:
1.Воспроизвести начальное поколение
Genomes используя случайный генератор числа.
2.Определить пригодность(соответствие)
всех Genomes.
3.Определить, Genomes способных к
воспроизведению.
4.Применить операцию Crossover
к Genome к данной популяции.
5.Выбрать двух самых пригодных
Genomes из 2 родителей и 2 детей, которые получились путем crossover, и
добавить их к следующему поколению.
6.Произвести случайные мутации через
следующую генерацию популяции.
7.Вычислить фитнес функцию
следующего поколения и повторить с шага 3.
Класс содержит ряд полей и методов.
kLength-целое значения для хранения
длины генерируемой хромосомы;
kCrossover-переменная, которая
определяет точку в хромосоме, в какой проводить операцию кроссоверинга;
kInitialPopulation-количество
популяций;
kMutationFrequency-вероятность с
которой возможна операция мутации;
kDeathFitness-переменная для
определения непригодности хромосомы;
kReproductionFitness-переменная для
определения возможности перехода хромосомы в новое поколение;
Genomes-список хромосом.(См. таб. 4.17);
Population- конструктор популяции автоматически
создает начальный набор хромосом, многократно вызывая метод NextGeneration ,
выполняется алгоритм, который генерирует следующее поколение. В конечном
счете, популяция содержит особи, у которых значение фитнес функции максимально;
Mutate-метод который проводит мутацию
генов с заданной вероятностью;
NextGeneration-определяются хромосомы
которые пригодны для дальнейшей селекции и какие нужно удалить. В этом методе удаляются индивидуумы, наименее
удовлетворяющие условиям задачи, и отбираются для скрещивания наиболее
подходящих индивидуумы (те, которые дают наилучшее решение задачи). Этот
процесс называется селекцией, аналогично отбору наиболее приспособленных
индивидуумов в природе. алгоритм берет двух подходящих индивидуумов и
производит между ними частичный обмен генетической информацией - скрещивание.
Потомство скрещенной пары будет нести в себе часть признаков от матери, а часть
- от отца.
После того, как алгоритм
скрещивает подходящих индивидуумов и производит мутации, наступает смена
поколений. Теперь популяция будет состоять из потомства плюс несколько старых
индивидуумов, которым алгоритм позволяет выжить, поскольку они являются
наилучшими в популяции.
Через десятки и даже
сотни "поколений" в конце концов возникает популяция, в которой
индивидуумы решают задачу очень хорошо.
CalculateFitnessForAll-рассчитывает
функцию пригодности;
DoCrossover-проводится операция
кроссовера. Две
хромосомы обмениваются частями своих данных друг с другом в указанной точке.
Выбирается две самые пригодные хромосомы из 2 родителей и 2 детей, которые
получились путем кроссовера, и добавляется к следующему поколению;
WriteNextGeneration-формируется
таблица куда записываются данные очередной генерации. (См. таб. 4.18);
Таблица 4.17 - Поля класса
Population
Название поля
|
Тип
|
Модификатор доступа
|
kLength
|
int
|
public
|
kCrossover
|
int
|
public
|
kInitialPopulation
|
int
|
public
|
kMutationFrequency
|
float
|
public
|
kDeathFitness
|
float
|
public
|
kReproductionFitness
|
float
|
public
|
Genomes
|
ArrayList
|
public
|
GenomeResults
|
ArrayList
|
public
|
Generation
|
int
|
public
|
Таблица 4.18 - Методы класса Population
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
Population
|
private
|
|
|
Mutate
|
private
|
Genome aGene
|
void
|
NextGeneration
|
public
|
|
void
|
CalculateFitnessForAll
|
public
|
ArrayList genes
|
void
|
DoCrossover
|
public
|
ArrayList genes
|
void
|
WriteNextGeneration
|
public
|
|
DataSet
|
Класс ListGenome-отвечает за
генерацию хромосомы.
TheSeed-генератор случайных значений,
которыми инициализируются хромосомы.(См. таб. 4.19)
Raschet-объект класса raschet;
Метод SetCrossoverPoint-получает точку в которой необходимо
выполнить кроссинговер;
ListGenome-конструктор, где в
качестве параметра выступает длина хромосомы. Здесь происходит инициализация
хромосомы случайными значения и последующая их нормализация. Сумма удельных
весов должна быть равна 1;
CanDie-выбор непригодных хромосом;
CanReproduce-отбор хромосом пригодных
для дальнейшей селекции.
Копии Genome без изменений переходят в следующее поколение;
GenerateGeneValue-генерирует
случайные значения;
Mutate-операция мутации;
CalculateFitness-расчет функции
пригодности, В этом методе вызываются метода класс Raschet- returen и
matrix_covar. Функцией пригодности будет отношения доходности ценной бумаги к
ее рисковости;
ToString-в этом методе формируется
строка вида
Ген1;ген2;Ген3;Генn;функция
пригодности;
CopyGeneInfo-копируются хромосомы;
Crossover-операция кроссовера. (См. таб. 4.20);
Таблица 4.19 - Поля класса ListGenome
Название поля
|
Тип
|
Модификатор доступа
|
TheArray
|
ArrayList
|
private
|
TheSeed
|
Random
|
private
|
Raschet
|
raschet
|
private
|
Таблица 4.20 - Методы класса ListGenome
Название метода
|
Модификатор доступа
|
Параметры
|
Результат
|
CompareTo
|
public
|
object a
|
int
|
ListGenome
|
public
|
long length
|
|
CanDie
|
public
|
float fitness
|
bool
|
CanReproduce
|
public
|
float fitness
|
bool
|
GenerateGeneValue
|
public
|
|
object
|
CalculateFitness
|
public
|
|
double
|
ToString
|
public
|
string
|
|
CopyGeneInfo
|
public
|
Genome dest
|
void
|
Crossover
|
public
|
Genome g
|
Genome
|
5
ТЕСТИРОВАНИЕ ПРОГРАММНОЙ СИСТЕМЫ
Тестирование программы
проводилось на данных анализа котировок акций ведущих компаний мира за три
года.
В ходе тестирования было
замечено, что при маленьком числе хромосом в популяции (менее 100) смена
поколений идет очень быстро, причем сначала виден довольно резкий скачок в
улучшении значения весовой функции, хотя, через достаточно небольшой промежуток
времени, изменение значений весовой функции практически не происходит, т.е.
маленькие популяции склонны «к вымиранию» или к «развитию по тупиковой ветви»,
кроссовер в которой не способен привести к появлению более приспособленных
особей. Только мутация может сдвинуть данную популяцию с тупикового пути
развития, хотя вероятность этого весьма невелика.(См. таб. 5.1)
Таблица 5.1 - Результаты
тестирования генетического алгоритма со сменным количеством хромосом
Количество хромосом в
популяции
|
Количество итераций
|
№ итерации, на которой
отриман наилучший результат
|
Значение фітнес-функции
|
10
|
400
|
22
|
5,85435
|
50
|
400
|
15
|
6,11074
|
100
|
400
|
14
|
6,49291
|
200
|
400
|
32
|
6,50236
|
500
|
400
|
28
|
6,51849
|
В тоже время большое количество хромосом
в популяции дает большое количество вариантов, но значительно увеличивает время
работы программы.(См.
таб. 5.2)
Таблица 5.2 - Результаты тестирования генетического
алгоритма со сменным количеством хромосом и количеством акций
Количество хромосом в
популяции
|
Количество итераций
|
Количество акций
|
Время робот программы
|
100
|
1000
|
3
|
2 мин. 11 сек.
|
100
|
1000
|
5
|
3 мин. 30 сек.
|
100
|
1000
|
7
|
5 мин. 01 сек.
|
100
|
1000
|
10
|
7 мин. 05 сек.
|
100
|
1000
|
15
|
11 мин. 01 сек.
|
300
|
1000
|
5
|
10 мин. 15 сек.
|
500
|
1000
|
5
|
17 мин. 30 сек.
|
1000
|
1000
|
5
|
33 мин. 10 сек.
|
Также негативным
качеством отличается сильно маленькое количество элитных особей (менее 5), так
как в этом случае часто происходит потеря хороших решений.
При сильно большом
количестве элитных особей (более 10-20% от размера популяции) также происходит
падение производительности генетического алгоритма, так как большое количество
неизменных хромосом мешает появлению новых решений.
Мутация является важным
механизмом, помогающим выбраться функции из локального минимума.
Таблица 5.3 - Результаты
тестирования генетического алгоритма с изменением вероятности мутации
Вероятность мутации
|
Количество хромосом в
популяции
|
Количество итераций
|
№ итерации, на которой
получен наилучший результат
|
Значение фитнес-функции
|
0,001
|
100
|
400
|
14
|
6,51291
|
0,01
|
100
|
400
|
30
|
6,45154
|
0,1
|
100
|
400
|
249
|
6,51907
|
0,9
|
100
|
1000
|
700
|
6,12066
|
Экспериментальным
путем было выявлено, что наиболее целесообразным является использование
количества хромосом в диапазоне 250-500 и количества элитных особей не более 5%
от размера популяции. Хотя эти оценки являются весьма приближенными.
ВЫВОДЫ
В ходе выполения
дипломного проекта, была изучена предметная область, связанная с оптимизацией
портфеля ценных бумаг. Были рассмотрены существующие на данный момент времени
методы решения задач, связанных с оптимизацией портфеля ценных бумаг.
Было расссмотрено
несколько существующих предложений на информационном рынке, проанализированы
функции существующих программ и определено несколько критериев, которым должна
отвечать современная программная система по оптимизации портфеля ценных бумаг.
Также подробно исследованы методы использования генетических алгоритмов,
которые применяются при решении поставленной задачи.
В результате была
изложена постановка задачи на разработку программного обеспечения, и
перечислены требования, в соответствии с которыми необходимо разрабатывать эту
систему. Спроектирована структура программной системы по оптимизации портфеля
ценных бумаг, перечислены основные формы и их назначение в программе.
Проведен анализ
эффективности генетического алгоритма от размера популяции и вероятности
мутации и скрещивания.
Разработанная программа
позволяет непрофессиональным игрокам на рынке бумаг, не имея специальных знаний
сформировать оптимальный портфель ценных бумаг и тем самым уменьшить риск
инвестиций в ценные бумаги.
В заключение можно
отметить, что существуют множество более совершенных систем автоматизированной поддержки принятия решений . Но
данная программа интересна тем , что использует генетический алгоритм для
решения многокритериальной постановки задачи
формирования оптимального портфеля ценных бумаг.
ПЕРЕЧЕНЬ ССЫЛОК
1
Исаев С.А.
Популярно в генетических алгоритмах,
Режим доступа: #"_Ref11430500">2
НейроПроект.
Генетические алгоритмы, февраль 1999, #"_Ref11441316">
7
Редька В.Г.
Прикладное эволюционное моделирование. Генетический алгоритм. Оценка
эффективности генетического алгоритма, #"Додаток_А">
ПРИЛОЖЕНИЕ А. ЛИСТИНГ ПРОГРАММЫ
(35 стр.)
Arhiv_kotir.Designer.cs
namespace diplom
{
partial class arhiv_kotir
{
private System.ComponentModel.IContainer
components = null;
protected override void Dispose(bool
disposing)
{
if (disposing && (components !=
null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.btn_load = new
System.Windows.Forms.Button();
this.btn_add = new
System.Windows.Forms.Button();
this.btn_edit = new
System.Windows.Forms.Button();
this.btn_delete = new
System.Windows.Forms.Button();
this.btn_export = new
System.Windows.Forms.Button();
this.btn_import = new
System.Windows.Forms.Button();
this.btn_close = new
System.Windows.Forms.Button();
this.label1 = new
System.Windows.Forms.Label();
this.label2 = new
System.Windows.Forms.Label();
this.treeView1 = new
System.Windows.Forms.TreeView();
this.dg = new
System.Windows.Forms.DataGridView();
this.openFileDialog1 = new
System.Windows.Forms.OpenFileDialog();
this.tree_ak = new
System.Windows.Forms.TreeView();
this.lbl = new
System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.dg)).BeginInit();
this.SuspendLayout();
// btn_load
this.btn_load.Location = new
System.Drawing.Point(26, 381);
this.btn_load.Name =
"btn_load";
this.btn_load.Size = new
System.Drawing.Size(75, 23);
this.btn_load.TabIndex = 1;
this.btn_load.Text =
"Загрузит";
this.btn_load.UseVisualStyleBackColor =
true;
this.btn_load.Click += new
System.EventHandler(this.btn_load_Click);
// btn_add
this.btn_add.Location = new
System.Drawing.Point(124, 381);
this.btn_add.Name = "btn_add";
this.btn_add.Size = new
System.Drawing.Size(75, 23);
this.btn_add.TabIndex = 2;
this.btn_add.Text = "Добавит";
this.btn_add.UseVisualStyleBackColor =
true;
// btn_edit
this.btn_edit.Location = new
System.Drawing.Point(221, 381);
this.btn_edit.Name =
"btn_edit";
this.btn_edit.Size = new System.Drawing.Size(75,
23);
this.btn_edit.TabIndex = 3;
this.btn_edit.Text = "Правка";
this.btn_edit.UseVisualStyleBackColor =
true;
// btn_delete
this.btn_delete.Location = new
System.Drawing.Point(321, 381);
this.btn_delete.Name =
"btn_delete";
this.btn_delete.Size = new
System.Drawing.Size(75, 23);
this.btn_delete.TabIndex = 4;
this.btn_delete.Text =
"Удалить";
this.btn_delete.UseVisualStyleBackColor
= true;
// btn_export
this.btn_export.Location = new
System.Drawing.Point(420, 381);
this.btn_export.Name =
"btn_export";
this.btn_export.Size = new
System.Drawing.Size(75, 23);
this.btn_export.TabIndex = 5;
this.btn_export.Text =
"Экспорт";
this.btn_export.UseVisualStyleBackColor
= true;
// btn_import
this.btn_import.Location = new
System.Drawing.Point(517, 381);
this.btn_import.Name =
"btn_import";
this.btn_import.Size = new
System.Drawing.Size(75, 23);
this.btn_import.TabIndex = 6;
this.btn_import.Text =
"Импорт";
this.btn_import.UseVisualStyleBackColor
= true;
// btn_close
this.btn_close.Location = new
System.Drawing.Point(621, 381);
this.btn_close.Name =
"btn_close";
this.btn_close.Size = new
System.Drawing.Size(75, 23);
this.btn_close.TabIndex = 7;
this.btn_close.Text =
"Закрыть";
this.btn_close.UseVisualStyleBackColor =
true;
this.btn_close.Click +=
new System.EventHandler(this.btn_close_Click);
// label1
this.label1.AutoSize = true;
this.label1.Location = new
System.Drawing.Point(29, 18);
this.label1.Name = "label1";
this.label1.Size = new
System.Drawing.Size(54, 13);
this.label1.TabIndex = 8;
this.label1.Text = "Символы";
// label2
this.label2.AutoSize = true;
this.label2.Location = new
System.Drawing.Point(255, 18);
this.label2.Name = "label2";
this.label2.Size = new
System.Drawing.Size(72, 13);
this.label2.TabIndex = 9;
this.label2.Text = "База
данных";
// treeView1
this.treeView1.LineColor =
System.Drawing.Color.Empty;
this.treeView1.Location = new
System.Drawing.Point(26, 46);
this.treeView1.Name =
"treeView1";
this.treeView1.Size = new
System.Drawing.Size(121, 311);
this.treeView1.TabIndex = 10;
// dg
this.dg.BackgroundColor =
System.Drawing.SystemColors.ActiveCaptionText;
this.dg.ColumnHeadersHeightSizeMode
= System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dg.Location = new
System.Drawing.Point(250, 46);
this.dg.Name = "dg";
this.dg.RowHeadersVisible = false;
this.dg.RowHeadersWidthSizeMode
= System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
this.dg.Size = new
System.Drawing.Size(621, 311);
this.dg.TabIndex = 11;
this.dg.CellContentClick +=
new
System.Windows.Forms.DataGridViewCellEventHandler(this.dg_CellContentClick);
// openFileDialog1
this.openFileDialog1.FileName =
"openFileDialog1";
// tree_ak
this.tree_ak.Location = new
System.Drawing.Point(29, 46);
this.tree_ak.Name = "tree_ak";
this.tree_ak.Size = new
System.Drawing.Size(194, 311);
this.tree_ak.TabIndex = 12;
this.tree_ak.AfterSelect +=
new System.Windows.Forms.TreeViewEventHandler(this.tree_ak_AfterSelect);
// lbl
this.lbl.AutoSize = true;
this.lbl.Location = new
System.Drawing.Point(450, 18);
this.lbl.Name = "lbl";
this.lbl.Size = new
System.Drawing.Size(35, 13);
this.lbl.TabIndex = 13;
this.lbl.Text = "label3";
// arhiv_kotir
this.AutoScaleDimensions = new
System.Drawing.Size(6F, 13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new
System.Drawing.Size(893, 449);
this.Controls.Add(this.lbl);
this.Controls.Add(this.tree_ak);
this.Controls.Add(this.dg);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.btn_close);
this.Controls.Add(this.btn_import);
this.Controls.Add(this.btn_export);
this.Controls.Add(this.btn_delete);
this.Controls.Add(this.btn_edit);
this.Controls.Add(this.btn_add);
this.Controls.Add(this.btn_load);
this.Name = "arhiv_kotir";
this.Text = "arhiv_kotir";
this.Load += new
System.EventHandler(this.arhiv_kotir_Load);
((System.ComponentModel.ISupportInitialize)(this.dg)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button
btn_load;
private System.Windows.Forms.Button btn_add;
private System.Windows.Forms.Button
btn_edit;
private System.Windows.Forms.Button
btn_delete;
private System.Windows.Forms.Button
btn_export;
private System.Windows.Forms.Button
btn_import;
private System.Windows.Forms.Button
btn_close;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TreeView
treeView1;
private System.Windows.Forms.DataGridView
dg;
private System.Windows.Forms.OpenFileDialog
openFileDialog1;
private System.Windows.Forms.TreeView tree_ak;
private System.Windows.Forms.Label lbl;
}
}
Arhiv_kotir.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Collections;
namespace diplom
{
public partial class arhiv_kotir : Form
{
load_file f = new load_file();
public arhiv_kotir()
{
InitializeComponent();
}
private void arhiv_kotir_Load(object sender,
EventArgs e)
{
InitializeOpenFileDialog();
FindFiles("D://dip_prog//kotirovki", "*.csv");
}
private void InitializeOpenFileDialog()
{
this.openFileDialog1.Filter =
"Text files
(*.TXT;*.CSV;*.PRN)|*.TXT;*.CSV;*.PRN|" +
"All files (*.*)|*.*";
this.openFileDialog1.Title =
"My Image Browser";
}
private void btn_close_Click(object sender,
EventArgs e)
{
this.Close();
}
public void FindFiles(string dir, string
pattern)
{
tree_ak.Nodes.Clear();
TreeNode aNode;
TreeNode bNode;
TreeNode cNode;
try
{
DirectoryInfo dir1 = new
DirectoryInfo(dir);
FileInfo[] txt_file =
dir1.GetFiles(pattern, SearchOption.AllDirectories);
ArrayList stocs_list = f.show();
for(int
i=0;i<stocs_list.Count;i++)
{
string tmp =
stocs_list[i].ToString();
string []a = tmp.Split(';');
aNode = new TreeNode(a[0]);
bNode = new
TreeNode("Неделя");
cNode = new TreeNode(a[1]);
bNode.Text = "Неделя";
aNode.Tag = "";
bNode.Tag = a[1]; ;
cNode.Tag = "";
bNode.ForeColor = Color.Orange;
cNode.Text = "Месяц";
aNode.Nodes.Add(bNode);
aNode.Nodes.Add(cNode);
tree_ak.Nodes.Add(aNode);
}
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Отказанно в
доступе " );
}
}
private void btn_load_Click(object sender,
EventArgs e)
{
StreamReader mFile;
try
{
if (openFileDialog1.ShowDialog() ==
DialogResult.OK)
{
mFile = new
StreamReader(openFileDialog1.FileName);
System.Data.DataTable table = new
DataTable("StocsTable");
DataColumn column;
DataRow row;
column = new DataColumn();
column.DataType =
System.Type.GetType("System.DateTime");
column.ColumnName =
"Data";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType =
System.Type.GetType("System.String");
column.ColumnName =
"Open";
column.AutoIncrement = false;
column.Caption =
"Open";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType =
System.Type.GetType("System.String");
column.ColumnName =
"Max";
column.AutoIncrement = false;
column.Caption =
"Максимум";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType =
System.Type.GetType("System.String");
column.ColumnName =
"Min";
column.AutoIncrement = false;
column.Caption =
"Минимум";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType =
System.Type.GetType("System.String");
column.ColumnName =
"Close";
column.AutoIncrement = false;
column.Caption =
"Закрытие";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType =
System.Type.GetType("System.String");
column.ColumnName =
"Volume";
column.AutoIncrement = false;
column.Caption =
"Объем";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
DataSet dataSet = new
DataSet();
dataSet.Tables.Add(table);
string lines;
string[] line;
while ((lines = mFile.ReadLine())
!= null)
{
row = table.NewRow();
line = lines.Split(',');
row["Data"] =
Convert.ToDateTime(line[0]);
row["Open"] =
line[2];
row["Max"] = line[3];
row["Min"] = line[4];
row["Close"]
=line[5];
row["Volume"]
=line[6];
table.Rows.Add(row);
}
mFile.Close();
dg.DataSource = dataSet;
dg.DataMember =
"StocsTable";
}
}
catch (Exception ex)
{
MessageBox.Show("Невозможно
загрузит текстовый документ: " + openFileDialog1.FileName.ToString()
+ ". У вас нет прав читать
этот файл, или " +
"файл поврежден.\n\nотчет
об ошибке: " + ex.Message);
}
}
private void tree_ak_AfterSelect(object
sender, TreeViewEventArgs e)
{
DirectoryInfo dir1 = new
DirectoryInfo("D://dip_prog//kotirovki");
if (e.Node.Tag.ToString() !=
"")
{
dataGrid_bind(e.Node.Tag.ToString());
}
}
public void dataGrid_bind( string path)
{
DataTable table= f.Load_file(path);
DataSet dataSet = new DataSet();
dataSet.Tables.Add(table);
dg.DataSource = dataSet;
dg.DataMember = "StocsTable";
}
}
}
Form1.Designer.cs
namespace diplom
{
partial class main
{
private System.ComponentModel.IContainer
components = null;
protected override void Dispose(bool
disposing)
{
if (disposing && (components !=
null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new
System.ComponentModel.Container();
this.menuStrip1 = new
System.Windows.Forms.MenuStrip();
this.ts_fail = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_new_chart = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_exit = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_servis = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_arhiv_kotir = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_nastroiki = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_optimization = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_start_optimization = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_parameters = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_spravka = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_about = new
System.Windows.Forms.ToolStripMenuItem();
this.ts_exit1 = new System.Windows.Forms.ToolStripMenuItem();
this.zedGraph = new
ZedGraph.ZedGraphControl();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
// menuStrip1
this.menuStrip1.Items.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.ts_fail,
this.ts_servis,
this.ts_optimization,
this.ts_spravka,
this.ts_exit1});
this.menuStrip1.Location = new
System.Drawing.Point(0, 0);
this.menuStrip1.Name =
"menuStrip1";
this.menuStrip1.Size = new
System.Drawing.Size(792, 24);
this.menuStrip1.TabIndex = 0;
this.menuStrip1.Text =
"menuStrip1";
// ts_fail
this.ts_fail.DropDownItems.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.ts_new_chart,
this.ts_exit});
this.ts_fail.Name = "ts_fail";
this.ts_fail.Size = new
System.Drawing.Size(48, 20);
this.ts_fail.Text = "Файл ";
// ts_new_chart
this.ts_new_chart.Name =
"ts_new_chart";
this.ts_new_chart.Size = new
System.Drawing.Size(158, 22);
this.ts_new_chart.Text = "Новый
график";
this.ts_new_chart.Click += new System.EventHandler(this.ts_new_chart_Click);
// ts_exit
this.ts_exit.Name = "ts_exit";
this.ts_exit.Size = new
System.Drawing.Size(158, 22);
this.ts_exit.Text = "Выход";
this.ts_exit.Click += new System.EventHandler(this.ts_exit_Click);
// ts_servis
this.ts_servis.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
{
this.ts_arhiv_kotir,
this.ts_nastroiki});
this.ts_servis.Name = "ts_servis";
this.ts_servis.Size = new
System.Drawing.Size(55, 20);
this.ts_servis.Text =
"Сервис";
// ts_arhiv_kotir
this.ts_arhiv_kotir.Name =
"ts_arhiv_kotir";
this.ts_arhiv_kotir.Size = new System.Drawing.Size(173,
22);
this.ts_arhiv_kotir.Text = "Архив
котировок";
this.ts_arhiv_kotir.Click += new
System.EventHandler(this.ts_arhiv_kotir_Click);
// ts_nastroiki
this.ts_nastroiki.Name =
"ts_nastroiki";
this.ts_nastroiki.Size = new
System.Drawing.Size(173, 22);
this.ts_nastroiki.Text =
"настройки";
// ts_optimization
this.ts_optimization.DropDownItems.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.ts_start_optimization,
this.ts_parameters});
this.ts_optimization.Name =
"ts_optimization";
this.ts_optimization.Size = new
System.Drawing.Size(86, 20);
this.ts_optimization.Text =
"Оптимизация";
// ts_start_optimization
this.ts_start_optimization.Name =
"ts_start_optimization";
this.ts_start_optimization.Size = new
System.Drawing.Size(193, 22);
this.ts_start_optimization.Text =
"Начать оптимизацию";
this.ts_start_optimization.Click += new
System.EventHandler(this.ts_start_optimization_Click);
// ts_parameters
this.ts_parameters.Name =
"ts_parameters";
this.ts_parameters.Size = new
System.Drawing.Size(193, 22);
this.ts_parameters.Text =
"Параметры";
this.ts_parameters.Click += new
System.EventHandler(this.ts_parameters_Click);
// ts_spravka
this.ts_spravka.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
{
this.ts_about});
this.ts_spravka.Name =
"ts_spravka";
this.ts_spravka.Size = new
System.Drawing.Size(62, 20);
this.ts_spravka.Text =
"Справка";
// ts_about
this.ts_about.Name =
"ts_about";
this.ts_about.Size = new
System.Drawing.Size(149, 22);
this.ts_about.Text = "О
программе";
// ts_exit1
this.ts_exit1.Name =
"ts_exit1";
this.ts_exit1.Size = new
System.Drawing.Size(52, 20);
this.ts_exit1.Text = "Выход";
// zedGraph
this.zedGraph.Location = new
System.Drawing.Point(62, 59);
this.zedGraph.Name =
"zedGraph";
this.zedGraph.ScrollGrace = 0;
this.zedGraph.ScrollMax = 0;
this.zedGraph.ScrollMax = 0;
this.zedGraph.ScrollMax2 = 0;
this.zedGraph.ScrollMin = 0;
this.zedGraph.ScrollMin = 0;
this.zedGraph.ScrollMin2 = 0;
this.zedGraph.Size = new
System.Drawing.Size(666, 392);
this.zedGraph.TabIndex = 1;
this.zedGraph.Visible = false;
this.zedGraph.Load += new
System.EventHandler(this.zedGraph_Load);
// main
this.AutoScaleDimensions = new
System.Drawing.Size(6F, 13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new
System.Drawing.Size(792, 569);
this.Controls.Add(this.zedGraph);
this.Controls.Add(this.menuStrip1);
this.MainMenuStrip = this.menuStrip1;
this.Name = "main";
this.Text = "Оптимизация портфеля
ценных бумаг";
this.Load += new
System.EventHandler(this.main_Load);
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip
menuStrip1;
private System.Windows.Forms.ToolStripMenuItem
ts_fail;
private
System.Windows.Forms.ToolStripMenuItem ts_new_chart;
private
System.Windows.Forms.ToolStripMenuItem ts_exit;
private
System.Windows.Forms.ToolStripMenuItem ts_servis;
private System.Windows.Forms.ToolStripMenuItem
ts_arhiv_kotir;
private
System.Windows.Forms.ToolStripMenuItem ts_nastroiki;
private
System.Windows.Forms.ToolStripMenuItem ts_optimization;
private
System.Windows.Forms.ToolStripMenuItem ts_start_optimization;
private
System.Windows.Forms.ToolStripMenuItem ts_parameters;
private
System.Windows.Forms.ToolStripMenuItem ts_spravka;
private
System.Windows.Forms.ToolStripMenuItem ts_about;
private System.Windows.Forms.ToolStripMenuItem
ts_exit1;
private ZedGraph.ZedGraphControl zedGraph;
}
}
Form1.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;
namespace diplom
{
public partial class main : Form
{
load_file f1 = new load_file();
ToolStripMenuItem akt;
DataTable table;
static string path;
public main()
{
InitializeComponent();
}
private void main_Load(object sender,
EventArgs e)
{
this.SuspendLayout();
ArrayList stocs_list = f1.show();
for (int i = 0; i < stocs_list.Count;
i++)
{
string tmp =
stocs_list[i].ToString();
string[] a = tmp.Split(';');
this.akt =new
ToolStripMenuItem(a[0]);
akt.Tag = a[1].ToString();
ts_new_chart.DropDownItems.Add(akt);
this.akt.Click += new
System.EventHandler(this.a_Click);
}
this.ResumeLayout();
}
private void a_Click(object sender,
EventArgs e)
{
string path =
((ToolStripMenuItem)sender).Tag.ToString();
table = f1.Load_file(path);
DrawGraph(table);
}
private void ts_exit_Click(object sender,
EventArgs e)
{
Application.Exit();
}
private void ts_arhiv_kotir_Click(object
sender, EventArgs e)
{
arhiv_kotir newparent = new
arhiv_kotir();
newparent.Show();
}
private void DrawGraph(DataTable table)
{
zedGraph.Visible = true;
GraphPane pane = zedGraph.GraphPane;
pane.CurveList.Clear();
PointPairList list = new
PointPairList();
int xmin = 0;
int xmax = table.Rows.Count;
for (int x = xmin; x < xmax; x++)
{
string a =
table.Rows[x][2].ToString().Replace('.', ',');
list.Add(x,Convert.ToDouble(a));
}
LineItem myCurve =
pane.AddCurve("курс акции", list, Color.Blue, SymbolType.None);
pane.XAxis.MajorGrid.IsVisible = true;
pane.XAxis.Title.Text =
"Период";
pane.YAxis.Title.Text =
"Курс";
pane.Title.Text = "Курс
акций";
pane.XAxis.MajorGrid.DashOn = 10;
pane.XAxis.MajorGrid.DashOff = 5;
pane.YAxis.MajorGrid.IsVisible = true;
pane.YAxis.MajorGrid.DashOn = 10;
pane.YAxis.MajorGrid.DashOff = 5;
pane.YAxis.MinorGrid.IsVisible = true;
pane.YAxis.MinorGrid.DashOn = 1;
pane.YAxis.MinorGrid.DashOff = 2;
pane.XAxis.MinorGrid.IsVisible = true;
pane.XAxis.MinorGrid.DashOn = 1;
pane.XAxis.MinorGrid.DashOff = 2;
zedGraph.AxisChange();
zedGraph.Invalidate();
}
private void ts_parameters_Click(object
sender, EventArgs e)
{
GA_options ga_options = new
GA_options();
ga_options.Show();
}
private void ts_start_optimization_Click(object
sender, EventArgs e)
{
Select_stocs select_stocs = new
Select_stocs();
select_stocs.Show();
}
}
}
GA_options.Designer.cs
namespace diplom
{
partial class GA_options
{
private System.ComponentModel.IContainer
components = null;
protected override void Dispose(bool
disposing)
{
if (disposing && (components !=
null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.label1 = new
System.Windows.Forms.Label();
this.label2 = new
System.Windows.Forms.Label();
this.popul = new
System.Windows.Forms.NumericUpDown();
this.iter = new
System.Windows.Forms.NumericUpDown();
this.groupBox1 = new
System.Windows.Forms.GroupBox();
this.mutat = new
System.Windows.Forms.TextBox();
this.label4 = new
System.Windows.Forms.Label();
this.groupBox2 = new
System.Windows.Forms.GroupBox();
this.textBox2 = new
System.Windows.Forms.TextBox();
this.label3 = new
System.Windows.Forms.Label();
this.button1 = new
System.Windows.Forms.Button();
this.button2 = new
System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.popul)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.iter)).BeginInit();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
// label1
this.label1.AutoSize = true;
this.label1.Location = new
System.Drawing.Point(12, 25);
this.label1.Name = "label1";
this.label1.Size = new
System.Drawing.Size(102, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Размер
популяции";
// label2
this.label2.AutoSize = true;
this.label2.Location = new
System.Drawing.Point(12, 61);
this.label2.Name = "label2";
this.label2.Size = new
System.Drawing.Size(116, 13);
this.label2.TabIndex = 1;
this.label2.Text = "Количество
итераций";
// popul
this.popul.Location = new
System.Drawing.Point(198, 25);
this.popul.Name = "popul";
this.popul.Size = new
System.Drawing.Size(78, 20);
this.popul.TabIndex = 2;
this.popul.Value = new decimal(new int[]
{
100,0, 0, 0});
// iter
this.iter.Location = new
System.Drawing.Point(198, 54);
this.iter.Maximum = new decimal(new
int[] {
5000,0, 0, 0});
this.iter.Name = "iter";
this.iter.Size = new
System.Drawing.Size(78, 20);
this.iter.TabIndex = 3;
this.iter.Value = new decimal(new int[]
{
1000,0, 0, 0});
// groupBox1
this.groupBox1.Controls.Add(this.mutat);
this.groupBox1.Controls.Add(this.label4);
this.groupBox1.Location = new
System.Drawing.Point(15, 94);
this.groupBox1.Name =
"groupBox1";
this.groupBox1.Size = new
System.Drawing.Size(237, 59);
this.groupBox1.TabIndex = 4;
this.groupBox1.TabStop = false;
this.groupBox1.Text =
"Мутация";
// mutat
this.mutat.Location = new
System.Drawing.Point(155, 19);
this.mutat.Name = "mutat";
this.mutat.Size = new
System.Drawing.Size(57, 20);
this.mutat.TabIndex = 2;
this.mutat.Text = "0,001";
this.mutat.TextAlign =
System.Windows.Forms.HorizontalAlignment.Right;
// label4
this.label4.AutoSize = true;
this.label4.Location = new
System.Drawing.Point(20, 26);
this.label4.Name = "label4";
this.label4.Size = new
System.Drawing.Size(72, 13);
this.label4.TabIndex = 1;
this.label4.Text =
"Вероятность";
// groupBox2
this.groupBox2.Controls.Add(this.textBox2);
this.groupBox2.Controls.Add(this.label3);
this.groupBox2.Location = new
System.Drawing.Point(15, 173);
this.groupBox2.Name =
"groupBox2";
this.groupBox2.Size = new
System.Drawing.Size(237, 59);
this.groupBox2.TabIndex = 5;
this.groupBox2.TabStop = false;
this.groupBox2.Text =
"Кроссинговер";
// textBox2
this.textBox2.Location = new
System.Drawing.Point(155, 20);
this.textBox2.Name =
"textBox2";
this.textBox2.Size = new
System.Drawing.Size(57, 20);
this.textBox2.TabIndex = 1;
this.textBox2.Text = "0,001";
this.textBox2.TextAlign =
System.Windows.Forms.HorizontalAlignment.Right;
// label3
this.label3.AutoSize = true;
this.label3.Location = new
System.Drawing.Point(20, 27);
this.label3.Name = "label3";
this.label3.Size = new
System.Drawing.Size(72, 13);
this.label3.TabIndex = 0;
this.label3.Text =
"Вероятность";
// button1
this.button1.Location = new
System.Drawing.Point(38, 252);
this.button1.Name = "button1";
this.button1.Size = new
System.Drawing.Size(75, 35);
this.button1.TabIndex = 6;
this.button1.Text = "OK";
this.button1.UseVisualStyleBackColor =
true;
this.button1.Click += new
System.EventHandler(this.button1_Click);
// button2
this.button2.Location = new
System.Drawing.Point(191, 252);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75,
35);
this.button2.TabIndex = 7;
this.button2.Text = "Отмена";
this.button2.UseVisualStyleBackColor =
true;
this.button2.Click += new
System.EventHandler(this.button2_Click);
// GA_options
this.AutoScaleDimensions = new
System.Drawing.Size(6F, 13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new
System.Drawing.Size(339, 299);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.iter);
this.Controls.Add(this.popul);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Name = "GA_options";
this.Text = "Параметры
генетического алгоритма";
this.Load += new
System.EventHandler(this.GA_options_Load);
((System.ComponentModel.ISupportInitialize)(this.popul)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.iter)).EndInit();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.NumericUpDown
popul;
private System.Windows.Forms.NumericUpDown
iter;
private System.Windows.Forms.GroupBox
groupBox1;
private System.Windows.Forms.GroupBox
groupBox2;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox mutat;
private System.Windows.Forms.TextBox
textBox2;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
}
}
GA_options.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace diplom
{
public partial class GA_options : Form
{
public static float Mutation;
public static int InitialPopulation = 100;
public static int Iteration = 1000;
public GA_options()
{
InitializeComponent();
Mutation = 0.9f;
InitialPopulation = 100;
Iteration = 1000;
}
private void button2_Click(object sender,
EventArgs e)
{
this.Close();
}
private void button1_Click(object sender,
EventArgs e)
{
bool isSuccess =
float.TryParse(mutat.Text, out Mutation);
InitialPopulation =
Convert.ToInt32(popul.Value);
Iteration = Convert.ToInt32(iter.Value);
this.Close();
}
}
}
Kotir_close.Designer.cs
namespace diplom
{
partial class kotir_close
{
private System.ComponentModel.IContainer
components = null;
protected override void Dispose(bool
disposing)
{
if (disposing && (components !=
null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.dg_close = new
System.Windows.Forms.DataGridView();
this.btn_start = new
System.Windows.Forms.Button();
this.lbl = new
System.Windows.Forms.Label();
this.lbl1 = new
System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.dg_close)).BeginInit();
this.SuspendLayout();
// dg_close
this.dg_close.ColumnHeadersHeightSizeMode =
System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dg_close.Location = new
System.Drawing.Point(12, 26);
this.dg_close.Name =
"dg_close";
this.dg_close.Size = new
System.Drawing.Size(726, 282);
this.dg_close.TabIndex = 0;
this.dg_close.CellContentClick += new
System.Windows.Forms.DataGridViewCellEventHandler(this.dg_close_CellContentClick);
// btn_start
this.btn_start.Location = new
System.Drawing.Point(83, 326);
this.btn_start.Name = "btn_start";
this.btn_start.Size = new
System.Drawing.Size(130, 23);
this.btn_start.TabIndex = 2;
this.btn_start.Text = "Начать
расчет";
this.btn_start.UseVisualStyleBackColor =
true;
this.btn_start.Click += new
System.EventHandler(this.btn_start_Click);
// lbl
this.lbl.AutoSize = true;
this.lbl.Location = new
System.Drawing.Point(292, 326);
this.lbl.Name = "lbl";
this.lbl.Size = new System.Drawing.Size(35,
13);
this.lbl.TabIndex = 4;
this.lbl.Text = "label1";
// lbl1
this.lbl1.AutoSize = true;
this.lbl1.Location = new
System.Drawing.Point(452, 326);
this.lbl1.Name = "lbl1";
this.lbl1.Size = new
System.Drawing.Size(35, 13);
this.lbl1.TabIndex = 5;
this.lbl1.Text = "label1";
// kotir_close
this.AutoScaleDimensions = new
System.Drawing.Size(6F, 13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new
System.Drawing.Size(768, 361);
this.Controls.Add(this.lbl1);
this.Controls.Add(this.lbl);
this.Controls.Add(this.btn_start);
this.Controls.Add(this.dg_close);
this.Name = "kotir_close";
this.Text = "Цены закрыти выбранных
акций";
this.Load += new
System.EventHandler(this.kotir_close_Load);
((System.ComponentModel.ISupportInitialize)(this.dg_close)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridView
dg_close;
private System.Windows.Forms.Button
btn_start;
private System.Windows.Forms.Label lbl;
private System.Windows.Forms.Label lbl1;
}
}
Kotir_close.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace diplom
{
public partial class kotir_close : Form
{
public kotir_close()
{
InitializeComponent();
}
private void kotir_close_Load(object sender,
EventArgs e)
{
dg_close.DataSource =
Select_stocs.dataSet;
dg_close.DataMember =
"newtable";
}
private void btn_start_Click(object sender,
EventArgs e)
{
result result = new result();
result.Show();
}
}
}
ListGenome.cs
using System;
using System.Collections;
using System.Globalization;
namespace diplom
{
public class ListGenome : Genome
{
ArrayList TheArray = new ArrayList();
public static Random TheSeed
= new Random((int)DateTime.Now.Ticks);
int TheMin = 0;
int TheMax = 100;
raschet Raschet = new raschet();
public override int CompareTo(object a)
{
ListGenome Gene1 = this;
ListGenome Gene2 = (ListGenome)a;
return
Math.Sign(Gene2.CurrentFitness - Gene1.CurrentFitness);
}
public override void
SetCrossoverPoint(int crossoverPoint)
{
CrossoverPoint = crossoverPoint;
}
public ListGenome()
{
}
public ListGenome(long length)
{
Length = length;
double[]
nextValue = new double[Length];
double sum = 0;
double normaliz=0;
for (int i = 0; i < Length;
i++)
{
nextValue[i] =
(double)GenerateGeneValue();
sum += nextValue[i];
}
for (int i = 0; i < Length; i++)
{
normaliz = nextValue[i] / sum;
TheArray.Add(normaliz);
}
}
public override bool CanDie(float
fitness)
{
if (CurrentFitness <= (int)(fitness
* 100.0f))
{
return true;
}
return false;
}
public override bool CanReproduce(float
fitness)
{
if (ListGenome.TheSeed.Next(100)
>= (int)(fitness * 100.0f))
{
return true;
}
return false;
}
public override object GenerateGeneValue()
{
return TheSeed.NextDouble();
}
public override void Mutate()
{
MutationIndex1 =
TheSeed.Next((int)Length);
MutationIndex2 =
TheSeed.Next((int)Length);
double val = (double)TheArray[MutationIndex1];
TheArray.RemoveAt(MutationIndex1);
TheArray.Insert(MutationIndex2,val);
}
public override double
CalculateFitness()
{
double []ER=Raschet.returen();
double[,] matrix = Raschet.matrix_covar();
double doxod = 0;
double risk = 0;
for (int i = 0; i < Length; i++)
{
doxod += ER[i]*(double)TheArray[i];
}
for (int i = 0; i < Length; i++)
{
for (int j = 0; j < Length; j++)
{
risk += matrix[i, j] *
(double)TheArray[i] * (double)TheArray[j];
}
}
CurrentFitness = (double)(doxod/risk);
return CurrentFitness;
}
public override string ToString()
{
string strResult = "";
double sum = 0;
for (int i = 0; i < Length;
i++)
{
strResult = strResult +
((double)TheArray[i]).ToString("F3", CultureInfo.InvariantCulture) +
" ";
strResult += ";";
}
strResult +=
CurrentFitness.ToString("F5", CultureInfo.InvariantCulture);
return strResult;
}
public override void CopyGeneInfo(Genome
dest)
{
ListGenome theGene =
(ListGenome)dest;
theGene.Length = Length;
theGene.TheMin = TheMin;
theGene.TheMax = TheMax;
}
public override Genome Crossover(Genome
g)
{
ListGenome aGene1 = new
ListGenome();
ListGenome aGene2 = new
ListGenome();
g.CopyGeneInfo(aGene1);
g.CopyGeneInfo(aGene2);
ListGenome CrossingGene =
(ListGenome)g;
for (int i = 0; i <
CrossoverPoint; i++)
{
aGene1.TheArray.Add(CrossingGene.TheArray[i]);
aGene2.TheArray.Add(TheArray[i]);
}
for (int j = CrossoverPoint; j
< Length; j++)
{
aGene1.TheArray.Add(TheArray[j]);
aGene2.TheArray.Add(CrossingGene.TheArray[j]);
}
ListGenome aGene = null;
if (TheSeed.Next(2) == 1)
{
aGene = aGene1;
}
else
{
aGene = aGene2;
}
double sum = 0;
for (int i = 0; i < Length; i++)
{
sum+=(double)aGene.TheArray[i];
}
for (int i = 0; i < Length; i++)
{
aGene.TheArray[i]=(double)aGene.TheArray[i]/sum;
}
return aGene;
}
}
}
Load_file.cs
using System;
using System.Collections;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace diplom
{
class load_file
{
static DirectoryInfo dir1 = new
DirectoryInfo("D://dip_prog//kotirovki");
static FileInfo[] txt_file =
dir1.GetFiles("*.csv", SearchOption.AllDirectories);
static DataTable table;
static StreamReader mFile;
string str = "";
ArrayList stocs_list = new ArrayList();
public ArrayList show()
{
foreach (FileInfo txt in txt_file)
{
int startIndex =
txt.Name.IndexOf("#");
int endIndex =
txt.Name.IndexOf("_", startIndex);
str = txt.Name.Substring(startIndex,
endIndex - startIndex);
str+=";";
str+= txt.FullName;
stocs_list.Add(str);
}
return stocs_list;
}
public DataTable Load_file(string path)
{
try
{
mFile = new StreamReader(path);
table = new
DataTable("StocsTable");
DataColumn column;
DataRow row;
column = new DataColumn();
column.DataType =
System.Type.GetType("System.DateTime");
column.ColumnName =
"Data";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType =
System.Type.GetType("System.String");
column.ColumnName =
"Open";
column.AutoIncrement = false;
column.Caption = "Open";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType =
System.Type.GetType("System.String");
column.ColumnName = "Max";
column.AutoIncrement = false;
column.Caption =
"Максимум";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType =
System.Type.GetType("System.String");
column.ColumnName = "Min";
column.AutoIncrement = false;
column.Caption =
"Минимум";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName =
"Close";
column.AutoIncrement = false;
column.Caption =
"Закрытие";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
column = new DataColumn();
column.DataType =
System.Type.GetType("System.String");
column.ColumnName =
"Volume";
column.AutoIncrement = false;
column.Caption = "Объем";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
string lines;
string[] line;
while ((lines = mFile.ReadLine()) !=
null)
{
row = table.NewRow();
line = lines.Split(',');
row["Data"] =
Convert.ToDateTime(line[0]);
row["Open"] = line[2];
row["Max"] = line[3];
row["Min"] = line[4];
row["Close"] =
line[5];
row["Volume"] =
line[6];
table.Rows.Add(row);
}
mFile.Close();
}
catch (Exception ex)
{
MessageBox.Show("Невозможно загрузит
текстовый документ" + ex.Message);
}
return table;
}
}
}
Pie_chart.Designer.cs
namespace diplom
{
partial class pie_chart
{
private System.ComponentModel.IContainer
components = null;
protected override void Dispose(bool
disposing)
{
if (disposing && (components !=
null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new
System.ComponentModel.Container();
this.zgc = new
ZedGraph.ZedGraphControl();
this.SuspendLayout();
// zgc
this.zgc.Location = new
System.Drawing.Point(12, 12);
this.zgc.Name = "zgc";
this.zgc.ScrollGrace = 0;
this.zgc.ScrollMax = 0;
this.zgc.ScrollMax = 0;
this.zgc.ScrollMax2 = 0;
this.zgc.ScrollMin = 0;
this.zgc.ScrollMin = 0;
this.zgc.ScrollMin2 = 0;
this.zgc.Size = new
System.Drawing.Size(448, 327);
this.zgc.TabIndex = 0;
this.zgc.Load += new
System.EventHandler(this.zgc_Load);
// pie_chart
this.AutoScaleDimensions = new
System.Drawing.Size(6F, 13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new
System.Drawing.Size(487, 351);
this.Controls.Add(this.zgc);
this.Name = "pie_chart";
this.Text = "pie_chart";
this.Load += new
System.EventHandler(this.pie_chart_Load);
this.ResumeLayout(false);
}
#endregion
private ZedGraph.ZedGraphControl zgc;
}
}
Pie_chart.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;
namespace diplom
{
public partial class pie_chart : Form
{
public pie_chart()
{
InitializeComponent();
}
private void pie_chart_Load(object sender,
EventArgs e)
{
CreateChart();
}
public void CreateChart()
{
GraphPane myPane = zgc.GraphPane;
myPane.Title.Text = "Удельный вес
ценных бумаг";
myPane.Title.FontSpec.IsItalic = true;
myPane.Title.FontSpec.Size = 24f;
myPane.Title.FontSpec.Family =
"Times New Roman";
myPane.Fill = new Fill(Color.White,
Color.Goldenrod, 45.0f);
myPane.Chart.Fill.Type = FillType.None;
myPane.Legend.Position =
LegendPos.Float;
myPane.Legend.Location = new
Location(0.95f, 0.15f, CoordType.PaneFraction,
Align.Right, Align.Top);
myPane.Legend.FontSpec.Size = 10f;
myPane.Legend.IsHStack = false;
PieItem segment1 =
myPane.AddPieSlice(20, Color.Navy, Color.White, 45f, 0, "#AXP");
PieItem segment3 =
myPane.AddPieSlice(30, Color.Purple, Color.White, 45f, .0, "#BAC");
PieItem segment4 =
myPane.AddPieSlice(10, Color.LimeGreen, Color.White, 45f, 0, "#DD");
PieItem segment2 =
myPane.AddPieSlice(20, Color.SandyBrown, Color.White, 45f, 0, "#DIA");
PieItem segment6 =
myPane.AddPieSlice(20, Color.Red, Color.White, 45f, 0, "#IBM");
segment2.LabelDetail.FontSpec.FontColor
= Color.Red;
CurveList curves = myPane.CurveList;
double total = 0;
for (int x = 0; x < curves.Count;
x++)
total += ((PieItem)curves[x]).Value;
TextObj text = new
TextObj("Значение фитнесс функции-6,519" ,
0.18F, 0.40F,
CoordType.PaneFraction);
text.Location.Align = Align.Center;
text.Location.Align = Align.Bottom;
text.FontSpec.Border.IsVisible = false;
text.FontSpec.Fill = new
Fill(Color.White, Color.FromArgb(255, 100, 100), 45F);
text.FontSpec.StringAlignment =
StringAlignment.Center;
myPane.GraphObjList.Add(text);
TextObj text2 = new TextObj(text);
text2.FontSpec.Fill = new
Fill(Color.Black);
text2.Location.X += 0.008f;
text2.Location.Y += 0.01f;
myPane.GraphObjList.Add(text2);
zgc.AxisChange();
}
}
}
Population.cs
using System;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.IO;
namespace diplom
{
public class Population
{
StreamWriter mfile = new
StreamWriter("D://rezult/1.txt");
int kLength;
int kCrossover;
int kInitialPopulation;
int kPopulationLimit;
float kMutationFrequency;
float kDeathFitness;
float kReproductionFitness;
ArrayList Genomes = new ArrayList();
ArrayList GenomeReproducers = new
ArrayList();
ArrayList GenomeResults = new
ArrayList();
ArrayList GenomeFamily = new
ArrayList();
int CurrentPopulation;
int Generation = 1;
bool Best2 = true;
public Population(int lenght,float mutation,
int population)
{
kLength = lenght;
kCrossover = kLength / 2;
kInitialPopulation = population;
kPopulationLimit = population;
kMutationFrequency = mutation;
CurrentPopulation = kInitialPopulation;
kDeathFitness = 0.00f;
kReproductionFitness = 0.0f;
for (int i = 0; i <
kInitialPopulation; i++)
{
ListGenome aGenome = new
ListGenome(kLength);
aGenome.SetCrossoverPoint(kCrossover);
aGenome.CalculateFitness();
Genomes.Add(aGenome);
}
}
private void Mutate(Genome aGene)
{
if (ListGenome.TheSeed.Next(100)
< (int)(kMutationFrequency * 100.0))
{
aGene.Mutate();
}
}
public void NextGeneration()
{
Generation++;
for (int i = 0; i <
Genomes.Count; i++)
{
if
(((Genome)Genomes[i]).CanDie(kDeathFitness))
{
Genomes.RemoveAt(i);
i--;
}
}
GenomeReproducers.Clear();
GenomeResults.Clear();
for (int i = 0; i <
Genomes.Count; i++)
{
if
(((Genome)Genomes[i]).CanReproduce(kReproductionFitness))
{
GenomeReproducers.Add(Genomes[i]);
}
}
DoCrossover(GenomeReproducers);
Genomes =
(ArrayList)GenomeResults.Clone();
for (int i = 0; i <
Genomes.Count; i++)
{
Mutate((Genome)Genomes[i]);
}
for (int i = 0; i <
Genomes.Count; i++)
{
((Genome)Genomes[i]).CalculateFitness();
}
if (Genomes.Count >
kPopulationLimit)
Genomes.RemoveRange(kPopulationLimit,
Genomes.Count - kPopulationLimit);
CurrentPopulation = Genomes.Count;
}
public void
CalculateFitnessForAll(ArrayList genes)
{
foreach(ListGenome lg in genes)
{
lg.CalculateFitness();
}
}
public void DoCrossover(ArrayList genes)
{
ArrayList GeneMoms = new
ArrayList();
ArrayList GeneDads = new
ArrayList();
for (int i = 0; i <
genes.Count; i++)
{
if
(ListGenome.TheSeed.Next(100) % 2 > 0)
{
GeneMoms.Add(genes[i]);
}
else
{
GeneDads.Add(genes[i]);
}
}
if (GeneMoms.Count >
GeneDads.Count)
{
while (GeneMoms.Count >
GeneDads.Count)
{
GeneDads.Add(GeneMoms[GeneMoms.Count
- 1]);
GeneMoms.RemoveAt(GeneMoms.Count
- 1);
}
if (GeneDads.Count >
GeneMoms.Count)
{
GeneDads.RemoveAt(GeneDads.Count
- 1); // make sure they are equal
}
}
else
{
while (GeneDads.Count >
GeneMoms.Count)
{
GeneMoms.Add(GeneDads[GeneDads.Count
- 1]);
GeneDads.RemoveAt(GeneDads.Count
- 1);
}
if (GeneMoms.Count >
GeneDads.Count)
{
GeneMoms.RemoveAt(GeneMoms.Count
- 1);
}
}
for (int i = 0; i <
GeneDads.Count; i ++)
{
ListGenome babyGene1 =
(ListGenome)((ListGenome)GeneDads[i]).Crossover((ListGenome)GeneMoms[i]);
ListGenome babyGene2 =
(ListGenome)((ListGenome)GeneMoms[i]).Crossover((ListGenome)GeneDads[i]);
GenomeFamily.Clear();
GenomeFamily.Add(GeneDads[i]);
GenomeFamily.Add(GeneMoms[i]);
GenomeFamily.Add(babyGene1);
GenomeFamily.Add(babyGene2);
CalculateFitnessForAll(GenomeFamily);
GenomeFamily.Sort();
if (Best2 == true)
{
GenomeResults.Add(GenomeFamily[0]);
GenomeResults.Add(GenomeFamily[1]);
}
else
{
GenomeResults.Add(babyGene1);
GenomeResults.Add(babyGene2);
}
}
}
public DataRow WriteNextGeneration()
{
string[] res;
mfile.WriteLine("Generation
{0}\n", Generation);
DataSet dataSet=new DataSet();
DataTable tb_result = new
DataTable("tb_result");
DataTable end = new
DataTable("end");
DataRow row = null;
DataRow row_end = null;
res =
((Genome)Genomes[0]).ToString().Split(';');
DataColumn column;
for (int j = 0; j <
Select_stocs.stocs_select.Count; j++)
{
column =
tb_result.Columns.Add(Select_stocs.stocs_select[j].ToString(), typeof(String));
column =
end.Columns.Add(Select_stocs.stocs_select[j].ToString(), typeof(String));
}
column =
tb_result.Columns.Add("fitnes", typeof(String));
column = end.Columns.Add("fitnes",
typeof(String));
for (int i = 0; i <
CurrentPopulation; i++)
{
row = tb_result.NewRow();
res =
((Genome)Genomes[i]).ToString().Split(';');
for (int j = 0; j < res.Length;
j++)
{
row[j] = res[j];
}
tb_result.Rows.Add(row);
}
string str="";
DataView genesort =
tb_result.DefaultView;
genesort.Sort = "fitnes DESC";
row_end=genesort[0].Row;
for (int i = 0; i < genesort.Count;
i++)
{
str = "";
for (int j = 0; j <
genesort.Table.Columns.Count; j++)
{
str +=
genesort[i][j].ToString();
}
mfile.WriteLine(str);
}
return row_end;
}
}
}
Raschet.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace diplom
{
class raschet
{
static int obs = 36;
static int kolvo =
Select_stocs.length_stocs;
double[][] prirost = new double[kolvo][];
double[] ER = new double[kolvo];
double sredznach = 0;
double covar_1_2 = 0;
double[,] matrix_cov = new double[kolvo,
kolvo];
string str = "";
double[][] stock = new double[kolvo][];
public raschet()
{
string str = "";
for (int i = 0; i < kolvo; i++)
{
stock[i] = new
double[Select_stocs.dataSet.Tables["newtable"].Rows.Count];
for (int j = 0; j <
Select_stocs.dataSet.Tables["newtable"].Rows.Count; j++)
{
string a = Select_stocs.dataSet.Tables["newtable"].Rows[j][i].ToString().Replace('.',
',');
stock[i][j] =
Convert.ToDouble(a);
}
}
}
public double[] returen()
{
double summcur = 0;
for(int i=0;i<kolvo;i++)
{
summcur=summcur+stock[i][stock[0].Length-1];
}
for (int i = 0; i < kolvo; i++)
{
prirost[i]=new double[obs];
sredznach = 0;
for (int j = 0; j < obs; j++)
{
prirost[i][j] = (stock[i][j + 1]
- stock[i][j]) / stock[i][j];
sredznach+= (stock[i][j + 1] -
stock[i][j]) / stock[i][j];
}
ER[i] = sredznach /
(stock[i].Length-1);
}
return ER;
}
public double[,] matrix_covar()
{
for (int i = 0; i < kolvo; i++)
{
for (int j = 0; j < kolvo; j++)
{
covar_1_2 = 0;
for (int k = 0; k <
prirost[0].Length - 1; k++)
{
covar_1_2 += (prirost[i][k] -
ER[i]) * (prirost[j][k] - ER[j]);
}
matrix_cov[i,j]=covar_1_2 /
(prirost[i].Length - 1);
}
}
return matrix_cov;
}
}
}
Result.Designer.cs
namespace diplom
{
partial class result
{
private System.ComponentModel.IContainer
components = null;
protected override void Dispose(bool
disposing)
{
if (disposing && (components !=
null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.dg_result = new System.Windows.Forms.DataGridView();
this.bt_chart = new
System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dg_result)).BeginInit();
this.SuspendLayout();
// dg_result
this.dg_result.ColumnHeadersHeightSizeMode
= System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dg_result.Location = new
System.Drawing.Point(30, 26);
this.dg_result.Name =
"dg_result";
this.dg_result.Size = new
System.Drawing.Size(406, 240);
this.dg_result.TabIndex = 0;
// bt_chart
this.bt_chart.Location = new
System.Drawing.Point(59, 288);
this.bt_chart.Name =
"bt_chart";
this.bt_chart.Size = new
System.Drawing.Size(75, 23);
this.bt_chart.TabIndex = 1;
this.bt_chart.Text = "График";
this.bt_chart.UseVisualStyleBackColor =
true;
this.bt_chart.Click += new
System.EventHandler(this.bt_chart_Click);
// result
this.AutoScaleDimensions = new
System.Drawing.Size(6F, 13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new
System.Drawing.Size(520, 334);
this.Controls.Add(this.bt_chart);
this.Controls.Add(this.dg_result);
this.Name = "result";
this.Text = "Результаты
работы";
this.Load += new
System.EventHandler(this.result_Load);
((System.ComponentModel.ISupportInitialize)(this.dg_result)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView
dg_result;
private System.Windows.Forms.Button
bt_chart;
}
}
Result.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace diplom
{
public partial class result : Form
{
public static DataTable tbl = new
DataTable("tbl");
public result()
{
InitializeComponent();
}
private void result_Load(object sender,
EventArgs e)
{
Population TestPopulation = new
Population(Select_stocs.length_stocs,GA_options.Mutation,GA_options.InitialPopulation);
GA_options ga = new GA_options();
DataColumn column;
DataRow row1;
for (int j = 0; j <
Select_stocs.stocs_select.Count; j++)
{
column =
tbl.Columns.Add(Select_stocs.stocs_select[j].ToString(), typeof(String));
}
column =
tbl.Columns.Add("fitnes", typeof(String));
DataSet ds = new DataSet();
for (int i = 0; i <
GA_options.Iteration; i++)
{
TestPopulation.NextGeneration();
row1 =
TestPopulation.WriteNextGeneration();
tbl.Rows.Add(row1.ItemArray);
}
ds.Tables.Add(tbl);
dg_result.DataSource = ds;
dg_result.DataMember = "tbl";
}
private void bt_chart_Click(object sender,
EventArgs e)
{
pie_chart pie = new pie_chart();
pie.Show();
}
}
}
Select_stocs.Designer.cs
namespace diplom
{
partial class Select_stocs
{
private System.ComponentModel.IContainer
components = null;
protected override void Dispose(bool
disposing)
{
if (disposing && (components !=
null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.label1 = new
System.Windows.Forms.Label();
this.ok = new
System.Windows.Forms.Button();
this.cansel = new
System.Windows.Forms.Button();
this.dg = new
System.Windows.Forms.DataGridView();
((System.ComponentModel.ISupportInitialize)(this.dg)).BeginInit();
this.SuspendLayout();
// label1
this.label1.AutoSize = true;
this.label1.Location = new
System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new
System.Drawing.Size(188, 39);
this.label1.TabIndex = 1;
this.label1.Text = "Выберите ценные
бумаги, \r\nкоторые вы хотите видеть в своем \r\nинвестиционном портф" +
"еле\r\n";
this.label1.Click += new
System.EventHandler(this.label1_Click);
// ok
this.ok.Location = new
System.Drawing.Point(28, 263);
this.ok.Name = "ok";
this.ok.Size = new
System.Drawing.Size(75, 23);
this.ok.TabIndex = 3;
this.ok.Text = "OK";
this.ok.UseVisualStyleBackColor = true;
this.ok.Click += new
System.EventHandler(this.ok_Click);
// cansel
this.cansel.Location = new System.Drawing.Point(169,
262);
this.cansel.Name = "cansel";
this.cansel.Size = new
System.Drawing.Size(75, 23);
this.cansel.TabIndex = 4;
this.cansel.Text = "Отмена";
this.cansel.UseVisualStyleBackColor =
true;
// dg
this.dg.ColumnHeadersHeightSizeMode =
System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dg.Location = new
System.Drawing.Point(15, 64);
this.dg.Name = "dg";
this.dg.RowHeadersVisible = false;
this.dg.Size = new
System.Drawing.Size(229, 150);
this.dg.TabIndex = 5;
this.dg.CellContentClick += new
System.Windows.Forms.DataGridViewCellEventHandler(this.dg_CellContentClick);
// Select_stocs
this.AutoScaleDimensions = new
System.Drawing.Size(6F, 13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new
System.Drawing.Size(320, 303);
this.Controls.Add(this.dg);
this.Controls.Add(this.cansel);
this.Controls.Add(this.ok);
this.Controls.Add(this.label1);
this.Name = "Select_stocs";
this.Text = "Выбор акций для
портфеля ценных бумаг";
this.Load += new
System.EventHandler(this.Select_stocs_Load);
((System.ComponentModel.ISupportInitialize)(this.dg)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button ok;
private System.Windows.Forms.Button cansel;
private System.Windows.Forms.DataGridView
dg;
}
}
Select_stocs.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Collections;
using System.Windows.Forms;
namespace diplom
{
public partial class Select_stocs : Form
{
load_file f = new load_file();
public static DataSet dataSet;
public static ArrayList stocs_select=new
ArrayList();
DataRow row;
public static int length_stocs;
public Select_stocs()
{
InitializeComponent();
}
private void Select_stocs_Load(object
sender, EventArgs e)
{
ArrayList stocs_list = f.show();
DataGridViewCheckBoxColumn column0 =new
DataGridViewCheckBoxColumn();
DataGridViewTextBoxColumn name =new
DataGridViewTextBoxColumn();
name.Name = "Префикс акции";
name.DataPropertyName =
"name";
name.ReadOnly = true;
DataGridViewTextBoxColumn fullpath = new
DataGridViewTextBoxColumn();
fullpath.Name = "полный путь";
fullpath.DataPropertyName =
"fulpath";
fullpath.ReadOnly = true;
fullpath.Visible = false;
DataGridViewColumn col1 = new
DataGridViewColumn();
dg.Columns.Add(column0);
dg.Columns.Add(name);
dg.Columns.Add(fullpath);
for (int i = 0; i < stocs_list.Count;
i++)
{
string tmp =
stocs_list[i].ToString();
string[] a = tmp.Split(';');
dg.Rows.Add(0, a[0], a[1]);
}
}
private void ok_Click(object sender,
EventArgs e)
{
dataSet = new DataSet();
DataTable newtable=new
DataTable("newtable");
for (int i = 0; i <dg.Rows.Count;
i++)
{
if
(Convert.ToBoolean(dg.Rows[i].Cells[0].Value) == true)
{
string path =
dg.Rows[i].Cells[2].Value.ToString();
DataTable table =
f.Load_file(path);
DataColumn column
=newtable.Columns.Add(dg.Rows[i].Cells[1].Value.ToString(), typeof(String));
stocs_select.Add(dg.Rows[i].Cells[1].Value.ToString());
for (int j = 0; j <
table.Rows.Count; j++)
{
if (i == 0)
{
row = newtable.NewRow();
newtable.Rows.Add(row);
}
row[dg.Rows[i].Cells[1].Value.ToString()] = table.Rows[j][4];
newtable.Rows[j][dg.Rows[i].Cells[1].Value.ToString()]=table.Rows[j][4];
}
}
}
length_stocs = newtable.Columns.Count;
dataSet.Tables.Add(newtable);
kotir_close close = new kotir_close();
close.Show();
this.Close();
}
}
}
ПРИЛОЖЕНИЕ Б. РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ
(7 стр.)
Программа очень проста в
использовании и не требует специальных знаний от пользователя. Интерфейс
программы интуитивно понятен.
Рассмотрим основные окна программы.
При запуске программы
открывается главное окно программы. В верхней части главного окна расположено
горизонтальное меню.
Рисунок Б.1 - Главное окно программы
Главное меню программы состоит из
таких пунктов меню:
-Файл
-Сервис
-Оптимизация
-Справка
-Выход
Рассмотрим каждое меню программы
более подробно.
Пункт меню “Файл”. Пункт меню “Файл”
содержит два подменю: “Новый график” и “Выход”. При нажатии на пункт меню “Новый
график” появляется выпадающее меню с перечнем доступных пользователю акций.
При щелчке на выбранной акции в главном окне выводится график, показывающий
курс акции, выбранной пользователем.
Рисунок Б.2 - Пункт меню “Новый
график”
При нажатии на пункт меню “Выход”
происходит выход из программы.
Пункт меню “Сервис”.
Пункт меню Сервис
содержит два подпункта – “Архив котировок” и “Настройки”.
Пункт меню “Архив
котировок” позволяет пользователю просматривать котировки выбранной акции, что
повышает удобство программы.
Пункт меню “Архив котировок”
позволяет пользователю загружать котировки акций из текстового файла,
редактировать котировки, удалять, экспортировать котировки в текстовый файл.
Рисунок Б.3 - Внешний вид
окна Архив котировок
Окно “Архив котировок”
представляет собой форму, которая разделена на две части в левой части
пользователь может выбрать префикс акции, курсы которой он хочет просмотреть.
При щелчке мышью на названии акции открывается список доступных временных
интервалов. Нажав на нужный временной интервал в правой части окна, пользователь
может увидеть котировки выбранной акции за определенный период.
В нижней части окна архива
котировок расположен ряд кнопок. Кнопка “Загрузить”
позволяет загрузить текстовый файл с котировками акции.
Кнопка «Добавить”
позволяет добавить строку котировок на определенную дату. Кнопка “Правка”
переводит таблицу с котировками акций в режим редактирования. Кнопка “Удалить”
позволяет удалять строки, выбранные пользователем. Кнопка “Экспорт” позволяет
экспортировать котировки акций в текстовый формат. Кнопка “Закрыть” закрывает
окно архива котировок.
Пункт меню “Оптимизация”
Пункт меню “Оптимизация”
содержит два подменю – «Начать оптимизацию” и “Параметры”.
При нажатии на пункт меню “Начать
оптимизацию” открывается мастер, который последовательно открывает ряд окон.
Рассмотрим эти окна.
Окно “Выбор акций для
портфеля ценных бумаг”.
В этом окне происходит
отбор акций тех компаний, акции которых будут включаться в портфель. После того
как пользователь выберет
необходимое количество акций он нажимает на кнопку “ОК” и переходит к
следующему окну.
Рисунок Б.4 - Внешний вид
окна выбор акций.
Окно “Цены закрытия выбранных акций”.
Это окно выводит в таблице цены
закрытия выбранных пользователем акций.
При нажатии на кнопку “Начать расчет”
происходит запуск работы генетического алгоритма.
Рисунок Б.5 - Внешний вид
окна Цены закрытия избранных акций
Рисунок Б.6 - Внешний вид
окна результаты работы
После окончания работы
генетического алгоритма открывается окно с результатами его работы. (См. рис
Б.6)
Как известно, генетический алгоритм
выдает множество вариантов решений поставленной задачи. В данном случае,
варианты решений располагаются по горизонтали. Первые несколько столбцов – это
доли в каждую ценную бумагу, по которым инвестор должен распределить свой
капитал. Последний столбец показывает значение фитнесс функции. Каждая строка
таблицы показывает лучшее решение на данной итерации. Внизу окна расположены
кнопки “График” и “Закрыть”.
При нажатии на кнопку “График”
открывается окно с круговым графиком, где в графическом виде представлен
удельный вес каждой из выбранных ценных бумаг в оптимизированном портфеле. (См.рис.Б.7)
Рисунок Б.7 - Окно с
результатами работы
Нажатие кнопки “Закрыть” закрывает
окно.
Пункт меню “Параметры”.
При нажатии на пункт меню
“Параметры” открывается окно, где пользователь может самостоятельно изменить
параметры работы генетического алгоритма. (См.рис.Б.8)
Рисунок Б.8 - Внешний вид
окна параметры генетического алгоритма
Пункт меню “Справка”.
При нажатии на этот пункт меню
открывается окно “О программе”.
ПРИЛОЖЕНИЕ В. ЭКРАННЫЕ ФОРМЫ
(4 стр.)
Рисунок
В.1 - Главное окно программы
Рисунок В.2 - Пункт меню “Новый
график”
Рисунок В.3 - Внешний вид
окна Архив котировок
Рисунок В.4 - Внешний вид
окна выбор акций.
Рисунок В.5 - Внешний вид
окна Цены закрытия избранных акций
Рисунок В.6 - Внешний вид
окна результаты работы
Рисунок В.7 - Окно с
результатами работы
Рисунок В.7 - Внешний вид окна
параметры генетического алгоритма
ПРИЛОЖЕНИЕ
Д
Перечень замечаний
нормоконтролера к дипломному проекту
Пометка
документа
|
Документ
|
Условная
отметка
|
Содержание замечания
|
|
|
|
|
Дата ____________ Подпись
_______________