bool Tr2MT::UpdOrder(int n) // Только если есть тикет или угадываем
{
string str;
int i;
bool flag=false;
MTOrder ord_tmp={0};
ulong ticket=Orders[n].Ticket;
if(ticket==0)
{
if(!GuessOrdTicket(n))returnfalse; // Если угадываем - он будет в Orders[n].Ticketelse ticket=Orders[n].Ticket;
}
switch(FindOrder(ticket,Orders[n].Time+100000))
{
case ORD_FOUND: //изменён или просто проверка//update (sync) orderif(Orders[n].Price==OrderGetDouble(ORDER_PRICE_OPEN)) // Цена не изменилась
{
if(Orders[n].State==(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE)&&Orders[n].MTState!=ORD_NA)
{
if(Orders[n].Vol==OrderGetDouble(ORDER_VOLUME_CURRENT))
returntrue; // Не нужно сохранять состояние, можно сразу выйтиelse
Orders[n].Vol=OrderGetDouble(ORDER_VOLUME_CURRENT);
}
else
{
//Orders[n].State=(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE);
SetOrdState(Orders[n],(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE)); // Обнулит и TimeNotFoundif(Orders[n].Vol!=OrderGetDouble(ORDER_VOLUME_CURRENT))
Orders[n].Vol=OrderGetDouble(ORDER_VOLUME_CURRENT);
}
}
else// Цена изменилась
{
ord_tmp=Orders[n];
//ord_tmp.State=(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE);
SetOrdState(ord_tmp,(ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE));
ord_tmp.Price=OrderGetDouble(ORDER_PRICE_OPEN);
ord_tmp.Vol=OrderGetDouble(ORDER_VOLUME_CURRENT);
switch(Orders[n].Type)
{
caseORDER_TYPE_BUY:
caseORDER_TYPE_BUY_LIMIT:
if(ord_tmp.Price>Orders[n].Price) // Цена ордера увеличилась, перемещаем вверх (по массиву - вниз)
{
for(i=n;i>=0;i--)
{
if(i==0// Конец массива ордеров
|| ord_tmp.Price<=Orders[i-1].Price) // Следующий - по большей цене, вставляем перед ним
{
Orders[i]=ord_tmp;
break;
}
else
{
Orders[i]=Orders[i-1]; // Сдвигаем следующий элемент
}
}
}
else// Цена ордера умньшилась, перемещаем вниз (по массиву - вверх)
{
for(i=n;i<ArraySize(Orders);i++)
{
if(i==ArraySize(Orders)-1// Конец массива ордеров
|| Orders[i+1].Ticket==0// Следующий элемент пустой
|| ord_tmp.Price>Orders[i+1].Price // Следующий - по меньшей цене, вставляем перед ним
|| Orders[i+1].Price>Orders[i].Price) // Следующий - ордер уже на продажу
{
Orders[i]=ord_tmp;
break;
}
else
{
Orders[i]=Orders[i+1]; // Сдвигаем следующий элемент
}
}
}
break;
caseORDER_TYPE_SELL:
caseORDER_TYPE_SELL_LIMIT:
if(ord_tmp.Price>Orders[n].Price) // Цена ордера увеличилась, перемещаем вверх (по массиву - вниз)
{
for(i=n;i>=0;i--)
{
if(i==0// Конец массива ордеров
|| Orders[i-1].Ticket==0// Следующий элемент пустой
|| ord_tmp.Price<Orders[i-1].Price // Следующий - по большей цене, вставляем перед ним
|| Orders[i-1].Price<Orders[i].Price) // Следующий - ордер уже на покупку
{
Orders[i]=ord_tmp;
break;
}
else
{
Orders[i]=Orders[i-1]; // Сдвигаем следующий элемент
}
}
}
else// Цена ордера умньшилась, перемещаем вниз (по массиву - вверх)
{
for(i=n;i<ArraySize(Orders);i++)
{
if(i==ArraySize(Orders)-1// Конец массива ордеров
|| ord_tmp.Price>Orders[i+1].Price) // Следующий - по меньшей цене, вставляем перед ним
{
Orders[i]=ord_tmp;
break;
}
else
{
Orders[i]=Orders[i+1]; // Сдвигаем следующий элемент
}
}
}
break;
default:
returnfalse;
break;
}
}
SaveState();
//str=OrdString();//Log(str);break;
case ORD_HIST_FOUND: //исполнен || снят//delete orderif(!DelOrder(n))
returnfalse;
SaveState();
str=OrdHistString(ticket); // Уточнить
Log(str);
break;
case ORD_NOT_FOUND: //отправлен в историю?if(Orders[n].MTState!=ORD_NA)
{
Orders[n].MTState=ORD_NA;
Orders[n].TimeNotFound=TimeCurrent();
SaveState();
printf(__FUNCTION__, "Order not found, ticket:",IntegerToString(Orders[n].Ticket)," TimeNF:",TimeToString(Orders[n].TimeNotFound,TIME_SECONDS));
}
else
{
if(TimeCurrent()-Orders[n].TimeNotFound>60) // > 60 секунд не найден
{
if(!DelOrder(n))
returnfalse;
SaveState();
str="Order not found >60s "+IntegerToString(ticket)+"\n";
Log(str);
}
}
break;
default:
returnfalse; //не тот ордерbreak;
}
returntrue;
}
を使用して、必要な価格とチケット、そして場合によっては時間などを構造体または配列に格納し、追加後すぐに価格によってソートすることができます。資源別に見ると、あまり見ない人は同じか少し高く、よく見る人は覚えておくとよいでしょう。もちろん、100500件の注文がない場合は)それでは高すぎるかもしれません。一般に、構造体や多次元配列のソートは、残念ながら最初のインデックスに対してのみ解決されます。
同じインデックス、チケット、時間、価格を持つ複数の一次元配列を使うこともあります。また、必要なプロパティのインデックスで検索します。もちろん、松葉づえではあるが、明確に機能する。
を使用して、希望する価格とチケット、そしておそらく時間などの他のものを構造体または配列に格納し、価格によって追加した後すぐにソートします。資源別に見ると、あまり見ない人は同じか少し高く、よく見る人は覚えておくとよいでしょう。もちろん、100500件の注文がない場合は)それでは高すぎるかもしれません。一般に、構造体や多次元配列のソートは、残念ながら最初のインデックスに対してのみ解決されます。
同じインデックス、チケット、時間、価格を持つ複数の一次元配列を使うこともあります。また、必要なプロパティのインデックスで検索します。もちろん松葉杖ではあるが、これは非常に有効である。
私はこのようにしました。
配列は常にソートされており、必要な位置に新しいオーダーが挿入され、他のオーダーはシフトされ、オーダーが削除されると、シフトされる。
ただし、これはMT5での話
私はこのようにしました。
配列は常にソートされており、新しいオーダーは他のオーダーをずらしながら正しい位置に挿入され、オーダーが削除されるときはずれが生じます。
しかし、これはMT5での話です。
書き込み時、削除時、ソート時にずれるようなコードがあると良い。配列構造をフィールドごとにソートするのは、私にとって些細な作業ではありません。はい、シフトもです)。
書き込み、削除、ソートなどのシフトコードがあると良い。配列構造をフィールドでソートするのは、私にとって些細な作業ではありません。シフトも)。
そして、おそらく最も興味深いのは、その部分でしょう。
ありがとうございます。
悪くないですね。私は配列が嫌いです)))、配列でデバッグしないと一回目は絶対にうまくいきません。)))特にシフト、コピー、ソートは規則的でない)))ありがとうございます。
悪くないですね。私は配列が嫌いです)))、配列でデバッグしないと一回目は絶対にうまくいきません。)))特にシフト、コピー、ソートは規則的でない)))どんな道具も、それ自体が良いものです。
しかし、陰湿なオフバイエラーチェックと再チェック ))
古いコードを見直すということは、そういうことなのです
前バージョンの名残で、同じ欠点が2つあるのが見えます。
明らかなサブオプティマイゼーションを1つ。
そして、1つの時代遅れのデザイン。
設定で指定した利益または損失に達したときにポジションを すべて閉じ、設定で指定した方向にすぐに新しいポジションを開く、無料のMT5 Expert Advisorを探しています。どなたか、このスレッドのリンクを教えてください。
あるいは、オープンポジションがないことを確認したら、マーケットで1つのポジションをオープンし、クローズしないEAを知っているかもしれません。
MT4 1353
ログにはどのようなエラーが表示されますか?
コードが正しく動作する
MT4 1353
ログにはどのようなエラーが表示されますか?
コードは正しく動作します。
new "で作成したオブジェクトが終了時に破棄されないものがあるようです。