Amibroker AFL code Buy Sell status is not fetching with if condition - algorithmic-trading

I have AFL which is working fine for crude oil. out of 10 trades, 8 trades are targets hitting. I have code for place orders auto trades. the auto trade code is working fine with other AFL codes but the problem is in below algorithm the BUY and SELL Boolean value is not giving to IF condition. But IIF(Buy .... conditions are working fine.
My main question is why BUY Sell True or false is not working in the last status in AFL. Kindly help me to resolve this.
_SECTION_BEGIN("T+4 day ");
Title = " ..:: duy ::.. - Filter of Stock " + " " + FullName() + " " + Date( ) ;
// 4-Day-Range Switch
prev=AMA2(C,1,0);
d=IIf(C>Ref(Max(Max(H,Ref(H,-20)),Max(Ref(H,-10),Ref(H,-15))),-1),Min(Min(L,Ref(L,-20)),Min(Ref(L,-10),Ref(L,-15))),
IIf(C<Ref(Min(Min(L,Ref(L,-20)),Min(Ref(L,-10),Ref(L,-15))),-1),Max(Max(H,Ref(H,-20)),Max(Ref(H,-10),Ref(H,-15))),PREV));
a=Cross(Close,d);
b=Cross(d,Close);
state=IIf(BarsSince(a)<BarsSince(b),1,0);
s=state>Ref(state,-1);
ss=state<Ref(state,-1);
sss=state==Ref(state,-1);
col=IIf(state == 1 ,51,IIf(state ==0,4,1));
Plot(C,"",Col,128);
Buy=s;
Sell=ss;
PlotShapes( shapeUpArrow * s ,6,0,L);
PlotShapes( shapeDownArrow *ss ,4,0,H);
dist = 0.8*ATR(10);
dist1 = 2*ATR(10);
for( i = 0; i < BarCount; i++ )
{
if( Buy )
{
PlotText( "\nBuy:" + L[ i ] + "\nT= " + (L*1.005) + "\nSL= " + (L*0.9975), i, L[ i ]-dist, colorGreen, colorWhite );
}
if( Sell )
{
PlotText( "Sell:" + H[ i ] + "\nT= " + (H*0.995) + "\nSL= " + (H*1.0025), i, H[ i ]+dist1, colorRed, colorWhite );
}
}
Buy = ExRem(Buy,Sell);
Sell = ExRem(Sell,Buy);
if ( LastValue(Buy)==1)
{
quantity=2;
orderId=placeOrderFuture("MCX", "FUTCOM", ChartSymbol, "BUY", "INTRADAY", "MARKET", quantity, 0, defaultTriggerPrice(), "19-APR-2018", defaultStrategyId(), defaultComments());
//orderId = placeOrderUsingParams(tradeType, AT_ORDER_TYPE, AT_QUANTITY, buyPrice, defaultTriggerPrice(), 1);
}
if ( LastValue(Sell) == 1 )
{
quantity=2;
orderId=placeOrderFuture("MCX", "FUTCOM", ChartSymbol, "SELL", "INTRADAY", "MARKET", quantity, 0, defaultTriggerPrice(), "19-APR-2018", defaultStrategyId(), defaultComments());
//orderId = placeOrderUsingParams("SELL", AT_ORDER_TYPE, AT_QUANTITY, sellPrice, defaultTriggerPrice(), 1);
}

LastValue documentation
With if statements, you need to specify a specific bar. And according to the documentation, LastValue may look into the future. I can't say for sure what's happening with your code, but the loops/if/switch can be tricky. This tutorial Looping in Amibroker might give you some insights into how they work.
You may try SelectedValue instead. If you haven't got any bars selected, it automatically defaults to the last bar. I use this for my realtime trading.
bi = SelectedValue(BarIndex());
if(Buy[bi])
{
...
}
On an unrelated note, your text plots aren't going to plot unfiltered signals, put your ExRem code under your initial Buy and Sell conditions.

Related

Getting non overlapping between two dates with Carbon

UseCase: Admin assigns tasks to People. Before we assign them we can see their tasks in a gantt chart. According to the task assign date and deadline, conflict days (overlap days) are generated between tasks.
I wrote this function to get overlapping dates between two dates. But now I need to get non overlapping days between two dates, below is the function I wrote.
$tasks = Assign_review_tasks::where('assigned_to', $employee)
->where('is_active', \Constants::$REVIEW_ACTIVE)
->whereNotNull('permit_id')->get();
$obj['task'] = count($tasks);
// count($tasks));
if (count($tasks) > 0) {
if (count($tasks) > 1) {
$start_one = $tasks[count($tasks) - 1]->start_date;
$end_one = $tasks[count($tasks) - 1]->end_date;
$end_two = $tasks[count($tasks) - 2]->end_date;
$start_two = $tasks[count($tasks) - 2]->start_date;
if ($start_one <= $end_two && $end_one >= $start_two) { //If the dates overlap
$obj['day'] = Carbon::parse(min($end_one, $end_two))->diff(Carbon::parse(max($start_two, $start_one)))->days + 1; //return how many days overlap
} else {
$obj['day'] = 0;
}
// $arr[] = $obj;
} else {
$obj['day'] = 0;
}
} else {
$obj['day'] = 0;
}
$arr[] = $obj;
start_date and end_date are taken from database,
I tried modifying it to,
(Carbon::parse((min($end_one, $end_two))->add(Carbon::parse(max($start_two, $start_one))))->days)->diff(Carbon::parse(min($end_one, $end_two))->diff(Carbon::parse(max($start_two, $start_one)))->days + 1);
But it didn't work, in simple terms this is what I want,
Non conflicting days = (end1-start1 + end2-start2)- Current overlapping days
I'm having trouble translate this expression . Could you help me? Thanks in advance
before trying to reimplement complex stuff I recommend you take a look at enhanced-period for Carbon
composer require cmixin/enhanced-period
CarbonPeriod::diff macro method is what I think you're looking for:
use Carbon\CarbonPeriod;
use Cmixin\EnhancedPeriod;
CarbonPeriod::mixin(EnhancedPeriod::class);
$a = CarbonPeriod::create('2018-01-01', '2018-01-31');
$b = CarbonPeriod::create('2018-02-10', '2018-02-20');
$c = CarbonPeriod::create('2018-02-11', '2018-03-31');
$current = CarbonPeriod::create('2018-01-20', '2018-03-15');
foreach ($current->diff($a, $b, $c) as $period) {
foreach ($period as $day) {
echo $day . "\n";
}
}
This will output all the days that are in $current but not in any of the other periods. (E.g. non-conflicting days)

Using hour as a condition for intraday scripting?

I'd like to make a very basic strategy for intraday momentum.
However, I'm stuck wondering: is it possible to use hour as a trading condition?
For instance:
strategy("Strat - Intraday Momentum", overlay=true)
market_open = hour == 9
market_open_hour = hour == 10
market_close = hour == 15
if (market_open)
strategy.entry("Open", strategy.long)
if (market_open_hour)
strategy.entry("Open +1 Hour", strategy.long)
strategy.close_all(when= hour == market_close)
Seems simple enough but so far haven't been able to make it work.
Was playing off this idea:
// Simple Example Code
// Designed to play around with Tradingview's close, close_all and exit functions
strategy("Close Example", overlay=true, pyramiding=2)
monCondition = dayofweek == dayofweek.monday
wedCondition = dayofweek == dayofweek.wednesday
if (monCondition)
strategy.entry("Monday", strategy.long)
if (wedCondition)
strategy.entry("Wednesday", strategy.long)
strategy.close_all(when=dayofweek == dayofweek.friday)
Source: https://backtest-rookies.com/2019/03/01/tradingview-strategy-close-strategy-close_all-vs-strategy-exit/
It's possible for sure, but your code's robustness should be improved. Would be preferable to build conditions on transitions. Example 2 is from the usrman:
//#version=4
study("Time begin", "", true)
// #1
timeOpen1 = hour == 9
timeOpenOk1 = not timeOpen1[1] and timeOpen1
plotchar(timeOpenOk1, "timeOpenOk1", "", location.abovebar, text = "▲")
plotchar(timeOpen1, "timeOpen1", "", location.belowbar, text = "•")
// #2
sessSpec2 = input("0900-0959", type=input.session) + ":1234567"
is_newbar(res, sess) =>
t = time(res, sess)
na(t[1]) and not na(t) or t[1] < t
timeOpenOk2 = timeframe.isintraday and is_newbar("1440", sessSpec2)
plotchar(timeOpenOk2, "timeOpenOk2", "", location.abovebar, color.orange, text = "▲\n‎")

Is it good design to loop through many users? - SpringBoot

I am looking into good design principles and would just like some feedback.
I want to go through every user in my application that is a patient, check their scheduled activities, see if there is one upcoming and send them an email. It looks a little like this:
List<Patient> listOfAllPatients = patientRepositoryJPA.findAll();
if (listOfAllPatients.size() != 0) {
for (Patient patient : listOfAllPatients) {
user = userRepositoryJPA.findByUsername(patient.getUsername());
Timestamp currentTimeAndDate = new Timestamp(System.currentTimeMillis());
Long closestDate = Integer.toUnsignedLong(31);;
List<Activity> activities = activityRepositoryJPA.findByPatientAndStartDateTimeAfter(patient, currentTimeAndDate);
for (Activity activity : activities) {
Timestamp activityDateAndTime = activity.getStartDateTime();
Long difference = getTimeDifferenceByMinutes(currentTimeAndDate, activityDateAndTime);
if (difference < closestDate) {
LocalDateTime upcomingDate = activity.getStartDateTime().toLocalDateTime();
emailHandler.sendEmail(javaMailSender, "Upcoming Activity Reminder", "The activity, " + activity.getName() + " is starting soon! (" +
upcomingDate.getHour() + ":" + upcomingDate.getMinute() + ")", user);
}
}
}
Now here I loop through every patient in the application and then through each of their activities. If there were many user (millions) surely there would be some bottlenecks or something here.
Does anybody have any advice on how big companies would handle data like this?
Or is what I am doing fine? Thanks.
After some advice, I have improved it to this:
Timestamp currentTimeAndDate = new Timestamp(System.currentTimeMillis());
LocalDateTime add31Minutes = LocalDateTime.now().plus(31, ChronoUnit.MINUTES);
Timestamp noLaterThanDateAndTime = Timestamp.valueOf(add31Minutes);
for (Activity activity : activityRepositoryJPA.findByStartDateTimeBetween(currentTimeAndDate, noLaterThanDateAndTime)) {
Patient patient = activity.getPatient();
LocalDateTime upcomingDate = activity.getStartDateTime().toLocalDateTime();
emailHandler.sendEmail(javaMailSender, "BAA - Upcoming Activity Reminder", "The activity, " + activity.getName() + " is starting soon! (" +
upcomingDate.getHour() + ":" + upcomingDate.getMinute() + ")", patient.getUser());
}
Now I find all activities between now and 31 minutes time in 1 query.

h2o steam prediction service results not being recognized as a BinaryPrediction for binomial estimator

I have a DRF model created in h2o flow that is supposed to be binomial and flow indicates that it is binomial
but I am having a problem where, importing it into h2o steam and deploying it to the prediction service, the model does not seem to be recognized as binomial. The reason I think this is true is shown below. The reason this is a problem is because I think it is what is causing the prediction service to NOT show the confidence value for the prediction (this reasoning is also shown below).
In the prediction service, I can get a prediction label, but no values filled in the index-label-probability table.
Using the browser inspector (google chrome), the prediction output seems to depend on a file called predict.js.
In order to get the prediction probability values to show in the prediction service, it seems like this block of code needs to run to get to this line. Opening the predict.js file within the inspector on the prediction service page and adding some debug output statements at some of the top lines (indicated with DEBUG/ENDDEBUG comments in the code below), my showResults() function then looks like:
function showResult(div, status, data) {
////////// DEBUG
console.log("showResult entered")
////////// ENDDEBUG
var result = '<legend>Model Predictions</legend>'
////////// DEBUG
console.log(data)
console.log(data.classProbabilities)
console.log("**showResult: isBinPred=" + isBinaryPrediction)
////////// ENDDEBUG
if (data.classProbabilities) {
////////// DEBUG
console.log("**showResult: data.classProbabilities not null")
////////// ENDDEBUG
// binomial and multinomial
var label = data.label;
var index = data.labelIndex;
var probs = data.classProbabilities;
var prob = probs[index];
result += '<p>Predicting <span class="labelHighlight">' + label + '</span>';
if (probs.length == 2) {
result += ' based on max F1 threshold </p>';
}
result += ' </p>';
result += '<table class="table" id="modelPredictions"> \
<thead> \
<tr> \
<th>Index</th> \
<th>Labels</th> \
<th>Probability</th> \
</tr> \
</thead> \
<tbody> \
';
if (isBinaryPrediction) {
var labelProbabilitiesMapping = [];
outputDomain.map(function(label, i) {
var labelProbMap = {};
labelProbMap.label = outputDomain[i];
labelProbMap.probability = probs[i];
if (i === index) {
labelProbMap.predicted = true;
}
labelProbMap.originalIndex = i;
labelProbabilitiesMapping.push(labelProbMap);
});
labelProbabilitiesMapping.sort(function(a, b) {
return b.probability - a.probability;
});
var limit = labelProbabilitiesMapping.length > 5 ? 5 : labelProbabilitiesMapping.length;
for (var i = 0; i < limit; i++) {
if (labelProbabilitiesMapping[i].predicted === true) {
result += '<tr class="rowHighlight">'
} else {
result += '<tr>'
}
result += '<td>' + labelProbabilitiesMapping[i].originalIndex + '</td><td>' + labelProbabilitiesMapping[i].label + '</td> <td>' + labelProbabilitiesMapping[i].probability.toFixed(4) + '</td></tr>';
}
} else {
for (var label_i in outputDomain) {
if (parseInt(label_i) === index ){
result += '<tr class="rowHighlight">'
} else {
result += '<tr>'
}
result += '<td>' + label_i + '</td><td>' + outputDomain[label_i] + '</td> <td>' + probs[label_i].toFixed(4) + '</td></tr>';
}
}
result += '</tbody></table>';
}
else if ("cluster" in data) {
// clustering result
result = "Cluster <b>" + data["cluster"] + "</b>";
}
else if ("value" in data) {
// regression result
result = "Value <b>" + data["value"] + "</b>";
}
else if ("dimensions" in data) {
// dimensionality reduction result
result = "Dimensions <b>" + data["dimensions"] + "</b>";
}
else {
result = "Can't parse result: " + data;
}
div.innerHTML = result;
}
and clicking the "predict" in the prediction service now generates the console output:
If I were to add a statement isBinaryPrediction = true to forcec the global variable to true (around here) and run the prediction again, the console shows:
indicating that the variable outputDomain is undefined. The variable outputDomain seems to be set in the function showModel. This function appears to run when the page loads, so I can't edit it in the chrome inspector to see what the variable values are. If anyone knows how to fix this problem (getting the prediction probability values to show up for h2o steam's prediction service for binomial models) it would a big help. Thanks :)
The UI has not been updated to handle MOJOs yet and there seems to be a bug. You're welcome to contribute: https://github.com/h2oai/steam/blob/master/CONTRIBUTING.md
My solution is very hacky, but works for my particular case (ie. I have a DRF, binomial model in h2o steam that is not being recognized as a binary model (how I know this is shown in this answer)).
Solution:
In my original post, there was a variable outputDomain that was undefined. Looking at the source code, that variable is set to (what is supposed to be) the domain labels of the output response for the model, here. I changed this line from outputDomain = domains[i1]; to outputDomain = domains[i1-1];. My output after clicking the predict button looks like:
From the official linux download for h2o steam, you can access the prediction service predict.js file by opening steam-1.1.6-linux-amd64/var/master/assets/ROOT.war/extra/predict.js, then saving changes and relaunching the jetty server $ java -Xmx6g -jar var/master/assets/jetty-runner.jar var/master/assets/ROOT.war.
Causes?:
I suspect the problem has something to do with that fact that the global variable isBinaryPrediction in predict.js seems to remain false for my model. The reason that isBinaryPrediction is false seems to be because in the function showInputParameters(), data.m has no field _problem_type. Using console.dir(data, {depth: null}) in the inspector console to see the fields of data.m, I see that the expectedd field data.m._problem_type does not exist and so returns undefined, thus isBinaryPrediction is never set true (here).
Why this is happening, I do not know. I have only used DRF models in steam so far and this may be a problem with that model, but I have not tested. If anyone knows why this may be happening, please let me know.

Why query just returns first 100 users?

I want get 40 users where "score" less or equal to some value, and 40 users where "score" greater or equal to the same value. But both queries return just first 100 users which sorted by score in descending order.
Here is some part of code
var query = ParseUser.Query;
if(mode==0)
{
query.WhereNotEqualTo("fbLogged", true)
.WhereNotEqualTo("username", SaveManager.Instance.TempUsername)
.WhereGreaterThanOrEqualTo("score", SaveManager.Instance.Score)
.Limit(40);
}
query.FindAsync().ContinueWith(t =>
{
if (t.IsCanceled || t.IsFaulted)
{
foreach (var e in t.Exception.InnerExceptions)
Debug.LogError("Error: " + e.Message);
return;
}
else
{
var query1 = ParseUser.Query;
if(mode==0)
{
query1.WhereNotEqualTo("fbLogged", true)
.WhereNotEqualTo("username", SaveManager.Instance.TempUsername)
.WhereLessThanOrEqualTo("score", SaveManager.Instance.Score)
.Limit(40);
}
query1.FindAsync().ContinueWith(t1=>
{
Debug.Log("first query count: " + t.Result.ToList().Count);
Debug.Log("second query count: " + t1.Result.ToList().Count);
var r = t.Result.ToList();
r.AddRange(t1.Result.ToList());
List<UserRank> ranks = new List<UserRank>();
r.ForEach(info => { ranks.Add(RetrieveUserRankData((ParseUser)info)); });
ranks = ranks.OrderByDescending(ur => ur.Score).ToList();
UserRank first = ranks.First();
UserRank last = ranks.Last();
Debug.Log("my score: " + SaveManager.Instance.Score);
Debug.Log("first name and score: " + first.Name + " " + first.Score);
Debug.Log("last name and score: " + last.Name + " " + last.Score);
Also here is the log
What did I do wrong?
By default, a query default limit is 100 rows. And the maximum number of rows is 1000. To increase the limit, use query.setLimit(1000) to increase the number of queried row to 1000.

Resources