У нас есть свечи, цена последней.
В зависимости от паттерна можно ввести комбинацию на среднесрок по пинцету, дожи, 3 солдата и др.
Допустим х1-цена последней свечи. Х2=Х-1 цена предпоследней.
Тайминг варьируется 5мин,15, час,2 часа от времени сколько захочется рыбачить".
(Х1-Х2)/t значение и оно колеблется от 0÷90 град и 0÷270 град.
Sinφ нужно вычислить.
Arcsin((х1-х2) /t) = φ.
φ1 и φ2 угол предыдущий и сейчашний.
Можно по действующей свече, предыдущей в зависимости как робот прибыльней.
Нужно ещо х3 и х4 и тд.
Arcsin((х1-х2) /t) = φ1
Arcsin((х3-х4) /t) = φ2
'Сам кусок
If φ1>φ2 to b 'покупка
If φ1>φ2 to s' продажа
Send tranzaction
Сейчас не испытываю роботов, работало только на ку lua, не ку пайл языке квика.
Быстро, работало на параболике.
На угле не делал.
Этот угол нужно доработать и угол атаки вниз или вверх он не будет выше 90 и ниже 270 град!
Программисты есть и заходят придумывают роботов.
Свечки считает хорошо и ищет гэпы в квике языке lua.
Сейчас квик на 128 кбайт перешел и выше возможно на компе старом не работает, да и роботы на свечках проскальзывают и убытки.
2 — 3 цикла условных внутри для лучшей фильтрации.
На обычных индикаторах долго работает и цена сквизы делает приличные, не гармоничная волна сбивает весь заработок.
у тя обычный нелинейный фильтр… каких 100500
тебе надо найти источик альфы… а алго это просто способ торговли этой альфы…
Можно в кварт ре, бомжи углы находят легко кстати.
Можно и первый импульс отквадрировать, если это торговля на м5.
И делённое на количество свечей, если несколько. Получится аналог тангенса. Что синус, что тангенс — результаты будут идентичными.
Ну ладно не принялимпрограммисты блин теорию в практику..
Торгуйте индикаторы мацд, параболик, рси… и другие.
Лайт-версия идеи:
//+------------------------------------------------------------------+
//| Angle EA «Кусок робота алго» |
//+------------------------------------------------------------------+
#property strict
#property description «Угловой робот: сравнивает φ1 и φ2 из arcsin((x1-x2)/t)»
#include <Trade/Trade.mqh>
CTrade trade;
//--- константы
#define M_PI 3.14159265358979323846
//--- входные параметры
input int InpTimeframeMinutes = 5; // t в минутах (5, 15, 60 и т.д.)
input double InpAngleScale = 10000.0; // масштаб для (x1-x2) перед asin
input double InpLots = 0.1; // фиксированный лот
input bool InpTradeOnNewBar = true; // торговать только на новом баре
input ulong InpDeviation = 10; // проскальзывание в пунктах
input string InpComment = «AngleEA»; // комментарий к ордеру
//--- глобальные переменные
datetime last_bar_time = 0;
ulong last_trade_time = 0;
//+------------------------------------------------------------------+
//| Вспомогательные функции |
//+------------------------------------------------------------------+
// Преобразование минут в ENUM_TIMEFRAMES
ENUM_TIMEFRAMES MinutesToTimeframe(int minutes)
{
switch(minutes)
{
case 1: return PERIOD_M1;
case 5: return PERIOD_M5;
case 15: return PERIOD_M15;
case 30: return PERIOD_M30;
case 60: return PERIOD_H1;
case 120: return PERIOD_H2;
case 180: return PERIOD_H3;
case 240: return PERIOD_H4;
case 360: return PERIOD_H6;
case 480: return PERIOD_H8;
case 720: return PERIOD_H12;
case 1440: return PERIOD_D1;
case 10080: return PERIOD_W1;
case 43200: return PERIOD_MN1;
default: return PERIOD_CURRENT;
}
}
double GetPrice(int shift)
{
// используем цену закрытия
ENUM_TIMEFRAMES tf = MinutesToTimeframe(InpTimeframeMinutes);
double close = iClose(_Symbol, tf, shift);
// если не получилось с указанным ТФ, берем текущий
if(close == 0)
close = iClose(_Symbol, PERIOD_CURRENT, shift);
return close;
}
// нормализованный asin
double AngleFromDiff(double diff)
{
// diff = (x1 — x2)/t * масштаб
double x = diff * InpAngleScale;
// ограничим аргумент [-1,1]
x = NormalizeDouble(x, 8);
if(x > 1.0) x = 1.0;
if(x < -1.0) x = -1.0;
// MQL5: используем asin() вместо MathAsin()
double rad = asin(x); // радианы [-π/2, π/2]
double deg = rad * 180.0 / M_PI; // градусы [-90, 90]
return deg;
}
// получить текущую позицию
bool GetCurrentPosition(long &pos_type, double &pos_volume)
{
if(!PositionSelect(_Symbol))
return false;
pos_type = (long)PositionGetInteger(POSITION_TYPE);
pos_volume = PositionGetDouble(POSITION_VOLUME);
return true;
}
// закрыть позицию
bool ClosePosition()
{
if(!PositionSelect(_Symbol))
return true;
if(GetTickCount() — last_trade_time < 1000)
return false;
ulong ticket = (ulong)PositionGetInteger(POSITION_TICKET);
trade.SetDeviationInPoints(InpDeviation);
trade.SetAsyncMode(false);
bool res = trade.PositionClose(ticket);
if(res)
last_trade_time = GetTickCount();
return res;
}
// проверка возможности торговли
bool IsTradeAllowed()
{
if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
{
Print(«Торговля запрещена в настройках терминала»);
return false;
}
if(!SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE))
{
Print(«Торговля по символу запрещена»);
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| OnInit |
//+------------------------------------------------------------------+
int OnInit()
{
last_bar_time = 0;
last_trade_time = 0;
trade.SetDeviationInPoints(InpDeviation);
trade.SetTypeFilling(ORDER_FILLING_IOC);
Print(«AngleEA инициализирован. Масштаб: », InpAngleScale);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| OnDeinit |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
Print(«AngleEA остановлен. Причина: », reason);
}
//+------------------------------------------------------------------+
//| Основная логика |
//+------------------------------------------------------------------+
void OnTick()
{
if(!IsTradeAllowed())
return;
// торговать только на новом баре
if(InpTradeOnNewBar)
{
ENUM_TIMEFRAMES tf = MinutesToTimeframe(InpTimeframeMinutes);
datetime curr_bar_time = iTime(_Symbol, tf, 0);
if(curr_bar_time <= last_bar_time)
return;
last_bar_time = curr_bar_time;
}
// проверка количества баров
ENUM_TIMEFRAMES tf_check = MinutesToTimeframe(InpTimeframeMinutes);
int bars = iBars(_Symbol, tf_check);
if(bars < 5)
{
Comment(«Недостаточно истории: », bars, " баров");
return;
}
double t = (double)InpTimeframeMinutes;
if(t <= 0.0)
{
Print(«Ошибка: Timeframe <= 0»);
return;
}
// получаем цены
double x1 = GetPrice(1);
double x2 = GetPrice(2);
double x3 = GetPrice(3);
double x4 = GetPrice(4);
if(x1 == 0 || x2 == 0 || x3 == 0 || x4 == 0)
{
Comment(«Ошибка получения цен»);
return;
}
// расчет углов
double diff1 = (x1 — x2) / t;
double diff2 = (x3 — x4) / t;
double phi1 = AngleFromDiff(diff1);
double phi2 = AngleFromDiff(diff2);
// фильтр шума
if(MathAbs(phi1 — phi2) < 0.1)
return;
// получаем позицию
long pos_type = -1;
double pos_volume = 0.0;
bool have_pos = GetCurrentPosition(pos_type, pos_volume);
if(GetTickCount() — last_trade_time < 3000 && have_pos)
return;
string status = StringFormat(«phi1=%.2f phi2=%.2f | x1=%.5f x2=%.5f»,
phi1, phi2, x1, x2);
// логика торговли
if(phi1 > phi2) // покупка
{
if(have_pos && pos_type == POSITION_TYPE_BUY)
{
Comment(status + " | Long");
return;
}
if(have_pos && pos_type == POSITION_TYPE_SELL)
{
if(!ClosePosition())
{
Comment(status + " | Closing SELL...");
return;
}
Sleep(100);
}
trade.SetDeviationInPoints(InpDeviation);
if(trade.Buy(InpLots, _Symbol, 0, 0, 0, InpComment))
{
Print(«Buy executed. phi1=», phi1, " phi2=", phi2);
last_trade_time = GetTickCount();
Comment(status + " | BUY");
}
else
{
Print(«Buy error: », GetLastError());
}
}
else if(phi1 < phi2) // продажа
{
if(have_pos && pos_type == POSITION_TYPE_SELL)
{
Comment(status + " | Short");
return;
}
if(have_pos && pos_type == POSITION_TYPE_BUY)
{
if(!ClosePosition())
{
Comment(status + " | Closing BUY...");
return;
}
Sleep(100);
}
trade.SetDeviationInPoints(InpDeviation);
if(trade.Sell(InpLots, _Symbol, 0, 0, 0, InpComment))
{
Print(«Sell executed. phi1=», phi1, " phi2=", phi2);
last_trade_time = GetTickCount();
Comment(status + " | SELL");
}
else
{
Print(«Sell error: », GetLastError());
}
}
else
{
Comment(status + " | Neutral");
}
}
//+------------------------------------------------------------------+
Как отправная точка для исследований может и ок, но по тестам навскидку работы слишком много...
Поробуйте торгануть
роман 30,![]()
Спасибо, сами пробуйте)