Using Foreign and SetForeign

In the reference it says

Foreign function synchronizes the data file
you are referencing with the currently selected symbol.
Synchronization makes sure that EACH bar of FOREIGN data
matches exactly with each bar of currently selected symbol.
So if DateNum() function returns 990503 for given bar
then Close array represents the CLOSE of currently selected symbol at May 3, 1999
and Foreign(“SYMBOL”, “C”) represents close of foreign symbol at May 3, 1999 TOO.
This is absolutely necessary because otherwise you won’t be able
to do ANY meaningful operations involving both selected symbol and foreign symbol.

Question : Any AFL code available to do check if I should have synchronization problems ?

Are you looking to compare the two ? Something like this maybe

method1C = Foreign( "IWM", "C" ); 
method1O = Foreign( "IWM", "O" ); 
method1H = Foreign( "IWM", "H" ); 
method1L = Foreign( "IWM", "L" ); 
method1V = Foreign( "IWM", "V" ); 


SetForeign("IWM");
method2Close = Close;
method2Open = Open;
method2High = High;
method2Low = Low;
method2Volume = Volume;
RestorePriceArrays();

Filter=1;
AddColumn(method1C, "method1C");
AddColumn(method2Close, "method2Close");
AddColumn(method1O, "method1O");
AddColumn(method2Open, "method2Open");
AddColumn(method1V, "method1V");
AddColumn(method2Volume, "method2Volume");


Produces this Exploration,

2 Likes

@AMSIEV Unless you have a very good reason, you should always use the default fixup=1 when calling Foreign or SetForeign. Similarly, it is also a good idea to set the “Pad and align all data to reference symbol” in the Backtester settings when testing your formulas with more than one symbol. If you follow this recommendation, you should not have any synchronization problems. However, if you really need to test if two arrays have different values, you could use a function like this:

// Calculate the cumulative number of differences between two arrays.
// Tiny floating point differences are ignored.
//
// Parameters
// ----------
// array1 : float array
//   First array
// array2 : float array
//   Second array
//
// Returns
// -------
// diff : integer array
//   cumulative number of differences between array1 and array2.
function CompareArrays(array1, array2)
{
  return Cum(!AlmostEqual(array1,array2));
}

Larry/Steve thanks for your answer. First of all I am always using FixUp=1 in Foreign and SetForeign. Also I am using a long term and tested index (^GSPC) as reference symbol in the Backtester settings. Still I am having problems when using Foreign/SetForeign. According to Amibroker HelpDesk the problem may have to do with synchronization …

Also I do not understand your code. Should the comparison of Foreign and SetForeign give me an indication about synchronization problems ??? AFAIK there is no difference between Foreign and SetForeign. Also see :

Single SetForeign( “ticker” ) call is EQUIVALENT to the following sequence:
C = Foreign( “ticker”, “C” );
O = Foreign( “ticker”, “O” );
H = Foreign( “ticker”, “H” );
L = Foreign( “ticker”, “L” );
V = Foreign( “ticker”, “V” );
OI = Foreign( “ticker”, “I” );
Avg = ( C + H + L )/3;

but 6x faster (SetForeign takes about the same time as single foreign). To restore original prices call RestorePriceArrays()

Kind regards, Ton.

@AMSIEV I misunderstood your original post. The little code snippet I wrote was so you could compare the two (which of course should be equal) and has nothing to do with synchronization problems. My mistake.

Sorry Ton I have not run into that problem and you appear to have already looked into the only problem I could think of, data holes (which is filled by your use of fixup=1).

Can you say more about the problems you are having with Foreign/SetForeign?

I am using the code from above.
Foreign = 52 week HILO
Open = 52 week high
High = 52 week low
Pad and align data to SP500

Some days I get same data for open, high, low close in 'exploration'

method1O = Foreign( "HILO", "O" );
method1H = Foreign( "HILO", "H" );
method1L = Foreign( "HILO", "L" );
method1V = Foreign( "HILO", "C" );

SetForeign("HILO");
method2Close = Close;
method2Open = Open;
method2High = High;
method2Low = Low;
method2Volume = Volume;
RestorePriceArrays();

SP500= Foreign("^gspc","C",True);

Filter=1;
AddColumn(SP500, "SP500");
AddColumn(method1O, "method1O");
AddColumn(method2Open, "method2Open");
AddColumn(method1H, "method1H");
AddColumn(method2High, "method2High");

image

Single SetForeign call is equivalent to multiple Foreign calls. Check out here.

Also check out fixup parameter

fixup parameter controls if data holes are filled with previous bar data or not.
0 - the holes are not fixed
1 - default value - missing data bar OHLC fields are all filled using previous bar Close and volume is set to zero.
2 - (old pre-4.90 behaviour) - causes filling the holes in the data with previous O, H, L, C, V values

If you insert code then please read here for getting guidance.

1 Like