//--- input variables inputdouble LotB=0.1; // Лот Buy inputdouble LotS=0.1; // Лот Sell inputint Pointsl=100; // StopLoss в пунктах inputint Pointtp=100; // TakeProfit в пунктах inputint NumBars=10; // Количество баров для поиска Max/Min inputint Magic=100500; // Magic
//--- global variables struct DataNumOrders { int buy; // Количество позиций Buy int sell; // Количество позиций Sell int buy_limit; // Количество ордеров BuyLimit int buy_stop; // Количество ордеров BuyStop int sell_limit; // Количество ордеров SellLimit int sell_stop; // Количество ордеров SellStop }; DataNumOrders numOrders; // Количество ордеров double lotB, lotS; int pointsl, pointtp, numBars; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ intOnInit() { numBars=(NumBars<1?1:NumBars>Bars?Bars:NumBars); pointsl=(Pointsl<0?0:Pointsl); pointtp=(Pointtp<0?0:Pointtp); double minLot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN); double maxLot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX); lotB=(LotB<minLot?minLot:LotB>maxLot?maxLot:LotB); lotS=(LotS<minLot?minLot:LotS>maxLot?maxLot:LotS); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ voidOnTick() { //--- заполним структуру количеством ордеров и позиций GetNumOrders(Symbol(),Magic,numOrders);
这个错误是在代码中更高的地方,在订单选择区。
我不碰其他的东西。
在任何情况下,你需要看到前面和后面的代码,而不仅仅是条件行。
...
你不能把代码清理干净,然后用SRC 正确粘贴, 对吗?
你 为什么不在尝试删除之前应用OrderSelect?
...
我不知道你为什么需要这么多的循环,因为你可以在一个结构中填写关于订单 和头寸数量 的必要结构字段。
我已经删除了不必要的东西,也删除了删除的内容。你不需要按票删除(你仍然需要在删除前知道它),而是在循环中按索引找到正确的顺序,并将其删除。
因此,我们还需要一个搜索和删除订单的函数,它应该在有条件的情况下被调用,但什么样的条件--我在翻看你的代码时没有马上明白,我也没有时间去看清楚。用文字描述必要条件,我们会告诉你如何删除。
我自己写的,没有看,所以在函数中可能有错误,用订单和头寸的数量填充结构--我没有检查。
input double LotB=0.1; // Лот Buy
input double LotS=0.1; // Лот Sell
input int Pointsl=100; // StopLoss в пунктах
input int Pointtp=100; // TakeProfit в пунктах
input int NumBars=10; // Количество баров для поиска Max/Min
input int Magic=100500; // Magic
//--- global variables
struct DataNumOrders
{
int buy; // Количество позиций Buy
int sell; // Количество позиций Sell
int buy_limit; // Количество ордеров BuyLimit
int buy_stop; // Количество ордеров BuyStop
int sell_limit; // Количество ордеров SellLimit
int sell_stop; // Количество ордеров SellStop
};
DataNumOrders numOrders; // Количество ордеров
double lotB, lotS;
int pointsl, pointtp, numBars;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
numBars=(NumBars<1?1:NumBars>Bars?Bars:NumBars);
pointsl=(Pointsl<0?0:Pointsl);
pointtp=(Pointtp<0?0:Pointtp);
double minLot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
double maxLot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
lotB=(LotB<minLot?minLot:LotB>maxLot?maxLot:LotB);
lotS=(LotS<minLot?minLot:LotS>maxLot?maxLot:LotS);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- заполним структуру количеством ордеров и позиций
GetNumOrders(Symbol(),Magic,numOrders);
//--- найдём максимальную и минимальную цены за bars свечей
double maxPrice=0.0; double minPrice=DBL_MAX;
for(int i=0; i<numBars; i++) {
double max_i=iHigh(Symbol(),PERIOD_CURRENT,i);
if(max_i>maxPrice) maxPrice=max_i;
double min_i=iLow(Symbol(),PERIOD_CURRENT,i);
if(min_i<minPrice) minPrice=min_i;
}
//--- выставим BuyLimit
if(numOrders.buy_limit==0 && numOrders.buy==0) {
double slB=(pointsl==0?0:NormalizeDouble(minPrice-pointsl*Point(),Digits()));
double tpB=(pointtp==0?0:NormalizeDouble(minPrice+pointtp*Point(),Digits()));
int ticketUP=OrderSend(Symbol(), OP_BUYLIMIT, lotB, minPrice, 3, slB, tpB, "", Magic, 0, clrRed);
if(ticketUP==-1) Print("ERROR OP_BUY");
else Print("OP_BUY OK");
}
//--- выставим SellLimit
if(numOrders.buy_limit==0 && numOrders.sell==0) {
double slS=(pointsl==0?0:NormalizeDouble(maxPrice+pointsl*Point(),Digits()));
double tpS=(pointtp==0?0:NormalizeDouble(maxPrice-pointtp*Point(),Digits()));
int ticketD=OrderSend(Symbol(), OP_SELLLIMIT, lotS, maxPrice, 3, slS, tpS, "", Magic, 0, clrBlue);
if(ticketD==-1) Print("ERROR OP_SELL");
else Print("OP_SELL OK");
}
//--- Тут должно быть удаление, но не понятно при каких условиях. Опишите их
//---
string a=(numBars==1)?"bar: ":IntegerToString(numBars,1)+" bar's: ";
Comment("Last ", a, "max ", DoubleToStr(maxPrice, Digits()), ", min ", DoubleToStr(minPrice, Digits()),".");
}
//+------------------------------------------------------------------+
//| Записывает в структуру количество позиций и отложенных ордеров |
//+------------------------------------------------------------------+
void GetNumOrders(string symbol_name, int magic_number, DataNumOrders &number_of) {
ZeroMemory(number_of);
for(int i=OrdersTotal()-1; i>=0; i--) {
if(OrderSelect(i,SELECT_BY_POS)) {
if(OrderMagicNumber()!=magic_number) continue;
if(OrderSymbol()!=symbol_name) continue;
if(OrderType()==OP_BUY) number_of.buy++;
if(OrderType()==OP_BUYLIMIT) number_of.buy_limit++;
if(OrderType()==OP_BUYSTOP) number_of.buy_stop++;
if(OrderType()==OP_SELL) number_of.sell++;
if(OrderType()==OP_SELLLIMIT) number_of.sell_limit++;
if(OrderType()==OP_SELLSTOP) number_of.sell_stop++;
}
}
}
//+------------------------------------------------------------------+
一般来说,你想用这个,对不起,令人毛骨悚然的代码做什么?
如何写出以下内容:
如果价格变化 了1%,比如说开放日比关闭日多了1%。
如何写出以下内容:
如果价格变化了1%,比如说开盘日比收盘日多了1%。
那是不同的,现在很清楚这1%是相对于什么而言的;)
专家顾问计算过去X个柱子的最小和最大值,并根据它们下订单。此外,如果有最大限度的减少或最小限度的增加,你需要删除相应的订单,并通过新的数据打开它。
当你可以修改设定的价格和相对于新水平的止损和退出时,为什么要删除?毕竟,你只有在没有挂单和没有市场头寸时才会下挂单。所以:如果市场上有一个挂单,而没有相应的市场位置,那么我们只需要修改挂单的价格--设定的价格到新的水平,其止损单--分别到新的水平。
每次你都需要记住最大和最小的发现价格。如果当前发现的Max的价格低于之前的价格,我们就修改待定的BuyLimit并记住Max的新价格。对于明码标价来说,镜子里的它。