Прошу помощи, в создании стандартного элемента кода, где будет
вестись проверка свободных средств, желательно с большой точностью.
Причем, я либо через массив, либо обычной строкой, буду передовать
валютные(ую) пары(у). Это проверка будет проверяться перед открытием
ордера.
- Создание и работа с проектом - Проекты и MQL5 Storage
- Исполнение по запросу - Открытие и закрытие позиций - Торговля - MetaTrader 5 для iPhone
- Установка в Mac OS - Для продвинутых пользователей - Начало работы
int start() { //---- int a; string para = "EURUSD"; double ask =MarketInfo(para,MODE_ASK); double lotsize =MarketInfo(para,MODE_LOTSIZE); double minlot =MarketInfo(para,MODE_MINLOT); a=(ask*lotsize/AccountLeverage()*minlot); if (AccountFreeMargin()<a) {Print ("Недостаточно средств на счете !!!"); return (0);} Print ("Para: ",para); //---- return(0); }При OP_BUY это выглядит где-то так.
А если валютная пара, кросскурс. То тогда как ???
DEan писал (а):
int start() { //---- int a; string para = "EURUSD"; double ask =MarketInfo(para,MODE_ASK); double lotsize =MarketInfo(para,MODE_LOTSIZE); double minlot =MarketInfo(para,MODE_MINLOT); a=(ask*lotsize/AccountLeverage()*minlot); if (AccountFreeMargin()<a) {Print ("Недостаточно средств на счете !!!"); return (0);} Print ("Para: ",para); //---- return(0); }При OP_BUY это выглядит где-то так.
Кто знает какова история этого, и почему так?
Истории не знаю, дошел своим умом:
Для селл надо вместо Аск надо использовать Бид, но поскольку Аск всегда будет больше, это не принципиально (погрешность небольшая, и не в опасную сторону).
double LotSize() { double lot_min = MarketInfo( _Symbol, MODE_MINLOT ); double lot_max = MarketInfo( _Symbol, MODE_MAXLOT ); double lot_step = MarketInfo( _Symbol, MODE_LOTSTEP ); double freemargin = AccountFreeMargin(); int leverage = AccountLeverage(); int lotsize = MarketInfo( _Symbol, MODE_LOTSIZE ); if( lot_min < 0 || lot_max <= 0.0 || lot_step <= 0.0 || lotsize <= 0 ) { Print( "LotSize: invalid MarketInfo() results [", lot_min, ",", lot_max, ",", lot_step, ",", lotsize, "]" ); return(-1); } if( leverage <= 0 ) { Print( "LotSize: invalid AccountLeverage() [", leverage, "]" ); return(-1); } double lot = NormalizeDouble( freemargin * MaximumRisk / leverage / 10.0, 2 ); lot = NormalizeDouble( lot / lot_step, 0 ) * lot_step; if ( lot < lot_min ) lot = lot_min; if ( lot > lot_max ) lot = lot_max; double needmargin = NormalizeDouble( lotsize / leverage * Ask * lot, 2 ); if ( freemargin < needmargin ) { Print( "LotSize: We have no money. Free Margin = ", freemargin ); return(-1); } return(lot); }
Для селл надо вместо Аск надо использовать Бид, но поскольку Аск всегда будет больше, это не принципиально (погрешность небольшая, и не в опасную сторону).
Integer писал (а):
Кто знает какова история этого, и почему так?
История банальна, не пропускали советник на конкурс без проверки
свободных средств.DEan писал (а):
int start() { //---- int a; string para = "EURUSD"; double ask =MarketInfo(para,MODE_ASK); double lotsize =MarketInfo(para,MODE_LOTSIZE); double minlot =MarketInfo(para,MODE_MINLOT); a=(ask*lotsize/AccountLeverage()*minlot); if (AccountFreeMargin()<a) {Print ("Недостаточно средств на счете !!!"); return (0);} Print ("Para: ",para); //---- return(0); }При OP_BUY это выглядит где-то так.
Кто знает какова история этого, и почему так?
Написал этот код и все ОК. ;)
А, в общем, у каждого своя точка зрения..
Написал, для общего случая. Жду ваших замечаний.
int start() { //---- double Lots = 1.0; int n = StringFind(Symbol(),AccountCurrency(),0); if (n>=0) { // Находим Валюту нашего счета в текущей валютной паре. //Print("Найдено ",AccountCurrency()," в паре ",Symbol()," n=",n); } else { // Не находим. Т.е. У нас кросс курс. рассмотрим для покупки. string Buy = StringSubstr(Symbol(),3); Buy = "USD"+Buy; double AskBuy = MarketInfo(Buy,MODE_ASK); //Print("не найдено ",AccountCurrency()," в паре ",Symbol()," Byu=",Buy); double Deneg = (MarketInfo(Symbol(),MODE_LOTSIZE)*Lots*Ask)/(AccountLeverage()*AskBuy); Print("Необходимо средст для открытия Длинной позиции по ",Symbol(),", ",AccountCurrency()," = ",Deneg); } //---- return(0); }проверил, пересчитал на бумаге вроде работает.
Проверку на наличие/отсутствие подстроки "USD" не делаете
или не надо? Последнее время тема постоянно на слуху :).
//+------------------------------------------------------------------+ //| _Open_BUY.mq4 | //| "СКРИПТЫ ДЛЯ ЛЕНИВОГО" | //| Скрипт открывает BUY на задаваемую часть FreeMargin | //| | //| Только для пар USDххх и хххUSD | //| | //| Bookkeeper, 2006, yuzefovich@gmail.com | //+------------------------------------------------------------------+ #property copyright "" #property link "" #property show_inputs // Если есть желание менять экстерны в процессе //+------------------------------------------------------------------+ extern int Interest = 35; // Выделить процент FreeMargin на позу extern int DistSL = 35; // StopLoss в пунктах extern int DistTP = 35; // TakeProfit в пунктах extern int Slippage = 7; // Проскальзывание extern bool StopLoss = true; // Ставить или нет extern bool TakeProfit = true; // Ставить или нет //+------------------------------------------------------------------+ void start() { int ticket=0; double SL=0,TP=0,Stake,MinLotDgts,Share,QQ=1.0; double MinLot=MarketInfo(Symbol(),MODE_MINLOT); double MaxLot=MarketInfo(Symbol(),MODE_MAXLOT); double LotStep=MarketInfo(Symbol(),MODE_LOTSTEP); int Dgts=MarketInfo(Symbol(),MODE_DIGITS); int Credit=AccountLeverage(); string FirstPart=StringSubstr(Symbol(), 0, 3 ); string SecondPart=StringSubstr(Symbol(), 3, 3 ); Share=0.01*Interest; if(SecondPart == "USD") QQ=Ask; else { if(FirstPart != "USD") Alert("OpenBUY: Who is that - ",Symbol(),"? I do not know..."); // :) } if(AccountFreeMargin()<MinLot*QQ*100000/Credit) { Alert("Open_BUY: No maney..."); return; } if(Share>1.0) Share=1.0; // Часть не бывает больше целого if(Share<0) Share=0; // (???) if(MinLot<0.1) MinLotDgts=2; else { if(MinLot<1.0) MinLotDgts=1; else MinLotDgts=0; } Stake=NormalizeDouble(AccountFreeMargin()*Share*Credit/100000/QQ,MinLotDgts); //Если выделенная часть депо будет меньше минимально допустимого лота, //поза будет открыта на минимальный лот if(Stake<MinLot) Stake=MinLot; //Если выделенная часть депо будет больше максимально допустимого лота, //поза будет открыта на максимальный лот if(Stake>MaxLot) Stake=MaxLot; RefreshRates(); if(StopLoss==true) SL=Bid-DistSL*Point; if(TakeProfit==true) TP=Ask+2*DistTP*Point; ticket=OrderSend(Symbol(),OP_BUY,Stake, // Не смотря на рефреш вместо Ask ставим: NormalizeDouble(MarketInfo(Symbol(),MODE_ASK),Dgts), Slippage, NormalizeDouble(SL,Dgts), NormalizeDouble(TP,Dgts), "",0,0,CLR_NONE); if(ticket<=0) Alert("Open_BUY LastError: ",GetLastError()); return(0); } //+------------------------------------------------------------------+Правильно или нет не знаю. Работает.
Я выложил очень простой вариант расчета маржевых требований
для форексных символов:
Очень простая функция расчета маржи для форексных символов.
Расчет автоматически идет в базовой валюте счета и учитывает
кредитное плечо.
Не работает для сложных видов курсов, которые не имеют прямого
пересчета в базовую валюту торгового счета.
//+------------------------------------------------------------------+ //| MarginCalculate.mq4 | //| Copyright © 2006, MetaQuotes Software Corp. | //| https://www.metaquotes.net/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2006, MetaQuotes Software Corp." #property link "https://www.metaquotes.net/" //+------------------------------------------------------------------+ //| Очень простая функция расчета маржи для форексных символов. | //| Расчет автоматически идет в базовой валюте счета и не работает | //| для сложных видов курсов, которые не имеют прямого пересчета | //| в базовую валюту торгового счета. | //+------------------------------------------------------------------+ double MarginCalculate(string symbol,double volume) { string first =StringSubstr(symbol,0,3); // первый символ, например EUR string second =StringSubstr(symbol,3,3); // второй символ, например USD string currency=AccountCurrency(); // валюта депозита, например USD double leverage=AccountLeverage(); // кредитное плечо, например 100 double contract=MarketInfo(symbol,MODE_LOTSIZE); // размер контракта, например 100000 double bid =MarketInfo(symbol,MODE_BID); // цена бид //---- допускаем только стандартные форексные символы XXXYYY if(StringLen(symbol)!=6) { Print("MarginCalculate: '",symbol,"' must be standard forex symbol XXXYYY"); return(0.0); } //---- проверка наличия данных if(bid<=0 || contract<=0) { Print("MarginCalculate: no market information for '",symbol,"'"); return(0.0); } //---- проверяем самые простые варианты - без кроссов if(first==currency) return(contract*volume/leverage); // USDxxx if(second==currency) return(contract*bid*volume/leverage); // xxxUSD //---- проверяем обычные кроссы, ищем прямое преобразование через валюту депозита string base=currency+first; // USDxxx if(MarketInfo(base,MODE_BID)>0) return(contract/MarketInfo(base,MODE_BID)*volume/leverage); //---- попробуем наоборот base=first+currency; // xxxUSD if(MarketInfo(base,MODE_BID)>0) return(contract*MarketInfo(base,MODE_BID)*volume/leverage); //---- нет возможности прямого перерасчета Print("MarginCalculate: can not convert '",symbol,"'"); return(0.0); } //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---- Print("Margin EURUSD: ",MarginCalculate("EURUSD",1.0)); Print("Margin USDCHF: ",MarginCalculate("USDCHF",1.0)); Print("Margin GBPCHF: ",MarginCalculate("GBPCHF",1.0)); Print("Margin CHFJPY: ",MarginCalculate("CHFJPY",1.0)); //---- return(0); } //+------------------------------------------------------------------+
Bookkeeper:
Проверку на наличие/отсутствие подстроки "USD" не делаете или не надо? Последнее время тема постоянно на слуху :).
Делал только для конкурса, поэтому не вникал =)Проверку на наличие/отсутствие подстроки "USD" не делаете или не надо? Последнее время тема постоянно на слуху :).
Для универсальной функции все будет сложнее )
komposter писал (а):
Для универсальной функции все будет сложнее )
Bookkeeper писал (а):
Проверку на наличие/отсутствие подстроки "USD" не делаете или не надо? Последнее время тема постоянно на слуху :).
Делал только для конкурса, поэтому не вникал =)Проверку на наличие/отсутствие подстроки "USD" не делаете или не надо? Последнее время тема постоянно на слуху :).
Для универсальной функции все будет сложнее )
Еще чуть-чуть, и может быть Ренат, чтоб отвязались, и этот вариант выложит... :).
Ренат, большое спасибо, куски добротного кода действительно очень нужны. Это для вас все легко и понятно...
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь