powerbi previous time period comparison - time

I have found on youtube a nice tutorial of how to get a dynamic time period comparison (idk if I'm allowed to put a link so just type "Previous Dynamic Period using DAX in Power BI" by radacad)
So here's the dax code:
sales_prev_period =
var a = CALCULATE(
SUM('MESURES'[valeur]),
FILTER(ALL('MESURES'),
DATEVALUE('MESURES'[date_heure]) >= DATEVALUE('prev_date_stamp'[prev_start_date])
&& DATEVALUE('MESURES'[date_heure]) <= DATEVALUE('prev_date_stamp'[prev_end_date])
)
)
RETURN
IF(a > 1000000000, CONCATENATE(FORMAT(a, "######,##,,,.0G"), "Wh"),
IF(a > 1000000, CONCATENATE(FORMAT(a, "######,##,,.0M"), "Wh"),
IF(a > 1000, CONCATENATE(FORMAT(a, "######,##,.0k"), "Wh"),
CONCATENATE(FORMAT(a, "###0.0"), "Wh"))
)
)
This part returns me always Null / Empty
In contrary this bit of code just under (which is the same but with the "current" dates) always returns me the sum of all values (like if the filter wasn't applyed)
sales_current_period =
var a = CALCULATE(
SUM('MESURES'[valeur]),
FILTER(ALL('MESURES'),
DATEVALUE('MESURES'[date_heure]) >= DATEVALUE('prev_date_stamp'[start_date])
&& DATEVALUE('MESURES'[date_heure]) <= DATEVALUE('prev_date_stamp'[end_date])
)
)
RETURN
IF(a > 1000000000, CONCATENATE(FORMAT(a, "######,##,,,.0G"), "Wh"),
IF(a > 1000000, CONCATENATE(FORMAT(a, "######,##,,.0M"), "Wh"),
IF(a > 1000, CONCATENATE(FORMAT(a, "######,##,.0k"), "Wh"),
CONCATENATE(FORMAT(a, "####"), "Wh"))
)
)
Any idea where it can come from? how to solve it?
Thanks!

Related

Time based Calculation groups - apply year to date to a yearly comparison

The workfile is available here
I wish to conduct time-based analysis on my datas.
For this purpose, I have created 2 calculation groups.
Year comparison that enables me to deal with relative yearly data :
N :=
VAR lv_MAX_YEAR =
[RELATIVE_MAX_YEAR] - 0
RETURN
CALCULATE (
SELECTEDMEASURE() ,
dim_CALENDAR[Year] = lv_MAX_YEAR
)
N-1 :=
VAR lv_MAX_YEAR =
[RELATIVE_MAX_YEAR] - 1
RETURN
CALCULATE (
SELECTEDMEASURE() ,
dim_CALENDAR[Year] = lv_MAX_YEAR
)
N/N-1 Evolution :=
VAR N = CALCULATE( SELECTEDMEASURE() , 'Year comparison'[Year comparison] = "N" )
VAR N_1 = CALCULATE( SELECTEDMEASURE() , 'Year comparison'[Year comparison] = "N-1" )
RETURN
N - N_1
Works fine for me with the expeced behaviour : N is by default the current year (max year in my calendar table), but if I filter on a given year, N becomes that one.
and Relative Period allows me to compare Sales by the number of passed day from the beginning of the year :
[MAX_YEAR_DAY] :=
VAR lv_MAX_YEAR =
CALCULATE (
MAX ( dim_CALENDAR[Year] ) ,
ALL ( dim_CALENDAR[Year] )
)
RETURN
CALCULATE (
MAX ( dim_CALENDAR[Year_day] ) ,
dim_CALENDAR[Year] = lv_MAX_YEAR
)
Year To Max Year_day :=
VAR lv_MAX_YEAR_DAY =
[MAX_YEAR_DAY]
RETURN
CALCULATE (
SELECTEDMEASURE () ,
dim_CALENDAR[YEAR_DAY] <= lv_MAX_YEAR_DAY
)
So far it's a partial success :
my grand totals seem correct ;
but my monthly details don't ;
and my yearly comparison gets busted when it's activated.
How can I use both calculation groups simultaneously?

Getting circular dependency error while creating calculated column

I have a measure in my Sales table :
WW_Anchor_R6Sales :=
VAR R6Sales =
CALCULATE (
[MeasureR6Sales] > 0,
FILTER ( Product, Product[Program] = "WW" && Product[Anchor] = "Y" )
)
RETURN
IF ( ISBLANK ( R6Sales ), 0, R6Sales )
LY_Anchor_R6Sales :=
VAR R6Sales =
CALCULATE (
[MeasureR6Sales] > 0,
FILTER ( Product, Product[Program] = "LY" && Product[Anchor] = "Y" )
)
RETURN
IF ( ISBLANK ( R6Sales ), 0, R6Sales )
MeasureR6Sales :=
VAR salesR6 =
CALCULATE (
SUM ( Sales[SalesAmount] ),
FILTER (
Sales,
Sales[InvoiceDate] >= EDATE ( [LastClosedMonth], -5 )
&& Sales[InvoiceDate] <= [LastClosedMonth]
&& Sales[SalesAmount] > 0
)
)
RETURN
IF ( ISBLANK ( salesR6 ), 0, salesR6 )
When I have created a calculated column:
WW_Anchor_R6 := IF ( [WW_Anchor_R6Sales] > 0, "Yes", "No" )
I am able to create, but when I am trying to create another calculated column say:
CalculatedColumn1 := IF ( [LY_Anchor_R6Sales] > 0, "Yes", "No" )
it is giving me an error saying that
Failed to save modifications to the server. Error returned: 'A circular dependency was detected: Sales[Calculated Column 1], Sales[WW_Anchor_R6], Sales[Calculated Column 1].
How to fix this error?

dax subtracting value from another column

I need your help on this below scenarios, We have data in column Date ,A and B.
I need the output like other column "Result"
steps :
A- B = Result
then take value from Result - next row value of B
until the result value get zero.
once you get zero then need to divide the previous value of result and corresponding vale of B . which i am highlight as red color.
this should be in measure. not by calculated column.
I will say that your desired result is a little confusing. You first say that you want output like the "Result" column in your screenshot. But then you later say that you want the division of the red numbers. Luckily, to do the division, the "Result" column needs to calculated (at least in a way), so here are both pieces.
First is the "Result" column (which is actually a measure).
The key to that is boiling down the problem to the simplest math terms. The number in the results column for any given row is the value from column A for the max date, minus the sum of column B for that date through the date of the given row (until we hit or go below 0).
First we will need to know what the date is for the given row
VAR SelectedDate = SELECTEDVALUE(Data[Date])
Then we will need to know the max date.
VAR MaxDate = MAXX(ALLSELECTED(Data), [Date])
Now that we know the max date, we can get the value from column A for that date.
VAR MaxDateA = SUMX(FILTER(ALL(Data), [Date] = MaxDate), [A])
With those three pieces, we can create our running total. Take the value of column A for the max date and subtract the sum of column B for all dates between the max date and the selected date (inclusive).
MaxDateA - SUMX(FILTER(ALL(Data), [Date] >= SelectedDate && [Date] <= MaxDate), [B])
Now we just need to handle the case for when the result hits, or goes below, 0. We can write a simple if statement that looks very similar to the running total above, with one simple change; exclude the selected date. It is basically checking if the prior date's running total is still greater than 0, calculate the running total for the given date.
IF(
MaxDateA - SUMX(FILTER(ALL(Data), [Date] > SelectedDate && [Date] <= MaxDate), [B]) > 0,
MaxDateA - SUMX(FILTER(ALL(Data), [Date] >= SelectedDate && [Date] <= MaxDate), [B])
BLANK()
)
Here is the formula in one piece.
Result =
VAR SelectedDate = SELECTEDVALUE(Data[Date])
VAR MaxDate = MAXX(ALLSELECTED(Data), [Date])
VAR MaxDateA = SUMX(FILTER(ALL(Data), [Date] = MaxDate), [A])
RETURN
IF(
MaxDateA - SUMX(FILTER(ALL(Data), [Date] > SelectedDate && [Date] <= MaxDate), [B]) > 0,
MaxDateA - SUMX(FILTER(ALL(Data), [Date] >= SelectedDate && [Date] <= MaxDate), [B]),
BLANK()
)
Next is the division measure.
We'll use some of the same logic as the first part. In this, "Selected" is for the given row context, so it will replace the function of the "Max" in the above.
VAR SelectedDate = SELECTEDVALUE(Data[Date])
VAR SelectedA = SUM(Data[A])
Once we have the selected date, we can generate a temporary table that will hold our running total. Basically, we are going to take a distinct list of dates from the data table and add a column (called "Result") that is defined very similarly to the formula for the first part.
VAR OlderDatesList = SUMMARIZE(FILTER(ALL(Data), [Date] <= SelectedDate), [Date], "Result", SelectedA - SUMX(FILTER(ALL(Data), [Date] <= SelectedDate && [Date] >= EARLIER([Date])), [B]))
Having this list lets us find the threshold when the running total hits (or goes below) 0. From that point, we want to know the date when the threshold was met, the running total right before that date, and the value of column B for that date.
VAR LastSelectedDate = MAXX(FILTER(OlderDatesList, [Result] <= 0), [Date])
VAR PriorSelectedResult = SUMX(FILTER(OlderDatesList, [Date] = MINX(FILTER(OlderDatesList, [Date] > LastSelectedDate), [Date])), [Result])
VAR LastSelectedB = SUMX(FILTER(ALL(Data), [Date] = LastSelectedDate), [B])
We now have both pieces to do the division.
DIVIDE(PriorSelectedResult, LastSelectedB, BLANK())
Again, here is the formula in one piece.
Division =
VAR SelectedDate = SELECTEDVALUE(Data[Date])
VAR SelectedA = SUM(Data[A])
VAR OlderDatesList = SUMMARIZE(FILTER(ALL(Data), [Date] <= SelectedDate), [Date], "Result", SelectedA - SUMX(FILTER(ALL(Data), [Date] <= SelectedDate && [Date] >= EARLIER([Date])), [B]))
VAR LastSelectedDate = MAXX(FILTER(OlderDatesList, [Result] <= 0), [Date])
VAR PriorSelectedResult = SUMX(FILTER(OlderDatesList, [Date] = MINX(FILTER(OlderDatesList, [Date] > LastSelectedDate), [Date])), [Result])
VAR LastSelectedB = SUMX(FILTER(ALL(Data), [Date] = LastSelectedDate), [B])
RETURN
DIVIDE(PriorSelectedResult, LastSelectedB, BLANK())
EDIT: Based on comment, here is the final piece to get the number of rows before the "Result" value hits (or goes below) 0.
The logic for this piece starts the same as the "Division" measure, since we need that OlderDatesList for this calculation as well. Once we have that list, we just need to check if the "Result" column ever hits (or goes below) 0, and if it does, return the number of rows before that point.
Count before Zero =
VAR SelectedDate = SELECTEDVALUE(Data[Date])
VAR SelectedA = SUM(Data[A])
VAR OlderDatesList = SUMMARIZE(FILTER(ALL(Data), [Date] <= SelectedDate), [Date], "Result", SelectedA - SUMX(FILTER(ALL(Data), [Date] <= SelectedDate && [Date] >= EARLIER([Date])), [B]))
RETURN
IF(
COUNTAX(FILTER(OlderDatesList, [Result] <= 0), [Date]) >= 1,
COUNTAX(FILTER(OlderDatesList, [Result] > 0), [Date]),
BLANK()
)

How to get the highest value of a standard deviation for last 2 hours in MQL4?

I'm trying to develop an Expert Advisor, so far I can understand and write this which will place orders when a new bar opens.
int BarsCount = 0;
int start()
{ if ( Bars > BarsCount )
{ OrderSend( Symbol(), OP_BUY, 0.01, Ask, 2, NULL, NULL );
BarsCount = Bars;
}
return( 0 );
}
how to get the highest value of standard deviation for last 2 hours to a variable?
E.g.: lets say the EA runs in a 30 mins chart and the bar1 has the standard deviation value 0.003, and bar2 has 0.001, bar3 has 0.004 and bar4 has 0.001.
So, the highest value for past 4 hours is bar3 which has the value of 0.004, so how to get that value to a variable?
I'm trying to make the EA place orders when this formula is true:
( ( current_value_of_standard_deviation
/ highest_value_of_standard_deviation_for_last_2_hours
)
* 100
) > 10
Use built-in tools:
input int MA_period = 27;
int BarsCount = 0;
int nCells2CMP= ( PERIOD_H1 * 2 / PERIOD_CURRENT ) - 1;
double Sig2H[100];
void OnInit(){
...
}
void OnTick(){
if ( Bars > BarsCount ){
if ( BarsCount == 0 ){
for ( int i = MA_period; i > 0; i-- ){
Sig2H[i] = iStdDev( _Symbol,
PERIOD_CURRENT,
0,
MODE_SMA,
PRICE_CLOSE,
i
);
}
}
for ( int i = MA_period; i > 1; i-- ) Sig2H[i] = Sig2H[i-1];
Sig2H[1] = iStdDev( _Symbol, // symbol
PERIOD_CURRENT, // timeframe
MA_period, // MA averaging period
0, // MA shift
MODE_SMA, // MA averaging method
PRICE_CLOSE, // applied price
1 // shift
);
}
Sig2H[0] = iStdDev( _Symbol, // symbol
PERIOD_CURRENT, // timeframe
MA_period, // MA averaging period
0, // MA shift
MODE_SMA, // MA averaging method
PRICE_CLOSE, // applied price
0 // shift
);
if ( 0.1 < ( Sig2H[0]
/ Sig2H[ArrayMaximum( Sig2H,
nCells2CMP,
1
)
]
)
){...}
}

How to open a Buy when a Buy-order hits a T/P, Sell if a Buy-order hits a S/L; a Sell if Sell-order hits a T/P and open Buy if Sell reaches S/L?

I have tried many things but can't get it to work with the code below.
I've tried variations of the logic of the code below but have failed and am not sure where to implement it:
if ( OrderSelect( OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY ) )
{
if ( OrderType() == OP_BUY )
{
if ( OrderClosePrice() > OrderStopLoss() ) Print( "Hit TP" );
else Print( "Hit SL" );
}
else if ( OrderType() == OP_SELL )
{
if ( OrderClosePrice() < OrderStopLoss() ) Print( "Hit TP" );
else Print( "Hit SL" );
}
}
or
Orderselect...
if ( MathAbs( OrderClosePrice()
- OrderTakeProfit()
) > MathAbs( OrderClosePrice()
- OrderStopLoss()
)
) Print( "StopLoss" );
if ( MathAbs( OrderClosePrice()
- OrderTakeProfit()
) < MathAbs( OrderClosePrice()
- OrderStopLoss()
)
) Print( "TakeProfit" );
The OrderSelect() has been an issue for me, so any help will be greatly appreciated.
Below is the EA I'm trying to add it to, but just knowing how and where to put it will help.
extern int MagicNumber = 10001;
extern double Lots = 0.01;
extern double StopLoss = 1;
extern double TakeProfit = 1;
extern int TrailingStop = 0;
extern int Slippage = 3;
//+------------------------------------------------------------------+
// expert start function
//+------------------------------------------------------------------+
int start() // New-MQL4.56789 #strict uses another constructor: int OnTick(){...}
{
double MyPoint = Point;
if ( Digits == 3
|| Digits == 5
) MyPoint = Point*10;
double TheStopLoss = 0;
double TheTakeProfit = 0;
if ( TotalOrdersCount() == 0 )
{
int result = 0;
if ( ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1 ) < iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 1 ) )
&& ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 0 ) > iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 0 ) )
) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is your open BUY rule
{
result = OrderSend( Symbol(),
OP_BUY,
Lots,
Ask,
Slippage,
0,
0,
"Buy",
MagicNumber,
0,
Blue
);
if ( result > 0 )
{
TheStopLoss = 0;
TheTakeProfit = 0;
if ( TakeProfit > 0 ) TheTakeProfit = Ask + TakeProfit * MyPoint;
if ( StopLoss > 0 ) TheStopLoss = Ask - StopLoss * MyPoint;
OrderSelect( result, SELECT_BY_TICKET );
OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( TheStopLoss, Digits ),
NormalizeDouble( TheTakeProfit, Digits ),
0,
Green
);
}
return(0);
}
if ( ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1 ) > iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 1 ) )
&& ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 0 ) < iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 0 ) )
) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is your open SELL rule
{
result = OrderSend( Symbol(),
OP_SELL,
Lots,
Bid,
Slippage,
0,
0,
"Sell",
MagicNumber,
0,
Red
);
if ( result > 0 )
{
TheStopLoss = 0;
TheTakeProfit = 0;
if ( TakeProfit > 0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
if ( StopLoss > 0 ) TheStopLoss = Bid + StopLoss * MyPoint;
OrderSelect( result, SELECT_BY_TICKET );
OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( TheStopLoss, Digits ),
NormalizeDouble( TheTakeProfit, Digits ),
0,
Green
);
}
return(0);
}
}
for ( int cnt = 0; cnt < OrdersTotal(); cnt++ )
{
OrderSelect( cnt, SELECT_BY_POS, MODE_TRADES );
if ( OrderType() <= OP_SELL
&& OrderSymbol() == Symbol()
&& OrderMagicNumber() == MagicNumber
)
{
if ( OrderType() == OP_BUY )
{
if ( TrailingStop > 0 )
{
if ( Bid - OrderOpenPrice() > MyPoint * TrailingStop )
{
if ( OrderStopLoss() < Bid - MyPoint * TrailingStop )
{
OrderModify( OrderTicket(),
OrderOpenPrice(),
Bid - TrailingStop * MyPoint,
OrderTakeProfit(),
0,
Green
);
return(0);
}
}
}
}
else
{
if ( TrailingStop > 0 )
{
if ( ( OrderOpenPrice() - Ask ) > ( MyPoint * TrailingStop ) )
{
if ( ( OrderStopLoss() > ( Ask + MyPoint * TrailingStop ) )
|| ( OrderStopLoss() == 0 )
)
{
OrderModify( OrderTicket(),
OrderOpenPrice(),
Ask + MyPoint * TrailingStop,
OrderTakeProfit(),
0,
Red
);
return(0);
}
}
}
}
}
}
return(0);
}
int TotalOrdersCount()
{
int result = 0;
for ( int i = 0; i < OrdersTotal(); i++ )
{
OrderSelect( i, SELECT_BY_POS, MODE_TRADES );
if ( OrderMagicNumber() == MagicNumber ) result++;
}
return( result );
}
... open WHEN ... is the key part of the goal
OrderSelect() is not of much help for you to solve the "Open WHEN" puzzle. It just crawls accross a db.POOL of records, that MetaTrader Terminal 4 localhost internal DBMS takes care of, which is slow and very, very inefficient way to handle event the order-management tasks, so try to avoid any arbitrary scans thereof in a production-grade system. Here, you even will not get any cardinal piece of information you need for your task from such devastating db.POOL scans, so let's focus on the goal first.
... WHAT ... is the idea behind the goal?
The EA is a scholastically trivial variation on a slow-200 / fast-30 simple moving average cross.
There I guess you would like to add your additional idea of opening additional trades on condition the underlying SMA-cross-originated trade has reached it's { SL | TP }-termination respectively, right?
For such case, Brokers with a MetaTrader Server 4 typically allow you to place a so called pending order, which instructs a Broker, to maintain a record about your will to enter market, supposing a price reaches a pre-defined level -- ( guess what, these would be the { SL | TP } as you requested in the title -- and such record is waiting ( with some more configurable options ), until a such price movement happens or not, during which such position is waiting in an inactive state, called a pending order ...
For Terms & Conditions, kindly check your Broker's contract and/or ask their Customer Care representative. Some special limitations may apply ( better to know a-priori ).
... WHERE ... to put the code?
Without re-designing the provided code ( some minor errors/inefficiencies there ) the code shall go here:
result = OrderSend( Symbol(),
OP_SELL, // PRIMARY SELL <<<AT-MARKET>>>
Lots,
Bid,
Slippage,
0,
0,
"Sell",
MagicNumber,
0,
Red
);
if ( result > 0 )
{
TheStopLoss = 0;
TheTakeProfit = 0;
if ( TakeProfit > 0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
if ( StopLoss > 0 ) TheStopLoss = Bid + StopLoss * MyPoint;
OrderSelect( result, SELECT_BY_TICKET );
OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( TheStopLoss, Digits ),
NormalizeDouble( TheTakeProfit, Digits ),
0,
Green
);
// ---------------------------------------------------- HERE ADD
OrderSend( Symbol(),
OP_SELLSTOP, // SELL-STOP PENDING ORDER ON SELL.TP
Lots,
NormalizeDouble( TheTakeProfit
- MarketInfo( _Symbol, MODE_SPREAD ),
Digits
),
Slippage,
0, // SL: T.B.D.
0, // TP: T.B.D.
"Sell on Sell.TP",
sTpMagicNumber, // avoid collisions with other logic
0, // never expires
Red
);
OrderSend( Symbol(),
OP_BUYSTOP, // BUY-STOP PENDING ORDER ON SELL.SL
Lots,
NormalizeDouble( TheStopLoss
- MarketInfo( _Symbol, MODE_SPREAD ),
Digits
),
Slippage,
0, // SL: T.B.D.
0, // TP: T.B.D.
"Buy on Sell.SL",
bSlMagicNumber, // avoid collisions with other logic
0, // never expires
Red
);
}
The spread-adjustment is not absolute, as during instable periods of time, the market is exposed to spurious spread volatilities. Again, Brokers' Terms & Conditions apply here, so be carefull.

Resources