Sending a notification only once and not on every tick - mql4

How would I enable my EA to send a notification only once to my iPhone when the else if (ClosePosition == false) condition returns true (in other words, when my EA fails to close an EA-opened position). At the moment, it pings on every tick.
The ClosePositionboolean for the OrderClose() function returns true when the EA successfully closes the position when the conditions specified are met. It returns ClosePosition == false when the EA fails to close the position.
Here is my code so far
else if(ClosePosition == false)
{
int failedClosePosition = OrdersTotal()-1;
bool fail = OrderSelect(failedClosePosition,SELECT_BY_POS,MODE_TRADES);
if(fail == true)
{
SendNotification("Order Number #"+IntegerToString(OrderTicket(),10)+" has failed to close. Please refer to error code "+IntegerToString(GetLastError()));
}
}

Without any context to the real solution ( ref. your other post's broader view ),the repetitively detected reasons to send a notification ought be locked-out by a first occasion such a notification was sent ( imagine an array of notifications positively sent to:
int ArrayOfNotificationsAlreadySENT[][3]; //[ <OrderTicketNUMBER>,
// <Notification_E.164_TargetNUMBER>,
// <TimeStampSECONDS>
// ],
storing an OrderTicket() number as a UUID of such "trouble-maker" )
For problems, where a repetitive detection takes place, may want to extend the definition and add a fourth column, where you update an amount of trouble detections for each respective UUID, and (as common) probably using some fallback policy to reduce the flow of messages according to some reasonable re-notification "distances" from on-first-detected to on-2nd-detect() to on-5th-detect() to on-10th-detect() to on-100th-detect() depending on your feasible trouble-context and business-acceptable density of re-notifications

Related

CAPL: How do I get the timestamp of the message containing a signal name?

I am sure this is much simpler than I'm making it out to be, but...
In CAPL, I'm trying to ouput the timestamp for signals that have a certain value:
on signal_update XXX
{
if ($XXX == 42) {
message * msg = { DLC = 15 };
getThisMessage(msg, 15);
write("Time: %f", messageTimeNS(msg));
}
}
So given a signal update, how do I get the containing message and its timestamp? (BTW, the 'DLC=15' is just the maximum value that the compiler let me include. I'm unsure of the correct value.)
You can always get the current simulation time by using
timeNowNS();
while you are in a on signal_update ... block, the time returned is the time which caused the event handler to be executed; in this case when a message was received which contained the signal of interest.
The simulation time will not change during execution of the event handlers.

Are these two Observable Operations Equivalent?

I'm not sure why, but for some reason when using the observable that is created via concat I will always get all values that are pushed from my list (works as intended). Where as with the normal subscribe it seems that some values never make it to those who have subscribed to the observable (only in certain conditions).
These are the two cases that I am using. Could anyone attempt to explain why in certain cases when subscribing to the second version not all values are received? Are they not equivalent? The intent here is to rewind the stream. What are some reasons that could explain why Case 2 fails while Case 1 does not.
Replay here is just a list of the ongoing stream.
Case 1.
let observable =
Observable.Create(fun (o:IObserver<'a>) ->
let next b =
for v in replay do
o.OnNext(v.Head)
o.OnNext(b)
o.OnCompleted()
someOtherObs.Subscribe(next, o.OnError, o.OnCompleted))
let toReturn = observable.Concat(someOtherObs).Publish().RefCount()
Case 2.
let toReturn =
Observable.Create(fun (o:IObserver<'a>) ->
for v in replay do
o.OnNext(v.Head)
someOtherObs.Subscribe(o)
).Publish().RefCount()
Caveat! I don't use F# regularly enough to be 100% comfortable with the syntax, but I think I see what's going on.
That said, both of these cases look odd to me and it greatly depends on how someOtherObs is implemented, and where (in terms of threads) things are running.
Case 1 Analysis
You apply concat to a source stream which appears to work like this:
It subscribes to someOtherObs, and in response to the first event (a) it pushes the elements of replay to the observer.
Then it sends event (a) to the observer.
Then it completes. At this point the stream is finished and no further events are sent.
In the event that someOtherObs is empty or just has a single error, this will be propagated to the observer instead.
Now, when this stream completes, someOtherObs is concatenated on to it. What happens now is a little unpreditcable - if someOtherObs is cold, then the first event would be sent a second time, if someOtherObs is hot, then the first event is not resent, but there's a potential race condition around which event of the remainder will go next which depends on how someOtherObs is implemented. You could easily miss events if it's hot.
Case 2 Analysis
You replay all the replay events, and then send all the events of someOtherObs - but again there's a race condition if someOtherObs is hot because you only subscribe after pushing replay, and so might miss some events.
Comments
In either case, it seems messy to me.
This looks like an attempt to do a merge of a state of the world (sotw) and a live stream. In this case, you need to subscribe to the live stream first, and cache any events while you then acquire and push the sotw events. Once sotw is pushed, you push the cached events - being careful to de-dupe events that may been read in the sotw - until you are caught up with live at which point you can just pass live events though.
You can often get away with naive implementations that flush the live cache in an OnNext handler of the live stream subscription, effectively blocking the source while you flush - but you run the risk of applying too much back pressure to the live source if you have a large history and/or a fast moving live stream.
Some considerations for you to think on that will hopefully set you on the right path.
For reference, here is an extremely naïve and simplistic C# implementation I knocked up that compiles in LINQPad with rx-main nuget package. Production ready implementations I have done in the past can get quite complex:
void Main()
{
// asynchronously produce a list from 1 to 10
Func<Task<List<int>>> sotw =
() => Task<List<int>>.Run(() => Enumerable.Range(1, 10).ToList());
// a stream of 5 to 15
var live = Observable.Range(5, 10);
// outputs 1 to 15
live.MergeSotwWithLive(sotw).Subscribe(Console.WriteLine);
}
// Define other methods and classes here
public static class ObservableExtensions
{
public static IObservable<TSource> MergeSotwWithLive<TSource>(
this IObservable<TSource> live,
Func<Task<List<TSource>>> sotwFactory)
{
return Observable.Create<TSource>(async o =>
{
// Naïve indefinite caching, no error checking anywhere
var liveReplay = new ReplaySubject<TSource>();
live.Subscribe(liveReplay);
// No error checking, no timeout, no cancellation support
var sotw = await sotwFactory();
foreach(var evt in sotw)
{
o.OnNext(evt);
}
// note naive disposal
// and extremely naive de-duping (it really needs to compare
// on some unique id)
// we are only supporting disposal once the sotw is sent
return liveReplay.Where(evt => !sotw.Any(s => s.Equals(evt)))
.Subscribe(o);
});
}
}

Using ReactiveCocoa to track UI updates with a remote object

I'm making an iOS app which lets you remotely control music in an app playing on your desktop.
One of the hardest problems is being able to update the position of the "tracker" (which shows the time position and duration of the currently playing song) correctly. There are several sources of input here:
At launch, the remote sends a network request to get the initial position and duration of the currently playing song.
When the user adjusts the position of the tracker using the remote, it sends a network request to the music app to change the position of the song.
If the user uses the app on the desktop to change the position of the tracker, the app sends a network request to the remote with the new position of the tracker.
If the song is currently playing, the position of the tracker is updated every 0.5 seconds or so.
At the moment, the tracker is a UISlider which is backed by a "Player" model. Whenever the user changes the position on the slider, it updates the model and sends a network request, like so:
In NowPlayingViewController.m
[[slider rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(UISlider *x) {
[playerModel seekToPosition:x.value];
}];
[RACObserve(playerModel, position) subscribeNext:^(id x) {
slider.value = player.position;
}];
In PlayerModel.m:
#property (nonatomic) NSTimeInterval position;
- (void)seekToPosition:(NSTimeInterval)position
{
self.position = position;
[self.client newRequestWithMethod:#"seekTo" params:#[positionArg] callback:NULL];
}
- (void)receivedPlayerUpdate:(NSDictionary *)json
{
self.position = [json objectForKey:#"position"]
}
The problem is when a user "fiddles" with the slider, and queues up a number of network requests which all come back at different times. The user could be have moved the slider again when a response is received, moving the slider back to a previous value.
My question: How do I use ReactiveCocoa correctly in this example, ensuring that updates from the network are dealt with, but only if the user hasn't moved the slider since?
In your GitHub thread about this you say that you want to consider the remote's updates as canonical. That's good, because (as Josh Abernathy suggested there), RAC or not, you need to pick one of the two sources to take priority (or you need timestamps, but then you need a reference clock...).
Given your code and disregarding RAC, the solution is just setting a flag in seekToPosition: and unsetting it using a timer. Check the flag in recievedPlayerUpdate:, ignoring the update if it's set.
By the way, you should use the RAC() macro to bind your slider's value, rather than the subscribeNext: that you've got:
RAC(slider, value) = RACObserve(playerModel, position);
You can definitely construct a signal chain to do what you want, though. You've got four signals you need to combine.
For the last item, the periodic update, you can use interval:onScheduler::
[[RACSignal interval:kPositionFetchSeconds
onScheduler:[RACScheduler scheduler]] map:^(id _){
return /* Request position over network */;
}];
The map: just ignores the date that the interval:... signal produces, and fetches the position. Since your requests and messages from the desktop have equal priority, merge: those together:
[RACSignal merge:#[desktopPositionSignal, timedRequestSignal]];
You decided that you don't want either of those signals going through if the user has touched the slider, though. This can be accomplished in one of two ways. Using the flag I suggested, you could filter: that merged signal:
[mergedSignal filter:^BOOL (id _){ return userFiddlingWithSlider; }];
Better than that -- avoiding extra state -- would be to build an operation out of a combination of throttle: and sample: that passes a value from a signal at a certain interval after another signal has not sent anything:
[mergedSignal sample:
[sliderSignal throttle:kUserFiddlingWithSliderInterval]];
(And you might, of course, want to throttle/sample the interval:onScheduler: signal in the same way -- before the merge -- in order to avoid unncessary network requests.)
You can put this all together in PlayerModel, binding it to position. You'll just need to give the PlayerModel the slider's rac_signalForControlEvents:, and then merge in the slider value. Since you're using the same signal multiple places in one chain, I believe that you want to "multicast" it.
Finally, use startWith: to get your first item above, the inital position from the desktop app, into the stream.
RAC(self, position) =
[[RACSignal merge:#[sampledSignal,
[sliderSignal map:^id(UISlider * slider){
return [slider value];
}]]
] startWith:/* Request position over network */];
The decision to break each signal out into its own variable or string them all together Lisp-style I'll leave to you.
Incidentally, I've found it helpful to actually draw out the signal chains when working on problems like this. I made a quick diagram for your scenario. It helps with thinking of the signals as entities in their own right, as opposed to worrying about the values that they carry.

Remove a ReactiveCocoa signal from a control

If I assign a signal to a property of a control:
RAC(self.loginButton.enabled) = [RACSignal
combineLatest:#[
self.usernameTextField.rac_textSignal,
self.passwordTextField.rac_textSignal
] reduce:^(NSString* username, NSString* password) {
return #(username.length > 0 && password.length > 0);
}];
But then wanted to assign a different RACSignal to enabled, how can I clear any existing one before doing so?
If I try and set it a second time, I get an exception like the following:
2013-10-29 16:54:50.623 myApp[3688:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Signal <RACSignal: 0x975e9e0> name: +combineLatest: (
"<RACSignal: 0x975d600> name: <UITextField: 0x10f2c420> -rac_textSignal",
"<RACSignal: 0x975de30> name: <UITextField: 0x10f306e0> -rac_textSignal"
) reduce: is already bound to key path "self.loginButton.enabled" on object <LoginViewController: 0x10f264e0>, adding signal <RACSignal: 0x9763500> name: +combineLatest: (
"<RACSignal: 0x97624f0> name: <UITextField: 0x10f2c420> -rac_textSignal",
"<RACSignal: 0x97629e0> name: <UITextField: 0x10f306e0> -rac_textSignal"
) reduce: is undefined behavior'
A big part of ReactiveCocoa's philosophy is the elimination of state. State is anything that can change in-place over time, and it's problematic for a few reasons:
You lose past information. Once a variable has been changed, it's like the previous values never existed.
Changes can come from any number of places. It's hard to look at stateful code and know exactly what will happen when — there's poor locality.
Concurrency and asynchrony makes state management difficult, because you now have to coordinate changes across multiple execution points. Determinism is hard to achieve when there are multiple actors that may conflict with each other.
The reason RAC disallows multiple bindings to the same property is that it makes the ordering nondeterministic. If I have two signals bound to enabled, which one takes precedence? How would I know which one sent the latest value?
The reason RAC disallows rebinding the same property is that it's a stateful thing to do. Changing the binding in-place is imperative, and bad for all the reasons outlined above.
Instead, use signals as a declarative way to express changes over time. Everything that changes a property — now or in the future — should be represented in one signal.
Based on your example, it's hard to know exactly what those inputs would be, but let's say you wanted to use different login text fields based on the value of a UISwitch:
// A signal that automatically updates with the latest value of
// `self.emailLoginSwitch.on`.
RACSignal *emailLoginEnabled = [[[self.emailLoginSwitch
rac_signalForControlEvents:UIControlEventValueChanged]
mapReplace:self.emailLoginSwitch]
map:^(UISwitch *switch) {
return #(switch.on);
}];
// Whether the user has entered a valid username and password.
RACSignal *usernameAndPasswordValid = [RACSignal
combineLatest:#[
self.usernameTextField.rac_textSignal,
self.passwordTextField.rac_textSignal
] reduce:^(NSString* username, NSString* password) {
return #(username.length > 0 && password.length > 0);
}];
// Whether the user has entered a valid email address.
RACSignal *emailValid = [self.emailTextField.rac_textSignal map:^(NSString *email) {
return #(email.length > 0);
}];
// Uses different conditions for validity depending (ultimately) on the value of
// `self.emailLoginSwitch`.
RAC(self.loginButton, enabled) = [RACSignal
if:emailLoginEnabled
then:emailValid
else:usernameAndPasswordValid];
In this way, the binding remains valid no matter what the inputs actually are (username/password or email), and we've avoided any need to mutate things at runtime.
Instead of using RAC macro, can you explicitly use :
[[RACSignal
combineLatest:#[
self.usernameTextField.rac_textSignal,
self.passwordTextField.rac_textSignal
] reduce:^(NSString* username, NSString* password) {
return #(username.length > 0 && password.length > 0);
}] setKeyPath:#"enabled" onObject:self.loginButton nilValue:nil];
For version < 2.0, use -toProperty:onObject: instead
I'm not sure if it handle your case, but try it, I'm new to ReactiveCocoa, but sure anyone can help you out, just stay tuned :)

iOS - Program method to execute specific code according to time on the phones clock

Is it possible to execute code when a specific time is reached on an iPhone's clock. Would this be able to work after the iPhone is closed (the screen goes black) but the app was left running (the user did not return to the home screen).
For example, would it be possible for a method to be programmed to go off at 1:30:15 PM with no relation to the current time, and are there any restrictions depending on whether the phone is closed or if the app is running in the background?
I found a similar post here How to generate event on a specific time of clock in C#? but this generates a timer based on the current time to run a method later, instead of using the clock without relation to the current time.
I have created a poor way of doing this-
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
NSLog(#"TESTSTART - TEST START");
// Check
if(timeinfo->tm_hour == 12 && timeinfo->tm_min == 01 && timeinfo->tm_sec == 48)
{
NSLog(#"Run Method");
printf("the time is 12:01:48");
} else {
NSLog(#"ELSE");
[self syncTest];
}
}
This would run a method at 12:1:48, but it is most likely not an acceptable way of doing this. Does anyone know of any better ways to do this and how much strain this way puts on the cpu? Thanks
Use an NSTimer and set the fireDate for whichever date you want the timer to fire on and then catch the notification that it has fired and perform you task.

Resources