# Swap Arbitrage

First of all, for who doesn't know what swaps are, they are implementation of differential interest rates. We aren't going to present here the implementation of swaps starting from the differentials, but the purpose of the article is to show how the swaps may be used to make money with a small amount of risk.

Swap Arbitrage, as a hedging for interest technique, is another application of Kreslik currency rings: this time there is no need for FPI calculation or generation of virtuals. All it matters is that the currency ring to be correctly placed, and to generate interest by its simple existence. I called it "Swap Arbitrage", because, if we cut out the forex impact, which is *usually* fixed due to hedging, it's *like* buying lower and selling higher swaps. The tinier the results, the more risky Swap Arbitrage is, because the swaps need longer time to recover spread loss, time in which fundamental events may alter the interest rates.

1. Generating all the possible versions of available Kreslik rings on a broker

======================================================

In my previous article about the Intercross Arbitrage I covered some BcLib functions helpful in reading MetaTrader content. The first function that needs to be called is GetSymbolsAppendix() to retrieve the symbols appendix, then the GetCurrenciesAndPairs() to get available currencies and pairs. The think pattern of this strategy is the one from Triangular or N-angular Arbitrage. We suppose that we have funds denominated in a currency, that we sell for the next proposed one, and so on, until the ring is completed. This would be hard to implement if we'd use directly the pairs. So we start using the currency list available in UsedCurrencies[] . Suppose we have n currencies (in fact, CurrenciesNo). Every one of them may be , or be not, in a currency ring. Thus we have 2^n combinations. Of course the 2^n include invalid rings, such as 0 , which includes no currency, and others with one or two currencies inside. These are sent to scrapyard and we focus on *almost valid* currency rings with at least three currencies. I said *almost* because at the time of their generation we don't know that the pairs to link up the currencies exist for real. Generation is simple, by using a simple cycle from 0 to (2^n)-1 and converting the number to binary, then completing the result with leading zeros. Say for example UsedCurrencies[] has EUR, USD, GBP, JPY and CHF (only these five). Then for example 13 would be translated to binary as 1101, completed with leading zeros to 01101 (to be five digits length), and then we can read the what the 1s mean: USD, GBP and CHF. Once that we have this combination, we could then *permutate* it to generate *the same ring from all possible directions*. Then we test each resulted ring for validity (if all pairs exist (of course, if the ring has three currencies, a test on original combination is enough, if it has more, there must be a test on each permuted combination). Once valid, we calculate the overall swap, and, if posible, we keep its combination and permutation numbers on hand (I couldn't generate *arrangements*, nor combinations directly ; arrangements are nothing more than *permuted* combinations). After studying all possible combinations or only some of them (say only 3-currency rings) we may have already a best ring, which is the maximum that can be got in given conditions. If there is no best ring, swap arbitrage is impossible.

Powerful BcLib functions to achieve this:

**string ConvertTo(int base,int number)**

The function converts the number in given base. It's reverse function is **int ReconvertFrom(int base,string number)** that converts back to base 10.

**string Padl(string s,int total,string fillwith)**

The function fills string <s> with <fillwith> strings (intended to be chars) to fill up the total length; similar functions: Padr and Padc. These functions originate from FoxPro.

**void GenPermutation(int n,int elem,int &perm[]) **

Generates the permutation <n> (0 - based) of <elem> elements inside array perm. Array will contain numbers from 1 to n.

The opposite of this function is **int FindPermutation(int elem,int perm[])** , which will return given's permutation index.

**bool ContractExists(string symbol)**

Returns true if given symbol exists in the datafeed. It's runtime based, doesn't look up the UsedPairs[] as it can be used for any symbol, not only forex pairs.

**bool ContractIsTraded(string symbol)**

This is an older function, written by me before I realised MarketInfo(...,MODE_TRADEALLOWED) is available. Now the function will ultimately return MODE_TRADEALLOWED inquiry, however this aspect is a bit controversial, although MODE_TRADEALLOWED inquiry may return False when trade context is busy, so when the contract is really traded.

This is a code excerpt from the SwapFinder (one of the first implementations of this algorithm):

for (icomb=maxim;icomb>=0;icomb--) { image=Padl(ConvertTo(2,icomb),CurrenciesNo,"0"); crrcies=Occurs("1",image); valid=false; if (crrcies>=3&&crrcies<=maxcrrcies) { maxperm=Factorial(crrcies)-1; combimg=""; for (iimg=0;iimg<CurrenciesNo;iimg++) { if (StringElement(image,iimg)=="1") combimg=StringConcatenate(combimg,UsableCurrencies[iimg]," "); } WriteLn(StringConcatenate("Studying ",combimg," having ",DoubleToStr(maxperm+1,0)," permutations")); for (iperm=0;iperm<=maxperm;iperm++) { ROA=-1; ROE=-1; valid=IsConfigValid(image,iperm,crrcies,Contracts,Ops); if (valid==True) { EstablishRing(crrcies,Contracts,Ops,Volumes,Usage,TotalUsed,Swaps,Interests,NormalROA,WeightedROA,ROA,ROE,FXResult,FinalROE,False);

As you see, the code is not complete, as none of the **for** cycles is completed; See how <image> is made up by ConvertTo() and Padl() , number of currencies is counted in <crrcies>, then currencies are extracted in the <iimg> cycle (only to be displayed), then permutations are being generated inside the <iperm> cycle, upon validation by IsConfigValid() function, and finally ring is being constructed by the EstablishRing procedure.

2. The mysterious realm of the swaps

============================

The swaps implementation in MetaTrader was always a mystery: the OrderSwap() function works ex-post, it retrieves the total interest cashed/payed on a order. The only way of knowing *before* is by using MarketInfo's MODE_SWAPLONG and MODE_SWAPSHORT. However, what it gives is a mysterious "swap". Is it an interest rate ? NO. Is it an interest ? NO. Ok. Enough fooling around with "Let's twist again". Let's see what it really is.

First of all, the result meaning is given by MODE_SWAPTYPE inquiry:

MODE_SWAPTYPE inquiry answer : 0

Metaquotes documentation : in points;

BcLib coverage: Yes;

Meaning: In pips;

Behaviour: the most stable ever seen;

Broker examples: ATC Brokers, Finex, FXLQ

==============================================

MODE_SWAPTYPE inquiry answer : 1

Metaquotes documentation : In the symbol base currency

BcLib coverage: No*

Meaning: In the first currency of the pair

Behaviour: Unknown,

but probably jumpy due to needed conversion in that currency

Broker examples: FXLQ recently (yes they have them different)

==============================================

MODE_SWAPTYPE inquiry answer : 2

Metaquotes documentation : by interest

BcLib coverage: No

Meaning: Unknown

Behaviour: Unknown

Broker examples: Never reported in wild

==============================================

MODE_SWAPTYPE inquiry answer : 3

Metaquotes documentation : In the margin currency

BcLib coverage: Yes

Meaning: In pips of the account currency

Behaviour: Very unstable

Broker examples: InterbankFX, FXDD

==============================================

The Swap2Interest_Volume from BcLib converts the swap to interest on a given volume (not lot). Useful when building swap strategies because you can find the actual swap before it would come.

*Not in the last version of BcLib. Find and replace the Swap2Interest_Volume function with the next body for this swap type to be included:

double Swap2Interest_Volume(double volume,int swapmode,string contract,string appendix) { double m_tick; double m_lotsize; double swap; double gc; double res; if (PairsNo==0) GetCurrenciesAndPairs(appendix); string contractf=StringConcatenate(contract,appendix); int swt=MarketInfo(contractf,MODE_SWAPTYPE); if (swt!=0&&swt!=1&&swt!=3) { if (BcLibAlerts==True) Alert("Swap2Interest***** : swap type "+DoubleToStr(swt,0)+" not implemented !"); return(0); } if (swapmode==MODE_SWAPLONG||swapmode==OP_BUY||swapmode==OP_BUYLIMIT||swapmode==OP_BUYSTOP) swap=MarketInfo(contractf,MODE_SWAPLONG); else swap=MarketInfo(contractf,MODE_SWAPSHORT); if (swt==0) { m_tick=MarketInfo(contractf,MODE_TICKVALUE); m_lotsize=MarketInfo(contractf,MODE_LOTSIZE); return(swap*m_tick*(volume/m_lotsize)); } if (swt==1) { m_lotsize=MarketInfo(contractf,MODE_LOTSIZE); gc=GetCurrency(StringSubstr(contractf,0,3),AccountCurrency(),appendix); res=swap*gc*(volume/m_lotsize); if (gc==0) { if (BcLibAlerts==True) Alert("Swap2Interest***** : could not convert swap type 1 for "+contractf+" as GetCurrency() failed! Check contract and appendix!"); } return(res); } if (swt==3) { m_lotsize=MarketInfo(contractf,MODE_LOTSIZE); return((volume*swap)/m_lotsize); } }

You can easily see in the code how the swap types were implemented:

Type 0: swap*m_tick*(volume/m_lotsize)

Type 1: swap*gc*(volume/m_lotsize), where gc is the first currency of the pair converted to account currency

Type 3: (volume*swap)/m_lotsize , similar to type 0 but without multiplicating with the tick value;

Picture of the SwapFinder_script running on ATC Brokers:

http://img222.imageshack.us/img222/2171/pictureofswapfinderscricm4.jpg

SwapFinder parameters:

extern int MarginUsage=90;

extern int MaxCurrenciesUsed=3;

extern bool JustTesting=False;

extern int Slippage=3;

extern bool ShowNegatives=False;

MarginUsage - the percent of the margin (or the leverage) that's used for the trades altogether;

MaxCurrenciesUsed - for 0, scans all the combinations (from 3 to n) currencies; for another value, scans combinations having from 3 to that value;

JustTesting - is a safety measure; it will trade only when the script is allowed to trade from the properties and JustTesting is set to True;

Slippage - trading slippage admitted;

ShowNegatives - if true, will display financial data gathered on negative swap rings too.

Again, be cautious about the MarginUsage. Don't set it too to near 100%, as your effective margin during initiation of trades might get under the required margin and you would run out of funds before completion of trades. Also, be careful that in dangerous situations broker's datafeed may be damaged (the problem I've been talking on the Intercross Arbitrage article) and you won't be fully hedged, your trades being placed in profit/loss territory until the issue being solved.

**How to read the SwapFinder window**

Usage - the volume , in account currency , of the trade. Under the usages there is their sum, interpreted as **Total Assets**

% - the weight of the trade volume in total traded. The trades must be hedged, so the % value must be almost the same at them all equal to (1/no. of trades)*100

Op. - trade direction

Volume - the volume of the trade, in units of the first currency of the pair

Lots - the volume, in lots

Contract - the pair symbol

Swap - the exact swaps for one lot, as answered by MODE_SWAPLONG and MODE_SWAPSHORT inquiries

Interest - the real interest earned/payed on the trade

NormalROA - the ROA (Return on Assets) of the trade as (Interest/Usage * 100) * 365 (later edited)

WeightedROA - the Normal ROA as weighted (by the percent occupied in Total Assets)

ROA is the sum of Weighted ROAs.

ROE (Return on Equity) calculated as ((ROA * Total Assets) / Account Equity) * 100

Forex result = costs of spreads

Final ROE = ROE - Forex result

3. Butterfly : a nonlinear hedge

=======================

Some time ago, as I was playing with pencil on paper drawing currency rings and trying to imagine a different kind of hedge that could make more swaps, I came up with the idea of a butterfly hedge ( because two currency rings with a common currency (common tip) look like the wings of a butterfly). However, two completed currency rings, with or without a common tip, are independant rings. They cannot produce more swaps, as one would be , say the best ring, and the other one, a lesser ring. However, this measure could add more safety to swap arbitrage, as it produces a slight *diversification* of the "investments" (the two currency rings). If we link up N currencies we obtain a simple , linear , currency ring, where EVERY CURRENCY IS EQUALLY BOUGHT AND SOLD. However, noone says it must be bought and sold once!

http://img166.imageshack.us/img166/8964/butterflyfm1.jpg

This was the first version of the butterfly hedge. The points are currencies. Among them O is mirrored (the two O represent the same currency). Features:

- the Z currency is bought 3 times (OZ, YZ, XZ) and sold 3 times (ZO, ZP, ZQ).

- the O currency is bought 3 times (PO, QO, ZO) and sold 3 times (OZ, OY, OX).

A better version of this hedge would be one without the needless ZO and OZ relationships and still the hedge would be a butterfly, since the "wings" could not work seperately.

Each model has a mirror. Just like any atom from Intercross Arbitrage could have played the role of bid or ask, similar any butterfly can be mirrorized simply by reversing the direction of the arrows.

This model doesn't look like a butterfly at all but it respects the same principles.

**Looks like electronic circuitry huh?**

http://img514.imageshack.us/img514/2331/rectanglehedgeoe2.jpg

(The double arrowed edges mean that volume , in account currency, is double than the one used on the other edges).

Now I don't say the butterfly hedges are necesarilly better than the currency rings. It may be worse in many situations, but tt's a different way of thinking hedge.

SwapButterfly's parameter list is similar to SwapFinder's. However, in the start(), you must assign UseModel to one of the preexistent models defined, or to a new one.

*TIP ABOUT BROKERS: If you find a swap hole in the broker's datafeed (meaning for one pair the cashed swap is bigger than the payed swap, don't just go long and short simultaneously, as this will alert the broker to repair the datafeed. Better place it as a ring or a butterfly, sure this opportunity will be included in the best provided solution).

## 70 Comentarii

## Comentarii Recomandate