//--- 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を適用してみては いかがでしょうか。
...
注文 数やポジション数など、必要な構造フィールドは1つで記入できるのに、なぜそこで多くのループが必要なのかわかりません。
不要なものは削除し、削除も削除しました。チケット単位で削除する必要はなく(それでも削除前に知る必要がある)、ループの中でインデックスによる正しい順序を見つけ、削除することができます。
そこで、注文を検索して削除するための関数がもう一つ必要 で、それは条件がある場合に呼ばれるはずですが、どのような条件なのか - あなたのコードに目を通していてもすぐには理解できませんでしたし、目を通している暇もありませんでした。必要な条件を言葉で 表現していただければ、削除の方法をお伝えします。
見ずに勝手に書いたので、注文数やポジション数を構造体に記入する関数に間違いがあるかもしれません - チェックしていません。
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%変動 した場合、例えばOPEN日がSlose日よりも1%多く変動している場合
の書き方を教えてください。
価格が1%変動した場合、OPEN日がSlose日よりも1%多いとします。
それは違う、今は1%が何に関連しているのかが明確になっている;)
Expert Advisor は、過去 X 本のバーの最小値と最大値をカウントし、その値で注文を出します。また、最大値の減少や最小値の増加があった場合は、該当する注文を削除し、新しいデータで開く必要があります。
設定価格とストップ、テイクアウトを新しいレベルに相対的に変更できるのに、なぜ削除するのですか?結局のところ、保留中の注文がなく、かつマーケットポジションがないときにのみ、保留中の注文を出すことになるのです。つまり、市場に保留中の注文が あり、対応する市場ポジションがない場合、保留中の注文の価格-設定価格を新しいレベルに、そのストップオーダー-をそれぞれ新しいレベルに変更すればよいのです。
毎回、MaxとMinの検出価格を覚えておく必要があります。もし現在見つかっているMaxの価格が以前のものより低ければ、保留中のBuyLimitを修正し、Maxの新しい価格を記憶させます。Min価格ならミラーリング。