личное мнения которое на форуме оказывается следует держать при себе. Основная цель разработки промежуточного софта (библиотек,классов, тулзов) - облегчить себе дальнейшее. Чтобы в прикладной части этого самого кода было как можно меньше. А чтобы было совсем хорошо, типичные вещи надо называть устоявшимися именами. Вот к примеру таблицы...
----------
Сама по себе таблица - это не модель из MVC, это всего-лишь представление данных. Удобное и привычное.
И оно может (и должно) быть максимально кратким в конкретной реализации.
Тестовый индикатор, в табличном представлении. Из 4-х рассчётных и отображаемых буферов и одним промежуточным вычислением,
/* тестовый индикатор */ /* имена (индексы) колонок в таблице данных */ enum ENUM_MY_COLUMNS { HIGH, // цена открытия LOW, // цена закрытия MEDIAN, // медиана MA, // средняя INTERM // тестовый промежуточный рассчёт }; const string MyColumns[]={"HIGH","LOW","MEDIAN","MA","INTERM"}; // строковые имена колонок (для отчётов и обращений по именам) /** основная рассчётная функция, */ bool CalcMyColumns(DataTable *table,int column,int row,double &result) { switch(column) { case HIGH: result=iHigh(table.Symbol(),table.Period(),row);break; // цены открытия/закрытие из iHigh/iLow case LOW: result=iLow(table.Symbol(),table.Period(),row);break; case MEDIAN: result=table["INTERM"][row]; break; // скопируем из промежуточного рассчёта (можно по имени) case INTERM: result=(table[(int)HIGH][row]+table[(int)LOW][row])/2.0;break; // промежуточный рассчёт } return true; } DataTable Table(MyColumns,CalcMyColumns); // таблица с данными (результаты вычислений кешируются, взаимозависимости разруливаются) //DataTable Table(CalcMyColumns); // можно без имён, но тогда нельзя будет обращаться по строковому имени int ma_handle=INVALID_HANDLE; // хендл внешнего индикатора int OnInit() { Table.SetIndexBuffer(0,HIGH,INDICATOR_DATA); // буфер 0 - из колонки OPEN Table.SetIndexBuffer(1,LOW,INDICATOR_DATA); Table.SetIndexBuffer(2,MEDIAN,INDICATOR_DATA); Table.SetIndexBuffer(3,MA,INDICATOR_DATA); // буфер 3 - из колонки MA Table.SetIndicator(MA,iMA(_Symbol,PERIOD_CURRENT,13,0,MODE_SMA,PRICE_OPEN)); // колонку MA ассоциируем с внешним индикатором EventSetTimer(15); return(INIT_SUCCEEDED); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { return Table.OnCalculate(rates_total,prev_calculated,time,open,high,low,close,tick_volume,volume,spread); } void OnTimer() { Table.Print(5); // по таймеру - печатаем 5 самых актуальных строк }
не скопипщены #property - итого без них ~50 строк включая форматирование и комментарии.
И конечно-же оно работает, хоть индикатор и тестовый и ничего толково-осмысленного не рисует :
И хотя простыми действиями в конкретном приложении получили о-го-го сколько плюшек:
- нужный результат - все графики построены и данные посчитаны)
- декларативный стиль - де-факто ведь просто описали таблицу на этапе OnInit;
- унифицированный доступ и интроспекцию - к данным обращаемся как к ячейкам таблицы.
- даже печать и вывод данных - в тесте выводится в журнал, но можно и в отдельные окна и формы
это всё ещё не табличная модель из MVC. У неё нет ничего для взаимодействий с другими компонентами. Есть интерфейс таблицы данных, но "это другое"