Can't retrieve data when two or more trades either open or close simultaneously - mql4

I have these functions to select the last opened order and the last closed order to retrieve multiple data points. This works, however if one or more orders open simultaneously or close simultaneously, it only picks up one order.
Find Last Opened Order
datetime LastOrderOpenTime = 0;
void SelectMostRecentOpened(int magic_number)
{
for(int i=OrdersHistoryTotal();i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_TICKET,MODE_HISTORY)
&& OrderSymbol()==_Symbol
&& OrderMagicNumber() == magic_number
&& OrderOpenTime() > LastOrderOpenTime)
{
...Fill a two dimensional array with data from the selected order
}
LastOrderOpenTime = OrderOpenTime();
}
}
Find Last Closed Order
datetime LastOrderCloseTime = 0;
void SelectMostRecentClosed(int magic_number)
{
for(int i=OrdersHistoryTotal();i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_TICKET,MODE_HISTORY)
&& OrderSymbol()==_Symbol
&& OrderMagicNumber() == magic_number
&& OrderCloseTime() > LastOrderCloseTime)
{
for(int x = ARRAYSIZE - 1; x>=0 ; x--)
{
double OrderTICKET = OrderTicket();
if(OrderTICKET == Prev_OrderTicket) continue;
if(OrderTICKET == Array_Orders[x, Arr_orderTICKET])
{
...Add data retrieved at orderclose to the same dataslot in the array
based off OrderTicket() to retrieve at a later date. i.e OrderOpenTime(),
OrderProfit() etc.
}
Prev_OrderTicket = OrderTicket();
LastOrderCloseTime = OrderCloseTime();
}
}
}
Each Magic Number per trade is different but still I cannot pick up more than one trade at a time. Any help would be appreciated.

Related

Is there any arithmetic formula that can test all given numbers are in row, like [ 3 5 4 ]

I m making a card game where 3 random numbers are generated..I need to check are these numbers Row numbers...
like 4 6 5 and 23,24,22. are row numbers
I have made method but I think there should be easy arithmetic formulas
I have tried this and working well, but I need simple arithmatic formula to avoid use of array and for
bool isAllInRow(int num1, int num2,int num3)
{
//subject : tinpati
List<int> numbers=[num1,num2,num3];
bool is_in_row=true;
numbers.sort();
if(numbers[0]==1 && numbers[1]==12 && numbers[2]==13)
return true;
for(int x=0;x<numbers.length-1;x++)
{
if(numbers[x]-numbers[x+1]!=-1)
{
is_in_row=false;
break;
}
}
return is_in_row;
}
So you want to know if the cards form a straight, with aces both low and high.
Is the "three cards" fixed, or would you want to generalize to more cards?
Sorting should be cheap for such a short list, so that's definitely a good start. Then you just need to check the resulting sequence is increasing adjacent values.
I'd do it as:
bool isStraight(List<int> cards) {
var n = cards.length;
if (n < 2) return true;
cards.sort();
var first = cards.first;
if (first == 1 && cards[1] != 2) {
// Pretend Ace is Jack if n == 3.
// Accepts if remaining cards form a straight up to the King.
first = 14 - n;
}
for (var i = 1; i < n; i++) {
if (cards[i] != first + i) return false;
}
return true;
}
This code rejects card sets that have duplicates, or do not form a straight.
I think you are looking for Arithmetic Progression.
bool checkForAP(List<int> numberArr) {
numberArr.sort();
int diff = numberArr[1] - numberArr[0];
if (numberArr[2] - numberArr[1] != diff) {
return false;
}
return true;
}
And modify your function like
bool isAllInRow(int num1, int num2,int num3) {
//subject : tinpati
List<int> numbers=[num1,num2,num3];
bool is_in_row=true;
numbers.sort();
if(numbers[0]==1 && numbers[1]==12 && numbers[2]==13)
return true;
return checkForAP(numbers);
}
Note: remove sort in AP method as it is of no use. Since your numbers
list length is 3 I directly compared numbers for AP, the same can also
be written for n numbers with for.
bool checkForAp(numberArr) {
numberArr.sort();
int diff = numberArr[1] - numberArr[0];
for(int i = 2; i< numberArr.length ;i++) {
if (numberArr[i] - numberArr[i - 1] != diff) {
return false;
}
}
return true;
}
You could do it like this:
bool isAllInRow(int num1, int num2,int num3) {
if (num1 == num2 || num2 == num3) return false;
var maxNum = max(num1, max(num2, num3));
var minNum = min(num1, min(num2, num3));
return (maxNum - minNum == 2) || (minNum == 1 && maxNum == 13 && num1 + num2 + num3 == 26);
}

how to track take profit and stoploss in mql4

I have the following code in mql4 and it is partially working but having an issue with order tracking.
int ticket;
void OnTick(){
... not included code, setting variables, etc ...
if(tenkan_sen < kijun_sen){
comment += "\nSHORT!";
if(OrderSelect(ticket,SELECT_BY_TICKET) && OrderType() == OP_BUY){
if(OrderClose(OrderTicket(),OrderLots(),Bid,1000,clrCrimson)){
ticket = 0;
}
}
if(ticket <= 0){
// need to set stoploss and takeprofit prices
double short_tp = current_close - (atr*6);
double short_sl = current_close + (atr*2);
ticket = OrderSend(_Symbol,OP_SELL,0.01,Bid,1000,short_sl,short_tp,"This is a sell",1,0,clrPink);
}
} else if(tenkan_sen > kijun_sen){
comment += "\nLONG!";
if(OrderSelect(ticket,SELECT_BY_TICKET) && OrderType() == OP_SELL){
if(OrderClose(OrderTicket(),OrderLots(),Ask,1000,clrPink)){
ticket = 0;
}
}
if(ticket <= 0){
// need to set stoploss and take profit prices
double long_tp = current_close + (atr*6);
double long_sl = current_close - (atr*2);
ticket = OrderSend(_Symbol,OP_BUY,0.01,Ask,1000,long_sl,long_tp,"This is a buy",1,0,clrCrimson);
}
}
}
This was previously based on the logic of closing the previous position upon opening the last position, it was working as expected before I added the sl and tp values. I am not sure how I should reset the ticket variable to 0 in the event of a sl or tp, or if there is a different way I should be handling this.

How can open orders continue in same trading condition

I want to open orders by orders whenever a certain trading condition is met.
I want to open pending orders in previous highest and lowest price.
So, I tried like this:
upper=iHigh(Symbol(),Period(),iHighest(Symbol(),Period(),MODE_HIGH,periods,0));
lower=iLow(Symbol(),Period(),iLowest(Symbol(),Period(),MODE_LOW,periods,0));
Comment("Upper: ",upper,"\nLower: ",lower);
int openCount=0;
int openpendCount=0;
for( int i = OrdersTotal()-1; i >= 0 ; i--)
{
if (OrderSelect(i, SELECT_BY_POS) && // Only my orders :
OrderMagicNumber() == 0 && // my magic number
OrderSymbol() == _Symbol) // and my symbol
{
if(OrderType() == OP_SELL && OrderType() ==OP_BUY) // count market orders
openCount++;
if(OrderType() == OP_SELLLIMIT && OrderType() ==OP_BUYLIMIT) // count market orders
openpendCount++;
}
}
if(openCount ==0 && openpendCount == 0 )
{ OrderSend(Symbol(), OP_SELLLIMIT,1,Ask+(upper-Ask), 3,0,0,"Sub Buy", MAGIC,0, Blue);
OrderSend(Symbol(), OP_BUYLIMIT,1,Ask-(Bid-lower), 3,0,0,"Sub Buy", MAGIC,0, Blue);
}
But no success,
Q: How can I make multiple new orders at the same time, and no more new orders when trade condition meet.
There are a number of problems with your code and it is difficult to know all the problems as you have not included your full code. However, try the following, it addresses the main issues I can see which are.
You should only check once on the close of each new bar
You need to check for successful selection of orders before working with them
Do not check for a magic number of 0, this indicates manually placed orders
You are mixing up && and || when checking your order types
You are placing your orders at strange levels. You need to set them at the previously found levels (adjusted for spread for buy orders).
int MAGIC=123;
datetime TimeBar;
int periods=50;
int start()
{
if(TimeBar==Time[0]) return(0);
double upper=iHigh(NULL, 0, iHighest(NULL, 0, MODE_HIGH, periods, 0));
double lower=iLow (NULL, 0, iLowest (NULL, 0, MODE_LOW , periods, 0));
Comment("Upper: ",upper,"\r\nLower: ",lower);
int openOrders=0;
int limitOrders=0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i, SELECT_BY_POS))
{
if(OrderMagicNumber()!=MAGIC || OrderSymbol()!=Symbol()) continue;
if(OrderType()==OP_SELL || OrderType()==OP_BUY) openOrders++;
if(OrderType()==OP_SELLLIMIT || OrderType()==OP_BUYLIMIT) limitOrders++;
}
}
if(openOrders==0 && limitOrders==0)
{
int res;
res=OrderSend(Symbol(), OP_SELLLIMIT, 1, upper, 3, 0, 0, "Sub Sell", MAGIC, 0, clrBlue);
res=OrderSend(Symbol(), OP_BUYLIMIT, 1, lower+(Ask-Bid), 3, 0, 0, "Sub Buy", MAGIC, 0, clrBlue);
}
TimeBar=Time[0];
return(0);
}
You will also need to address the problem that the EA could potentially try to open an order within MarketInfo(Symbol(), MODE_STOPLEVEL) of the current price which would cause the order to be rejected by the trade server.
It is also good practice to check your OrderSend for errors.

Max subtree sum in tree with limited length

I've got a tree structure.
The task is to find the biggest sum/weight of path nodes, but i can only move n times. Thats ok, but going "up"/"back" cost nothing.
How can i accomplish that?
Below is my code, but the problem is that the each node can only be accessed once, so it doesnt work.
int mSum(Node* node, int mvLeft) {
if (node == nullptr) { return 0; }
if (mvLeft == 0) { return node->value; }
mvLeft--;
int sum = max(mSum(node->left, mvLeft), mSum(node->right, mvLeft));
return node->value + max(sum, mSum(node->parent, mvLeft + 1));
}
Here is the example graph. The numbers on the nodes represent the cost of getting to it. Each node can be visited only once except going "back".
The n step limit here is 3, we're counting entering the graph too, so the proper result is 21 because: 2->8->11.
If we would have limit of 4 steps the result would be 31: 2->10->8->11
My friend tried to do it with DFS, is he right? What's the best algorithm?
Good answer is taking multiple routes at the same time.
I mean we could go with 2-length limit:
2 left 0 right
1 left 1 right
0 left 2 right
Working, but somewhat slow, code :)
Its working time is 28s while other solutions can go with 2s (10 not known tests)
int mSum(Node* node, int mvLeft) {
mvLeft--;
if (mvLeft < 0) {
return 0;
}
else if (mvLeft == 0) {
return node->value;
}
if (node->left != nullptr && node->right != nullptr) {
int max = 0;
for (int i = 0; i <= mvLeft; i++) {
max = Max(max, mSum(node->left, i) + mSum(node->right, mvLeft - i));
}
return max + node->value;
}
else if (node->left != nullptr) {
return mSum(node->left, mvLeft) + node->value;
}
else if (node->right != nullptr) {
return mSum(node->right, mvLeft) + node->value;
}
return node->value;
}

Filtering IQueryable result set using parameters

I'm getting confused with this and I know there will be a more slick way of starting it off. The 'result' variable has many records and I want to check if IN_SiteId is > 0 and filter on it, same after that for LandownerId and PaymentCategoryId etc. If I can get the right approach for the first 2 I will be ok from there. This should be easier but having a brick wall day. Any comments appreciated
public IQueryable rptRentPaidMonthly(int IN_SiteId, int IN_LandownerId, int IN_PaymentCategoryId, int IN_PaymentTypeId, string IN_ShowRelevantProportion)
{
var result = this._lmsDb.rptRentPaidMonthly(IN_daysFrom, IN_daysTo, IN_SiteId, IN_LandownerId, IN_PaymentCategoryId, IN_PaymentTypeId, IN_ShowRelevantProportion);
if (IN_SiteId > 0)
{
var searchResults = (from s in result
where (s.SiteId == #IN_SiteId)
select s);
return searchResults.AsQueryable();
}
return result.AsQueryable();
}
I'm not a LINQ expert but I think you can do something like this:
public IQueryable rptRentPaidMonthly(int IN_SiteId, int IN_LandownerId, int IN_PaymentCategoryId, int IN_PaymentTypeId, string IN_ShowRelevantProportion)
{
var result = this._lmsDb.rptRentPaidMonthly(IN_daysFrom, IN_daysTo, IN_SiteId, IN_LandownerId, IN_PaymentCategoryId, IN_PaymentTypeId, IN_ShowRelevantProportion);
var searchResults = (from s in result
where (IN_SiteId <= 0 || s.SiteId == IN_SiteId)
&& (IN_LandownerId <= 0 || s.LandownerId == IN_LandownerId)
&& (IN_PaymentCategoryId <= 0 || s.PaymentCategoryId == IN_PaymentCategoryId)
&& (IN_PaymentTypeId <= 0 || s.PaymentTypeId == In_PaymentTypeId)
select s);
return searchResults.AsQueryable();
}
The where clause checks if each filter value is less than or equal to 0, if so then it will return true and will not evaluate the next bit which attempts to filter the actual field on the value provided.

Resources