I want to back test simple EA only BUY with MT4 Simple moving average 20 period
I see a buy signal and up to 3 orders are running
But when the price is below MA20 it does not automatically close the order
Help me to deal with
void OnTick()
{
double sma20 = iMA(Symbol(),PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE,0);
if(OrdersTotal()<3)
{
if(Low[1]>sma20)
{
bool ticket = OrderSend(Symbol(),OP_BUY,0.01,Ask,3,0,0,NULL,0,0,clrAliceBlue);
}
}
for(int i=0; i<= OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS))
{
if(OrderType()==OP_BUY)
{
if(Close[1] < sma20)
{
bool ticket_close = OrderClose(OrderTicket(),OrderLots(),Ask,3,clrAliceBlue);
}
}
}
}
}
To close order with type OP_BUY, you should use Bid price insted of Ask.
Check why order isn't close by GetLastError(), in your case it should looks like:
bool ticket_close = OrderClose(OrderTicket(),OrderLots(),Bid,3,clrAliceBlue);
if(!ticket_close){
Print("Error closing the order id: ", OrderTicket(), ", Error code: ", GetLastError());
}
Related
When closing a (selected) existing order with the api, and in that moment I try to get the closing price, sometimes (Perhaps one out of ten times) returns a price diferent from the one I can see in the history pool.
The code is something like this:
RefreshRates();
if(type == OP_BUY)
{
currentPrice = NormalizeDouble(MarketInfo(symbol, MODE_ASK), vdigits);
}
else if(type == OP_SELL)
{
currentPrice = NormalizeDouble(MarketInfo(symbol, MODE_BID), vdigits);
}
if (meetsRequirementsToClose(currentPrice))
{
desiredPrice = currentPrice;
// And then....
bool retVal = OrderClose(OrderTicket(), numLots, desiredPrice, currSlippage);
if (retVal)
{
this.reportClosePrice (myOrderId, OrderClosePrice(), desiredPrice, numLots, "closing");
return true;
}
}
The order was previously selected using SELECT_BY_POS in the pool MODE_TRADES.
anyone knows how to fix it?
Edited:
We have a broker that sometimes respects the requested price... sometimes not.
Disregarding the fact that we have to change broker for a more reliable one, we cannot rely on the requested price.
The deviation we see is greater than one hundred points, both for better and for worse prices than the real ones.
As sugested by #TheLastStark, the problem is solved selecting the order by its ticket just before closing.
The final code is something like:
RefreshRates();
if(type == OP_BUY)
{
currentPrice = NormalizeDouble(MarketInfo(symbol, MODE_ASK), vdigits);
}
else if(type == OP_SELL)
{
currentPrice = NormalizeDouble(MarketInfo(symbol, MODE_BID), vdigits);
}
if (meetsRequirementsToClose(currentPrice))
{
desiredPrice = currentPrice;
// And then....
int tickNum = OrderTicket();
bool retVal = OrderClose(OrderTicket(), numLots, desiredPrice, currSlippage);
if (retVal)
{
if (OrderSelect(tickNum,SELECT_BY_TICKET,MODE_HISTORY)== false)
{
//this.logger.error ("Error selecting the order");
this.reportClosePrice (myOrderId, -1, desiredPrice, numLots, "closing");
}
else
{
this.reportClosePrice (myOrderId, OrderClosePrice(), desiredPrice, numLots, "closing");
}
return true;
}
}
I want to create "Expert advisor" which scaling in\pyramiding\snowballing into trend,
(Another winning position is openning after first one already in breakeven)
Im stuck with function which checks if previous LONG\SHORT open position is already profitable
Seems like my current function always return 1,
extern double ProfitForOpenAnother = 30;
double IsLastLongProfitable(string sy="", int op=OP_BUY) {
int LastLongProfitable = 0;
datetime o;
double l=-1;
int i, k=OrdersTotal();
if (sy=="0") sy=Symbol();
for (i=0; i<k; i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==sy || sy=="") {
if (OrderType()==OP_BUY) {
if (op<0 || OrderType()==op) {
if (OrderMagicNumber()==Magic) {
if (o<OrderOpenTime()) {
o=OrderOpenTime();
l=OrderProfit();
if(l>ProfitForOpenAnother)
{
LastLongProfitable=1;
}
}
}
}
}
}
}
}
return(LastLongProfitable);
} ```
double profit_buy=0,profit_sell=0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
{
datetime time_order=OrderOpenTime();
double profit_order=OrderProfit()-OrderCommission()+OrderSwap();
if(OrderType()==OP_BUY && time_buy<time_order)
{
time_buy=time_order;
profit_buy=profit_order;
}
if(OrderType()==OP_SELL && time_sell<time_order)
{
time_sell=time_order;
profit_sell=profit_order;
}
}
}```
I have some entries in my app which contain some numbers and I have a button that when I click on the button it adds one unit to the number in the entry that is focused, but the problem is that when i click the button, the entry loses the focus and keyboard disappears, although I want the entry to be focused, I found a solution for Android, but couldn't find anything for iOS!!
Does anybody know what to do? I don't want the entry to lose focus
Update:
private void StepUpButton_Clicked(object sender, EventArgs e)
{
double value;
for (int i = 0; i < 30; i++)
{
if (GetEntries(i).IsFocused)
{
if (String.IsNullOrEmpty(GetEntries(i).Text) || GetEntries(i).Text.Equals("-"))
{
value = 0.00;
}
else
{
value = Convert.ToDouble(GetEntries(i).Text);
}
for (int j = 0; j < 10; j++)
{
if (GetEntries(i) == GetVa1ToVb1Amp(j))
{
GetVa1ToVb1Amp(j).Text = controller.StepUpClicked(0, value).ToString("F2");
}
if (GetEntries(i) == GetIa1ToIb3Amp(j))
{
GetIa1ToIb3Amp(j).Text = controller.StepUpClicked(1, value).ToString("F3");
}
if (GetEntries(i) == GetVa1ToIb3Phase(j))
{
GetVa1ToIb3Phase(j).Text = controller.StepUpClicked(2, value).ToString("F2");
}
if (GetEntries(i) == GetVa1ToIb3Freq(j))
{
GetVa1ToIb3Freq(j).Text = controller.StepUpClicked(3, value).ToString("F3");
}
}
}
}
}
I am trying to code my EA where if my close conditions are met, I want my EA to close all the open trades ( there are potentially more than 1 open trades ).
Here is my code for the closing trade section and when I run it through the Strategy Tester, I noticed it doesn't close my trades.
Total=0; // Amount of orders
for(int i=1; i<=OrdersTotal(); i++) // Loop through orders
{
if (OrderSelect(i-1,SELECT_BY_POS)==true) // If there is the next one
{ // Analyzing orders:
if (OrderSymbol()!=Symb)continue; // Another security
Total++; // Counter of market orders
}
}
while(true) // Loop of closing orders
{
if (OrderType()==0 && Close_Buy_Condition==true) // Order Buy is opened & Close Buy Condition is true
{
for (c=Total-1; c>=0; c--)
{
RefreshRates(); // Refresh rates
Ans=OrderClose(OrderTicket(),Lot,Bid,Slippage); // Closing Buy
}
}
if (OrderType()==1 && Close_Sell_Condition==true) // Order Sell is opened & Close Sell Condition is true
{
for (d=Total-1; d>=0; d--)
{
RefreshRates(); // Refresh rates
Ans=OrderClose(OrderTicket(),Lot,Ask,Slippage); // Closing Sell
}
}
break; // Exit while
}
I don't know where do you set value for Ask, Bid and Lot variables. But they've to change when you loop through your open positions.
You can try this function to close all positions:
bool CloseAllPositions()
{
double total;
int cnt;
while(OrdersTotal()>0)
{
// Close pending orders first, you can remove this section if you don't want pending orders to be deleted
total=OrdersTotal();
for(cnt=total-1; cnt>=0; cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
{
switch(OrderType())
{
case OP_BUYLIMIT :OrderDelete(OrderTicket()); break;
case OP_SELLLIMIT :OrderDelete(OrderTicket()); break;
case OP_BUYSTOP :OrderDelete(OrderTicket()); break;
case OP_SELLSTOP :OrderDelete(OrderTicket()); break;
}
}
}
// then close opened orders
total=OrdersTotal();
for(cnt=total-1; cnt>=0; cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
{
switch(OrderType())
{
case OP_BUY:
if (Close_Buy_Condition==true) {
OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,Violet);
}
break;
case OP_SELL:
if (Close_Sell_Condition==true) {
OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3,Violet);
}
break;
}
}
}
}
return true;
}
Edit:
if you don't want to deal with pending orders at all, use this code instead of OrdersTotal():
int GetNumOpenPositions() {
int total = OrdersTotal();
double OpenBuyOrders = 0, OpenSellOrders = 0, PendBuys =0, PendSells =0;
for( i=0;i<total;i++)
{
OrderSelect(i, SELECT_BY_POS );
if ( OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
int type = OrderType();
if (type == OP_BUY ) {OpenBuyOrders=OpenBuyOrders+1;}
if (type == OP_SELL ) {OpenSellOrders=OpenSellOrders+1;}
if (type == OP_BUYSTOP ) {PendBuys=PendBuys+1;}
if (type == OP_SELLSTOP ) {PendSells=PendSells+1;}
}
}
return (OpenBuyOrders + OpenSellOrders);
}
Then total orders would be
Some help with the following would be appreciated. I am writing some console test programs, and I want to be able to enter some parameters from the terminal (I don't want to use command line arguments - too many parameters). I have tried some variations, but I cannot find how to accomplish this. The following is the latest version of my test for terminal input. The problem with this program is that if an error is encountered, the Completer closes automatically, and I want to continue from either the Main() or from fGetNumber() function. While I can see why this program doesn't work, it illustrates what I need to achieve - re-enter the number, but I cannot find how to achieve that. If a valid number is entered, there is no problem. If an invalid number is entered, I cannot find out how to re-enter the number.
The code is as follows, and the problem I have is highlighted by "//////////" :
import "dart:async" as async;
import "dart:io";
void main() {
fGetNumber("Enter Nr of Iterations : ", 0, 999999)
.then((int iIters){
print ("In Main : Iterations selected = ${iIters}");
if (iIters == null) {
print ("In Main: Invalid Number of iterations : ${iIters}.");
} else {
fProcessData(iIters);
}
print ("Main Completed");
});
}
async.Future<int> fGetNumber(String sPrompt, int iMin, int iMax) {
print ("In fGetNumber");
int iIters = 0;
async.Completer<int> oCompleter = new async.Completer();
while (!oCompleter.isCompleted) { /////////// This loop does not work ///////
return fGetUserInput(sPrompt).then((String sIters) {
iIters = int.parse(sIters);
if (iIters < iMin || iIters > iMax) throw new Exception("Invalid");
oCompleter.complete(iIters);
return oCompleter.future;
}).catchError((_) => print ("Invalid - number must be from ${iMin} to ${iMax}")
).whenComplete(() => print ("fGetNumber - whenComplete"));// always gets here
}
print ("In fGetNumber (at end of function)"); //// it never gets here
}
async.Future<String> fGetUserInput(String sPrompt) {
print ("In fGetUserInput");
async.Completer<String> oCompleter = new async.Completer();
stdout.write(sPrompt);
async.Stream<String> oStream = stdin.transform(new StringDecoder());
async.StreamSubscription oSub;
oSub = oStream.listen((String sData) {
oCompleter.complete("$sData");
oSub.cancel();
});
return oCompleter.future;
}
void fProcessData(int iIters) {
print ("In fProcessData");
for (int iPos = 1; iPos <= iIters; iPos++ ) {
if (iPos%100 == 0) print ("Processed = ${iPos}");
}
print ("In fProcessData - completed ${iIters}");
}
// This loop does not work
Of course it does - you enter it exactly once, where you immediately return and therefore leave the loop and method.
// always gets here
That's because whenComplete() always gets called, on success or on error.
// it never gets here
Because you already returned out of the method.
So what can be done?
The easiest way would be to not rely on fGetUserInput(). Listen to stdin in fGetNumber and only complete the completer / cancel the subscription if the input is valid:
async.Future<int> fGetNumber(String sPrompt, int iMin, int iMax) {
print ("In fGetNumber");
async.Completer<String> oCompleter = new async.Completer();
stdout.write(sPrompt);
async.Stream<String> oStream = stdin.transform(new StringDecoder());
async.StreamSubscription oSub;
oSub = oStream.listen((String sData) {
try {
int iIters = int.parse(sData);
if (iIters < iMin || iIters > iMax) throw new Exception("Invalid");
oCompleter.complete(iIters);
oSub.cancel();
} catch(e) {
print("Invalid - number must be from ${iMin} to ${iMax}");
stdout.write(sPrompt);
}
});
return oCompleter.future;
}
Are there alternatives?
Of course. There are likely many, many ways to do this. This one for example:
async.Future<int> fGetNumber(String sPrompt, int iMin, int iMax) {
print ("In fGetNumber");
async.Completer<int> oCompleter = new async.Completer();
fGetUserInput(sPrompt, oCompleter, (String sIters) {
try {
int iIters = int.parse(sIters);
if (iIters < iMin || iIters > iMax) throw new Exception("Invalid");
return iIters;
} catch(e) {
print ("Invalid - number must be from ${iMin} to ${iMax}");
stdout.write(sPrompt);
}
return null;
});
return oCompleter.future;
}
void fGetUserInput(String sPrompt, async.Completer oCompleter, dynamic inputValidator(String sData)) {
print ("In fGetUserInput");
stdout.write(sPrompt);
async.Stream<String> oStream = stdin.transform(new StringDecoder());
async.StreamSubscription oSub;
oSub = oStream.listen((String sData) {
var d = inputValidator(sData);
if(d != null) {
oCompleter.complete(d);
oSub.cancel();
}
});
}
If you really feel there should be something addressed by the Dart team, you could write a feature request. But the Completer is designed to only be completed once. Whatever code you write, you can't just loop to complete it again and again.