2

my target is to have a plot that shows Stochastic oscillator on forex market, and in order to validate which parameter is the best one to setup it, I would use a slider to modify it and show updated result on plot.

I have my historical data, for a defined pair (let say AUDUSD) and after loading it, I calculate Stocastic oscillator:

function [stoch, fk, dk] = stochastic(n, k, d)
    X=csvread("AUDUSD_2017.csv");
    C=X(2:length(X),5);
    L=X(2:length(X),4);
    H=X(2:length(X),3);
    O=X(2:length(X),2);
    for m=n:length(C)-n
        stoch(m)=((C(m)-min(L(m-n+1:m)))/(max(H(m-n+1:m))-min(L(m-n+1:m))))*100;

    endfor

for m=n:length(C)-n

    fk(m)=mean(stoch(m-d:m));

 endfor
for m=n:length(C)-n

    dk(m)=mean(fk(m-d:m));
endfor


endfunction

This is a picture of what I have when I plot stoch, fk and dk:

Plot based on parameters (14,7,7 as insput

I would add 3 sliders to the figure in order to change, in a range, parameters as input, so i.e. to have a slider that changes first parameter "n" between 3 and 50, "k" between 2 and 20, and "d" between 2 and 20.

I would use UI package in octave, can someone address me to have a plot updated when I use sliders?

Francesco

  • see my answer [here](http://stackoverflow.com/questions/40570494/minimal-example-of-a-standalone-matlab-gui-app/40570717#40570717) for a super-simple example – Tasos Papastylianou Apr 20 '17 at 13:21
  • @TasosPapastylianou Your example doesn't work out of the box in octave. Have you tried it? – Andy Apr 20 '17 at 15:13
  • @TasosPapastylianou I'll look at your link! Thank you very much – Francesco Piantedosi Apr 21 '17 at 06:59
  • @Andy oh that's right, sorry, I mention it at the bottom that for the time being one should avoid nested functions in Octave for callbacks, but I should have pointed it out to Francesco here. Thanks for pointing it out. In which case, I might as well fix the code for Octave and post as an answer I guess. – Tasos Papastylianou Apr 21 '17 at 07:42

2 Answers2

7

Have a look at this demo which will give you an window like that which should answer all your questions:

demo uicontrol

The relevant parts for your specific questions are:

h.noise_slider = uicontrol ("style", "slider",
                            "units", "normalized",
                            "string", "slider",
                            "callback", @update_plot,
                            "value", 0.4,
                            "position", [0.05 0.25 0.35 0.06]);
....
 noise = get (h.noise_slider, "value");

Be sure to use the Qt toolkit!

Andy
  • 7,931
  • 4
  • 25
  • 45
5

Andy pointed out in the comments that the example I linked to doesn't work on octave out of the box; this is because Octave doesn't like nested functions for certain things for the time being, so I've reproduced an 'octave version' below. Update (2023-03-31): nested functions have been supported for a while now: see update below old post for an example

%%%%%% In file myplot.m %%%%%
function myplot

  %% Create initial figure and spiral plot
  figure;  axes ('position', [0.1, 0.3, 0.8, 0.6]);
  global t;   t = linspace (0, 8*pi, 100);
  x = t .* cos(t);  y = t .* sin(t);
  plot (x, y);  axis ([-100, 100, -100, 100]);

  %% Add ui 'slider' element      
  hslider = uicontrol (                    ...
         'style', 'slider',                ...
         'Units', 'normalized',            ...
         'position', [0.1, 0.1, 0.8, 0.1], ...
         'min', 1,                         ...
         'max', 50,                        ...
         'value', 10,                      ...
         'callback', {@plotstuff}          ...
       );
end

%% Callback function called by slider event
%% Also in file myplot.m (i.e. a subfunction)
function plotstuff (h, event)
  global t;
  n = get (h, 'value');
  x = n * t .* cos(t);  y = n * t .* sin(t);
  plot (x, y);  axis ([-100, 100, -100, 100]);
end

enter image description here

UPDATE (2023-03-31)

Not sure at which point nested functions got properly supported, but at least as of octave 8.1 they are. Therefore the old example that used to be linked in the comments (but now points to a deleted matlab question) now works as intended. I am reproducing it here for future reference. Using a nested function instead of a subfunction is convenient, since this gives you access to the parent function's local variables, which removes the need for 'global variable' hacks, etc.

%%%%%% In file myplot.m %%%%%
function myplot

  %% Create initial figure and spiral plot
  figure;  axes ('position', [0.1, 0.3, 0.8, 0.6]);
  t = linspace (0, 8*pi, 100);  x = t .* cos(t);  y = t .* sin(t);
  plot (x, y);  axis ([-100, 100, -100, 100]);

  %% Add ui 'slider' element      
  hslider = uicontrol (                    ...
         'style', 'slider',                ...
         'Units', 'normalized',            ...
         'position', [0.1, 0.1, 0.8, 0.1], ...
         'min', 1,                         ...
         'max', 50,                        ...
         'value', 10,                      ...
         'callback', {@plotstuff}          ...
       );

  %% Callback function called by slider event
  function plotstuff (h, event)
    n = get (h, 'value');
    x = n * t .* cos(t);  y = n * t .* sin(t);
    plot (x, y);  axis ([-100, 100, -100, 100]);
  end
end
Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
  • 1
    nice short answer. Btw, we should integrate some uicontrol demos into core for GNU Octave 4.4.... – Andy Apr 21 '17 at 08:54