Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Пишем библиотеку DLL для Metastock с нуля.Часть2

Anna | 24.06.2014 | нет комментариев
В этой статье будут детально рассмотрены наша функция (часть1), правила приобретения данных из Metastock’а, их обработки и возврата итога обратно в Metastock. Эта информация поможет избежать ошибок в работе MSX DLL.

Наша функция имеет вид:

DLL_EXPORT BOOL __stdcall Price(const MSXDataRec *a_psBasic, 
					            const MSXDataInfoRecArgsArray *a_psArrayArgs,
					            const MSXNumericArgsArray *a_psNumericArgs, 
					            const MSXStringArgsArray *a_psStringArgs, 
					            const MSXCustomArgsArray *a_psCustomArgs,  
					            MSXResultRec *a_psResult)

, где
*a_psBasic — указатель на конструкцию MSXDataRec (все доступные данные о дорогих бумагах);
*a_psArray — указатель на конструкцию MSXDataInfoRecArgsArray (доводы массивов);
*a_psNumeric — указатель на конструкцию MSXNumericArgsArray (числовые доводы);
*a_psString — указатель на конструкцию MSXStringArgsArray (строковые доводы);
*a_psCustom — указатель на конструкцию MSXCustomArgsArray (Custom-доводы);
*a_psResult — указатель на конструкцию MSXResultRec (итог обработки данных возвращаемый в Metastock);
*a_psValue — указатель на конструкцию MSXDataInfoRec (все числовые данные, используемые в расчетах).
Все конструкции описываются в файле MSXStruc.h.

Хранение данных и расчеты

Все числовые данные, используемые в расчетах индикаторов, сохраняются в конструкциях, знаменитых как массивы данных. Массивы данных применяются для хранения данных цен (скажем, Open, High, Low, и т.д.), числовых констант и итогов расчета индикаторов. Когда MetaStock поставляет данные о дорогих бумагах и доводах функций MSX DLL, эти данные применяются как массивы. Когда функция, вычисленная MSX DLL, возвращает итоги индикатора в MetaStock, то итог возвращается в виде массива данных.
Массивы данных реализованы в структуре MSXDataInfoRec и имеют три основных компонента:
• Data elements — элементы данных.
• First valid index — исходная точка отсчета (Fvi).
• Last valid index — финальная точка отсчета (Lvi).
Элементы данных являются фактическими числовыми значения, связанными с массивом данных. Эти значения сохраняются в массиве в виде float значений. 1-й и конечный возможный индекс применяются для определения, какие элементы данных содержат подлинные значения. Все элементы данных между первым и последним возможным индексом (включительно) содержат подлинные данные. Все элементы вне этого диапазона имеют неопределенные значения и обязаны игнорироваться для всех расчетов.
Массив данных считается “пустым“, если Fvi<Lvi. Пустые массивы данных не являются редкостью и обязаны быть обработаны надлежащим образом. Как правило, пустой массив данных будет иметь Fvi = 0 и Lvi = -1, правда всякое сочетание при условии Fvi<Lvi следует рассматривать пустым. Пустой массив данных возникает, когда данные не доступны. Скажем, массив данных ‘Open Interest’ применяется для ценной бумаги (ЦБ), которая не имеет открытый интерес.
Либо, если итог 100 — периодной скользящей средней используется к массиву данных цен ЦБ, тот, что содержит поменьше 100 элементов, тогда получаем пустой массив данных.
1-й и конечный возможные индексы дюже главны во время расчета индикатора. Расчеты неизменно обязаны быть ограничены элементами данных, содержащихся между ними. Два значимых момента следует понимать, Дабы верно установить Fvi и Lvi индексы для возвращаемого массива данных:
• Неизменно ограничивать расчеты в интервале возможных диапазонов всех используемых входных массивов данных.
• Fvi и Lvi в итоге расчета обязаны сберегать свои позиции по отношению к значениям всех массивов входных данных.

Конструкция MSXDataRec содержит семь массивов данных:
• sOpensHighsLowsClosesVolsOIsInd,
хранящих свои значения в MSXDataInfoRec структуре. Эти массивы данных хранят все нужные ценовые данные ЦБ.
Некоторые из этих массивов могут быть пустым, если ЦБ не имеет данных для этого поля цен (скажем, Open Interest).
• Помимо того, в структуре MSXDataRec содержится указатель на массив из конструкции MSXDateTime.
Данный массив содержит информацию о дате и времени для всякой точки данных. Если функции расчета нужен доступ к дате и времени для N-го бара инструмента, нужно ссылаться на N-ый элемент массиваpsDate. Обратите внимание, что данный массив отличается от такого массива данных как sHigh, sLow, и т.п.
• Массив данных sInd содержит данные для индикатора, выбранного пользователем. В случае пользовательского индикатора данный массив данных будет содержать значение для объекта диаграммы, к которой индикатор был прикреплен. Если не выбран участок sInd массив данных будет пустым.
• Обратите внимание, что расположение данных в этих массивах синхронизированы с N-м элементом всякого элемента массива, соответствующего временного периода.
• Массив данных sClose неизменно содержит наивысшее число элементов данных. Все остальные массивы данных содержат число элементов <= sClose.iLastValid.
• Настройки iFirstValid и iLastValid в массиве данных sClose дюже значимы.
Традиционно число элементов в этом массиве определяет наивысшее число элементов данных, хранящихся в других массивах цен. Это значимо для определения числа возможных элементов, содержащихся в массиве psDate. Скажем, если поле sClose.iFirstValid = 100 и поле sClose.iLastValid = 200, вы можете быть уверены, что массив psDate содержит действительные данные на интервале от psDate [100] до psDate [200].
• Позже того, как расчет выполнится, значение iLastValid в a_psResult -> psResultArray никогда не должно быть огромнее, чем значение iLastValid массива данных sClose.
• iFirstValid и iLastValid из sClose обязаны быть использованы для определения того, сколько значений доступно для хранения всех данных массивов. Для хранения всех массивов выдается довольно памяти, только до точки данных sClose.iLastValid. Данные возвращаемые в a_psResult — > psResultArray от MSX DLL обязаны уложиться в эти же ограничения по хранению.
• Предисловие массива данных a_psResult->psResultArray возвращаемого из MSX DLL никогда не должно быть поменьше sClose.iFirstValid. Конец массива данных a_psResult — >psResultArray никогда не обязаны быть огромнее, чем sClose.iLastValid.

Что нужно помнить

• Функции расчета никогда не обязаны изменять всякие входящие доводы, за исключением результирующей записи (a_psResult). Входящие доводы определяются как ‘const‘, где это допустимо, в предоставленных образцах, Дабы гарантировать, что не произойдет нелегальных изменений.
• Непременно установите a_psResult -> psResultArray -> iFirstValid и a_psResult — > psResultArray — > iLastValid до возвращения из вашей функции.
• Если ваша функция возвращает MSX_ERROR, что указывает на внутреннюю ошибку, удостоверитесь, что вы скопировали в расширенную строку ошибки, причину описывающую ошибку a_psResult — >pszExtendedError.
• Никогда не устанавливайте a_psResult — > psResultArray — > iFirstValid поменьше sClose.iFirstValid.
• Никогда не устанавливайте a_psResult — > psResultArray — > iLastValid огромнее sClose.iLastValid. Запись в a_psResult — > psResultArray -> pfValue за значение sClose.iLastValid вызовет перепонение памяти в MetaStock и аварийному заключению работы программы.
• Непременно проверьте iFirstValid и iLastValid всяких доводов MSXDataInfoRec либо a_psBasic, которые вы собираетесь применять. Никогда не думайте, что данные будут доступны в любом массиве данных. Если данные не доступны для вашей функции для обработки, установите
a_psResult — > psResultArray — > iFirstValid = 0 и
a_psResult — >psResultArray — > iLastValid = -1,
Дабы указать, что нет подлинных данных для возвращения массива. Данный способ разрешает избежать аварийного заключения работы программы Metastock.

Изменяем код

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

DLL_EXPORT BOOL __stdcall Price(const MSXDataRec *a_psBasic, 
					            const MSXDataInfoRecArgsArray *a_psArrayArgs,
					            const MSXNumericArgsArray *a_psNumericArgs, 
					            const MSXStringArgsArray *a_psStringArgs, 
					            const MSXCustomArgsArray *a_psCustomArgs,  
					            MSXResultRec *a_psResult)

{
   BOOL l_bRtrn = MSX_SUCCESS;

    for (int i= a_psBasic ->sClose.iFirstValid; i<= a_psBasic ->sClose.iLastValid; i  )
        a_psResult->psResultArray->pfValue[ i ] = a_psBasic ->sClose.pfValue[ i ];

      // Задаем предисловие и конец массива.
	a_psResult->psResultArray->iFirstValid = a_psBasic->sClose.iFirstValid;
    a_psResult->psResultArray->iLastValid = a_psBasic->sClose.iLastValid;

      // Если данные не доступны, возвращаем пустой массив.
	if (l_bRtrn != MSX_SUCCESS)
      {
		strncpy (a_psResult->szExtendedError, "Error: Corrupted Result Array.",
			     sizeof(a_psResult->szExtendedError)-1);
		a_psResult->psResultArray->iFirstValid = 0;
		a_psResult->psResultArray->iLastValid = -1;
       }
  return l_bRtrn;
}

Итог в файл

Для итога наших данных непременно подключите заголовочный файл stdio.h, в котором объявлен особый тип данных – конструкция FILE.
• #include <stdio.h>

Комментарии

Для организации работы с файлами, программе нужно применять указатели на файлы. Для создания файловой переменной-указателя применяется оператор типа: FILE *file (объявление потока). Дабы дозволено было обращаться к файлу его нужно открыть. Функция fopen() открывает для применения поток, объединяет файл с данным потоком, возвращает указатель FILE на данный поток и имеет дальнейший вид:
• file = fopen(«путь к файлу»,«режим работы файла»).
Режим “w” применяется для записи в файл. Запись в файл осуществляет функция fprintf():
• fprintf(file,[строка формата], [список переменных, констант]).
Функция fclose() применяется для закрытия потока, ранее открытого с поддержкой fopen().
• fclose(file)
Вызов fclose() освобождает блок управления файлом, связанный с потоком, и делает его доступным для повторного применения.

Давайте выведем следующие данные: имя ЦБ, период (‘D’aily, ‘W’eekly, ‘M’onthly, ‘Q’uarterly, ‘I’ntraday), индекс, наш индикатор, время и дату в файл.

DLL_EXPORT BOOL __stdcall Price(const MSXDataRec *a_psBasic, 
								const MSXDataInfoRecArgsArray *a_psArrayArgs,
								const MSXNumericArgsArray *a_psNumericArgs, 
							    const MSXStringArgsArray *a_psStringArgs, 
							    const MSXCustomArgsArray *a_psCustomArgs,  
							    MSXResultRec *a_psResult)
{
   BOOL l_bRtrn = MSX_SUCCESS;
   FILE *file;
   file = fopen("D:\example.txt", "w");
    for (int i= a_psBasic ->sClose.iFirstValid; i<= a_psBasic ->sClose.iLastValid; i  )
	{
        a_psResult->psResultArray->pfValue[ i ] = a_psBasic ->sClose.pfValue[ i ];

	  if (file)
		fprintf(file, "%-10s %2c %5u %12.4f %5u %10un", a_psBasic ->pszSecurityName, 
			   a_psBasic ->iPeriod, i, double (a_psResult->psResultArray->pfValue[i]), 
			   a_psBasic ->psDate[i].lTime/1000, a_psBasic ->psDate[i].lDate);
	}
		fclose(file);
      // Задаем предисловие и конец массива.
	a_psResult->psResultArray->iFirstValid = a_psBasic->sClose.iFirstValid;
    a_psResult->psResultArray->iLastValid = a_psBasic->sClose.iLastValid;

      // Если данные не доступны, возвращаем пустой массив.
	if (l_bRtrn != MSX_SUCCESS)
      {
		strncpy (a_psResult->szExtendedError, "Error: Corrupted Result Array.",
			     sizeof(a_psResult->szExtendedError)-1);
		a_psResult->psResultArray->iFirstValid = 0;
		a_psResult->psResultArray->iLastValid = -1;
       }
  return l_bRtrn;
}

В итоге у меня на одноминутном графике фьючерса на индекс РТС получилось следующее:

example.txt

SP_RTS_1m   I     1  112310.0000  1725   20140417
SP_RTS_1m   I     2  112320.0000  1726   20140417
SP_RTS_1m   I     3  112130.0000  1727   20140417
...
SP_RTS_1m   I   497  117150.0000  1336   20140418
SP_RTS_1m   I   498  117170.0000  1337   20140418
SP_RTS_1m   I   499  117200.0000  1338   20140418
SP_RTS_1m   I   500  117190.0000  1339   20140418

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

 

Источник: programmingmaster.ru

 

Оставить комментарий
БАЗА ЗНАНИЙ
СЛУЧАЙНАЯ СТАТЬЯ
СЛУЧАЙНЫЙ БЛОГ
СЛУЧАЙНЫЙ МОД
СЛУЧАЙНЫЙ СКИН
НОВЫЕ МОДЫ
НОВЫЕ СКИНЫ
НАКОПЛЕННЫЙ ОПЫТ
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB