Patrick,

Vectors, matrices, and frames, oh my!

Your post was very helpful and is much appreciated.

Below is my first working demo, which incorporates your fixes and illustrates:

 Doing a calculation in R and returning it for display in a plot or Exploration

 Selecting an array from an R-side Matrix result for return to AB

 Saving the R workspace so that all R-side variables can later be examined

 Building R command strings based on AB parameters

 Checking the class of an object

As I move along, I hope to create more.  I'll be accumulating them here:  
http://www.codefortraders.com/phpBB3/viewforum.php?f=60

- Progster

-----------


    /*
       R_SMA_01.p2         by Progster

       Calculate SMA in R by using package:TTR .

       This code demonstrates:

          Doing a calculation in R and returning it for display in a plot or 
Exploration
       
          Selecting an array from an R-side Matrix result for return to AB
       
          Saving the R workspace so that all R-side variables can later be 
examined
       
          Building R command strings based on AB parameters

       You are allowed to bypass all calls to R by setting DoRStuff to N.
       This allows inspection of native-only Close and MA for confidence 
building.

       Thanks to Patrick who noted key concepts and provided corrected code!

       This test worked with:

       AB 5.3
       RAndFriendsSetup2092V3.0-17-2.exe:  R 2.9.2, statconnDCOM 3.1-2B6
       RMath 1.0.0      per Tools -> Plug-ins ...

       Note:  package:TTR must be installed separately

       After experimentation, use the Parameter Reset button to return to 
"correct" default values

    */

    //   Uncomment to turn QuickAFL OFF
    //   Many of the displayed numbers will not seem intuitive if QuickAFL is 
on.
    //   Alignment issue can appear if QuickAFL is on.
    //   So, to "get on with it" in the simplest fashion, turn QuickAFL OFF 
when working with R
    SetBarsRequired( sbrAll, sbrAll );      

    //   Parameter settings
    PlotCandles = ParamToggle( "PlotCandles", "N|Y", 1 ) ;
    PlotNativeMA = ParamToggle( "PlotNativeMA", "N|Y", 1 ) ;

    MA_Length = Param( "MA_Length", 20, 1, 50, 1 ) ;

    DoRStuff = ParamToggle( "DoRStuff", "N|Y", 1 ) ;

    PlotRClose = ParamToggle( "PlotRClose", "N|Y", 1 ) ;
    AddToRClose = Param( "AddToRClose", 0, -200, 200, 1 ) ;
    RCloseShift = Param( "RCloseShift", 0, -20, 20, 1 ) ;
    RMAShift = Param( "RMAShift", 0, -20, 20, 1 ) ;
    ExplorationShift = Param( "ExplorationShift", 0, -20, 20, 1 ) ;

    Save_R_Workspace = ParamToggle( "Save_R_Workspace", "N|Y", 0 ) ;

    //   Load needed non-default R libraries
    if( DoRStuff ){
       EnableTextOutput( False ) ;
       RMathDebugOn() ;
       RMathProcedure( "library( TTR )" ) ;            //   package:TTR   
(Technical Trading Rules)
       RMathProcedure( "library( fSeries )" ) ;      //   package:fSeries
       RMathDebugOff() ;
    }

    //   Build R command strings
    Close_RStr = "MyClose <- MyClose + " + NumToStr(AddToRClose, 1.0)  ;
    printf( "Close_RStr:  " + Close_RStr + "\n" ) ;            //   e.g.  
MyClose <- MyClose + 0

    //   Dynamically build the R command string to calculate the specified SMA
    MA_RStr = "MyMA <- SMA( MyClose, " + NumToStr(MA_Length, 1.0) + ")" ;
    printf( "MA_RStr:      " + MA_RStr + "\n" ) ;            //   e.g.  MyMA <- 
SMA(MyClose, 20)

    //   Do R-side calculations
    if( DoRStuff ){

       RMathSetArray(Close, "MyClose" ) ;                     //   send AB 
Close array to R
       
       // To prove changes can be made on R side, and then returned
       //   RMathProcedure( " MyClose <- MyClose + 1 " ) ;      //   not dynamic

       //   default Close_RStr:  "MyClose <- MyClose + 0" 
       RMathProcedure( Close_RStr ) ;   
       
       //   These work but they are are not dynamic
       //   RMathProcedure( " MyMA <- SMA(MyClose) " ) ;       // works on R 
side, per examination of saved workspace
       //   RMathProcedure( " MyMA <- SMA(MyClose, 3) " ) ;    // works on R 
side, per examination of saved workspace
       
       //   Dynamic MA calc in R, varies per MA_Length parameter.
       //   default MA_RStr:  "MyMA <- SMA(MyClose, 20)"
       //   Note: MyMA is not an Array, it is a Matrix! (that's the TTR package 
implementation)
       RMathProcedure( MA_RStr ) ;       // works on R side, per examination of 
saved workspace
       

       //   IMPORTANT:   Nothing will come out right if you attempt to pass 
back NA values from R to AB!
       //   One way to fix this is shown here, using substituteNA()

       //   Deal with R-side NA values   
       RMathProcedure( " MA_Clean <- substituteNA(MyMA, type = <DQ>zeros<DQ>) " 
) ;      //   substitution to new name OK
       
       RMathProcedure( " MyMA <- substituteNA(MyMA, type = <DQ>zeros<DQ>) " ) ; 
        //   self-substitution also OK
    }

    //   RMathDebugOn() ;
    bi = BarIndex() ;         //   0 to (N - 1)

    //   from 1 to N, this is the one that will match the crosshairs, PROVIDED 
QuickAFL is OFF
    bn = bi + 1 ;   

    arrayitem = SelectedValue( bi ) - bi[ 0 ];
    printf( "Close at selected bar:" + NumToStr( Close[ arrayitem ], 1.2 ) + 
"\n" ) ;

    LBI = LastValue( bi ) ;
    SBI = SelectedValue( bi ) ;
    SBN = SelectedValue( bn ) ;
    FVB = Status("firstvisiblebar");
    LVB = Status("lastvisiblebar");
    LVBI = Status("lastvisiblebarindex");      //   note:  case matters!
    BTR = LBI - LVBI  ;   //   actual bars to the Right of selected bar

    EnableTextOutput( True ) ;
    printf( "\n" + "The following numbers make obvious sense only if QuickAFL 
is OFF : \n" ) ;
    printf( "LBI: " + NumToStr(LBI, 1.0) + "\n" ) ;
    printf( "BarCount: " + NumToStr(BarCount, 1.0) + "\n" ) ;
    printf( "SBI: " + NumToStr(SBI, 1.0) + "\n" ) ;      //   Selected Bar Index
    printf( "SBN: " + NumToStr(SBN, 1.0) + "\n" ) ;      //   Selected Bar 
Number
    printf( "FVB: " + NumToStr(FVB, 1.0) + "\n" ) ;
    printf( "LVB: " + NumToStr(LVB, 1.0) + "\n" ) ;
    printf( "LVBI: " + NumToStr(LVBI, 1.0) + "\n" ) ;
    printf( "BTR: " + NumToStr(BTR, 1.0 ) + "\n\n" ) ;
    EnableTextOutput( False ) ;

    //   Return R-side calculations to AB
    if( DoRStuff ){

       rtnClose = RMathGetArray( "MyClose" ) ;

       //   rtnMA = RMathGetArray( "MyMA" ) ;            //   bogus call!  MyMA 
is a Matrix, not an array!

       /*
       RMathDebugOn() ;
       RMathProcedure( " class(MyMA) " ) ;            //   display the R type 
of MyMA in the RMath debug window
       RMathDebugOff() ;
       */

       rtnMA = RMathGetArray( "MyMA[,1]" ) ;            //   NOTE: Matrix 
notation !!!
       rtnClean = RMathGetArray( "MA_Clean[,1]" ) ;      //   NOTE: Matrix 
notation !!!

    }

    //   Optionally save the R workspace image.
    //   If saved, you can later reopen it in an interactive session of R and 
examine everything.
    if(Save_R_Workspace){
       RMathDebugOn() ;
       //   Set desired output directory
       RMathProcedure( "  setwd( <DQ>C:/Users/Steve/Documents<DQ> )  " ) ;
       //   Save the workspace to specified file in the cwd
       RMathProcedure( " save.image( file=<DQ>R_SMA_01.p2.Rdata<DQ>) " ) ;      
//   works!
       RMathDebugOff() ;
    }

    if(PlotCandles == 1)
       Plot( Close, "Candle Close", colorGrey50, styleCandle, 0, 0, 0, 0 ) ;

    if(PlotNativeMA == 1)
       Plot( MA(Close, MA_Length), "NativeMA", colorWhite, styleLine, 0, 0, 0, 
7 ) ;

    if( DoRStuff ){

       if(PlotRClose){
          //   Plot( rtnClose, "rtnClose", colorWhite, styleLine, 0, 0, 0, 8 ) 
;                     //   Zorder of 8 puts this on top
          Plot( Ref(rtnClose, RCloseShift ), "rtnClose", colorWhite, styleLine, 
0, 0, 0, 8 ) ;      //   Zorder of 8 puts this on top
       }   
       
       Plot(Ref(rtnMA, RMAShift), "rtnMA", colorRed, styleDashed, 0, 0, 0, 8 ) ;
       //   Hack to prevent plot of leading zeros which are really NA (but 
affects all zeros!)
       //   Plot(IIf( Ref(rtnMA, RMAShift) != 0, Ref(rtnMA, RMAShift), Null ), 
"rtnMA", colorRed, styleDashed, 0, 0, 0, 8 ) ;
       
       //   Plot(Ref(rtnClean, RMAShift), "rtnClean", colorYellow, styleDashed, 
0, 0, 0, 8 ) ;
       //   Hack to prevent plot of leading zeros which are really NA (but 
affects all zeros!)
       Plot(IIf( Ref(rtnClean, RMAShift) != 0, Ref(rtnClean, RMAShift), Null ), 
"rtnClean", colorYellow, styleDashed, 0, 0, 0, 8 ) ;
    }

    EnableTextOutput( True ) ;
    printf( "Close: " + NumToStr(Close, 6.2 ) + "\n" ) ;
    if( DoRStuff ) printf( "rtnMA: " + NumToStr(rtnMA, 6.2 ) + "\n" ) ;
    EnableTextOutput( False ) ;

    //   Show all results in the Exploration
    Filter = 1 ;

    AddColumn( Close, "Close" ) ;

    if( DoRStuff ){
       AddColumn( rtnClose, "rtnClose" ) ;

       //   Seems correct at ExplorationShift = 0
       AddColumn( Ref(rtnMA, ExplorationShift), "rtnMA" ) ;
       AddColumn( Ref(rtnClean, ExplorationShift), "rtnClean" ) ;

    }




--- In [email protected], "vlanschot" <vlansc...@...> wrote:
>
> Hi Progster,
> 
> Appreciate your initiative, so let me give you some help to get you going 
> (further).
> 
> 1) Remember that R has multiple ways of handling data, including multiple 
> arrays in matrix format. This is what the SMA function actually did. Using 
> the RMathDebugOn(), you can see that the MyMA-series shows a format like this:
> 
> [1230,] 99.0
> [1231,] 100.0
> etc.
> 
> It means that it is a matrix. See my code below on how to call the 1st column 
> of it (i.e. your array with data).
> 
> 2) Remember that, unless you use R's timeseries functions, R will not 
> recognize AB's "bars to the right" settings. It means that in charts you'll 
> see a drop-off to zero for, say, the last 10 bars. This is why I use AB's Ref 
> function below.
> 
> 3) Please have a look at the package Zoo, as well as related timeseries 
> packages. It allows you much more flexibility to link R's series to dates, 
> etc. On that note, I often use AB's Status("firstvisiblebar"), etc to 
> manipulate R's series by filling its matrix notation (i.e. [...,...]) with 
> these "barnrs". You need to play around with it, but you'll get the idea. 
> 
> Here is the adjusted code which will correct the errors:
> 
> RMathSetArray(Close, "MyClose" ) ;
> RMathProcedure( " MyClose <- MyClose + 1 " ) ; // to prove changes can be 
> done on R side, AND returned
> RMathProcedure( " MyMA <- SMA(MyClose) " ) ; // seems to work on R side, 
> based on examination of saved workspace
> 
> RMathProcedure( " MA_Clean <- substituteNA(MyMA, type = <DQ>zeros<DQ>) " ) ; 
> rtnClose = RMathGetArray( "MyClose" ) ;
> 
> RMathDebugOn() ;
> FVB = Status("firstvisiblebar");
> LVB = Status("lastvisiblebar");
> 
> rtnMA = RMathGetArray( "MyMA" ) ;
> rtnClean = RMathGetArray( "MA_Clean[,1]" ) ;
> 
> Plot( rtnClose, "rtnClose", colorBlue ) ;
> Plot( Ref(rtnMA,-10), "rtnMA", colorRed ) ;
> Plot(Ref(rtnClean,-10), "rtnClean", colorGreen ) ;
> 
> Finally, you are right: the link with R opens a new universe. Still, I don't 
> have time to support the plugin to a larger extent. Again, your initiative is 
> much appreciated in that regard. But at the end of the day, people have to be 
> willing to spend time learning it, and thus R. It took me a few weeks, but 
> now I can anything (except the coffee thing ;-)).
> 
> 
> best,
> 
> PS
> 
> --- In [email protected], "progster01" <progster@> wrote:
> >
> > Hello RMath plug-in users!
> > 
> > Beginning work with the RMath plug-in for AB, I've had success with simple 
> > tests such as passing Close to the R side, adding a number to it, passing 
> > it back to the AB side, and then showing the results on a chart on in an 
> > Exploration.
> > 
> > However, adding just a little more complexity seems to introduce problems.  
> > 
> > Below is a complete code that loads a couple of extra packages and then 
> > attempts to generate a simple moving average (SMA) on the R side and pass 
> > it back to the AB side.
> > 
> > After saving the session on the R side (code provided, just un-comment it 
> > and set the path as desired), the session can be reloaded in R 
> > interactively and it can be confirmed that the SMA was generated correctly, 
> > incl. a few NA values at the front of the array while it ramps up.
> > 
> > However, something is not right when passing the SMA back to AB, as the 
> > result on the AB side is an array of zeros.  This is true even after an 
> > attempt to substitute 0 for NA (on the R side), on the theory that NA does 
> > not pass pack to AB cleanly (?).
> > 
> > So, what appears as if it should work, does not.
> > 
> > Is the code incorrect?
> > 
> > Does RMath have some limitation in this respect?
> > 
> > Is there an aspect of series handling on the R side I need to learn more 
> > about?
> > 
> > Are there perhaps version incompatibilities in my installation?
> > 
> > I'm appealing to other users of the RMath plugin here to see if anyone can 
> > shed some light on this, or report that this code works or does not work on 
> > their installation.
> > 
> > I was hoping to make available a short suite of demos using RMath and AB, 
> > but I seem to have driven directly into a hole!
> > 
> > Public or private responses are welcome.  So far, it seems there are very 
> > few postings here related to RMath.  The potential of the AB-R connection 
> > is huge, IMO, but it's starting to seem that a bit of user-to-user 
> > co-support may be important to have available.  I'll certainly throw in on 
> > this myself if I can get "over the hump".
> > 
> > At this point, it doesn't look like there's any danger of swamping the 
> > message-base here with RMath discussion.  But if that becomes an issue, we 
> > can take it to the CFT Forum or elsewhere.
> > 
> > Thanks to anyone who can take a look and comment.
> > 
> > - Progster
> > 
> > /*
> >     R_SMA_01.p1                     by Progster
> > 
> >     Attempt to calculate SMA in R by using package:TTR .
> > 
> >     Problem is, the rtnMA array is all zeros on the AB side, 
> >     even though it is calculated correctly on the R side.
> > 
> >     This test failed with:
> > 
> >     AB 5.3
> >     RAndFriendsSetup2092V3.0-17-2.exe:  R 2.9.2, statconnDCOM 3.1-2B6
> >     RMath 1.0.0             per Tools -> Plug-ins ...
> > 
> >     Note:  package:TTR must be installed separately
> > 
> > */
> > 
> > EnableTextOutput( False ) ;
> > RMathDebugOn() ;
> > RMathProcedure( "library( TTR )" ) ;                        //      
> > package:TTR   (Technical Trading Rules)
> > RMathProcedure( "library( fSeries )" ) ;            //      package:fSeries
> > RMathDebugOff() ;
> > 
> > RMathSetArray(Close, "MyClose"  ) ;
> > RMathProcedure( " MyClose <- MyClose + 1 " ) ;                      //      
> > to prove changes can be done on R side, and returned
> > 
> > RMathProcedure( " MyMA <- SMA(MyClose, n=10) " ) ;          //      seems 
> > to work on R side, based on examination of saved workspace
> > 
> > //  RMathProcedure( "        MyMA <- filter(MyClose, rep(1/5,5), sides=1) " 
> > ) ;             //      
> > http://tolstoy.newcastle.edu.au/R/help/04/09/4302.html
> > 
> > //  RMathProcedure( " MyMA <- removeNA( MyMA ) " ) ;        
> > 
> > //  With or without this call, rtnMA does not come out correct on the AB 
> > side
> > RMathProcedure( " MA_Clean <- substituteNA(MyMA, type = <DQ>zeros<DQ>)  " ) 
> > ;               //      fSeries:substituteNA
> > 
> > //  RMathProcedure( "  " ) ;        
> > 
> > rtnClose = RMathGetArray( "MyClose" ) ;
> > 
> > rtnMA = RMathGetArray( "MA_Clean" ) ;
> > 
> > //  Finished on the R side - save image if desired.
> > //  You can save the image here, then reload it in an R session 
> > //  to confirm the R side calculation of MA_Clean.
> > 
> > /*
> > RMathDebugOn() ;
> > //  Set desired output directory
> > RMathProcedure( "  setwd( <DQ>C:/Users/Steve/Documents<DQ> )  " ) ;
> > //  Save the workspace to specified file in the cwd
> > RMathProcedure( " save.image( file=<DQ>R_SMA_01.p1.Rdata<DQ>) " ) ;         
> > //      works!
> > RMathDebugOff() ;
> > */
> > 
> > Plot( rtnClose, "rtnClose", colorBlue ) ;
> > Plot( rtnMA, "rtnMA", colorRed ) ;
> > 
> > EnableTextOutput( True ) ;
> > printf( "Close: " + NumToStr(Close, 6.4 ) + "\n" ) ;
> > printf( "rtnMA: " + NumToStr(rtnMA, 6.4 ) + "\n" ) ;
> > EnableTextOutput( False ) ;
> > 
> > //  Show all results in the Exploration
> > Filter = 1 ;
> > 
> > AddColumn( Close, "Close" ) ;
> > AddColumn( rtnClose, "rtnClose" ) ;
> > AddColumn( rtnMA, "rtnMA" ) ;
> >
>


Reply via email to