Новая роль учредителя. В этой модели мы — не просто CEO, а учредитель и основной бенефициар (отдельной компании). Наша задача — управлять компанией «Я Holdings» так, чтобы:
1. Ее операционная деятельность (доходы от инвестиций) полностью покрывала ваши финансовые изъятия (вашу "зарплату"). 2. Ее инвестиционная деятельность (реинвестирование прибыли) обеспечивала постоянный рост капитала для защиты от инфляции и увеличения будущих доходов.
Когда эти условия выполняются, наш инвестиционный бизнес становится по-настоящему пассивным источником дохода и финансовой независимости.
Переход от бухгалтерской констатации фактов и финансового планирования к настоящему финансовому анализу. Да, мы должны это оценить. «И тогда наверняка вдруг запляшут облака» — метафора для этого эффекта, который дают эти рычаги: они могут вознести к облакам, но могут и породить грозу.
Оценим операционный и финансовый рычаг для нашей инвестиционной компании «Я Holdings».
1. Операционный рычаг (Леверидж) в инвестиционной компании. Что это такое? В классическом бизнесе — это отношение постоянных затрат к переменным. В нашем случае — это структура доходов компании. * Компания с ВЫСОКИМ операционным рычагом: Доход формируется в основном за счет роста капитала (продажа подорожавших активов). Это акции роста, венчурные проекты. Доля дивидендов мала. * Компания с НИЗКИМ операционным рычагом: Доход формируется в основном за счет текущих денежных потоков (дивиденды, купоны). Это дивидендные аристократы, облигации.
Как оценить? Коэффициент операционного рычага = (Доход от прироста капитала) / (Денежный доход (дивиденды + купоны)). * > 1 (Высокий рычаг):** Ваша прибыль сильно зависит от рыночной конъюнктуры. На бычьем рынке «облака запляшут» — доходность взлетит. На медвежьем — у вас не будет стабильного денежного потока для изъятий, придется продавать активы в убыток. * = 1 (Сбалансированный):** Золотая середина. Есть и рост, и стабильный cash flow. * < 1 (Низкий рычаг):** Ваша компания устойчива. Она генерирует стабильный денежный поток, почти не зависящий от курсовых колебаний. Но и взлететь к «облакам» ей сложнее.
Пример: а) Портфель А (Высокий рычаг): За год получили 50 тыс. руб. дивидендов и 500 тыс. руб. прибыли от продажи акций. Рычаг = 500 / 50 = 10. Высокий. Доходность «пляшет» вместе с рынком. б) Портфель Б (Низкий рычаг): За год получили 400 тыс. руб. дивидендов и 100 тыс. руб. прибыли от продаж. Рычаг = 100 / 400 = 0.25. Низкий. Компания стабильна, как скала.
2. Финансовый рычаг (Леверидж) в инвестиционной компании. Что это такое? Это использование заемных средств для увеличения размера инвестируемого капитала. То самое «плечо» (leverage). Как оценить? Есть несколько ключевых метрик: а) Коэффициент финансового левериджа = Обязательства / Капитал. * 0.5 (1:2): На 1 рубль заемных средств приходится 2 рубля собственных. Консервативно. * 1.0 (1:1): Соотношение 50/50. Агрессивно. * > 1.0: Заемных средств больше, чем собственных. Крайне рискованно.
б) Ставка покрытия долга = (Операционный Денежный Поток) / (Проценты по долгу). * > 3: Отлично. Доходы более чем в 3 раза покрывают процентные платежи. * 1 - 2: Опасно. Почти все денежные потоки съедают проценты. * < 1: Критично. Вы не можете обслуживать долг из текущих доходов.
Совместный эффект двух рычагов. Вот где начинается настоящая магия и настоящий риск. Эффекты рычагов умножаются, а не складываются!
Сценарий 1: «Облака запляшут» (Золотой сценарий). * Высокий операционный рычаг - (портфель из растущих акций) + Умеренный финансовый рычаг (дешевое плечо 1:0.5). * Результат: На бычьем рынке мы получаем доходность не только на свои деньги, но и на заемные. Наш капитал растет опережающими темпами.
Сценарий 2: «Гроза и шторм» (Катастрофический сценарий). * Высокий операционный рычаг** (волатильные активы) + Высокий финансовый рычаг (плечо 1:1 или выше). * Результат: На медвежьем рынке падение стоимости залога приводит к маржин-коллу. Брокер принудительно продает наши активы по низким ценам, фиксируя убытки и уничтожая наш капитал. Это тот случай, когда «облака» не пляшут, а обрушиваются ливнем.
Сценарий 3: «Уверенный рост» (Стратегия богатого папы). * Низкий операционный рычаг - (портфель генерирует стабильный cash flow) + Умеренный финансовый рычаг (дешевый долг, например, ипотека на доходную недвижимость). * Результат: Наш арендный денежный поток стабильно покрывает платежи по кредиту и наши изъятия. Компания растет надежно и предсказуемо.
Резюме для CEO «Я Holdings». 1. Операционный рычаг — это наш выбор стратегии (рост vs. доход). Определяет волатильность нашей прибыли. 2. Финансовый рычаг — это наш источник финансирования (свои vs. заемные). Определяет уровень риска ликвидации. 3. Вместе они создают коктейль с непредсказуемым эффектом. Высокие значения обоих рычагов — удел профессионалов, готовых к полной потере капитала.
Теперь наша задача как управляющего. Найти такое сочетание рычагов, который соответствует нашему темпераменту, опыту и горизонту инвестирования. Для большинства «облака запляшут» при умеренном операционном и минимальном финансовом рычаге. Помним: рычаг режет в обе стороны. ------------------------
Мы переходим от качественного анализа к количественному управлению, что является сутью профессионального подхода. И нашей конечной целью, создать такой алгоритм и написать код скрипта, который бы однозначно превращал пассивный доход в основной доход инвестора!
Формализуем эту задачу. Эту проблему идеально моделировать как задачу оптимального управления с граничными условиями, где мы управляем двумя видами рычагов для максимизации функции роста капитала при ограничении на максимальный убыток. Но это уже другая тема.
Внесу уточнение в модель, когда мы рассматриваем инвестиционную компанию как самостоятельный бизнес, фокус несколько смещается, и на мой взгляд упрощается, ведь управление отдельной компанией проще управления холдингом, сохраним рабочее название прежним «Я Holdings». Уточним модель для этого случая.
В этой модели компания «Я Holdings» — это самостоятельный бизнес, который живет по своим внутренним законам. Её цель — самоокупаемость и рост за счет реинвестирования прибыли.
Ключевые допущения: * Источник средств: Первоначальные взносы учредителей (наши личные накопления). * Доходы: Только доходы от инвестиционной деятельности (дивиденды, купоны, реализованная прибыль от продажи активов). * Расходы: Все изъятия средств учредителями на личные цели, а также комиссии и налоги. * Реинвестирование: Вся нераспределенная прибыль остается в компании и реинвестируется.
Три главных отчета остаются прежними, внесу лишь уточнение, в Отчет о движении денежных средств (ДДС) — «Хватает ли компании денег?»*. Это по-прежнему самый важный отчет, но его структура меняется.
* Операционная деятельность (ОСНОВНАЯ): Доходы от инвестиций. * Приток: Дивиденды, купоны, проценты. * Отток: Комиссии брокеров, оплата услуг управляющего. * Инвестиционная деятельность (ЦЕЛЕВАЯ): Покупка и продажа активов. * Отток: Покупка новых акций, облигаций. * Приток: Продажа активов (возврат капитала). * Финансовая деятельность (СВЯЗЬ С ВЛАДЕЛЬЦЕМ): Взаимодействие с учредителем. * Приток: Дополнительные взносы учредителя. * *Отток: Изъятия учредителя на личные расходы.
Главная формула успеха для самоокупаемой компании: Операционный Денежный Поток >= Изъятия (Финансовая деятельность) * Цель достигнута: Если дивидендов и купонов хватает на все ваши изъятия, значит, компания вышла на самоокупаемость. Вы живете на доход от ее деятельности, не трогая основной капитал. * Цель не достигнута: Если изъятия больше операционного потока, вам приходится продавать активы (Инвестиционная деятельность) или докладывать свои деньги (Финансовая деятельность), что тормозит рост.
2. Отчет о прибылях и убытках (ОПУ) — «Прибыльна ли компания?»
* Выручка: Совокупный инвестиционный доход (дивиденды + купоны + реализованная прибыль от продаж). * Расходы: Комиссии, налоги. * Чистая прибыль / убыток: Выручка - Расходы. * Важный нюанс: Нереализованная прибыль/убыток (изменение стоимости портфеля) здесь не отражается. Этот отчет показывает реальный денежный результат.
3. Баланс — «Сколько стоит компания?»
* АКТИВЫ: Только инвестиционные активы. Деньги на брокерском счете, акции, облигации, ETF. (Личные активы типа машины и квартиры теперь не учитываются — они принадлежат нам лично, а не компании ). * ОБЯЗАТЕЛЬСТВА: Кредитное плечо, маржинальные займы. * КАПИТАЛ: Активы - Обязательства. Это чистая стоимость вашего инвестиционного бизнеса. Рост капитала — главная KPI. ---
Забегая вперед отмечу, что прекрасно вписываются в данный подход и метрики трейдинга: * Профит фактор, * Процент выигрышных сделок, * Мат. ожидания системы, без расчета которого не должна существовать ни одна система, в том числе и данная. Управление капиталом вообще отдельная тема, но я сейчас про управление системой как бизнес. Вот система метрик ни чего нового, то как понимаю подход, структурированная по трем основным отчетам и ключевым бизнес-процессам.
1. Метрики Операционной деятельности (Income Statement & Cash Flow). Цель: Оценить эффективность генерации свободных денежных средств — «топлива» для инвестиций.
* Коэффициент сбережений (Savings Rate): * Формула: (Доходы - Расходы) / Доходы * 100% * Смысл: Это*рентабельность по чистой прибыли (Net Profit Margin) нашего личного «бизнеса». Показывает, какая доля дохода остается после всех жизненных «операционных расходов». Цель — постоянное увеличение. * Свободный денежный поток (Free Cash Flow - FCF): * Формула: Доходы - Все расходы (включая налоги и обязательные платежи) * Смысл: Абсолютная сумма в рублях/долларах, которую вы можете направить в инвестиционную деятельность (CFI) без привлечения заемных средств. Это главный источник роста.
2. Метрики Финансовой деятельности (Balance Sheet & Leverage). Цель: Оценить финансовое здоровье, структуру капитала и риски, связанные с долгом.
* Коэффициент долговой нагрузки (Debt-to-Income Ratio - DTI): * Формула: Сумма ежемесячных платежей по долгам / Ежемесячный доход * 100% * Смысл: Показывает, какая часть вашего операционного cash flow съедается обслуживанием долга. >40-50% — сигнал опасности. * Коэффициент финансового рычага (Leverage Ratio): * Формула: Обязательства / Активы или Обязательства / Собственный капитал (Equity) * Смысл: Показывает, насколько вы зависите от заемных средств. Для частного инвестора цель — низкое значение (например, <0.3 или 30%). * Стоимость заемного капитала (Cost of Debt): * Формула: Средневзвешенная процентная ставка по всем кредитам * Смысл: Критически важная метрика. Доходность от инвестиций (CFI) должна быть заведомо выше этой цифры.
3. Метрики Инвестиционной деятельности (Performance & Efficiency) Цель: Оценить эффективность управления портфелем-проектом.
* Общая доходность портфеля (Total Portfolio Return): * Формула: (Текущая стоимость портфеля - Внесенные средства) / Внесенные средства * 100%` * Смысл: ROI (Return on Investment) для всего вашего «бизнеса». Показывает общую эффективность. * Доходность с учетом дивидендов (Total Return): * Смысл: Важно учитывать не только рост цены, но и реинвестируемый cash flow (дивиденды, купоны). Это более точная метрика. * Скорректированная на риск доходность (Risk-Adjusted Return): * Метрика: Коэффициент Шарпа. * Смысл: Показывает, сколько дохода вы получаете за единицу риска (волатильности). Доходность 20% при волатильности 5% гораздо лучше, чем те же 20% при волатильности 25%. * Сравнение с бенчмарком (Benchmark Tracking): * Метрика: Отставание/опережение индекса (например, IMOEX или MSCI World). * Смысл: Ответ на вопрос: «А не мог бы я просто купить индекс и спать спокойно?». Если вы отстаете от бенчмарка, ваш «активный» управленческий труд не приносит добавленной стоимости.
4. Метрики Баланса (Balance Sheet Health) Цель: Оценить структуру и качество активов.
* Аварийный фонд (Emergency Fund Ratio): * Формула: Сумма на "черный день" / Среднемесячные расходы * Смысл: Показывает, на сколько месяцев вы можете прожить без дохода. Цель — 3-6 месяцев. Это коэффициент ликвидности. * Аллокация активов (Asset Allocation): * Метрика: % акций, % облигаций, % кэша, % альтернативных активов * Смысл: Главный драйвер риска и доходности. Отслеживание отклонений от целевой аллокации — основа управления портфелем. * Диверсификация (Diversification Metrics): * Метрики: * Количество эмитентов/стран/секторов. * Максимальная доля одного актива в портфеле.* (Например, правило: не более 5% на одну акцию). * Смысл: Показывает уровень несистематического риска. Снижает риск банкротства одного «проекта» для всей «компании».
5. Сводная таблица KPI для CEO «Я Holdings»**
| Сфера | Ключевая метрика | Целевое значение | ----------------- | ----------------------------------------- | ------------------------------------------------- | Операции | Коэффициент сбережений (>20%) | Постоянный рост | | Свободный денежный поток (FCF) | Положительный и растущий | Финансы | Коэффициент долговой нагрузки (DTI) (<30%)| Менее 30% | | Стоимость заемного капитала | Минимизировать; < ожидаемой доходности портфеля | Инвестиции | Общая доходность (Total Return) | Опережать инфляцию + целевой бенчмарк | | Коэффициент Шарпа | >1 (чем выше, тем лучше) | Баланс/Риски | Аварийный фонд | 3-6 месяцев расходов | | Отклонение от целевой аллокации | Не более ±5% по каждому классу активов | | Макс. доля одного актива | Не более 5%
Управляя этими метриками, мы превращаемся из пассивного владельца активов в активного CEO, который на основе данных принимает решения: * о распределении капитала, * управлении рисками * и стратегическом развитии своего главного бизнеса «Я Holdings» — собственного финансового будущего. ----------------- А не кто и не обещал, что будет легко.
Портфель - как проект в бизнесе. Это завершающая и самая важная мысль.
Каждый актив в нашем портфеле — это не просто "бумажка", а инвестиционный проект со своими параметрами:
* Бизнес-план. Наша инвестиционная идея. Почему эта акция/облигация должна принести доход? * Цель (KPI). Ожидаемая доходность, срок горизонта инвестирования. * Бюджет (CAPEX). Сколько мы готовы вложить. * Управление рисками. Каковы риски проекта (отраслевые, страновые, валютные)? Какой максимальный убыток мы допускаем (стоп-лосс)? * Отчетность. Мы регулярно (но не ежедневно!) смотрим на результаты проекта. И отвечаем себе на вопросы: изменилась ли первоначальная идея? Выполняются ли KPI?
Управление портфелем — это управление «Я Holdings» состоящей из таких проектов. Вы как CEO компании «Я Holdings»: 1. Распределяете капитал между проектами (активами). 2. Закрываете убыточные проекты (продаете активы, если идея не сработала). 3. Увеличиваете финансирование успешных проектов (докупаете качественные активы). 4. Следите, чтобы один провальный проект не потопил всю компанию (диверсификация).
Итог. Новая парадигма. Перестаем думать, "Куда бы вложить 1000 рублей?". Начинаем думать как генеральный директор компании «Я Holdings» - владелец пусть и миноритарий:
1. Как мне увеличить денежный поток от моей операционной деятельности? (Больше зарабатывать, разумно тратить). 2. Нужно ли мне привлекать финансовый рычаг для моих инвестиционных проектов, и если да, то на каких условиях? (Осторожно с долгами, это одельная тема управление капиталом). 3. Какой инвестиционный проект (актив) соответствует моей стратегии и имеет наилучшее соотношение риска и доходности? 4. Как выглядит отчетность моего "бизнеса" в целом? (Баланс, отчет о прибылях и убытках, движение денежных средств).
Такой подход превращает инвестиции из лотереи в осознанный, управляемый бизнес-процесс. Как Вам такой путь к настоящей финансовой свободе?
Развернем идею и посмотрим на портфельное управление через призму бизнес-управления. (Или "Три богатыря" в управлении бизнесом, а что у них в руках, возможно то самый рычаг?)
Бизнес-подход к личным финансам. Вы — генеральный директор самого себя, или компании под рабочим названием "Я Холдинг" ("IHoldings"). А что имеем полное право, приобретая акции разных компаний, становимся собственниками этих компаний. С точки зрения бизнеса получаем Актив, а диверсификация дает нам право назваться холдингом, что собственно и отрежет смысл владения разными активами. Следовательно и наш личный капитал должен управляться с позиции управляющего холдингом.
Если отразить деятельность "IHoldings" как: Инвестиционная деятельность = Операционная деятельность + Финансовая деятельность. То ее можем описывать так же, как это делает бизнес.
Три основных управленческих отчета при управлении бизнесом (Три богатыря).
а) Отчет о прибылях и убытках (Income Statement) - Отвечает на вопрос: "Как я генерирую денежный поток?" * Выручка (Revenue): Дивиденды, купоны, проценты по вкладам, другие средства на инвестирование. * Расходы (Expenses): Текущие жизненные траты (если тратим на разные нужды), налоги, комиссии брокеров, затраты на инфраструктуру ... * Чистая прибыль (Net Income): = Выручка - Расходы. * Смысл: Этот отчет отвечает на вопрос "Насколько эффективно я превращаю свои труд и капитал в свободные деньги?". Положительный и растущий Cash Flow — это топливо для нашей инвестиционной деятельности.
б) Баланс (Balance Sheet) - Отвечает на вопрос: "Чем я владею и кому должен?" * Активы (Assets): * Оборотные: Деньги на счетах, вклады. * Внеоборотные: Акции, облигации, ETF, недвижимость, золото. * Обязательства (Liabilities): * Краткосрочные: Кредитки, потребительские кредиты. * Долгосрочные: Ипотека, автокредит, маржинальное плечо. * Капитал (Equity): = Активы - Обязательства. * Смысл: Это моментальный снимок нашего финансового здоровья. Наша цель — не просто рост активов, а рост капитала (Equity). Сильный баланс — это низкая доля обязательств и качественные, диверсифицированные активы.
в) Отчет о движении денежных средств (Cash Flow Statement) - Отвечает на вопрос: "Откуда приходят и куда уходят деньги?" Это самый важный на мой взгляд в нашей компании отчет! Он делится на три части, которые идеально ложатся на нашу формулу: 1. Денежный поток от операционной деятельности (CFO): Ваш заработок, минус все жизненные траты. Это фундамент. 2. Денежный поток от инвестиционной деятельности (CFI): Покупка и продажа активов. Покупка — отток денег (-), продажа — приток (+). 3. Денежный поток от финансовой деятельности (CFF): Взятие и погашение кредитов, использование плеча. Взятие кредита — приток (+), погашение — отток (-).
И вот наша ключевая формула в действии: CFI = CFO + CFF. Простыми словами: * Если у вас сильная операционная деятельность (CFO > 0), вы можете инвестировать (CFI < 0 на покупки) без долгов. * Если операционной деятельности не хватает, вы привлекаете финансовую деятельность (кредиты, CFF > 0), чтобы усилить инвестиционную. Хотя это — повышение риска, но и повышение ROI на собственные средства!
Таким образом, управление портфелем есть не что иное как Управление Двумя Рычагами: Операционным и Финансовым.
Рычаг №1: Операционная деятельность (Зарабатывание) * Задача: Максимизировать разницу между доходами и расходами. * Управление: Повышение квалификации, разумное сокращение неэффективных расходов ("оптимизация издержек"). * Результат: Увеличение CFO — источника сил для инвестиций без долгов.
Рычаг №2: Финансовая деятельность (Заемные средства) * Задача: Привлекать дешевый и долгосрочный капитал для усиления инвестиционной деятельности и . * Управление: * Плохо: Дорогие кредитки для спекуляций, короткие плечи на волатильных активах. * Хорошо: Низкопроцентный займ на доходную часть активов, долгосрочное маржинальное плечо для покупки диверсифицированных активов (нужно крайне осторожно!). * Ключевой вопрос: Будет ли доходность от актива (CFI) заведомо выше стоимости привлеченных средств (CFF)?
То для успеха нужно управлять обеими составляющими эффективно. Возникает вопрос так для кого "доход пассивный"?
Александр М, Так, принимайте участие в обсуждениях, ведь не сторонний человек в трейдинге, всегда интересно мнение со стороны, ведь нельзя оставаться всегда правым. Кстати Ваш журнал хочу опробовать в этом инвест. проекте.
Продолжая тему модернизации инвестиционного портфеля (Рефакторинг кода). Огляделся вокруг, что происходит, каков рыночный фон?
1. Пожалуй сложно не согласиться с аналитиками утверждающими об отсутствии инвестиционных денег на рынке в настоящий момент, следовательно крупный капитал вынуждено занимается спекуляциями! А это уже профессиональная деятельность.
2. Пассивный доход - от куда сегодня только не звучит. Идея простая, Свободные (и не очень) средства направлять на инвестиции или спекуляции. Есть 1000 руб. купил на них Акцию и жди дивиденд, и вот вам доход, Ура. Но все ли так безмятежно.
Что то "пахнет" противоречиями современного инвестирования. Давайте разберем ключевое противоречие по частям.
1. Иллюзия безмятежности, что скрывается за мантрой "пассивного дохода". Главный ключ к пониманию можно обозначить так: «Свои дорогие - после налогов. Заемные - бизнес» — это и есть главный ключ к пониманию.
1.1. «Свои средства — всегда дорогие, после налогов». Наши 1000 рублей — это не просто 1000 рублей. Это "уже очищенные от налогов" деньги. * Если вы работаете по найму, то это ваш зарплатный доход, с которого уже удержан НДФЛ. * Если вы предприниматель — вы заплатили налоги с прибыли.
Эти деньги можно потратить на образование, отдых, текущие нужды или на развитие другого бизнеса. Используя их для инвестиций, мы отказываетесь от этих альтернатив. Это и есть их "цена" - Альтернативная стоимость. Если наши инвестиции (дивиденды + рост стоимости) не покрывают официальную инфляцию (а часто и реальную, которая выше), мы в убытке. Наш "пассивный доход" на самом деле — пассивное проедание капитала - Инфляция как скрытый налог.
Пример: Депозит под 10% при инфляции в 8% и налоге на доход свыше ключевой ставки дает нам мизерную реальную доходность. А дивиденд по акции в 5% при падении цены самой акции на 10% — это убыток. Вывод: Свои средства лишь *кажутся* бесплатными. Их реальная стоимость определяется упущенными возможностями и инфляцией.
1.2. «Заемные — так поступает бизнес». Вот здесь начинается настоящая игра с огнем. Использование заемных средств (кредитов, маржинального плеча) кардинально меняет природу операции.
По своим деньгам мы можем переждать просадку. Акция упала на 30%? Мы можем держать ее годами, ожидая восстановления. С заемными средствами так не получится. При падении стоимости залога брокер вынужден будет продать наши активы по самой низкой цене (маржин - колл), чтобы вернуть себе деньги. Мы превращам временную бумажную просадку в невосполнимый реальный убыток - мы фиксируете убыток! :cry:
Процент по кредиту/марже — это наша постоянная статья расходов. Наши инвестиции должны не просто приносить доход, а приносить доход, заведомо превышающий стоимость этого плеча. Это создает гигантское давление и вынуждает идти на большие риски. Стоимость плеча, это постоянные расходы сказал бы управляющий бизнесмен! Торговля на заемные средства к тому же — это колоссальный стресс, который приводит к эмоциональным, нерациональным решениям - психологическое давление. Вывод: Использование заемных средств — это не "инвестирование", это профессиональная спекулятивная деятельность, требующая глубоких знаний, железной дисциплины и готовности к полной потере капитала. :what:
Так что же на самом деле представляет собой эта "1000 рублей в акцию"? Это безмятежный пассивный доход или ЭТО: 1. Микро-бизнес? Вы становитесь совладельцем бизнеса (акция) или его кредитором (облигация). Бизнес может процветать, а может и обанкротиться. 2. Управление рисками? Вам нужно диверсифицировать портфель, чтобы крах одной компании не уничтожил все ваши вложения. Те самые 1000 рублей — это не одна акция, а, возможно, доля в ETF на весь рынок. 3. Постоянная работа и обучение? "Пассивность" — это миф. Даже индексное инвестирование требует регулярной ребалансировки, мониторинга макроэкономической ситуации и железной выдержки, чтобы не продавать активы на панике. 4. Осознание горизонта инвестирования? Эти 1000 рублей вам не понадобятся в течение 10-15 лет? Отлично, вы можете вложить их в акции. Понадобятся через год? Это должны быть максимально надежные и ликвидные инструменты, с почти нулевой доходностью.
Заключение. Массовый нарратив о "пассивном доходе" часто упрощает реальность до опасной степени. Настоящий пассивный доход — это не результат единоразового действия "купил акцию" и жди дивиденд.
Это результат: - Постоянного дисциплинированного формирования капитала (сначала накопить, потом инвестировать). - Грамотной стратегии, основанной на целях и приемлемом для вас риске. - Понимания всех издержек — как явных (налоги, комиссии), так и неявных (инфляция, альтернативная стоимость). - Отказа от иллюзий быстрого обогащения, особенно с использованием заемных средств.
Наши 1000 рублей — это не билет в безмятежную жизнь, а "семена будущего капитала". Но чтобы это семя проросло, за ним нужен уход, терпение и понимание, в какой почве оно растет и какие бури могут быть над горизонтом. Это именно тот уровень осознанности, который отделяет "играющего в инвестиции" от профессионального управляющего капиталом. :smile:
Вывод, по своей экономической природе "пассивны доход" с родни бизнес - управлению компанией. Но тогда и нужно сформировать такой подход, себя превратить, из безмятежного наблюдателя, в генерального директора, владельца бизнеса! А это уже новая парадигма, дело тут в разных подходах в отношении, если хотите психологии! Или вариант совсем ни наш, передать управление. :what:
Конкретные смыслы и практические преимущества, или как сопрограммы меняют парадигму!
Смысл 1: Простота - читаемость и ясность кода. --------------------------------------------------------
* Теория: Мы пишем последовательный код. * Смысл: Мы можем описать сложную асинхронную логику так, как мы о ней думаем — шаг за шагом, без нагромождения хаоса колбэков. "Ад колбэков" — код растет вглубь, асинхронная логика размазана по функциям. После (красота сопрограмм)!
Код
function сложнаяЗадача()
local data = загрузитьДанные("url") -- Здесь может быть yield
local result = обработатьДанные(data) -- И здесь
local success = сохранитьВБД(result) -- И здесь
если success then
обновитьИнтерфейс()
end
end
-- Создаем сопрограмму и "опросом" управляем ее выполнением
local task = coroutine.create(сложная Задача)
Смысл: Код выглядит как обычный, линейный и "блокирующий", но на деле он асинхронный. Мозг читает его без напряжения.
Смысл 2: Архитектор - "Кооперативная многозадачность" и контроль. ------------------------------------------------------------ * Теория: Мы сами решаем, когда отдать управление. * Смысл: Мы становимся архитекторами своего планировщика. Мы не зависим от прерываний по таймеру, а сами говорим: "Стоп, я сейчас подожду, а ты пока выполни что-то еще".
Код
-- Пул из нескольких "независимых задач", как вы и сказали
local tasks = {
coroutine.create(function() ... end), -- Задача 1: загрузка контента
coroutine.create(function() ... end), -- Задача 2: анимация UI
coroutine.create(function() ... end), -- Задача 3: обработка ввода
}
-- Главный цикл "опросом" управляет всеми задачами
function главныйЦикл()
while true do
local всеЗавершены = true
for i, co in ipairs(tasks) do
if coroutine.status(co) ~= "dead" then
всеЗавершены = false
coroutine.resume(co) -- "Опрос" конкретной сопрограммы!
end
end
если все Завершены then break end
end
end
* Смысл: Мы точно знаем, в какой момент какая задача будет выполняться. Нет гонки данных, нет сложных примитивов синхронизации, как в потоках. Мы создаем детерминированную систему.
Смысл 3: Эффективность - эффективное ожидание и реактивность. ------------------------------------------------------------------------------------------------------ * Теория: Сопрограмма может быть приостановлена в любой точке. * Смысл: Мы можем элегантно реализовать ожидание без блокировки всего приложения.
Код
-- В движке: ждем 2 секунды перед загрузкой данных.
function ждать(секунды)
local времяСтарта = os.clock()
while os.clock() - времяСтарта < секунды do
coroutine.yield() -- "Спим", не блокируя основной поток, отдавая управление другим задачам
end
end
* Смысл:** Мы пишем логику, которая "живет" во времени, но не замораживает весь мир вокруг себя. Это основа для AI, анимаций, диалогов в играх.
Смысл 4: Эффективность - генераторы и бесконечные последовательности. ------------------------------------------------------------------------------------------------------------------ * Теория: Сопрограмма может yield-ить промежуточные результаты. * Смысл: Мы создаем "ленивые" вычисления и потенциально бесконечные потоки данных.
Код
function бесконечнаяПоследовательность(старт, шаг)
local текущее = старт
while true do
coroutine.yield(текущее)
текущее = текущее + шаг
end
end
-- Создаем генератор чисел, начиная с 10, с шагом 5
local генератор = coroutine.wrap(бесконечнаяПоследовательность)
local gen = генератор(10, 5)
print(gen()) --> 10
print(gen()) --> 15
print(gen()) --> 20
-- Можно получать значения по требованию, не вычисляя все сразу.
* Смысл: Экономия памяти и вычислений. Мы рассчитываем следующее значение только тогда, когда оно реально нужно.
Итого. Вся прелесть — в этом "превращении". Сопрограммы в Lua — это мост между двумя мирами: 1. Мир для программиста: Удобный, последовательный, понятный код. 2. Мир для машины: Гибкое, асинхронное, неблокирующее выполнение.
И ключ к управлению этим миром — наш "опрос" с помощью `coroutine.resume`. Это диалог: "Ты готова поработать?", "Сделай шаг", "Отдохни, я спрошу тебя позже". Это и есть тот самый глубокий смысл, который делает сопрограммы в Lua таким элегантным и мощным инструментом.
От теории к смыслам! Вся прелесть и заключается использования сопрограмм в превращении выполнения одной последовательной задачи луа в ряд независимых задач! Как добиваемся независимости, опросом сопрограмм, там где нужно и тогда когда нужно!
Вот мой рабочий пример (как есть прямо в таком виде сейчас крутится, это не образец для подражания, но), что я только с ним не делал? И сейчас на вечерней падает сопрограмма - обработка таблицы всех сделок, ну и ладно скрипт работает, а с вечеркой когда руки дойдут разберусь.
Код
function OnMain()
Log:trace("OnMain started")
-- Создаем корутины Прверка пароля
local coPassword = coroutine.create(checkPassword)
-- Прверка пароля при первом входе!(корутина с безопасным вызовом)
safe_resume(coPassword, "coPassword")
--[[GUI.initialize()
-- Создание таблицы ордеров
GUI.createTable({
name = "orders",
title = "Active Orders",
width = 1000,
height = 400,
x = 10,
y = 50,
columns = {
{
iCode = 1,
title = "Time",
par_type = QTABLE_TIME_TYPE,
width = 120
},
{
iCode = 2,
title = "Price",
par_type = QTABLE_DOUBLE_TYPE,
width = 100
},
{
iCode = 3,
title = "Volume",
par_type = QTABLE_INT64_TYPE,
width = 100
}
}
})
-- Создание информационной метки
GUI.createLabel({
id = "statusLabel",
text = "System Status: OK",
x = 10,
y = 10,
width = 300,
color = "#00FF00",
bgColor = "#333333"
})
--]]
GUI.initialize()
-- Создание таблицы ордеров
GUI.createTable({
name = "orders",
title = "Активные ордера",
columns = {
{
iCode = 1,
title = "Время",
type = QTABLE_TIME_TYPE,
width = 120
},
{
iCode = 2,
title = "Операция",
type = QTABLE_STRING_TYPE,
width = 100
},
{
iCode = 3,
title = "Объем",
type = QTABLE_INT_TYPE, -- Теперь правильно QTABLE_INT_TYPE = 1
width = 80
}
}
})
-- Пример использования в главном цикле
local hook = PerformanceHook()
--local performanceHook = PerformanceHook()
local fatal = nil
AutoUpdateVersion()
CreateWindowRobot()
if Start ~= nil then
Start()
end
AtExit(function()
for _, so in pairs(SmartOrder.pool) do
so:enough()
so:process()
end
end)
if Robot ~= nil then -- Провека на наличие основтой функции
---- функция для получения информации о классе
local ClassInfo = getClassInfo(class_names[1]);
firmid = ClassInfo and ClassInfo.firmid or ''; Log:trace('firmid = ' .. tostring(firmid ) );
-- Создаем корутину для функции Robot
local routine = coroutine.create(Robot)
Log:trace("Robot started")
-- Создаем корутины
--local coPassword = coroutine.create(checkPassword)
local coConnection = coroutine.create(checkConnection)
local coTradeDate = coroutine.create(checkTradeDate)
local coServerTime = coroutine.create(checkServerTime)
local coWorkTime = coroutine.create(checkWorkTime) -- Сопрограмма для отслеживания рабочего времени
--local coStopTimeTrading = coroutine.create(checkStopTimeTrading)
-- Cоздание корутин для стратегий реального времени
--if not rejime.test and event_co.connected == 1 and event_co.servertime[2] and flagTimeTrading then
-- Cоздание корутины function
local coCapitalManager = coroutine.create(CapitalManagerCo--function() CapitalManagerCo(CONFIG) end
)
local coMoneyManagement = coroutine.create(function()
--for _, class in ipairs(class_names) do
--for n, symbol in ipairs(symbol_names) do
--if mm[class][symbol] ~= nil then
--MoneyManagementCo( mm[class][symbol] )
MoneyManagementCo( firmid, account, class_names, symbol_names )
--else
--Log:error("MoneyManagement instance 'mm[n]' is nil. Cannot start MoneyManagementCoroutine.")
--end
--end
--end
end)
--if not rejime.test and event_co.connected == 1 and event_co.servertime[2] and flagTimeTrading then
local co_alltrade = coroutine.create(alltrade_processor)
local co_order_book = coroutine.create(order_book_processor)
--local co_tt_parametrs = coroutine.create(trade_data_processor)
local futuresCoroutine = coroutine.create(futures_position_processor)
local futuresLimitCoroutine = coroutine.create(futures_limit_processor)
--end
while WORKING_FLAG do
--------------------------
local sek = os.clock();
--------------------------
--[[-- Обновление данных
--GUI.update_connection_status(isConnected())
--GUI.update_last_activity(os.time())
--GUI.update_uptime(getUptime())
-- Добавление новых ордеров
--while hasNewOrders() do
-- GUI.add_order(getNextOrder())
--end
-- Обновление торговой панели
GUI.updateComponent("trading_panel", {
{"BUY", 100.50, 10},
{"SELL", 101.00, 5}
})
-- Добавление метки на график
GUI.Chart.addLabel("MAIN_CHART", "Support Level", {
YVALUE = 98.50,
COLOR = RGB(46, 204, 113)
})--]]
-- Обновление данных
GUI.updateTable("orders", {
{os.date("%H:%M:%S"), "BUY", 10},
{os.date("%H:%M:%S"), "SELL", 5}
})
-- Запуск корутин с безопасным вызовом
if not rejime.test then
safe_resume(coConnection, "coConnection")
SetCell(table_id, 1, 1, tostring(event_co.connected == 1 and 'Connect' or 'NoConnect'))
if event_co.connected == 1 then
safe_resume(coTradeDate, "coTradeDate")
safe_resume(coServerTime, "coServerTime")
safe_resume(coWorkTime, "coWorkTime")
--safe_resume(coStopTimeTrading, "coStopTimeTrading")
--if event_co.connected == 1 then
-- Запуск корутины MoneyManagement
--safe_resume( MoneyManagementRoutine, "MoneyManagementRoutine")
safe_resume( coCapitalManager, "coCapitalManager")
--end
-- Запускаем корутину (История сделок и стакан)
--Log:info('tradedate[1] =' ..tostring(event_co.tradedate[1]) ..'; worktime =' ..tostring(event_co.worktime[2]) ..'; servertime[2] =' ..tostring(event_co.servertime[2]) --..'; flagTimeTrading =' ..tostring(flagTimeTrading) )
if event_co.tradedate[1]
and event_co.worktime[2]
and event_co.servertime[2]
then
safe_resume(co_alltrade, 'co_alltrade')
safe_resume(co_order_book, 'co_order_book')
end
--coroutine.resume(co_tt_parametrs)
-- Функция для запуска корутины
--start_futures_position_processing(futuresCoroutine)
--start_futures_limit_processing(futuresLimitCoroutine)
safe_resume(futuresCoroutine, 'futuresCoroutine')
--safe_resume(futuresLimitCoroutine, 'futuresLimitCoroutine')
end
-- Формирем модуль СМ
--safe_resume( coCapitalManager, "coCapitalManager")
--safe_resume( coMoneyManagement, "coMoneyManagement")
end
-- co Robot Затем используйте его методы
local res, errmsg = coroutine.resume(routine)
if not res then
fatal = "Broken coroutine (Robot): " .. errmsg
-- Вариант 1: Использование глобального обработчика (рекомендуется)
_G.global_error_handler:handle_error(fatal, "Robot")
-- Вариант 2: Статический вызов
-- ErrorHandler.handle_error_static(fatal, "Robot")
break
end
if coroutine.status(routine) == "dead" then
Log:trace("Robot routine finished")
break
end
ProcessRegistered()
--local elapsed_ms = performanceHook(sek) -- sleep(1000)
hook(sek) -- Обновляем метрики
sleep(spinner.config.interval * 1000) -- Контроль частоты
--if rejime.test then
-- sleep(100)
--else
-- Log:trace(math.floor(1000 - tonumber(elapsed_ms)))
--sleep( )
-- sleep(1000)
--end
end
end
if Stop ~= nil then Stop() end
ProcessAtExit() -- Вызов ProcessAtExit
ErrorCollector.log_all_errors() -- Логирование всех ошибок при завершении
Log:trace("Robot stopped")
if fatal ~= nil then
error(fatal)
end
end
Насколько понял Вашу задачу. Задача заключается в том, чтобы использовать IUP с корутинами в Lua, чтобы интерфейс не блокировал основной поток выполнения программы, а позволял продолжать выполнение других операций в программе, пока окно IUP остаётся открытым. Возможно этот пример подойдет, нужно проверять, но разобраться поможет. Удачи.
Код
require "iuplua"
-- Указываем глобальный атрибут для работы с корутинами
iup.SetGlobal("IUPLUA_THREADED", "YES")
-- Функция для создания диалога с текстовым полем
function create_input_dialog()
local text = iup.text{expand = "HORIZONTAL", value = ""}
local ok_btn = iup.button{title = "OK", size = "50"}
local cancel_btn = iup.button{title = "Cancel", size = "50"}
local dlg = iup.dialog{
iup.vbox{
iup.label{title = "Введите текст:"},
text,
iup.hbox{ok_btn, cancel_btn}
},
title = "Ввод данных",
size = "300x100"
}
return dlg, text, ok_btn, cancel_btn
end
-- Функция для асинхронного ввода через корутину
function async_input(coroutine_fn)
return function(...)
local co = coroutine.create(coroutine_fn)
local success, result = coroutine.resume(co, ...)
return result
end
end
-- Основная функция диалога как корутина
function input_dialog_coroutine()
local dlg, text, ok_btn, cancel_btn = create_input_dialog()
-- Создаем promise-like объект для синхронизации
local result = { waiting = true, value = nil }
-- Callback для OK
ok_btn.action = function()
result.value = text.value
result.waiting = false
return iup.CLOSE
end
-- Callback для Cancel
cancel_btn.action = function()
result.value = nil
result.waiting = false
return iup.CLOSE
end
-- Показываем диалог (не модальный!)
dlg:show()
-- Ждем завершения в цикле (можно заменить на более изящное решение)
while result.waiting do
coroutine.yield() -- Отдаем управление обратно
iup.LoopStep() -- Обрабатываем события IUP
end
dlg:destroy()
return result.value
end
-- Пример использования в основном потоке Quik
function main()
print("Начало работы скрипта")
-- Запускаем диалог в корутине
local co = coroutine.create(input_dialog_coroutine)
-- Основной цикл обработки
local timer = os.clock()
while coroutine.status(co) ~= "dead" do
-- Периодически возобновляем корутину
if os.clock() - timer > 0.1 then -- каждые 100 мс
local success, input_text = coroutine.resume(co)
if success and input_text then
print("Пользователь ввел: " .. input_text)
break
elseif not success then
print("Ошибка в корутине:", input_text)
break
end
timer = os.clock()
end
-- Здесь может выполняться другой код
-- Например, обработка данных из Quik
process_quik_data()
-- Небольшая пауза чтобы не грузить CPU
os.execute("ping -n 1 127.0.0.1 > nul") -- для Windows
-- os.execute("sleep 0.1") -- для Linux
end
print("Скрипт продолжает работу после диалога")
end
function process_quik_data()
-- Здесь может быть код для работы с данными Quik
-- который выполняется параллельно с открытым диалогом
end
-- Запуск основной функции
main()
Модернизация инвестиционного портфеля (Рефакторинг кода). Или почему нельзя путать скальсперские или внутридневные стратегии с инвестициями. Спекуляция против инвестиции (Speculation versus investment).
Пару слов про свою задачу. Есть не просто старый, а древний портфель ИИС, для анализа и выработки решений используется тайм фрейм месячный, это основной, изредка опускаешься для детализации на недельный, ну а для входа раз в год бывает уточняешь H4. Так как т. ф. месячный, то тренд классический в 12 бар равен периоду 1 год. Наблюдать ежедневно за таким подходом означает 365 раз заснешь. Поэтому здесь важно отслеживать не которые реперные точки, и получать сигнал.
Это масштабы "Крупных денег", глобальных игроков, и здесь прекрасно работает классический тех. анализ. А Волатильность в 1 стандартное отклонение, сообщает о возможных изменениях на месяц. Делая вход в позицию, рассматриваешь месячный горизонт как минимум. Торгуя руками психологически не комфортно "скакать" по разным т. ф. сюда нужно добавить что инвестиционный портфель нужно диверсифицировать, иногда хеджировать, а если несколько портфелей? Как тут проводить разбалансировку?
Заглядывая в приложения своих брокеров, рекомендации покупать, все как один, мотивируя что рынок внизу и перепродан, открываешь тех. анализ тренды в шорт, но разве что на сегодня, "Новатек" делает исключение и то в канале (бумаги моего портфеля). Здесь открыты крупные позиции, таким позициям (участникам) сложно развернуться, при низкой ликвидности целиком на рынке (про ММВБ, возможно отсюда и такие рекомендации), следовательно, если сказали будем расти, другие варианты просто отсутствуют, будем расти, а позиции крупный игрок умеет защищать.
Торговать можно без всяких индикаторов, используя графический свечной анализ. Мне нравится еще добавлять функции роста, для отражения градиента. Удержание позиции резко отличается от спекулятивных стратегий. Если рынок отразил линейный тренд, то стоп всегда бежит впереди уровня позиции, тем самым защищая предыдущей набор, для Лонга выше цены позиции, для шорта ниже цены позиции. Усреднение применяется для добора позиции, ну а если оказался не прав лучше выйти из позиции, так как ни каких денег не хватит для усреднения убыточной позиции (именно про такие ситуации шутят, что они погубили ни одного трейдера). По сути этот подход наиболее комфортен, не отнимает много времени, с точки зрения шансов наиболее вероятен. Для алгоритмической торговли набор индикаторов понятен, частота обращения к данным низкая, ребалансировка минимальна, где защищать позицию понятно, а сколько забирать отвечает господин рынок.
А вот размер нужно считать, это одна из основных задач рефакторинга, это прежде всего про эффективность позиции на месяцы и в целом про эффективность инвестиции. Вот и обозначен основной вопрос инвестиций!
--- Функциональный стиль: кольцевой буфер
-- @param size_power_of_two степень двойки (например, 3 → буфер на 8 элементов)
function CreateRingBuffer(size_power_of_two)
local size = 1 << size_power_of_two -- 2^n
local mask = size - 1
local data = {}
for i = 1, size do
data[i] = 0
end
local head = -1
local count = 0
local buffer = {}
--- Добавление элемента
function buffer:add(value)
head = (head + 1) & mask
data[head + 1] = value
count = math.min(count + 1, size)
end
--- Получение элемента (1 - последний)
function buffer:get(index)
if index < 1 or index > count then return nil end
local pos = (head - index + 1 + size) & mask
return data[pos + 1]
end
--- Последний элемент
function buffer:last()
if count == 0 then return nil end
return data[head + 1]
end
--- Первый элемент (самый старый)
function buffer:first()
if count == 0 then return nil end
local pos = (head - count + 1 + size) & mask
return data[pos + 1]
end
--- Количество элементов
function buffer:length()
return count
end
--- Очистка буфера
function buffer:clear()
head = -1
count = 0
end
--- Итератор для цикла for (новые → старые)
function buffer:iter()
local i = 0
return function()
i = i + 1
return buffer:get(i)
end
end
--- Преобразование в таблицу (новые сначала)
function buffer:toTable()
local t = {}
for i = 1, count do
t[i] = buffer:get(i)
end
return t
end
--- Проверка на заполненность
function buffer:isFull()
return count == size
end
return buffer
end
TGB, Да вы целиком правы, спасибо за уточнение! Производительность в Lua 5.4.1 реально зависит от использования встроенных операторов, и побитовая операция & становится явным лидером, когда дело операций с числами, являющимися степенями двойки.
«При 300% прибыли нет такого преступления, на которое не рискнул бы капитал» К. Маркс.
И опять двойственность, или почему побитные операции 2^n предпочтительнее!
В Lua оператор % — это остаток от деления (modulus). Он возвращает остаток от деления одного числа на другое. И остаток от деления на степень двойки можно сделать с помощью побитовой маски. Если нам нужен остаток x % 2^n, то это равносильно тому, что мы обнуляем все биты выше n-го. Для этого используем побитовое И (bit.band): bit.band — чистая побитовая операция на целых, выполняется через С-библиотеку, работает на порядок быстрее, особенно если много итераций.
Этот метод работает только для делителей, являющихся степенью двойки 2^n (2, 4, 8, 16, …).
* Если делитель — степень двойки, используем bit.band(x, 2^n - 1). Это и быстрее, и чище в контексте масок. * Если делитель любой, лучше оставить обычный % или написать функцию на математику.
В своей практике, вспомнив высказывание К. Маркса, тоже не удержался, и перевел кольцевой буфер на bit.band. Кольцевой буфер как раз классический случай, где % заменяется на bit.band. И именно здесь ускорение становится реально заметным, потому что операция повторяется на каждом обращении к буферу. Простая замена оператора % (modulus) на bit.band приводит к приросту в скорости от 2 - 10 раз! Как здесь не вспомнить К. Маркса.
Добрый день Anton Belonogov, Понял в чем проблема, раз наблюдается только у меня, значит где то в моем скрипте переопределение, то есть моя невнимательность, скорее всего. Извиняюсь за допущенную оплошность, вопрос снимается. Так же хочу отметить, что терминал последних версий стал намного стабильней, на одном ноутбуке весит три от разных брокеров, один из очень сильно нагружен, уже и не припомню когда были падения (3 раза постучал по дереву ). В любом случае Вам спасибо за разъяснения.
Добрый день Anton Belonogov, Более чем описано выше прокомментировать не могу. Скрип с того времени больше, не работал, да и что там, чистый вызов функции. Единственное что могу добавить, время вечерней сессии оно отражено в логах, если и это отдано на откуп брокеру, то север был Сбера.
Рассуждая взаимодействии результат / процесс, собственно про эффективность, вспомнил еще один основополагающий принцип механики. Принцип наименьшего действия (ПНД - "Ленивиц").
Принцип наименьшего действия — это концепт взятый из физики, который объясняет, как системы природы выбирают свой путь или эволюцию, исходя из минимизации определённого количества, называемого "действием". Этот принцип лежит в основе множества физических теорий, включая механику, оптику и квантовую теорию.
Логически, принцип наименьшего действия можно трактовать как следствие принципа оптимальности. Он говорит о том, что в естественных процессах, в большинстве случаев, природа "выбирает" такой путь, который оптимален по каким-то критериям (в данном случае, минимизации действия). Это не обязательно означает буквальную минимизацию, а скорее означает, что система должна следовать пути, который приводит к экстремальному значению действия: * минимальному, если система находится в стабильном состоянии, * или максимально эффективному, если система переходила от одного состояния в другое.
Таким образом, принцип наименьшего действия в логическом плане можно рассматривать как правило минимизации затрат энергии или времени. Здесь "затраты" — это не буквальные физические затраты, а Меры, которые представляют собой оптимальные пути или процессы.
Хотя на первый взгляд принцип наименьшего действия может показаться чисто математической абстракцией, его универсальность и его применение в самых разных областях подтверждают важность этого концепта. Представляется наиболее интересны подход применения в квантовой механике. Здесь принцип наименьшего действия имеет важное значение, он уже трактуется через путь, который минимизирует сумму всех возможных путей. (В квантовой механике возможны и другие варианты путей, не всегда связанные с минимизацией в классическом смысле). Частица не двигается по единственному пути, а скорее может следовать нескольким путям, каждый из которых имеет свою вероятность.
Разве это не что не напоминает с точки зрения экономики и финансовой математики?
Финансовая математика и оптимизация. В финансовой математике аналогичные принципы оптимизации и минимизации затрат могут быть использованы для поиска наилучших стратегий, таких как минимизация риска, максимизация прибыли или оптимизация портфеля. Однако здесь "действие" не измеряется физически, а скорее через стоимость или ожидаемую прибыль.
Добрый день Nikolay, Вы отчасти правы, подсветив двойственное отношение процесс / результат.
1. О себе. Я не отношу себя к программистам, здесь более уместно высказывание "Я не волшебник, я только учусь!".
2. О Уязвимости. Бывает увлекаюсь откладывая результат, благо времени в распоряжении стало побольше. А саму уязвимость можно оценивать, с помощью двойственного отношение уязвимость = результат / процесс , свои соображения на этот счет выкладывал выше в постах (завел себе даже телеграмм - канал, оказалось удобно как записную книгу использовать).
3. О Подходе. Подход заключается в развитии идей модульности, асинхронности, много функциональности, универсальности, а главное надежности, торговой программы. Высказываясь публично, высказываю только свое мнение, стараюсь обосновано. Но речь ведь не обо мне.
4. О Процессе. Подход и идеи заложенные в hacktrade, получили у меня дальнейшее развитие, от самого Фреймворка остались лишь разве идеи. Версий программы действительно много. Каждая находка в программировании, находит отражение в программе, то что для специалиста обыденность, для меня целое открытие, просто выкладываю на обсуждение, перерабатывая свой код. К сожаление последнее время ни какого обсуждения?
5. О Результате. Результат есть последняя рабочая версия крутится в боевом режиме. Дело в том что не все устраивает в ней, а вопросы доводки, заключаются не только в программировании, поэтому идет поэтапное развитие усовершенствование, об этом и статья выше.
PS. Заметил, даже у опытных программистов сквозит не кое пренебрежение к использованию луа в чистом виде, оно ошибочно, это просто недопонимание специфики языка. Луа == таблица, работать нужно с таблицей == матрица, вектор, объект и тогда мир обретает всю полноту красок, оживает трехмерное пространство. Недочеты языка уходят на задний план. А в распоряжении создателя появляется широкий спектр возможностей.
Решительный рефакторинг или почему "Слабое зацепление" предпочтительнее использования глобальных переменных и "прямого взаимодействия"!
Покажу на своем примере. В своем подходе создания торговой системы, использую асинхронный подход, разделение ответственности выполнения задач, через выполнение их в отдельных корутинах (идея взята из hacktrade написано много постов).
Функция Robot() является ядром торговой системы. Это псевдоним основной корутины торгового робота, которая содержит огромное количество функционала. Вот не полный перечень ее задач: Инициализирует данные, переменные, алгоритмы и подключения. В бесконечном цикле (while WORKING_FLAG do): Получает и обрабатывает рыночные данные (котировки, стаканы, параметры инструментов). Вычисляет множество технических индикаторов и аналитических показателей и метрик на разных таймфреймах. Управляет рисками и рассчитывает размер позиции (проектирование позиции на основании полученной информации). Генерирует торговые сигналы на основе сложной логики, объединяющей результаты всех анализаторов. Управляет позициями и приказами на отправку ордеров на исполнение (открытие, закрытие, модификация), останавливая свое выполнение, передовая управление в главный цикл. Визуализирует состояние в таблице QUIK. Работает в нескольких режимах: автоматическая торговля (avto), тестирование (test), экспертный режим (expert).
Учитываем, что Robot() — это корутина, которая формирует условия на создание заявки и передачи управление обратно в главный цикл для исполнения ордера. Сфокусировал рефакторинг прежде всего на (Процессе А - формирование заявки). Это потребовало значительных усилий, но совершенно необходимо для создания надежной и поддерживаемой торговой системы.
Текущий код Robot() — это пример "большого шаблонного анти паттерна". Он обладает огромной функциональностью, но его монолитная и запутанная природа делает его крайне уязвимым к ошибкам и сложным для развития. Путь к исправлению лежит через решительный рефакторинг, направленный на разделение этого монолита на независимые, хорошо спроектированные модули.
Вот основные Проблемы варианта до рефакторинга: 1. Модули тесно связаны через глобальные переменные; 2. Изменение структуры данных ломает все модули; 3. Невозможно тестировать модули по отдельности; 4. Сложно отследить, кто и когда изменяет данные.
Сравнение подходов: ------------------------------|----------------------------------------|-----------------------------------------------| Аспект |Сильное зацепление |Слабое зацепление ------------------------------|----------------------------------------|-----------------------------------------------| Изменения |Ломает все модули |Ломает только интерфейсы Тестирование |Сложно тестировать |Легко тестировать Понимание |Сложно понять связи |Четкие зависимости Пере использование |Сложно пере использовать |Легко пере использовать -----------------------------------------------------------------------------------------------------------------------| Таким образом, слабое зацепление через четкие интерфейсы данных делает систему:
Устойчивой к изменениям - изменения в одном модуле не ломают другие;
Легкость тестирования - модули можно тестировать изолированно;
Понятный смысл - четкие контракты между модулями;
Гибкой к модернизации - легко заменять и модифицировать компоненты.
Вот мой путь, от "рабства на галерах", к оптимизации времени разработки скриптов в квик. Или почему рабочий конвейер создания и доведения скрипта до нужного состояния, необходимо минимизировать. Ответ очевиден чтоб "не отупеть". Да, да именно такие чувства пробуждает много разовое тыканья на одни и теже кнопки.
Что теперь. Код основного индикатора загружаем один раз в папке LuaIndicators в каталоге терминала, и забыли о нем!
Код
-- путь, по которому находится запускаемый скрипт Модуля.
local module_path = getScriptPath().."\\modules\\MultiplierModule.lua"
Settings=
{
Name = "***MultiplierIndicator",
scale = 0,
}
local M
function Init()
M = dofile(module_path)
M.init_run()
-- Используем настройки линий из модуля
Settings.line = M.settings.line
return #Settings.line
end
function OnCalculate(index)
return M.run(index)
end
Преимущества такого подхода: 1. Код основного индикатора стал проще, минимально корректно отвечает требованиям, и полностью отделен от логики! 2. Полная инкапсуляция - все настройки и логика в модуле! 3. Гибкость - можно легко менять количество и параметры линий работая только в модуле. 4. Согласованность - настройки линий соответствуют возвращаемым значениям. 5. Ну и конечно Масштабируемость - легко добавить новые линии.
В модуле: Все настройки и доводку логики до рабочего состояния производим в модуле, в том числе все настройки линий (M.settings.line) Для целей обновления параметров индикатора достаточно теперь, создать режим связанных окон, допустим "таблица текущих торгов" + "график", и перейти на другой тикер. Хорошего кода.
От любительского технического анализа, к уровню профессионального quantitative finance!
Или почему Дуальность (двойственность) - это основополагающий принцип и не только в логике и математике но и в трейдинге. "Дуальность (двойственность) — знание, которое основано на принципах противоположности. Но это не деление мира на два полюса, а неразделимая связь двух противоположных начал. Если не будет одного полюса, то не будет и другого".
Применение. Большинство классических индикаторов технического анализа используют техники, основанных на аддитивных вычислениях (аддитивной логике): средняя доходность, разница цен, арифметическое усреднение. Это удобно, но не совсем то, неправильно, если мы хотим реально понять поведение цены, капитала. Именно за этот подход часто слышишь критику или даже отрицание технического анализа в трейдинге.
Альтернативный этому подходу - мультипликативный подход. Этот переход делает систему более строгой, логически цельной и экономически осмысленной. В своей "quantitative finance" применяю подход — мультипликативный, основанный на HPR (Holding Period Return) и геометрической средней.
Зачем и почему мультипликативный подход?
1. Стационарность. Стационарность означает, что статистические свойства (среднее, дисперсия) не меняются во времени. Почему важно?
Цены сами по себе — нестационарные (они могут расти от 10$ до 1000$ и выше).
А вот доходности в виде HPR** (например, «рост на 2% за день») стационарны: процентные изменения распределяются схожим образом и в 2010-м, и в 2025-м.
Это даёт возможность применять математику корректно (модели, прогнозы, статистику).
2. Сплиты и корпоративные события. "Сплит" — деление акций компании: например, 1 акция по 1000$ превращается в 10 акций по 100$. Формально цена упала в 10 раз, но капитал инвестора не изменился. Если считать «разницы цен», мы получим ложный обвал. Но если работать через HPR, то процесс корректно учтёт изменение (HPR = 1).
3. Компаундинг— эффект «сложных процентов». Доходность в каждый следующий период считается на увеличенный или уменьшенный капитал. Пример:
День 1: +10% > капитал вырос с 1000 до 1100.
День 2: +10% > теперь рост идёт от 1100, а не от 1000 > итог = 1210, а не 1200.
Арифметическое усреднение (например, просто среднее доходности = 10%) игнорирует компаундинг. Только геометрическая средняя даёт правильный результат — «средний множитель роста» за период.
4. Метрика HPR. HPR = Final Value / Initial Value.
HPR = 1 > капитал не изменился.
HPR > 1 > рост (например, 1.05 = рост на 5%).
HPR < 1 > падение (например, 0.90 = падение на 10%).
Это просто удобно. Нет проблем с «нулевой ценой» (акция может стоить 0, но HPR всегда > 0). Универсальная метрика для любых активов, таймфреймов и событий. Легко переводится в доходность: Return = HPR - 1.
Преимущества мультипликативного подхода.
Стационарность: статистические свойства не «дрейфуют», а значит, можно применять строгую математику.
Сравнимость: разные активы и стратегии измеряются в одной метрике.
Экономический смысл: HPR напрямую связан с изменением капитала.
Автомасштабирование: метрики автоматически подстраиваются под волатильность.
Совместимость с управлением капиталом: идеальная база для методов Винса (Optimal f, Kelly).
В заключении: Переход от аддитивного к мультипликативному анализу — это не косметика, а смена парадигмы:
В аддитивном подходе — иллюзия доходности и искажённые риски.
В мультипликативном подходе — корректная математика, единая метрика и прозрачная связь с ростом капитала.
Экономический смысл:
В аддитивной логике мы думаем категориями «прибыль против убытка».
В мультипликативной логике мы видим единую систему, где рост и падение — два направления одного процесса.
Это и есть проявление двойственности: Не «два мира», а одно пространство. Не «линейная сумма», а множитель, который может быть больше или меньше 1. Двойственность в quantitative finance проявляется через мультипликативность. Прибыль и убыток — это не противоположные сущности, а два состояния одного процесса, описываемого единой метрикой HPR. В эту концепцию отлично вписывается fuzzy logic. Дуальность в нечеткой логике. В fuzzy logic (нечёткой логике) используют функции принадлежности, где одна и та же шкала отражает и «истину», и «ложь», но с разной степенью принадлежности.
Это и есть по моему мнению настоящий "quantitative finance" — строгая, самосогласованная система, лишённая противоречий, с ясной экономической интерпретацией.
Немного пишу на луа скрипты для квик, и проблема возникает при тестировании и исправлениях в скрипте - постоянной загрузки обновлённого скрипта. Очень не удобно реализовано, в квик, как на конвейере тыкаешь одни и те же кнопки совершая одни те же операции.
Задача стала как моно оптимизировать процесс обновления скриптов в квик. Если для индикаторов алгоритм нашелся сразу сам собой, заключается в обработке функции в обработчике, один раз загрузив обработчик на график, все изменения проводить в функции расчета индикатора, а режим связанных окон позволяет при смене инструмента обновлять все расчёты индикатора. Данный подход значительно сократил конвейер, время на редактирование, а главное раздражение от бесконечного однообразия.
Что то подобное хотелось собрать для более сложных торговых алгоритмов, прийти к базовой архитектуре скрипта - модульному построению. Задача все та же уйти от однообразных операций, но повышалась сложность значительно расширялась сама задача. Требования к структуре:
1. Четкое разделение по функциональности; 2. Легко добавлять новые модули и группы; 3. Централизованное управление модулями; 4. Строгий контроль глобальных переменных; 5. Четкая структура для документации; 6. Удобная организация тестов.
Такая структура обеспечивает легкую поддержку в будущем, профессиональную организацию проекта, а главное избавляет от бесконечной переделки торговой системы, так как модули могут использоваться неоднократно. Четко обозначилась еще одна важная структура - технологическая, отвечающая за подержание работоспособности самой системы, а это уже огромный шаг к надежной автоматической системе.
Не пугайтесь, самому страшно. Вот базовая архитектура моего проект при таком подходе.
Принципы написания кода Lua для Квик (торговый терминал QUIK).
При создании индикатора, написании кода Lua для Квик, пришел к выводу необходимости учета несколько важных аспектов, направленных на улучшение производительности, точности расчетов и адекватности реакции на изменения рынка. Каждый принцип по полочкам, детально:
А). Буферизация.
Буферизация данных — это процесс накопления информации для последующего использования или анализа. В контексте торговли с использованием Lua в QUIK буферизация может быть полезна для:
Снижения частоты запросов к API (например, запрос котировок, данных по счету).
Применения накопленных данных для более точных расчетов, например, для вычисления скользящих средних.
Эффективного хранения исторических данных, если вам нужно просматривать прошлые значения индикаторов, цен и объемов.
В коде Lua это можно реализовать через массивы или таблицы, которые накапливают данные о ценах или индикаторах за определенный период. Далее эти данные могут быть обработаны для получения сигналов или индикаторов.
Б). Адаптивность периода или окна расчетов.
Это важно, для того чтобы расчеты индикаторов или других метрик автоматически адаптировались к текущим рыночным условиям. Это можно сделать, например:
Использовать изменяющийся период для расчетов (например, для скользящих средних, полос Боллинджера) в зависимости от волатильности или тренда на рынке.
Можно создать динамическое окно, которое подбирает оптимальный период для расчета индикаторов на основе текущей рыночной ситуации.
В Lua это можно организовать с помощью вычисления метрик, которые изменяются в зависимости от волатильности или других рыночных параметров. Например, вычисление скользящей средней может быть более чувствительным при повышенной волатильности и наоборот.
В). Фильтрация и сглаживание с уменьшением лага.
Фильтрация и сглаживание данных с уменьшением лага — это важная задача при расчетах для избегания запаздывающих сигналов. Возможные способы:
Применение фильтров, таких как экспоненциальное сглаживание (EMA) или алгоритм Калмана, которые уменьшают лаг при обработке данных, позволяя быстрее реагировать на изменения.
Использование фильтрации по коэффициентам сглаживания, чтобы адаптировать поведение индикатора к быстроменяющимся данным.
Для этого нужно тщательно выбирать параметры фильтра и протестировать его работу на различных рыночных сценариях.
С). Мультипликативность в расчетах двойственных отношений.
Этот принцип включает в себя использование мультипликативных факторов для анализа и расчетов между двумя взаимоотношениями. Например:
Если индикатор или метрика для анализа трейдера зависит от множества других факторов, то их можно использовать в качестве множителей для корректировки сигналов.
Пример: если показатель волатильности увеличивается, он может умножать другие показатели, такие как величина стоп-лосса или размер позиции.
В Lua можно использовать формулы, которые учитывают такие множители, и корректировать расчеты с их учетом. Но главное здесь, мультипликативность в расчетах, позволяет применять, в этих расчета геометрическую среднею, как не линейный фактор.
Д). Применение метрики HPR (Holding Period Return) вместо доходности при расчетах индикаторов.
В отличие от стандартной доходности, которая вычисляется как разница между текущей ценой и ценой покупки, HPR учитывает стоимость активов на протяжении определенного периода. Это может быть полезно для:
Учет промежуточных дивидендов, сплитов, и других корпоративных событий.
Применение к позициям с разными временными горизонта.
В коде это можно реализовать через переменные, которые отслеживают цену покупки и текущую цену, а также время, прошедшее с момента покупки, чтобы правильно вычислить HPR. Этот подход избавляет в вычислениях от 0, и легко преобразуется в доходности HPR - 1.
Е). Применение доходностей и правила 3 сигма при определении риска и цели
Использование стандартного отклонения для оценки риска является часто используемым моментом для определения «нормальных» и «аномальных» значений в торговле. Правило 3 сигма гласит, что в нормальном распределении 99.7% значений должны попадать в интервал в пределах 3 стандартных отклонений от среднего.
nikolz написал: Про производительность у Вас вообще ерунда написана.
Согласен: в классическом определении производительность труда = выпуск продукции / затраты труда. Если я в примере некорректно связал это с коэффициентами «товар/деньги» — это моя ошибка. В нашем случае корректнее говорить не о производительности труда, а о рентабельности или ценовой структуре (доля себестоимости в выручке).
Таким образом, цена говорит вам, где вы сейчас находитесь, а ценность (КПД) показывает, насколько далеко вы сможете уехать и пережить ли дорожные испытания.
Учебники экономики фокусируются на спидометре (цене, объёмах). Данный подход даёт вам диагностический сканер для двигателя вашего бизнеса.
nikolz написал: А чем "ценность" товара отличается от цены товара ?Цена товара - говорит, что 1 единица товара дает 100 руб выручки. Т е по смыслу, тоже самое что и придуманная вами "ценность" товара.
Очень справедливое замечание. Давайте аккуратно разберёмся с терминами и математикой, без "придумывания" новых смыслов. Первый раз я с понятием ценность лично столкнулся в работе А, Эльдара о аккуратненько ввел понятие не заделав пояснений, второй принципиальный у Ральфа Винса. Мне тоже изначально показалось некой надуманностью. Обо всем и по порядку.
Цена товара — это объективная, фиксируемая характеристика: сколько рублей нужно заплатить за 1 единицу товара. Формально: P = Выручка / Количество товара; Пример: 100 булок × 100 руб. = 10 000 руб. → Цена = 100 руб. за булку.
Ценность товара — это уже субъективная категория (экономическая теория, «полезность» ). Она не измеряется напрямую в рублях, а определяется тем, насколько товар удовлетворяет потребность потребителя.
цена = денежная мера;
ценность = мера полезности.
В математическом анализе лучше не путать эти термины.
Цена — это данность. Она как погода на рынке. Её можно наблюдать и подстраиваться, но нельзя контролировать напрямую.
Ценность в данном подходе (Язык Системы)
Это отношение Товар / Деньги. Это внутренний, системный параметр, который показывает, насколько эффективно производство преобразует товар в деньги.
Как определяется? Только внутренними процессами: производительностью труда, качеством сырья, организацией работы. Это объективная мера эффективности бизнеса как системы.
Ценность (в нашем понимании) — это КПД вашего двигателя. Аналогия: Цена - Спидометр (показывает текущую скорость); Ценность - Мощность двигателя (показывает потенциал автомобиля).
«Весы» можно корректно, переформулировать через классические экономические коэффициенты, и тогда не будет путаницы с терминами вроде «ценность», но я ставлю своей задачей вернуть Смыслы! Смыслы понятные даже бабушке решивший инвестировать.
nikolz, Не знаю такой школы, где припадают наука о смыслах и отношениях? Её аппаратом является не только математика чисел, но и математика форм, структур, пропорций и инвариантов.
1. Чем этот подход фундаментально отличается от учебников и почему он может быть мощнее?
Ключевое отличие не в примерах, а в самом типе математики и системе координат для анализа. Учебники экономики оперируют абсолютными величинами (объёмы, рубли, штуки) и линейными зависимостями (спрос падает при росте цены). Это язык количества. Данный подход оперирует безразмерными отношениями (Товар/Деньги, Спрос/Предложение) и их балансом. Это язык пропорций, структуры и качества.
2. Пояснение на Конкретной Математике Возьмём пример: Товар / Деньги. В учебнике: Это два отдельных показателя. Выручка 10 000 руб. и производство 100 единиц товара. Анализ линейный: «Надо производить больше, чтобы больше продать». В данном подходе: Мы сразу смотрим на отношение Товар/Деньги = 100 / 10 000 = 0.01.
2.1 Что это число на самом деле означает? Это коэффициент окупаемости или «ценность» товара в денежном выражении. Число 0.01 говорит, что 1 рубль выручки «обеспечен» всего 0.01 единицы товара. Это крайне низкая производительность труда или маржинальность. А если бы отношение было равно 1? Это означало бы идеал: 1 единица товара приносит 1 условную единицу денег. То система работала бы на 100% своей эффективности.
2.2 Сравните анализ: Учебник: «Мало товара -> надо производить больше». Данный подход: «Система обладает низкой эффективностью преобразования товара в деньги (КПД=0.01). Рост количества товара без изменения этого коэффициента бесполезен. Надо менять качество системы: повышать цену, переходить на более маржинальные товары, оптимизировать издержки». Это качественно иной вывод, основанный не на количестве, а на структурном соотношении.
3. Система Координат для Принятия Решений Мы строим универсальную систему координат для любого рынка. Использую квадрат состояний вписанный в единичную окружность. Рычажные весы — это не метафора, а математическая модель. Любое экономическое состояние можно точно позиционировать на этом графике, получив исчерпывающую диагностику.
3.1 Возьмем кризис перепроизводства (например, падение цен на нефть):
Товар/Деньги >> 1 (товара много, денег он приносит мало)
Спрос/Предложение << 1 (предложение сильно превышает спрос)
Точка на графике будет четко находиться в левом нижнем квадранте («Кризис»).
3.2 Возьмем «горячий» стартап на подъеме:
Товар/Деньги < 1 (денег (инвестиций) пока вложено больше, чем создано продукта)
Точка на графике будет в правом верхнем квадранте («Рост»).
Это не подбор примеров под теорию. Это классификация состояний системы на основе объективных измеряемых соотношений. Вы не игнорируете данные, а получаете их точный «диагноз».
4. Кому и для чего это реально нужно?
Владельцу малого бизнеса: Чтобы не просто видеть «упала выручка», а понимать какое именно соотношение нарушилось: упал спрос? стало невыгодно производить? увеличились долги? Это позволяет бить точно в причину, а не по симптомам.
Инвестору/Трейдеру: Чтобы оценивать не отдельные показатели компании (выручка, долги), а их системную сбалансированность. Компания с идеальными точками на этих весах — устойчива. Компания с точками в крайних положениях — кандидат на взлёт или банкротство.
Экономисту-аналитику: Чтобы строить нелинейные прогнозы. Если точка ушла в крайнее положение («перегрев» рынка), система по законам маятника будет стремиться качнуться назад. Это позволяет предсказывать коррекции рынка и кризисы.
Итог: Это не «вольная интерпретация», а прикладной системный анализ, переводящий экономику с языка абсолютных величин на язык структурных отношений и балансов. Он не заменяет учебники, а дает инструмент для синтеза их данных в целостную картину, понятную для принятия решений на любом уровне.
nikolz, Согласен с Вами, несколько сумбурно, но описываемая тема сложна, поэтому растянута на нескольких постах выше. Это абсолютно новый подход идеи концепции механики Г.Я. Зверева с развитием их М.И. Беляевым. Я лишь описываю прикладной характер использования в экономике и в частности трейдинге. На основе этих идей и логике построены две модели, торговые системы, отражающие взаимодействие: 1. Рынок / трейдер. 2. Рынок / Портфель.
Механика, о которой идет речь, выглядит немного сложной, постараюсь объяснить её понятным языком, так как вижу и понимаю.
1. Что такое сила? В классической механике сила — это как бы нечто первичное, что заставляет вещи двигаться. Например, когда вы толкаете мяч, сила заставляет его катиться. Но в механике Зверева сила не является чем-то основным. В этом подходе сила — это результат взаимодействия разных процессов, а не что-то самостоятельное. Представьте, что сила — это как следствие того, что два разных процесса (например, две "энергии") начинают взаимодействовать друг с другом. Сила появляется всякий раз, когда что-то нарушает баланс этих процессов. То есть, сама сила — это не "изначальная сущность", а нечто вторичное, что появляется в результате взаимодействия.
2. Что такое "поток"? Поток — это не то же самое, что вода, текущая по реке. Здесь под потоком понимается фундаментальное движение, основное "древнее" движение, которое лежит в основе всего бытия. Это не просто что-то, что течет, а движение, которое носит в себе потенциал для создания всего, что мы видим вокруг нас. Поток не является простым или однообразным. Он возникает как результат множества взаимодействий более фундаментальных сил. Это как если бы всё, что происходит в мире, являлось результатом сложных взаимодействий на более глубоком уровне.
3. Взаимодействие двух потоков — что происходит? Когда два потока взаимодействуют друг с другом, они могут создать нечто третье. Это взаимодействие напоминает сложение векторов в математике, когда два вектора (направления) создают третий, который несёт совершенно новое качество. Это как если бы два человека, работая вместе, создавали нечто гораздо более значимое и сложное, чем если бы каждый действовал по отдельности. В результате такого взаимодействия возникает новое качество — третья "сила", которая не сводится к простому сложению двух первоначальных потоков.
4. Резонанс как основа всего. Представим себе гигантский музыкальный инструмент, в котором все его части связаны между собой. Когда одна из частей начинает вибрировать, другие части начинают резонировать с ней. Эта вибрация и взаимодействие частей и называется "резонансом". Всё в мире также резонирует с другими частями. Масса, заряд, все свойства вещей — это результат того, как они "вибрируют" в этой общей симфонии мира. Каждое явление или объект, будь то частица или целое тело, не существует самостоятельно, а является частью общей гармонии. Это как музыка, где каждая нота и инструмент создают общий звук, который зависит от того, на каком месте в этом оркестре находится каждая нота.
Главная идея:
Поток — это основное движение, которое лежит в основе всего.
Взаимодействие потоков создаёт новое качество.
Резонанс с более общей "партитурой" мироздания определяет свойства объектов.
Таким образом, мы живем не в мире отдельных предметов, а в мире, где всё связано, взаимодействует и создаёт новые качества через сложные процессы. Классическая механика (Ньютон) объясняет, как частицы взаимодействуют с силами. А эта механика Зверева и Беляева предлагает новую парадигму, где всё объясняется через взаимодействия и паттерны (резонансные связи), а не через отдельные силы и частицы.
В этом подходе важно не то, что есть отдельные сущности, а то, как эти сущности взаимодействуют друг с другом, создавая новые свойства. Простыми словами: Это как оркестр, где каждый инструмент (сущность) играет свою роль, но важно, как эти инструменты взаимодействуют друг с другом, создавая целый симфонический спектакль.
На мой взгляд, продемонстрировать свойства записи пропорции выше, наглядней всего можно с помощью "Золотой пропорции", просто подставив значения в формулу и получая свойства. Об этом уникальном отношении (золотом сечении) написано много книг; напомню его определение, это отношение двух величин, при котором отношение большей части (a) к целому равно отношению большего к меньшему (b): (a + b) /a = a / b = φ ≈ 1.618
Золотое сечение — это особое отношение двух величин, при котором их соотношение обладает уникальными и не только c математической точке зрения, свойствами. Золотая пропорция, математически описывает гармонию, а также является основой для создания систем, которые обладают свойством саморегулирования. Золотое сечение — это механизм оптимизации и саморегуляции в природе, выражающий принцип самоподобия и поддержания баланса через внутреннюю и внешнюю гармонию.
Вот некоторые основные свойства этой уникальной пропорции: 1. принцип Самоподобие; 2. принцип Самодостаточности; 3. принцип Само нормирования саморегуляция или само балансировка.
Когда речь заходит о двойственности, симметрия и асимметрия часто оказываются двумя сторонами одной медали. Взаимосвязь симметрии и асимметрии в золотом сечении — это двусторонняя реальность, где на внешней гармонии строится скрытая, но столь важная асимметрия. Именно эта двусторонность отражает и математическую, и физическую природу мира.
Раскрываем Смыслы:
А). Диагональ 1/1 в записи рычажных весов выражает принцип меры: конвертацию одних свойств в другие. Она придаёт уравнению динамику — систему можно трактовать не только как статичную запись параметров, но и как модель процесса, где силы и расстояния компенсируют друг друга. В экономике аналогом служит закон спроса и предложения. Смысл этой диагонали выражает меру, меру конвертации одних свойств в другие (в том числе конвертацию цен).
Мера здесь становится центральной идеей, которая связывает все взаимодействующие системы в единое целое, устанавливая гармонию и равновесие. Это модель для анализа баланса между различными силами их величинами, но и также контроль изменения их свойств. Эта модель, символизирует баланс между прерывностью и непрерывностью в процессе изменений. Это как в квантовой механике принцип суперпозиция. Концепцию квантовой запутанности, по смыслу, означает, что системы, взаимодействующие друг с другом, могут быть неразделимы и их состояния можно описать лишь через их взаимосвязь.
Б). О смысле масштаба (уровне иерархии). Бинарные отношения имеют гиперкуб состояний 2^n, где n - это масштаб, вложенность процессов, их взаимосвязь, и их фрактальная природа. Каждый уровень иерархии в контексте трейдинга может быть связан с определенным временным масштабом (тайм фреймом). Каждый такой уровень может быть трактован как масштаб ценового движения, где динамика рынка на одном уровне может влиять на динамику рынка на другом уровне. И это отдельная большая тема, я лишь про состояния двойственных отношений.
2^0=1 - монада; 2^1=2 - проявление противоположных свойств; 2^2=4 - квадрат состояний; 2^3=8 - куб состояний, 8 - вершин, 6 - граней, переходы по которым образуют замкнутый цикл преобразований сложного отношения (из проекционной геометрии);
Куб состояний - это достаточная модель, чтоб описать все фазовые переходы бинарной системы, этой экономической модели. Таким образом, квадрат можно рассматривать как проекцию куба на плоскость — упрощённую модель. А куб уже способен отразить более сложные переходы и циклы.
Эти выше описанные принципы, применяемые в идеи создании прикладной системы саморегулирования. Системы, которая бы описывала и управляла динамикой процессов, таких как рыночные отношения и портфель инвестора. Не которые подходы данной идеи, уже демонстрировал на этой ветке. Тема конечно обширна и громоздка для данного форума, а алгоритмы положенные в код луа, относительно небольшие, показывают прекрасные торговые результаты на тестах. Есть еще несколько идей по оптимизации результатов и одна из них нечеткая логика в системе принятия решений. Всем удачи.
Артем написал: Что есть реально другой путь кроме удали-добавь индикатор? Например, при написании кода того же индикатора, он меняется по 10 раз в день, какждый раз я делаю удалил-добавил, можно как то иначе?
В режиме связанных окон (допустим таблица текущих торгов + график), при переходах с тикера на тикер, индикатор будет обновляться в месте с графиком, получая данные и пересчитывая значения. Также заметил в Вашем примере ошибки с типом данных, если на нем экспериментируете лучше поправить, пробелы в именах, линей меньше выводит.
nikolz, _ Ни о каком лучше или хуже речь не идет, речь о надежности, промышленной надежности. Мой пример реализован в модуле, то есть можно использовать в OnCalculate, так и в потоке main создавая псевдонимы функций.
Вот реализация для индикаторов
Код
function Init()
-- создаю псевдоним
local Wilder = dofile("E:\\cached.lua") -- getWorkingFolder() ..
f = Wilder.RSI_Indicator()
Wilder=nil
-- Задаю линии для вывода
Settings.line = {
{Name = "50", Color = RGB(24, 24, 24), Type = TYPE_DASHDOT, Width = 1},
{Name = "lineup", Color = RGB(240, 0, 0), Type = TYPE_DASHDOT, Width = 1},
{Name = "linedw", Color = RGB(240, 0, 0), Type = TYPE_DASHDOT, Width = 1},
{Name = "RSI", Color = RGB(0, 0, 255), Type = TYPE_DASHDOT, Width = 2},
--{Name = "trigger",Color = RGB(255, 0, 0), Type = TYPE_LINE, Width = 1},
--{Name = "signal",Color = RGB(055, 055, 055), Type = TYPE_HISTOGRAM, Width = 1}
}
return #Settings.line
end
function OnCalculate(I)
-- получаю расчеты из внутренней функции
local out = f(I, Settings)
-- вывод результатов
if out then
return 50, Settings.lineup, Settings.linedw, out.rsi , out.rsi1
end
return
end
В потоке main тоже самое, индексация через Size().
Замерять быстродействие? 1) в OnCalculate (в потоке терминала) плохой тон, да и что это дает, одно дело пустой терминал, совсем другое загруженных графиками в часы пик, это совсем другая задача. 2) в скрипте (в потоке main) делаю по умолчанию, замеряя метрики производительности для всей программы (высказывался про это, разбираясь с промышленной реализацией). Да и что измерять, если речь идет о статистических метриках, окно в 14 бар а лаг половину периода в этой реализации (Миг против Вечности). Собственно код должен быть рабочим и Вы все сами можете замерить и сравнить.
Повторюсь я лишил подсветил проблему надежности исполнения скрипта, те вопросы которые относятся к технологическим аспектам выполнения расчетов.
Вот алгоритм из примера выше: В публичной части (константы для приватной части) -- 1. Локальные утилиты для оптимизации -- Форматирование даты и времени -- Функция округления -- 2. Функции сглаживания -- 3. Состояние индикатора
Код
local cache = {
initialized = false,
last_index = 0,
history = {}, -- Хранилище для исторических значений
Configs = {
period = 14,
method = "SMMA",
max_history = 100
},
prev_price = nil
}
В приватной части: -- A. Обновление параметров -- D. Получение текущей цены закрытия -- E. Инициализация записи для текущего индекса -- F. Расчет изменения цены -- H. Расчет средних значений -- I. Расчет RSI -- K. Формирование результата в {} return {}
На проблему озвученную в первом сообщении, там же есть ответ, проблема в версии, все что нужно для нормального вывода, выбросить данную фикцию, получить таблицу и вернуть необходимое количество линий?
Не есть и другой вариант: ждать год пока ответит разработчик, следующие 2 года будет исправлять, а в новой выпущенной версии, какой ни будь "молодой талант" все опять грохнет. На мой взгляд, подход тупиковый! А в целях надежности исполнения вычислений, такие функции нужно уменьшать в коде, лучше совсем убрать.
Извиняюсь что опять вмешиваюсь, просто хочу подсветить параллельную нерешенную задачу. Решение лежит в плоскости создания - универсальной, технологической обвязки, в которою можно было бы не опасаясь загружать любой алгоритм и она с ним справлялась, выдавая на гора результат. Примерный алгоритм такой обвязки я привел в своем примере выше (мягко говоря не идеальный вариант), а хотелось чтоб профессиональное сообщество обсудило, не в соревновательном режиме, а в рамках сотрудничества, чтоб получить надежный публичный вариант. Все одна только польза!
Nikolay написал: Все же эта тема посвящена конкретной технической проблеме терминала.
Nikolay, Весь этот форум посвящён одной большой проблеме, если Вы думаете что устранив данную, не будет похожей, через некоторое время, я думаю мягко говоря Вы ошибаетесь.Думаю нужна профессиональная смекалка, или как тут выражался пользователь "покумекать", чтоб по крайней мере следующая проходила мимо.
Код который я выложил несет в себе две основные особенности. 1) Буферизация. (Зачем скажем 65 000 свечей если окно 14 бар?); 2) Своевременную очистку данных (Зачем скажем 65 000 свечей хранить, если окно 14 бар); ну и конечно момент обновлений и расчётов, зачем рассчитывать каждый тик, если квик с трудом обновляет данные за одну секунду?
Не берусь судить о том, что в очередной раз "изобрели и наваяли" Разработчики, хочу лишь добавить, что в версиях 12.*.*.* при входе в терминал по долгу читаются самописные луа индикаторы (значительно по долгу). Хотя допускаю, что это и моих рук дело, может быть?
Тема написания индикаторов на луа многократно обсуждалась и разбиралась на форуме, и тем не менее, нет внутренней уверенности, что реализация луа индикаторов как минимум оптимальна? Вот и я в очередной раз столкнулся с проблемой создания надежной реализации индикаторов при реализации подхода по Wilder (реализация индикаторов и стратегий). Собственно трудности вызывает не сам алгоритм расчетов, а особенности реализации скриптов луа в QUIK.
Задачу ставил следующую: 1) Скрипт должен использоваться без переделок, как в OnCalculate, так и в потоке луа; 2) Одинаково быстро работать на разных тайм фреймах; 3) Технологическое исполнение (правила написания) должны быть едины, выполняться принцип создания "по Образу и Подобию". Код через класс луа, требует доработки, и вызывает у меня некоторые сложности в реализации, хотя интуитивно на мой взгляд и более предпочтителен, так как хранит свое внутреннее состояние (инкапсулирует). Вот что получилось при использовании подхода с замыканием, код привожу ниже, там же см. в комментариях и порядок написания, единая технология написания скрипта, на мой взгляд логична?
Код
function Wilder.RSI_Indicator()
-- 1. Локальные утилиты для оптимизации
local math_abs = math.abs
local math_max = math.max
local math_min = math.min
local math_floor = math.floor
local string_format = string.format
-- Форматирование даты и времени
local get_date = function(td)
return td and string_format("%.4d%.2d%.2d", td.year, td.month, td.day) or "00000000"
end
local get_time = function(td)
return td and string_format("%.2d%.2d%.2d", td.hour, td.min, td.sec) or "000000"
end
-- Функция округления
local round = function(x, n)
n = n or 0
local mult = 10 ^ n
return x >= 0 and math_floor(x * mult + 0.5) / mult or math_floor(x * mult - 0.5) / mult
end
-- 2. Функции сглаживания
local smoothing = {
EMA = function(new_val, prev, period)
local alpha = 2 / (period + 1)
return alpha * new_val + (1 - alpha) * prev
end,
SMMA = function(new_val, prev, period, bars_count)
if bars_count <= period then
return (prev * (bars_count - 1) + new_val) / bars_count
else
return (prev * (period - 1) + new_val) / period
end
end
}
-- 3. Состояние индикатора
local cache = {
initialized = false,
last_index = 0,
history = {}, -- Хранилище для исторических значений
Configs = {
period = 14,
method = "SMMA",
max_history = 100
},
prev_price = nil
}
return function(I, F, ds)
-- A. Обновление параметров
if F then
cache.Configs.period = F.Period or cache.Configs.period
cache.Configs.method = F.Method or cache.Configs.method
cache.Configs.max_history = F.Max_History or cache.Configs.max_history
end
local period = cache.Configs.period
local method = cache.Configs.method
-- B. Проверка нового бара
local is_new_bar = I > cache.last_index
-- C. Очистка старых данных при новом баре
if is_new_bar then
cache.last_index = I
-- Удаляем устаревшие данные
local min_index = I - cache.Configs.max_history
for i = min_index - 10, min_index do
if cache.history[i] then
cache.history[i] = nil
end
end
end
-- D. Получение текущей цены закрытия
local current_price = Value(I, "C", ds)
if not current_price then
return {
d = "00000000",
t = "000000",
rsi = 50,
rsi1 = 50,
rsi2 = 50,
rsi3 = 50,
gain = 0,
loss = 0,
avg_gain = 0,
avg_loss = 0
}
end
-- E. Инициализация записи для текущего индекса
if not cache.history[I] then
cache.history[I] = {
price = current_price,
change = 0,
gain = 0,
loss = 0,
avg_gain = 0,
avg_loss = 0,
rsi = 50
}
end
-- F. Расчет изменения цены
local prev_price = cache.prev_price
if not prev_price then
-- Для первого бара используем текущую цену как предыдущую
prev_price = current_price
end
local change = current_price - prev_price
cache.history[I].change = change
cache.prev_price = current_price -- Сохраняем для следующего вызова
-- G. Расчет положительных и отрицательных изменений
local gain = math_max(change, 0)
local loss = math_max(-change, 0)
cache.history[I].gain = gain
cache.history[I].loss = loss
-- H. Расчет средних значений
if I == 1 then
-- Первый бар
cache.history[I].avg_gain = gain
cache.history[I].avg_loss = loss
else
local prev_entry = cache.history[I-1] or cache.history[I]
local bars_count = math_min(I, period)
if method == "SMMA" then
cache.history[I].avg_gain = smoothing.SMMA(
gain,
prev_entry.avg_gain,
period,
bars_count
)
cache.history[I].avg_loss = smoothing.SMMA(
loss,
prev_entry.avg_loss,
period,
bars_count
)
else -- EMA
cache.history[I].avg_gain = smoothing.EMA(
gain,
prev_entry.avg_gain,
period
)
cache.history[I].avg_loss = smoothing.EMA(
loss,
prev_entry.avg_loss,
period
)
end
end
-- I. Расчет RSI
local avg_gain = cache.history[I].avg_gain
local avg_loss = cache.history[I].avg_loss
local rs = (avg_loss > 1e-5) and (avg_gain / avg_loss) or 0
local rsi = 100 - (100 / (1 + rs))
-- Корректировка граничных значений
rsi = math_max(0, math_min(100, rsi))
cache.history[I].rsi = rsi
-- J. Получение предыдущих значений
local prev1 = cache.history[I-1] or {rsi = 50}
local prev2 = cache.history[I-2] or {rsi = 50}
local prev3 = cache.history[I-3] or {rsi = 50}
-- K. Формирование результата
local td = ds:T(I)
local Out = {
d = get_date(td),
t = get_time(td),
rsi = round(rsi, 2),
rsi1 = round(prev1.rsi, 2),
rsi2 = round(prev2.rsi, 2),
rsi3 = round(prev3.rsi, 2),
gain = round(gain, 4),
loss = round(loss, 4),
avg_gain = round(avg_gain, 4),
avg_loss = round(avg_loss, 4),
_cache = cache.history[I]
}
Wilder.Log( tostring(I)..') '.. Out.d ..' / '.. Out.t
..'; rsi = ' .. tostring(Out.rsi)
..'; rsi1 = ' .. tostring(Out.rsi1)
..'; rsi2 = ' .. tostring(Out.rsi2)
..'; rsi3 = ' .. tostring(Out.rsi3)
..'; gain = ' .. tostring(Out.gain)
..'; loss = ' .. tostring(Out.loss)
--..'; atr = ' .. tostring(Out.atr)
..'; avg_gain = ' .. tostring(Out.avg_gain)
..'; avg_loss = ' .. tostring(Out.avg_loss)
--..'; trend = ' .. tostring(Out.trend)
--..'; trend1 = ' .. tostring(Out.trend1)
--..'; trend2 = ' .. tostring(Out.trend2)
--..'; signal = ' .. tostring(Out.signal)
--..'; signal1 = ' .. tostring(Out.signal1)
--..'; signal2 = ' .. tostring(Out.signal2)
)--[[--]]
cache.initialized = true
return Out
end
end
Или почему русский язык (его остатки + вся совокупность языковой группы), является языком программирования природных операционных механизмов (самоорганизация, самосохранение, саморегулирование, самонормировка ...). Родной язык сохранил СМЫСЛЫ, то что без СМЫСЛА, бессмыслица == не родное!
Этот не большой пример, помогает проиллюстрировать этот подход. В арифметике существуют четыре основные операции (+, -, *, /): Операция 1) (+) Говорим СЛОЖИТЬ или прибавить. Сложить - смыслы что то упорядочить, сохранить (сложить на складе), прибавить что - то к чему - то. Операция 2) (-) Говорим Вычесть Отнять. Тут и комментировать нечего, отнять так отнять. Операция 3) (*) Говорим Умножить. Допустим, то что всех интересует в инвестициях - приумножить капитал. Ведь никто не говорит сложить капитал? Операция 4) (/) Говорим Делить или Отношение. Как ты ко мне относишься? Так формируем смысловой вопрос. Смыл операции делить комментировать излишни. Есть еще операция возведения в степень, но это собственно умножение. Да и четыре математических операций по смыслу далеко не четыре!
Сермяжная правда, или почему инвестиции - это при Умножение капитала, а следовательно ключевыми становятся операции при УМНОЖЕНИЯ и ОТНОШЕНИЯ! Выяснения отношения - проводим анализ, а умножение это процесс - созидания. Эти двойственные взаимно дополнительные отношения, есть не что иное, как главное звено системы. Выделяя главное звено, потяну за которое распутывается весь клубок взаимоотношений. Верно и обратное!
Имея двойственные отношения, записанные в виде закона РЫЧАГА, можно сделать математические преобразования и вернуть полную СМЫСЛОВУЮ запись уравнения математических весов. (М1 / 1)^(+n) = (1 / М2)^(-n), где M - выступает как момент силы; n - можно назвать уровень развития - степень иерархии. Именно так, с помощью математических весов, можно записать производящие функции природных операционных механизмов (генетический код), а это уже "Наивысшая Математика" и совсем другая тема!
В целях задачи анализа, интерес вызывает вторая часть этого уравнения, которая отражает внутреннее содержание или структуру (нет ничего больше 1, а единица это целое). То есть, определив главное звено системы, записав таким образом двойственные ОТНОШЕНИЯ, со всей математической строгостью, можно применять структурный анализ, на каждой ступени иерархии. А если рассматриваются взаимодополнительные ОТНОШЕНИЯ, то весы уже станут монадой, и можно со всей математической строгостью, применять весь тот исторический аппарат анализа и прогнозов сохранившихся знаний. Не только распутывать, но и строить новые генетические цепочки, делать прогнозы (СУДЬБЫ) для систем любой природы, используя математический аппарат "Наивысшей Математики". И это уже не философские аспекты Лейбница, а строгий математический аппарат "Наивысшая Математика", здесь вероятно правильней, сохраняя смыслы, назвать "ВЫСШЕЙ АРИФМЕТИКОЙ".
На помню что, момент силы выступает мерой по отношению к силе (или плечу рычага?), и всегда можно развернуть, уточняя детали. Тогда записи вида: Капитал = Деньги + Активы, Активы = Спрос на Акции + Предложение Денег ..., приобретают новые СМЫСЛЫ, а у нас появился новый дополнительный универсальный аппарат анализа и что не менее важно СОЗИДАНИЯ - "вычисление судьбы"!
Или как инженерный подход к рынку Уайлдера, превратил трейдинг из искусства в науку, введя стандартизированные метрики (ATR, ADX, SAR). Цитата Уайлдера (из интервью Forbes, 1980): «Рынок — не хаос. Это машина, и моя задача — найти её инструкцию по эксплуатации». Вот уже почти полвека назад, опубликована работа Уэллса Уайлдера «Новые концепции в технических торговых системах» (1978). Кто не знаком с формулами, которые до сих пор используются в алгоритмической торговле. Идеи легли в основу миллионов торговых роботов. Любая торговая платформа, включет эти индикаторы, как стандартный инструмент.
Вот несколько его принципов к анализу рынка. Рынок трактуется как механизм, где цена, объем и время — взаимосвязанные переменные. Задача трейдера — вывести «формулы» их взаимодействия. Отказ от традиционных методов анализа, визуальной интерпретации графиков, в пользу математически верифицируемых систем. Несмотря на акцент на математике, его системы требуют понимания рыночного контекста.
Почему Механика? Одной из основных концепций в механике является концепция РЫЧАГА. Математическая запись принципа действия рычага является тождество либо неравенство. Тождество (F₁ * d₁ = F₂ * d₂), выражает фундаментальное условие его равновесия в идеализированной модели. Это тождество лежит в основе понимания того, как рычаги позволяют нам умножать силу или изменять направление ее действия, и является одной из краеугольных концепций механики, известной еще со времен Архимеда.
Момент силы, тогда выражается M = F * d — и является МЕРОЙ действия силы.
Именно так записан Закон Спроса и Предложения в экономике, просто меняются переменные и смысл, а закон прежний - закон РЫЧАГА. Точно так же можно применять в любой сфере анализа, по этому принципу работает и финансовый рычаг, и валютные пары.
Судя по откликам и комментариям были "индусы" , но это уже не важно, а проверять видимо нужно все! Понятие Веры не из финансов. Быстрый поиск на просторах не дал нужного эффекта, друг у друга копируют перерисовывают и публикуют. Обратился к источнику, хотя моя версия электронной книги не очень удобна, но оно того стоило! 190 страниц без всякой "воды", одни выкладки и миллиметровка! "Да, были люди в наше время, Не то, что нынешнее племя: Богатыри — не вы!"
Сработал и принцип монады (взаимно дополнительные двойственные отношения) "нет худа, без добра", заприметил несколько интересных идей.
Сама ошибка банальна, но принципиальна, кто знаком с до историческими (до ПВМ) работами трейдеров (Ганн, Вайкофф вот и Уайлдер приверженец старой школы) по определению трендов, знает что кроме баров трендовых, есть бары поглощения и внутренние, собственно которые и не учтены при определениях направленных движений.
Еще одно что смущает, так это в каком варианте использовать истинный диапазон (TR), для нормализации данных, сглаживать или нет? В своем варианте я пока предпочитаю сглаживать, так как использование простого TR приводит к значительным выбросам.
На помню для чего так подробно разбираюсь с ADX? Интересуют инвестиционная алгоритмическая стратегия (ну или средний срок), а на этих временных интервалах, где дневной график выступает как 1 минутный, индикатор уже и в этой реализации дает отличные результаты. Когда ADX входит в резонанс с одним из направлений движений, это означает что у противоположной стороны заберут всю ликвидность, именно про эти ситуации говорят и пишут, "не стой на пути у паровоза"! За дело взялись большие деньги (Крупный игрок, а Маркет Мейкер за частую вынужден участвовать в противофазе), здесь входят инвестиционые фонды, банки и поддерживают свои позиции. Про эти ситуации говорят, дай прибыли течь!
Пару слов про индекс относительной силы (RSI), ранее как то я его не до оценивал, предпочитая стохастик как более очевидный. Но RSI с ADX, это дополнительная мощность в принятии решений, автор его спроектировал так что он является центростремительным в отличии от стохастика который гуляет по локальным минимумам / максимумам. Что бы сдвинут RSI в зоны 70 или 30 нужно очень сильно постараться! А выход из этих зон говорит об однозначно слабости стороны.
Вот и судите сами стоит такая стратегия и Уайлдер, чтоб пели про них "дифирамбы"?
ADX («Индекс направления движения усредненной цены»)
Индикатор ADX (Average Directional Movement Index) предназначен для определения направления движения среднего значения цены на основе сравнения двух индикаторов направленности
* +DI (положительного изменения цены) и
* -DI (отрицательного изменения цены),
построенных по 14 периодам.
По рекомендации автора индикатора Уэллса Уайлдера преобладание линии +DI над -DI является сигналом «покупать», и «продавать» если значение -DI поднимается выше значения +DI.
Вычисление:
ADXj = EMA (DXj , N), Где DXj вычисляется следующим образом:
DXj = |(+DIj - -DIj)| / (+DIj + -DIj) * 100
+DIj = EMA (+SDIj , N)
-DIj = EMA (-SDIj , N)
+SDIj = +DMj / TRj * 100 если TRj <> 0, иначе +SDIj = 0
-SDIj = -DMj / TRj * 100 если TRj <> 0, иначе -SDIj = 0
TRj = max(|HIGHj - LOWj|, |HIGHj - CLOSEj-1|, |LOWj - CLOSE j-1|)
+DMj = |HIGHj - HIGHj-1| если HIGHj > HIGHj-1, иначе +DMj = 0
-DMj = |LOWj-1 - LOWj| если LOWj < LOWj-1, иначе -DMj = 0
если +DMj > -DMj, то -DMj = 0
если -DMj > +DMj, то +DMj =0
если +DMj = -DMj, то +DMj =0, -DMj =0
где:
CLOSE — цена закрытия;
LOW — минимальная цена интервала;
HIGH — максимальная цена интервала.
Значения индикаторов +DI и –DI учитываются с двумя знаками после запятой.
Параметры настройки:
«Кол-во периодов» - количество периодов N для расчета MA.
«Метод» - метод расчета МА (Simple, Exponential, Vol.Adjusted, Smoothed), по умолчанию используется метод «Exponential».
«Цвет +DI» - выбор цвета линии +DI.
«Цвет -DI» - выбор цвета линии -DI.
Мало того что в вычислениях ошибка, так еще и "к верху тормашками" , видимо кто английскую школу окончил или индусов наняли. Но от этого нелегче. Не ужели все перепроверять нужно за ARQA Technologies? Вообще в приличных домах принято, если оригинальный алгоритм подвергается изменениям, хотя бы "пометочку" делать!
Самое главное, встроенный индикатор отлично располагается в нормированном поле. Возможно кто то знаком с проблемой и про комментирует, или разработчики внесут пояснения (разъяснения), что не так с алгоритмом?
Прогнозная зона графика, График цены или индикатора по оси времени можно сдвигать образуя прогнозную зону. Но как с ней работать с самописными индикаторами?
Вариант 1. "Редактирование настроек графика", "Диаграмма", позволяет сдвигать правый край графика на заданное количество баров. Тем самым как бы образуется прогнозная зона на графике относительно текущего значения.
Вариант 2. Вкладка "Дополнительно", сдвиг графиков, позволяет двигать график в обе стороны.
Но как с ними работать из луа, не понятно? Какие индексы применять? На мой взгляд, было бы отлично, если бы простой интеграцией можно было отрисовывать индикаторы в этой зоне. В общем понимания совсем нет, рад любой информации. Спасибо что откликнулись.
-- Получение значений индикаторов
local rsi_val = rsi(I, {period = period_rsi}, ds)
local adx_val, plusDI, minusDI = adx(I, {di_len = period_adx, adx_len = period_adx}, ds)
local ema_val = ema(I, {period = period_ema}, ds)
local price = C(I) or 0
-- Определение рыночной фазы
local market_phase
if adx_val > 25 and plusDI > minusDI
--and price > ema_val
then
market_phase = "uptrend"
elseif adx_val > 25 and minusDI > plusDI
--and price < ema_val
then
market_phase = "downtrend"
else
market_phase = "range"
end
-- Сигналы управления
local signal = 0
-- Правило 2: Не торгуем в флэте
if market_phase == "range" then
if position ~= 0 then
signal = -position -- Закрытие позиции
end
return signal
end
-- Длинные позиции
if market_phase == "uptrend" then
-- Сигнал на покупку (Правило 3)
if position <= 0 and
price > ema_val and
adx_val > prev_adx and
rsi_val < 75 then
signal = 1
end
-- Выход из лонга (Правило 4)
if position == 1 and
(rsi_val > 75 or adx_val < prev_adx) then
signal = -1
end
end
-- Короткие позиции
if market_phase == "downtrend" then
-- Сигнал на продажу (Правило 5)
if position >= 0 and
price < ema_val and
adx_val > prev_adx and
rsi_val > 25 then
signal = -1
end
-- Выход из шорта (Правило 6)
if position == -1 and
(rsi_val < 25 or adx_val < prev_adx) then
signal = 1
end
end
-- Обновление состояния
prev_adx = adx_val or 0
position = position + signal
-- Ограничение позиции [-1, 0, 1]
position = math.max(-1, math.min(1, position))
Прежде чем продолжить экспериментировать с фильтрами, нужна торговая стратегия для этих самых эксперементов, "велосипед будет старый", за основу возьму ТОРГОВЫЙ АЛГОРИТМ 1.0 (ВАЛЕНТИНА САВЕНКОВА) из Школы МосБиржи.
От туда же и правила, просто формализую для алгоритмической торговли:
[Правило 1. 3 фазы динамики цены: Растущий тренд ADX>25 +DI>-DI, Флэт (боковик) ADX<25 , Падающий тренд ADX>25 -DI>+DI. Правило 2. Флэт (боковик) ADX<25 не торгуем. Правило 3. Сигнал продолжения на покупку Price > Ema, Растущий тренд ADX>25 +DI>-DI, Сильный ADX (ADX[I]>ADX[I-1]. Правило 4. Выход из позиции Long сигналы RSI на продажу и слабый ADX (ADX[I]<ADX[I-1] Правило 5. Сигнал продолжения на продажу Price < Ema, Падающий тренд ADX>25 -DI>+DI, Сильный ADX (ADX[I]>ADX[I-1]. Правило 6. Выход из позиции Short сигналы RSI на покупку и слабый ADX (ADX[I]<ADX[I-1]. Правило 7. Для RSI: зона перекупленности >75; перепроданности <25; Выход из зон торговый сигнал.
В процессе тестирования будут меняться правила и условия, поэтому зафиксирую базовые особенности. Особенности реализации: --[[код стратегии для QUIK на Lua 5.4 (процедурный стиль). Все расчеты выполняются последовательно, -- состояние хранится в глобальных таблицах (или буферизация?), минимальные вычислительные затраты, локальное кэширование ценовых данных. Рекуррентные формулы для EMA и RSI, трекинг состояния через переменную position, защита от повторных входов, Четкие правила выхода. Визуализация, ? независимых графических серий, Цветовое кодирование элементов, Настройки графического интерфейса в QUIK: Сигналы отображать стрелками: AddSignal(index, signal > 0 and 1 or signal < 0 and -1 or 0) Добавить горизонтальные уровни для RSI: AddLevel(75, "Overbought", RGB(255,0,0)) AddLevel(25, "Oversold", RGB(0,255,0)) Добавить горизонтальные уровни для ADX: AddLevel(25, "Weakness", RGB(0,255,0))
Торговая стратегия на основе ADX, RSI и EMA. Правила входа/выхода, согласно условиям задачи см. выше. ТОРГОВЫЙ АЛГОРИТМ 1.0 (ВАЛЕНТИНА САВЕНКОВА) Школа МосБиржи. --]]
Древний не значит ненадежный! Спасибо, разобрался исходную версию, перевел на луа 5.4, оказывается все отрисовывает, видимо была какая то моя уже модернизация. Отличный индикатор!