- Citește mai mult...
- 16 comentarii
- 85.742 citiri
-
Număr mesaje
204 -
Înregistrat
-
Ultima Vizită
-
Zile Câștigate
1
Tip conținut
Profiluri
Forumuri
Bloguri
Intrări Blog postat de TheEconomist
-
Finally, after some work, the blog is back in business, and with a new address : http://mqlmagazine.com
-
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).
- Citește mai mult...
- 70 comentarii
- 734.624 citiri
-
As I promised to my readers, I am returning with an article about the "new" currency futures contracts introduced by the non-NFA regulated brokers. Together with arbitrageable commodities, currency futures prove to be some of the most valuable contracts to be found in a broker's datafeed.
1. Basics of Currency Futures
======================
Currency futures are the standardized, transferrable version of currency forwards. Currency forward contracts lock in the price at which an entity can buy or sell a currency on a future date. But how is a currency futures priced?
A spot forex rate is the rate at which two currency amounts are equal : for example, 10000 USD are (at a moment, "spot") equal to 1.230.000 JPY at 123 JPY/USD rate. Since the time value of a currency is given by the interest, the currency futures rate which equalizes them incorporates the differential rate.
Suppose we have two currencies, A and B, both equal now, as A/B = 1 spot rate.
A interest in 20%, while B interest is 5%
so there is a rate which equalizes 1.20 with 1.05 , and that rate is 0.875 , as 1.20 x 0.875 = 1.05
Hence the futures formula:
http://img514.imageshack.us/img514/6458/futuresformulaax8.jpg
In our case, the spot rate didn't had any effect, since it was 1.
We must know 2 elements:
1. The interest rates
2. Futures expiry dates
1. The interest rates
That's an easy one. A reliable source for this can be found here on FXStreet .
2. Futures expiry dates
This can be done in a few ways:
a. Download WHC's MetaTrader. Then point to Market Watch, right click, (Show All if they are not already) , Show All, then Properties, then expand the Currencies top folder.
b. Directly from CME website (see below)
Of course, when you use the formula you must calculate the time to expiry as precise as possible , because it influences the interests put inside the formula.
For example, if we have 90 days to expiry, that 1+C2 Interest Rate % from the formula transforms in 1 + (0.5/100) / 365 x 90 = 1.001232876
Almost forgot: depending on the strategy you'll decide to use, it may be useful to check when the next meetings of the central banks officials will take place and also what's the expectation about the interest rates.
2. Spot-to-Futures Arbitrage
=====================
Since the futures are linked to the spot by the interest to expiry, and futures at expiry equalizes the spot (this equalization is a feature of all futures contracts that have a spot counterpart) there are two possible spot-to-futures arbitrages:
http://img128.imageshack.us/img128/4825/eurusdarbitragebigfa2.jpg
a. exploiting the difference between spot and futures (often called basis) and cashing it in while paying interest on spot position (the "Covered Interest Arbitrage" in finance books) ; or, depending on the broker's feed , the reverse : paying the basis and getting interest on spot position (which is ockward and not likely to happen for real, but never say never)
b. exploiting missalignments of the converted futures to the spot (or of the real futures to the calculated futures , which is the same thing) using interest rates.
However, type b. arbitrage is not as seldom as that picture lets to be understood. You don't have to be a genius to see that a misprice happens not only when futures is on the wrong side, but also when futures is not where it should be: We could also discount (let's call it like that the conversion of futures to spot, even if some futures are discounted, e.g. USDJPY) the futures and see how far is from the real spot. We should also have a neat time conversion on hand to have a continuous time, not a jumpy one (e.g. not the time that decreases by one day when a day passes, but a time in real number format). The discounted futures is calculated using the reversed upper formula (get the spot from the equation to find it out).
Discounted futures to spot basis fluctuation
http://img517.imageshack.us/img517/2136/eurusdarbitrage2te3.jpg
The overlay indicator : DiscountedFutures
The window indicator : DiscountedBasis
As you can see, with 5-6 pips in magnitude of arbitrage windows, you could cover the 4 pip costs of arbitrage (2 pips on EURUSD, 2 pips 6E equivalent commission in pips). But is MetaTrader fast enough? However, with a pretty superior account trading at 1 pip spread it might work smoothly... With a regular case of EURUSD - 6E you could, for example, when DiscountedBasis has a higher value, sell the futures and buy the spot, and close when it reaches a lower than regular value...
Now let's return to the a. arbitrage type ("Covered Interest Arbitrage")
The picture below depicts the basis and swaps consuming reciprocally (in the normal swap rate regime), while the new, swap-free accounts based on brokers arrangements with islamic banks provide new, outstanding arbitrage opportunities:
Parameters : Account equity about 450 USD; Account leverage about 200 ; Margin usage = 90% ;
http://img524.imageshack.us/img524/7725/spottofuturesarbitrageme1.jpg
from Futures.mq4 script
This example was run on WHC (although WHC doesn't offer swap free accounts).
How are the calculations done?
Below is a picture with the implementation made by Beaverhea Financial. Although it's an untrustable broker, the implementation is useful for calculus and demo.
http://img166.imageshack.us/img166/9504/beaverheadfuturesyf1.jpg
The real currency futures implementations on CME
The ones that can be found with brokers are:
CME Euro FX
CME Australian Dollar
CME Canadian Dollar
CME British Pound
CME Japanese Yen
CME Swiss Franc
WHC comes also with these two, but they don't seem to work properly:
CME EC/JY Cross Rate
CME EC/SF Cross Rate
Now the arbitrage is pretty simple to understand if it's about EURUSD and 6E. Provided that EURUSD's lotsize is 100K and 6E's lotsize is 125K, the ratio : EURUSD traded lots / 6E traded lots = 5/4, as 5 x 100K = 4 x 125K to equalize pip movements.
But what if it's a reversed futures, such as USDJPY to 6J ?
This is a calculus example, using the Impeccable Hedge algorithm that powers FPI, Intercross Arbitrage and Swap Arbitrage
We consider:
USD - 5.25%
JPY - 0.25%
USDJPY right before old futures expiry: 123.00
6J right before old futures expiry = 100/123.00 = 0.8130
New futures, in the first moments, with expiry in 3 months:
http://img64.imageshack.us/img64/6761/futurescalculation6jcd5.jpg
Actually tested the formula on june 15 data and it was accurate on a range of 6 pips
(of course I used 92 days period instead of dividing to 4)
Prepairing the hedge : USDJPY spot > transformed USDJPY futures : Sell USDJPY, Sell 6J
Sold 100000 (1 lot) USDJPY @ 123
Sold 100000 USD
Bought 12300000 JPY
Sold 12300000 (0.98 lots) JPYUSD (6J) @ 0.8232 (/100)
Sold 12300000 JPY
Bought = 101253.6 USD
That 1253.6 must be the embedded interest in the futures.
Supposing now USDJPY=127 on expiry ; 6J is right reversed = 0.7874
Sell 100000 USDJPY @ 123 -> (1 pip = 10*100/127 = 7.87 USD) : -400 pips x 7.87 = -3148 USD
Sell 1230000 6J @ 0.8232 -> (1 pip = 12.3 USD) : 358 pips x 12.3 = 4403.40 USD
Result = 1255.40
Supposing now USDJPY=119 on expiry ; 6J is right reversed = 0.8403
Sell 100000 USDJPY @ 123 -> (1 pip = 10*100/119 = 8.40 USD) : 400 pips x 8.40 = 3360 USD
Sell 1230000 6J @ 0.8232 -> (1 pip = 12.3 USD) : -171 pips x 12.3 = -2103.30 USD
Result = 1256.70
As you see, arbitrage holds no matter the direction. And if the regime is swap free, pocket all of it... about 200K USD in traded volume, this would be tradable with a 500 USD account at about 450 leverage! This means more than double!
Of course it is advisable to review articles on central banks monetary policies especially if their meetings happen close to the beginning of futures. Create scenarios about what might happen if interest differential enlarges. Calculate the damage done to the equity, add 20-30 pips or more of market "missalignments" and see at what leverage it is sustainable (also include here the issues about not trading microlots - see the Intercross Arbitrage article). If you're heavy leveraged and faint hearted, better close positions before central bank meetings, and , most important, don't EVER forget to close positions before expiry or your account will likely be blown up due to violent futures shift on expiry change (or hopefully you'll just lose the profit!) . You could even test broker's vigilance by reversing positions with a day before expiry in order to make the entire profit on the expiry shift moment... Whatever, the method is a great progress from leaving the forex madness for a slow paced and profitable trading with controllable risks!
3. Warnings about Attachments
========================
Be very careful about how you set up DiscountedFutures and DiscountedBasis, especially with the interest rates and the expiries!
Look close at the SwapFree parameter when running Futures.mq4 script!
And be extremely careful when running on real accounts! Measure ten times and cut once! The script supposes all margin requirements are the same, however with some brokers margins for futures are bigger. Experiment first on demo.
- Citește mai mult...
- 33 comentarii
- 85.923 citiri
-
I thought about this system several months ago. I wasn't able to find a suitable implementation, because I tweaked it to the point I completely screw it up, so I'll put it the way I initially thought it.
Trader's Fallacy: Hey, I can follow that trend and make cash like a pro!
Traders love charts. Perhaps our reason for entering stock , forex or other markets was watching trending markets and simple indicators. The simplest indicator that someone gets in touch with when entering forex or stocks is the Moving Average (MA). Look how beautiful it is:
http://img259.imageshack.us/img259/4120/beautifulmatk0.jpg
You always used the MA as an indicator and always it tricked you! Damn whipsaws!
But the MA is pretty neat. Whatever happens and wherever far the market will go, eventually it will slow down and be catch up by the MA.
Haven't you ever dreamed that the MA to be an asset to hedge against the market itself ? Say go short the market, long the MA, and get profit on cometogether?
Look at the highest peek, it's so far from that 200 values MA at about 183 pips!
But how in the world could we trade that way...?!
The value of a MA is roughly the arithmetic average of the last N values (We consider Simple Moving Average). So if we have N trades, done at these prices, this composite asset will have been traded at about the MA value!
Well, you may say...how we do that? How do we know if we buy the MA and sell the market or we do the reverse ?
I have an answer...Good news and bad news. Starting with the bad news: it's gonna cost. Not a killer cost, but it will be. And the good news: you will be able to trade both ways, without needing to know what will happen and without being whipsawed!
Not knowing what will happen
It's gonna be either BUY or SELL. But until then, it's gonna be both: You construct the moving average, every bar, until it's ready: on every bar, buy and sell the Nth part of the position you take. Once the moving averages, completely hedged of course, will be ready, on every bar you will close the oldest pair buy/sell and place a new pair of buy/sell, keeping the moving average "assets" in line with the moving average itself.
How much it will cost ? Well, you get slipped on both placing and closing trades, and you will pay the spread on both buys and sells. That means that after the first N bars you will have a spread cost of about
2 x spread (for buys and sells)
Any other series of N bars came in will produce this cost, plus the slippage costs:
((2 x average slippage) for opens and closes ) x 2 for buys and closes)
Now once the basis (market minus moving average) jumps over a fixed , predefined value (say 50 pips), we will trigger the "trade": say the market trades at 1.4503 and the moving average is at 1.4320 . That means, sell the market, buy the moving average. We keep the series of BUYS, since its ready, and close the sells. Nothing happens, we were hedged. We place another sell at about 1.4503 , a huge trade, by the volume equal to the series of closed sells. We continue to "refresh" the moving average, replacing the oldest buy with a new entry on every bar. When the market will join the MA, we will have a fixed profit on the SELL side, some profits made by current BUYS and closed profits of the older BUYS. Of course, the extra spread and slippage costs for maintaing buys will be added. We close all trades and start rebuilding the moving average. Until the moving average is finished, no "trading" will be allowed ; at the moment when this is ready, we barely start up waiting for a new "trade".
Problems to think about
1. Enlarged spread
Once you take a "trade" you will be exposed to the basis going higher thus generating virtual losses. Take care not touch the margin call!
2. Broker limits
You need a broker that allows microlots and an outrageous number of trades. More trades possible, the bigger moving averages used, the higher number of pips caught!
3. Market delay
If the market will come together with the MA too late, hedge maintaing costs may be significant!
I'm awaiting comments!
- Citește mai mult...
- 10 comentarii
- 33.844 citiri
-
I. Evolution towards Intercross Arbitrage
1. Triangular Arbitrage
================
It is perhaps one of the most known arbitrage strategies learned in finance school. It consists in converting a given amount of cash in a currency thru some other currencies and back to original currency and getting profit, thus completing a currency ring transformation. It can be applied as an N-angular Arbitrage, when it has N currencies to deal with, but usually it's about three and this is why it's called Triangular Arbitrage. So, if we'd have some USD and market rates would allow arbitrage, it would mean, for example, to convert it to EUR, then to JPY and back to USD and have profit.
Example: we have $500
Market Rates:
EURUSD 1.3700/03
EURJPY 162.09/12
USDJPY 118.18/20
So we decide to:
1. sell USD to buy EUR (LONG EURUSD @ 1.3703) : 500 USD/1.3703 = 364.8836 EUR
2. sell EUR to buy JPY (SHORT EURJPY @ 162.09) : 364.8836 EUR * 162.09 = 59143.9827 JPY
3. sell JPY to buy USD (LONG USDJPY @ 118.20) : 59143.9827 / 118.20 = 500.37 USD
So, by making a conversion thru all the 3 currencies, we won 37 cents, meaning a ROE (Return on Equity) of 0.074%. Seems simple, huh?
The problem of Triangular Arbitrage is that it works only in EXCHANGE ENVIRONMENTS, where amounts of money are EFFECTIVELY EXCHANGED. Banks work in an EXCHANGE ENVIRONMENT. They are simultaneously in excess and need of liquidity. For example a bank has USD and needs EUR. It would then wire USD to another bank and get EUR wired back. It won't do a forex style LONG EURUSD, as it doesn't need a position on EURUSD, but the real EUR to make payments. Exchange houses are an example of an exchange environment. But, different than the one of the banks, they don't provide: tight spreads, electronic market and leverage. Going back to the trade example, when a bank finishes the three trades, it would have the profit in it's account, as every trade would cancel the previous trade result. One of the works that treats Triangular Arbitrage as Yukihiro Aiba's master thesis, "Triangular Arbitrage as an Interaction among Foreign Exchange Rates". However we forex traders don't have access to such an environment. We trade in the FOREX MARKET ENVIRONMENT and we can't do the Triangular Arbitrage as in theory, which remains only a simple theoretical base : our trades are independant, don't close each other. Once opened, we have the spread loss in our account. We must find the point where to close them. And this lead to step 2, the Fractional Products Inneficiency strategy.
2. Fractional Products Inneficiency
=========================
Fractional Products Inneficiency, as it was designed by its author, Michal Kreslik, on the end of 2006, beginning of 2007, is the application on FOREX of the Triangular or N-angular Arbitrage. Trade decisions of entry and exit are made on the Fractional Products Inneficiency (on short, FPI) swing.
On the earlier example, we could calculate a FPI like this
FPI = 1.3703 / 162.09 * 118.20 = 0.99925.
The no-arbitrage relationship would mean that FPI to be equal to 1. FPI less than 1, we can trade. In order to get profit we should wait for the FPI (CALCULATED THE SAME WAY, not changing bids with asks and vice-versa) to go to 1.0003 and so.
Michal's explanation of FPI strategy lacked:
a. a precise FPI calculation method as well as a precise ring establishment method (confusion between Buy-Sell-Sell and Sell-Buy-Buy currency rings almost last on all forum pages)
b. a link between FPI swing and results
c. embedding of spread costs in strategy
The most important things learned from Michal's FPI are:
a. hedging principle: each currency must be EQUALLY BOUGHT AND SOLD (by his words, "The Impeccable Hedge", although hedging in MetaTrader may be only good at its best);
b. the volume calculations for each operations, which is the pinnacle of his achievement.
Trying to overcome the mysteries and paradoxes of FPI explanation (as Michal said, "I hid the gold in many places for friends to find it"), I redesigned his strategy under the Intercross Arbitrage name.
3. Intercross Arbitrage
================
Before jumping to Intercross Arbitrage, let's first correct the ring confusion : which pairs should be bought and which pairs should be sold in a Kreslik currency ring ?
I consider the following:
Once the currencies are established (say EUR, USD, JPY), we imagine we are transforming the currency from one to the other
We have EUR.
1. We sell EUR to gain USD. EURUSD exists, we sell it.
2. We sell USD to gain JPY. USDJPY exists, we sell it.
3. We sell JPY to gain EUR. JPYEUR does not exist to sell it. EURJPY exists, and since we reversed the pair, we buy.
This can be done with n currencies. If one of the transformations cannot be done, for example neither PLNNOK nor NOKPLN exists, the entire ring is scrap, going to another combination. More about this on the Swap Arbitrage topic.
So, what's arbitrage?
A simple answer would be (for the complicated stuff, go see Wikipedia): "Simultaneously buying and selling the same asset at different prices to get immediate profit". Well, we don't have a New York EURUSD to arbitrage against a London EURUSD. So , how do we do it?
Let's return to the earlier example:
1. LONG EURUSD
2. SHORT EURJPY
3. LONG USDJPY
Let's translate it:
1. LONG EUR, SHORT USD
2. SHORT EUR, LONG JPY
3. LONG USD, SHORT JPY
We can see clearly that bought JPY in (2) is sold in (3) so JPY clears out, and what we have now is:
1. LONG EUR, SHORT USD
2. SHORT EUR
3. LONG USD
or:
1. LONG EUR, SHORT USD
2,3: SHORT EUR, LONG USD
So operations 2 and 3 are practically a virtual SHORT EURUSD. Now we have a secondary EURUSD to arbitrage against main, real EURUSD.
Not only the traded forex pairs have virtual counterparts, but also conceptual pairs may have only virtuals.
For example, let's say a broker doesn't trade GBPCHF at all.
GBPCHF could be made by: GBPUSD & USDCHF, but also by: GBPJPY & CHFJPY
We could actually have an arbitrage of "Virtual GBPCHF ask" against a "Virtual GBPCHF bid"
Market rates:
GBPUSD 2.0250/53
USDCHF 1.1988/91
GBPJPY 239.64/70
CHFJPY 98.78/83
Virtual GBPCHF ask means that we buy GBPCHF, so we must have:
LONG GBP, SHORT CHF , given by:
LONG GBP / SHORT XXX
LONG XXX / SHORT CHF
Similar, Virtual GBPCHF bid means that we sell GBPCHF:
SHORT GBP / LONG XXX
SHORT XXX / LONG CHF
By looking at the rates, we can spot the Virtual GBPCHF bid and ask:
Virtual GBPCHF ask:
LONG GBPJPY @ 239.70 (LONG GBP, SHORT JPY)
SHORT CHFJPY @ 98.78 (LONG JPY, SHORT CHF)
Virtual GBPCHF ask = 239.70 / 98.78 = 2.4266 as GBP/JPY / CHF/JPY = GBP/JPY * JPY/CHF = GBP/CHF
Virtual GBPCHF bid:
SHORT GBPUSD @ 2.0250 (SHORT GBP, LONG USD)
SHORT USDCHF @ 1.1988 (SHORT USD, LONG CHF)
Virtual GBPCHF bid = 2.0250 * 1.1988 = 2.4275 as GBP/USD * USD/CHF = GBP/CHF
So, this should mean we buy GBPCHF @ 2.4266 and sell it @ 2.4275 for 9 small CHF-sized pips as a potential. We should wait for the market to swing this and get our profit. But, how much do we pay for it?
First of all, let's calculate lotsizing to know exactly how much to trade.
The most remarcable of Michal Kreslik's achievements is lotsizing, how much to trade out of each pairs to keep hedging.
Suppositions:
1. USD 500 account equity
2. Maximum leverage : 200
3. Broker allows microlots (0.01) . I will explain later why microlots are important and how much they make the difference in hedging for the small guy.
4. We use 85% of available leverage . We allow a window of risk to cover for spreads and broker datafeed damage.
5. Size of a standard lot : 100000 units for USD and CHF denominated pairs, 70000 units for GBP denominated pairs
Calculus:
Total funds = 500 x 200 = 100000 USD
Available funds = 100000 x 85% = 85000 USD
We make 4 trades, so each one would be allocated around 85000/4 = 21250 USD:
The trades are:
LONG GBPJPY @ 239.70 (LONG GBP, SHORT JPY)
SHORT CHFJPY @ 98.78 (LONG JPY, SHORT CHF)
SHORT GBPUSD @ 2.0250 (SHORT GBP, LONG USD)
SHORT USDCHF @ 1.1988 (SHORT USD, LONG CHF)
One of the most difficult aspects is the one of the first trade. We must have a start point, so we must know how much is the first currency of the first trade in the account currency. It's simple now, as we must know how much is GBP in USD, but what if we'd had PLN or another exotic?
GBPUSD trades 2.0250/53, so we consider a rough GBP/USD = 2.02515
We have allocated 21250 USD for the trade, so this means 21250/2.02515=10,493.05 GBP. For a lotsize of 70000 GBP, we have 0.149 lots, rounded at two decimals 0.15 (normally not advisable to round up, but in this case the difference is very small) .
1. LONG 0.15 GBPJPY @ 239.70 (LONG GBP, SHORT JPY)
BOUGHT 10500 GBP = 0.15 x 70000 10500 GBP x 239.70 = 2516850 JPY SOLD
2.
Now we don't know how much CHF to short for the 2nd operation, but we know how much JPY to buy.
2516850 JPY / 98.78 = 25479.35 CHF. 25479.35/100,000 CHF = 0.2548 lots
Now we can use: 0.25 lots or 0.26 lots, depending on how much unhedged JPY may have:
a. SHORT 0.25 CHFJPY @ 98.78 (LONG JPY, SHORT CHF)
SOLD 25000 CHF = 0.25 x 100000 25000 CHF x 98.78 = 2469500 JPY BOUGHT (47350 JPY NET SOLD)
b. SHORT 0.26 CHFJPY @ 98.78 (LONG JPY, SHORT CHF)
SOLD 26000 CHF = 0.26 x 100000 26000 CHF x 98.78 = 2568280 JPY BOUGHT (51430 JPY NET BOUGHT)
So the a) version is better, as JPY unhedged side is smaller.
Since Virtual bids and asks calculations are independent, we could consider a new currency ring and start calculation from the beginning for the virtual ask, like we did before. Or we could use the GBP exposure and continue calculation. I am writing the 2nd version here to accustom readers with currency ring calculations.
10500 GBP / 70000 = 0.15 lots
3. SHORT 0.15 GBPUSD @ 2.0250 (SHORT GBP, LONG USD)
SOLD 10500 GBP = 0.15 x 70000 10500 x 2.0250 = 21262.5 USD BOUGHT (GBP completely hedged)
1417.5 USD / 100000 = 0.01 lots
4.
21262.5 USD / 100000 = 0.212 lots
a. SHORT 0.21 USDCHF @ 1.1988 (SHORT USD, LONG CHF)
SOLD 21000 USD = 0.21 x 100000 21000 x 1.1988 = 25174.8 CHF BOUGHT (262.5 USD NET BOUGHT, 174.8 CHF NET BOUGHT) ;
TOTAL UNHEDGED AMOUNT = (47350 JPY / 118.38 as USDJPY rate = 399.98) + 262.5 USD + (174.8 CHF = 145.81 USD) = 808.29 USD
b. SHORT 0.22 USDCHF @ 1.1988 (SHORT USD, LONG CHF)
SOLD 22000 USD = 0.22 x 100000 22000 x 1.1988 = 26373.6 CHF BOUGHT (737.5 USD NET SOLD, 1,373.6 CHF NET BOUGHT) ;
TOTAL UNHEDGED AMOUNT = (47350 JPY / 118.38 as USDJPY rate = 399.98) + 737.5 USD + (1373.6 CHF = 1145.81 USD) = 2283,29 USD
So the a) trade is chosen.
Still, the example shows a 808.29 USD unhedged volume, which slips with a 0.08 USD/pip on total position fluctuation
II. Exposure under assumptions of using and not using microlots
Exposure is generated from the simple fact that currencies obtained or sold during SELL and BUY operations cannot be offset due to the fact that the lotsize cannot mimic this value.
For example we want to hedge USD in the following example by buying USDJPY.
BUY 0.2 EURUSD @ 1.33
We are LONG 20000 EUR, SHORT 26600 USD
1.Using microlots (0.01)
We could:
a. LONG 0.26 USDJPY @ 121
We are SHORT 13000 USD, LONG 3146000 JPY
USD exposure: SHORT 26600-26000 = 600 USD
b. LONG 0.27 USDJPY @ 121, LONG 3267000 JPY
We are LONG 27000-26600 = 400 USD
Given the fact we always choose for hedging the appropriate lotsize, the maximal unhedged volume may go up to 500* units (500 USD, 500 EUR, 500 GBP and so on), being also the indifference point where it doesn?t matter if you hedge by choosing upper or lower volume.
2. Using mini lots (0.1)
We could:
a. LONG 0.2 USDJPY @ 121
We are SHORT 20000 USD, LONG 2420000 JPY
USD exposure: SHORT 26600-20000 = 6600 USD
b. LONG 0.3 USDJPY @ 121, LONG 3630000 JPY
We are LONG 30000-26600 = 3400 USD
Given the fact we always choose for hedging the appropriate lotsize, the maximal unhedged volume may go up to 5000* units (5000 USD, 5000 EUR, 5000 GBP and so on), being also the indifference point where it doesn?t matter if you hedge by choosing upper or lower volume.
*Note: 500 or 5000 on the assumption that a full lot is 100000 units.
1. Unhedged volume is also a function of contracts traded and pair configuration.
If there are 3 contracts traded, one currency will be completely hedged, 2 incompletely hedged.
Example 1:
EURUSD
EURGBP
GBPUSD
EUR will be completely hedged, GBP and USD not completely.
If there are 4 contracts, 2 or 3 currencies may be incompletely hedged:
Example 1:
USDGBP
USDJPY
EURGBP
EURJPY
Only GBP and JPY not completely hedged.
Example 2:
EURGBP
EURCHF
GBPUSD
USDCHF
GBP, CHF and USD not completely hedged.
The hedged currencies are the ones that are being bought and sold being the first currency in the involved pairs.
2. Proportional unhedged volume, proportional equity
Say a $500 account trades at 200 leverage, using 80% of available margin, USING MICROLOTS.
Used funds = 500x200x80% = 80.000 USD. Say we have 4 trades. Maximum exposure is 500 units each. We would have exposure of 500 GBP, 500 EUR, 500 USD (wouldn?t happen in practice, only in theory; I considered the 3 currencies starting from GBP, the most expensive).
So ~1500 EUR unhedged currency, about 1,875% of total volume
Say the arb is 4 USD pip high. The unhedged part of 1500 EUR values ~ 2000 USD.
The 4 pips correspond to 80000 USD, meaning a profit of 8 x 4 = 32 USD
There would be needed a bad luck of 160 USD pips on the aggregated volume of the 3 unhedged currencies to wipe out the profit.
WITHOUT MICROLOTS, maximal exposures would be 5000 GBP, 5000 EUR, 5000 USD ..~15000 EUR = 18,75%
Unhedged part, ~ 20000 USD
Only 16 USD pips bad movement on the 3 currencies needed to wipe out profit.
But if the account is $5000, maximal exposure is the same as before.
Profit comes on 800000 USD = 320 USD
So 160 pips needed to wipe out profit.
Without microlots, risks can be brought down from $5000 in account equity? Sorry, that?s it.
III. Completing the Fractional Product Inneficiency : Potential, Costs and Required
One of the greatest FPI drawbacks was the fact you had to rely only on FPI value to initiate trade or close. There was no way to know it was enough except for closing when you could have watched the total profit. But how about the entry point ? Would just a fixed value of FPI 0.9997 be enough as entry criteria ?
Being given the fact that we are virtually long and short on the same pair, we know that these "assets" can't stay forever on this position. Having the same meaning as the pair they represent, they have to be, randomly, on both sides of it, so, what gives now a virtual bid will make a virtual ask in the days to come and vice versa.
We have to answer the following questions:
1. How much is for real for the gap between virtual bid and virtual ask ?
Created gap is in the Virtual pair secondary currency. We must convert it to account currency for correct comparison.
2. How much do we pay for this stuff?
Different trade results are in different currencies, costs must be brought to a single currency.
3. How much potential needs a trade group in order to cover spreads, slippage and have decent profit?
1. How much is the real gap between virtual bid and virtual ask?
==============================================
Even if the synthetic pair has a virtual/real bid and a virtual/real ask, the atoms, meaning the trade subgroups that create the buy-side and the sell-side have also another real/virtual of their own. Like in the GBP/CHF example earlier,
looking at the buyside atom:
LONG GBPJPY @ 239.70 (LONG GBP, SHORT JPY)
SHORT CHFJPY @ 98.78 (LONG JPY, SHORT CHF)
It's true that traded prices make up the Virtual ask, but the close prices for each trade make up the bid of the entire group.
Let the TakenBid and TakenAsk be the Virtual bid and ask prices;
if aask and abid being the mirror (close prices),
CrossPair the pair you arb on;
then you can write:
Pips = (TakenBid-aask) * multiplicator + (abid - TakenAsk) * multiplicator , where multiplicator is usually 10000 or 100 for JPY ended pairs (10^n , where n is the number of decimals)
Now the pips are denominated in the second currency, meaning CHF.
We want to convert it to our account currency, USD, and we'd better do that via USDCHF rate.
2. How much do we pay for this stuff ?
============================
And I'm asking here:
How much is a tick of the account currency on a standard lot?
With MarketInfo you can find out how much is a tick on a given currency pair:
MarketInfo(contract, MODE_TICKVALUE) , and , for a USD account on EURUSD test gives 10, because you have 10 USD/pip trading EURUSD.
What if you have the account denominated in EUR? Because your account currency is EUR, applying the same MarketInfo("EURUSD",MODE_TICKVALUE) won't give you that 10 again... and if you don't have any XXXEUR pair on hand, what you could do is multiply the MarketInfo result by EURUSD, cancelling the correction embedded in MarketInfo.
A short route to appendix now: Appendix is what some MetaTrader brokers add to currency pairs. For example, mini InterbankFX accounts have that "m" appended to the end of currency pair, like EURUSDm. To get the appendix, use BcLib function GetSymbolsAppendix(). Just a simple call like appendix=GetSymbolsAppendix() and your strategy would then run on any broker without other modifications due of this. Call it once per EA, in the init(), takes some time!
Now, the implementation of tick of the account currency in BcLib is this:
double GetTickDenominator(string appendix) { string acctcurrency=AccountCurrency(); double res=0; if (acctcurrency=="USD") res=MarketInfo(StringConcatenate("EURUSD",appendix),MODE_TICKVALUE); if (acctcurrency=="EUR") res=MarketInfo(StringConcatenate("EURUSD",appendix),MODE_TICKVALUE)*MedPrice(StringConcatenate("EURUSD",appendix)); if (acctcurrency=="GBP") res=MarketInfo(StringConcatenate("EURGBP",appendix),MODE_TICKVALUE)*MedPrice(StringConcatenate("EURGBP",appendix)); if (acctcurrency=="CHF") res=MarketInfo(StringConcatenate("GBPCHF",appendix),MODE_TICKVALUE); if (acctcurrency=="JPY") res=MarketInfo(StringConcatenate("USDJPY",appendix),MODE_TICKVALUE); return(res); }
*Note: the MedPrice function just returns a simple (bid+ask)/2
Now let's head back to our account currency evaluation:
For each contract traded inside, we calculate it like this:
pipcost=MarketInfo(contract,MODE_SPREAD)*MarketInfo(contract,MODE_TICKVALUE)/GetTickDenominator(appendix);
the volumes are equivalent, no need to think about them!
Now we can see that the implementation of GetTickDenominator was correct. Supposing our contract was EURUSD trading at about 1.37. GetTickDenominator would give us a 10, since 10 EUR won on a EUR account is the same as 10 USD won on a USD account. MarketInfo("EURUSD",MODE_TICKVALUE) would return about 7.2 (would have been 10 if account would have been USD denominated) ; GetTickDenominator would return 10, so the result would be around 2.16, or 3/1.3700 .
3. How much potential needs a trade group in order to cover spreads, slippage and have decent profit?
=========================================================================
Problem of the costs is that the costs are dynamic. The spread is fluctuating, and the costs once with it. Here there is freedom of choice.
We could calculate the Required potential to include the costs + a percent of the costs + a fixed amount of pips to compensate for slippage and spread fluctuations...
http://img402.imageshack.us/img402/3323/virtualbidsandaskstg1.jpg
IV. Implementation
MetaTrader or Reuters Dealing ?
http://img77.imageshack.us/img77/1440/arbtraderfigtingthemarkcn4.jpg
*Note that the displayed bids and asks will be the ones on the best bids and asks, even if a trade group is placed and old "lesser" bid and ask atoms are now the best ones.
1. How are the pairs generated
=======================
MetaTrader doesn't have a function to enumerate available currencies and pairs. This is overcome in BcLib by the following mechanism:
The TestCurrencies[] , which includes 15 currencies: "EUR","USD","GBP","JPY","CHF","AUD","CAD","NZD","HKD","THB","NOK","SEK","DKK","PLN","TRY".
If you want to add more currencies to be tested, just use AddCurrencyToTest(currency) , before going further.
By calling GetCurrenciesAndPairs(Appendix) you get the used currencies and used pairs in UsableCurrencies[] and UsablePairs[] ; the numbers of currencies and pairs are indicated in CurrenciesNo and PairsNo integers. This procedure will test the currencies of the TestCurrencies[] agains each other. When one currency pair exists, it is aded to UsablePairs[], and the two currencies that make it are added, if not already there, in UsableCurrencies[].
In order to know exactly what rates appear on screen and how are they calculated, BcArb creates a series of crosslists, by combining every 2 currencies with a 3rd-one. What it gets, is, all the atoms that can be used for buy or sell that emulate a currency pair (this example is generated on WHC's Metatrader):
EUR/USD EURUSD GBP21 JPY22 CHF22 AUD21 CAD22 NZD21
EUR/GBP EURGBP USD22 JPY22 CHF22 AUD22 CAD22
EUR/JPY EURJPY USD21 GBP21 CHF21 AUD21 CAD21 NZD21
EUR/CHF EURCHF USD21 GBP21 JPY22 AUD21 CAD21 NZD21
EUR/AUD EURAUD USD22 GBP21 JPY22 CHF22 CAD22 NZD22
EUR/CAD EURCAD USD21 GBP21 JPY22 CHF22 AUD21 NZD21
EUR/NZD EURNZD USD22 JPY22 CHF22 AUD21 CAD22
GBP/USD GBPUSD EUR11 JPY22 CHF22 AUD21 CAD22
USD/JPY USDJPY EUR11 GBP11 CHF21 AUD11 CAD21 NZD11
USD/CHF USDCHF EUR11 GBP11 JPY22 AUD11 CAD21 NZD11
AUD/USD AUDUSD EUR11 GBP11 JPY22 CHF22 CAD22 NZD21
USD/CAD USDCAD EUR11 GBP11 JPY22 CHF22 AUD11 NZD11
NZD/USD NZDUSD EUR11 JPY22 CHF22 AUD11 CAD22
GBP/JPY GBPJPY EUR11 USD21 CHF21 AUD21 CAD21
GBP/CHF GBPCHF EUR11 USD21 JPY22 AUD21 CAD21
GBP/AUD GBPAUD EUR11 USD22 JPY22 CHF22 CAD22
GBP/CAD GBPCAD EUR11 USD21 JPY22 CHF22 AUD21
GBP/NZD EUR11 USD22 JPY22 CHF22 AUD21 CAD22
CHF/JPY CHFJPY EUR11 USD11 GBP11 AUD11 CAD11 NZD11
AUD/JPY AUDJPY EUR11 USD21 GBP11 CHF21 CAD21 NZD21
CAD/JPY CADJPY EUR11 USD11 GBP11 CHF21 AUD11 NZD11
NZD/JPY NZDJPY EUR11 USD21 CHF21 AUD11 CAD21
AUD/CHF AUDCHF EUR11 USD21 GBP11 JPY22 CAD21 NZD21
CAD/CHF CADCHF EUR11 USD11 GBP11 JPY22 AUD11 NZD11
NZD/CHF NZDCHF EUR11 USD21 JPY22 AUD11 CAD21
AUD/CAD AUDCAD EUR11 USD21 GBP11 JPY22 CHF22 NZD21
AUD/NZD AUDNZD EUR11 USD22 JPY22 CHF22 CAD22
NZD/CAD NZDCAD EUR11 USD21 JPY22 CHF22 AUD11
In order to obtain the list, just call CreateCrosslistsTable(Appendix) from BcArb. The list is contained in CrosslistsTable[] and its length is specified by the CrosslistsNo integer.
Note that, if one pair has only one atom, it won't appear in the list, as one atom does not have a counterpart to be arbitraged to.
Let's analyse a line:
EUR/USD EURUSD GBP21 JPY22 CHF22 AUD21 CAD22 NZD21
The first word of the line specifies the cross: EUR/USD
The atom which contains the pair itself is the real one; the others are virtuals;
GBP21 = EURGBP & GBPUSD;
In combination with the first currency of the cross (EUR), the combined currency (GBP) appears on the 2nd position
In combination with the second currency of the cross (USD), the combined currency (GBP) appears on the 1st position
In this example, EURGBP is Pair1 and GBPUSD is Pair2.
Calculating cross virtual bid and ask
===========================
If the atom is a real pair, virtual bid and ask are pair's bid and ask. If not:
1. We analyse the indexes (what comes after the currency, e.g. 2 and 1 after GBP), and we establish buy and sell prices for Pair1 and Pair2.
a. First index
Case 1:
Pair1.buy=bid;
Choice for buy : Short;
Pair1.sell=ask;
Choice for sell : Long;
Case 2:
Pair1.buy=ask;
Choice for buy : Long;
Pair1.ask=bid;
Choice for sell : Short;
b. Second index
Case 1:
Pair2.buy=ask;
Choice for buy : Long;
Pair2.sell=bid;
Choice for sell : Short;
Case 2:
Pair2.buy=bid;
Choice for buy : Short;
Pair2.sell=ask;
Choice for sell : Long;
Now, once we established the prices for both pairs upon what we want to do with the cross, we calculate the cross price:
Case 11:
cross bid=(1/Pair1.sell)*Pair2.sell;
cross ask=(1/Pair1.buy)*Pair2.buy;
Case 12:
cross bid=(1/Pair1.sell)/Pair2.sell;
cross ask=(1/Pair1.buy)/Pair2.buy;
Case 21:
cross bid=Pair1.sell*Pair2.sell;
cross ask=Pair1.buy*Pair2.buy;
Case 22:
cross bid=Pair1.sell/Pair2.sell;
cross ask=Pair1.buy/Pair2.buy;
This job is automatically done by BcArb's GetAtomData()...
Transforming units to lots
===================
Lotsize calculations are based on volume calculations on bought and sold amounts of currency. DO NOT PRESUME LOTS ARE 100000 FOR EACH CONTRACT!
Use always the UnitsToLots function, as it is implemented in BcLib. As it is implemented now, it will always choose the appropriate volume, except for 0, which will never be chosen, if it may be appropriate volume (for example on a broker that doesn't allow microlots we transform 3000 units on EURUSD. Appropriate volume is 0, yet answer will be 0.1 (for 10000).
double UnitsToLots(double units,string contract) { double dlotsize=MarketInfo(contract,MODE_LOTSIZE); double mag=MarketInfo(contract,MODE_LOTSTEP); double mini=MarketInfo(contract,MODE_MINLOT); double big=1/mag; double size=dlotsize/big; double dlots0,dlots1,back0,back1; dlots0=NormalizeDouble(units/size,0)*mag; dlots1=dlots0+mag; back0=dlots0*big*size; back1=dlots1*big*size; if (back1-units<units-back0) { if (dlots1<mini) return(mini); else return(dlots1); } else { if (dlots0==0) return(mini); else { if (dlots0<mini) return(mini); else return(dlots0); }//else if (dlots0==0) }//else if if (back1-units<units-back0) }
2. Implementation details
===================
These are ArbTrader_script's working parameters (it is a script, put it in the \scripts folder)
extern int DisplaySetup=2;
extern int Tryouts=5; //0 for unlimited tryouts, don't put that!
extern int MarginUsed=85;
extern int Slippage=100;
extern int MaxTickDelay=30;
extern double TakePipsRatio=50;
extern double TakePipsFixed=2;
extern double TakePipsCloseRatio=50;
extern double TakePipsCloseFixed=2;
extern bool EnableFreshness=true;
extern bool EnableLiveTest=false;
extern int DontRepeatLiveTestForSecs=300;
extern bool AllBips=False;
Do not change the display type; 1 may work, but not tested.
Tryouts means how many times it will try opening a trade.
MarginUsed is the used ratio from available leverage;
Slippage is very high; I set it like that in order to leave some space for opening last trade; it's not good to remain unhedged while losing time trying to open last;
MaxTickDelay works if Freshness is enabled; All the pairs last quotes must be fresher than MaxTickDelay, otherwise trade won't be triggered;
TakePipsRatio and TakePipsFixed establish the Potential for opening ; TakePipsClose and TakePipsCloseFixed establish the Potential for closing (close moment is calculated like a potential, too);
EnableFreshness enables Freshness test;
EnableLiveTest is good to be on false; if not, before triggering trades at full scale , it will do them at the smallest tradable amount and close them. If one crashes, the big trades won't be triggered; The program remembers last arb data ; so if a new test is to come, generating further account drainage, this will be prevented if it comes in DontRepeatLiveTestForSecs seconds;
AllBips is an older setting; On previous MetaTrader versions, using a sound (from dll) that didn't exist, a system error bip was produced; This bip was to be enabled on all yellow lightings if AllBips was true; Otherwise, Cepstral Amy's voice should to be heared when arbitrages where entered and closed. (place ArbEnter.wav and ArbClose.wav in C:\Windows)
V. Conclusions
Both FPI and Intercross Arbitrage are versions of the hardest strategy to understand or implement. Problem is, the result doesn't seem to cover the huge effort for understanding and implementing it. The strategy is cripled by one of the pairs going off quotes... It stays behind the others, generates arbitrage, then can't be traded for minutes. When it's traded, it's already on loss... Plus that trading occurs rarer than seldom. But, despite this, the strategy remains practically the single arbitrage strategy that can be applied with forex alone, without using futures.
- Citește mai mult...
- 34 comentarii
- 139.701 citiri
-
The explosion of brokerage firms on the Internet leads to an ever increasing competition among them ; one of the ways to have a better offer than the competitors is offering more markets to the trader , broadening his trading horizons from the narrowness of random forex; and since we're talking about MetaTrader, the most easy to automate and yet free platform of this kind, this is done by non-NFA regulated brokers, since NFA forbids the implementation of other contracts as CFDs (futures , stocks and bonds can't be implemented on MetaTrader the way they are). Ultimately, this is what traders wanted from the beginning: a single automated platform usable for trading many markets , in order to deploy logical and profitable strategies, not only indicator-hunting strategies... Perhaps NFA has its reasons for banning CFDs, however, if technical solutions are not found to this problem, US brokers will be effectively wiped out by the competition abroad on the retail segment where MetaTrader is the backbone of traders strategies. There must be a way to solve the fractional trading of futures. Thirty years ago when forex was Zurich centered and trades made by phone minilots and microlots were considered science fiction and these are a reality today. Futures must follow the same path and become sizable for very small accounts... Traders consider NFA no longer to be a "trademark". Exactly how "wireless broadband" grew more important than "Intel inside", the same way "futures inside" has become more important than "NFA-regulated". Think about how much cash the forex retail traders lost just because they couldn't access the contracts they really wanted and were forced to trade markets they didn't understood well... If NFA considers as its duty to protect the traders from fraudulent brokers it should have banned retail forex too : misleading advertising to cover up a casino-like trading environment (no arbitrageable assets). Among the "new" assets introduced by non-NFA regulated brokers (that's the irony of the fate, we must use russian or Middle East brokers to trade american assets) there are the currency futures (I will speak about them in another article), but also commodities. Similar commodities are traded on different markets, so arbitrage opportunities appear. Real and frequent, and not so easy to be manipulated by the broker (as FPI / Intercross Arbitrage with forex , where arbitrage opportunities are so easy to remove as slapping the fingers). Many brokers offer, of course, many have seen this already, Gold and Silver. However, since there are not at least two gold contracts and two silver contracts it's easy to understand these are not arbitrageable.
The single broker supporting the commodities below:
WHC forex (the most extensive datafeed) . Since it's not too regulated, you'd better wait for others to follow them!
A brief look at the commodities contracts possibly to be used for arbitrage:
Oil contracts:
WTI = West Texas Intermediate (InterContinentalExchange) ; download contract specification: WTI Contract Specifications on ICE
CL = Crude Light oil (New York Mercantile EXchange) CL Contract Specifications on NYMEX
BRN = BReNt oil (InterContinentalExchange) ; download contract specification: BRN Contract Specifications on ICE (ICE acquired IPE - International Petroleum Exchange)
QM = miNY Light Sweet Crude Oil (New York Mercantile EXchange) QM Contract Specifications on NYMEX
Natural gas contracts:
NG = Henry Hub Natural Gas Futures (New York Mercantile Exchange) NG Contract Specifications on NYMEX
QG = Natural Gas (New York Mercantile Exchange) QG Contract Specifications on NYMEX
Gold contracts:
ZG = 100 oz Gold Futures (Chicago Board of Trade) ZG Contract Specifications on CBOT
GC = Gold Futures (COMEX) GC Contract Specifications on COMEX (division of NYMEX)
Silver contracts:
ZI = Silver 5000 oz (Chicago Board of Trade) ZI Contract Specifications on CBOT
SI = Silver Futures (COMEX) SI Contract Specifications on COMEX (division of NYMEX)
Wheat contracts:
KW = Kansas Wheat (Kansas City Board of Trade , open outcry)
KE = Kansas Wheat (Kansas City Board of Trade , electronic)
KW Contract Specification on KBOT
Cocoa:
C = Cocoa (Euronext) C Contract Specifications on Euronext
CC = Cocoa (New York Board Of Trade) CC Contract Specifications on NYBOT
I did not make an extensive analysis of this arbitrage, but I looked upon a few assets and strategies:
1. Cocoa
=======
Most time I'd tried to trade them I got "Trade is disabled". They move in a similar way, however, their values are way different. A statistical arbitrage strategy may be deployed, however, a version of Intercross could be applied, since CC is quoted in USD while C is quoted in GBP.
2. Wheat
=======
http://img441.imageshack.us/img441/8058/keandkwik6.jpg
The two versions of the Kansas Wheat are very closely correlated, moving almost parallel. However, commissions drain out the arbitrage possibilities.
3. Oil
====
The variety of oil contracts make possible a large variety of arbitrage strategies.
3.a. CL to QM
===========
Almost impossible to work out. It's necessary to trade a volume of QM 20 times more than CL to equal pip value. At this ratio, commissions are so high, that breakthru is somewhere at 70-80 CL pips (cents/barrel) difference...
3.b. BRN to CL
===========
Brent and Crude Light have different fundamentals behind. On a range of 500 daily bars, BRN / CL fluctuates +/- 500 pips. Statistical arbitrage may be deployed. However, a normal arbitrage strategy aiming to pyramidize positions at each 100 pips difference may, or not, work. It may work if both BRN and CL are implemented as continuous futures, the trader having unlimited time to wait for them to come together (this point is where they are not equal, but BRN quoted 100 pips above CL). Otherwise, arbitrage is impossible. Futures have too close expiries compared to the BRN - CL divergence - convergence cycle. An expiry in loss damages account equity and reduces available funds. Even worse, the positions can't be reconstructed from the place they were before expiry because prices are jumpy (new expiry, new interest to expiry embedded).
Difference in USD trading Short BRN , Long CL one lot each (for pips, divide by 10) courtesy Matt Trigwell
(comprises ~500 daily bars)
http://img178.imageshack.us/img178/2497/oilspreadtradebr7.jpg
3.c. BRN to WTI
============
It's almost the same as BRN to CL, as WTI floats very close to CL. Which is very useful in the next arbitrage strategy,
3.d. CL to WTI
===========
This is the most interesting arbitrage strategy with oil. It is quite fast, the strategy could trade one time a day. Usually WTI and CL are on a close range, however arbitrage opportunities appear pretty often. Both trade with 10 pip spread and 1 pip commission. If you would consider mid prices (between bid and ask), trade them when the difference is about 15 pips between mid prices and close when it's reversed. Results are pretty amazing, however execution errors may criple it a little.
http://img212.imageshack.us/img212/8590/wtitoclarbitrageaq9.jpg
Probably the Gold and Silver contracts hide also other "golden" arbitrage opportunities.
My source proposed for this article is WTI2CLsimpleArbitrageScript (see attachment). Please run it a while and report here problems encountered (the initial version was pyramiding trades, but I removed this because I considered it not necessary).
- Citește mai mult...
- 4 comentarii
- 12.060 citiri
-
This is, indeed, the first decision that you have to make.
We have two categories of brokers (I mean only from MetaTrader brokers here):
1. US, trusted, NFA-regulated, USELESS brokers.
2. Non-US, controversial, FSA or other regulation authority, USELESS or USEFUL brokers.
The term "arbitrage" from the title has its initial meaning : choice.
Except for the Intercross Arbitrage and the Swap Arbitrage, which work with forex only, all the other arbitrage strategies, which are also the "normal" arbitrage strategies found in books, require futures contracts implementation in MetaTrader. It seems they can only be implemented as CFDs. And NFA is against this.
So if we choose a US broker, we are left with:
a. Intercross Arbitrage
b. Swap Arbitrage
The Intercross Arbitrage relies on broker delivering not only small spread contracts, but real, not "engineered" quotes that can be used to arbitrage different versions of the same currency crosses. The Swap Arbitrage relies on small swap spreads combined with stability in time, which can't be forecast...
The second type of brokers may be USELESS or USEFUL.
If their datafeed is as poor as the first kind, it's stupid to even think opening the account. You can get the same datafeed from a trusted broker.
But if they come with currency futures, commodities, even swap free feed on forex, they are USEFUL as arbitrage techniques may be applied with success. However, GETTING THE MONEY OUT of there may be an issue, but as long as they are regulated, is a risk worth to be taken...
- Citește mai mult...
- 3 comentarii
- 3.866 citiri
-
This BcLib issue adds new trading functions:
- ReliableModifyTakeProfit() and ReliableModifyStopLoss(), which attempt to place and repair the TP and SL levels , by moving them up or down (take profit, for buys and sells) , down or up (stop loss, for buys and sells) in order to avoid ERR_INVALID_STOPS, which is the only error handled by these functions. The fast functions ModifyTakeProfit() and ModifyStopLoss(), older, simply attempt to do this once without handling any error.
- ReliableOrderPlace(), which is an upgrade of the ReliableOrderSend() . The difference is that SL and TP are integers , given by the user in pips. ReliableOrderPlace() calls ReliableOrderSend() to manage placing of the order without SL and TP, then it uses ReliableModifyTakeProfit() and ReliableModifyStopLoss to set TP and SL levels. This is why, if any errors appear in the log, they are reported by ReliableOrderSend(), not by ReliableOrderPlace().
- Citește mai mult...
- 3 comentarii
- 3.544 citiri
-
After weeks of making a long, costly and complicated SWIFT transfer , I finally managed to open account with WHC. (Tell you guys that do SWIFT, always wire to the final beneficiary bank, disregarding any info on the corresponding bank). With 10% of equity consumed during this madness , also caused by the fact WHC wasn't quite accepting EUR deposits, as stated on their IB's website, I was almost pissed off. However, their real datafeed is beyond my previous expectations : lots of forex (including the dangerous, but easy tradable USDHKD - easy to forecast due to Hong Kong's monetary council regime), stocks (common and some preferred), all kinds of commodities , indexes and currency futures, with various expiries and some quoted on different exchanges. I didn't have the patience to count all the symbols , so I decided to make a movie about it and uploaded on YouTube:
Presently I'm a bit tired due to various collaborations, hope to start trading as soon as I digest the new trading opportunities given by the new stuff!
- Citește mai mult...
- 4 comentarii
- 8.035 citiri
-
I'm answering to Pion's request to release the code for BcWin and BcTools. These were both written in Dev-Pascal. I am attaching the pas and project files , as a test script for them too.
- Citește mai mult...
- 1 comentariu
- 2.614 citiri
-
Last week our fellow TradeLover from the forum (who is also a contestant in MetaQuotes Automated Trading Championship 2007 - let's give him an for that) made a shocking and very disturbing discovery: a tick is not quite a pip in forex (we even argued for that, but he was right - never take anything for granted)
Running a simple script like this:
int start()
{ Print("tick size= ",MarketInfo(Symbol(),MODE_TICKSIZE),
" - tick value= ",MarketInfo(Symbol(),MODE_TICKVALUE));
return(0);
}
what he got after some hours was this:
22:40:03 ticksize GBPCHF,M1: tick size= 0.0001 - tick value= 8.53
22:40:13 ticksize GBPCHF,M1: tick size= 0.0001 - tick value= 8.53
22:40:20 ticksize GBPCHF,M1: tick size= 0.0001 - tick value= 8.53
22:40:24 ticksize GBPCHF,M1: tick size= 0.0001 - tick value= 8.53
22:40:27 ticksize GBPCHF,M1: tick size= 0.0001 - tick value= 8.53
22:40:30 ticksize GBPCHF,M1: tick size= 0.0001 - tick value= 8.53
22:40:31 ticksize GBPCHF,M1: tick size= 0.0002 - tick value= 17.07
22:40:32 ticksize GBPCHF,M1: tick size= 0.0001 - tick value= 8.53
22:40:46 ticksize GBPCHF,M1: tick size= 0.0001 - tick value= 8.53
Now what if that tick value is caught in a hedge calculus that calculates lotsizing or results for months ahead ?
In order to settle this issue once and for all, I made the RealTickValue() function as follows:
double RealTickValue(string contract)
{
double res;
res= MarketInfo(contract,MODE_TICKVALUE) / (MarketInfo(contract,MODE_TICKSIZE)/MarketInfo(contract,MODE_POINT));
return(res);
}
The function now works as a proxy for MODE_TICKVALUE inquiries. Now both BcLib and BcArb call that first when dealing with MODE_TICKVALUE.
Found surprise bugs in ReliableOrderSend and ReliableOrderClose. Don't know how they got there, as they seem to work well.
Also corrected past scripts that use MODE_TICKVALUE. Discovered also mistakes in updated SwapFinder, that's why I corrected and updated again, along with SwapButterfly.
Inserted also a mechanism for calculating futures using London InterBank rates. It doesn't seem to be too much of use, as indicators are still wrong, but you can correct their parameters, so I added DiscountedFuturesLIB and DiscountedBasisLIB indicators.
Corrected bugs in Futures script. Now it's set up with a MarginUsage of 50% and a SwapFree regime set to True by default.
P.S.
I will keep you posted with my arbitrage trades working (Spot-to-Futures type A)
- Citește mai mult...
- 3 comentarii
- 9.295 citiri
-
Updates list:
- Updated code for ReliableOrderSend(), ReliableOrderClose() as I wrote earlier in this blog;
- Modified fast Order_**** functions to lookup history , after checking current trades ; added function Order_Pool to retrieve the place of an order: MODE_TRADES, MODE_HISTORY, or -1;
- Replaced calls to ObjectsRedraw() with calls to WindowRedraw().
The RealTickValue() function remains in place as a proxy for getting tick values, although MetaQuotes corrected the MODE_TICKVALUE bug since build 211.
P.S. We are still working on the FXIndia issue...
- Citește mai mult...
- 1 comentariu
- 1.889 citiri
-
Well, finally managed to pull money out of FXINDIA. Was it a good broker? Well, they payed. (Perhaps because we didn't make noise on their forums, who knows). Did they do everything against us? Well, after the tricky swap charge they saw we are more stubborn than anticipated and decided to get rid of us and almost banned logins. Thanks to Matt we managed an awesome rate of about 170%... But again, trading on the edge, with more than MT4. The natural exploit of difference in volatility between forex and futures has been one of the keys used in this situation.
But now it's over. Have to look at other brokers... Does anybody know RELIABLE brokers offering same datafeed as WHC ?
- Citește mai mult...
- 2 comentarii
- 4.287 citiri
-
You're right Andi, I have kinda forgot posting results...
http://img81.imageshack.us/img81/7180/tradestatus1710xf6.jpg
After a jump last week from around $150 - $250 now it's consolidating in $300 - $350 area. The time it happened the DiscountedBasis indicator jumped over 0 ; generally it's negative (-1 to -7, average -3 to -5), except for the unhedged hour when Globex is shut down.
- Citește mai mult...
- 18 comentarii
- 65.717 citiri
-
http://img339.imageshack.us/img339/552/shutdownsg8.jpg
Damn! With that big -978.76 bucks swap....I had to close! This will not remain unpunished!
- Citește mai mult...
- 3 comentarii
- 3.855 citiri
-
Since I'm using this strategy, I observe that sometimes the account stays a lot constant, then jumps suddenly. Finally found the catch. Here is also my account status for november 8:
http://img258.imageshack.us/img258/9493/marketineficienciesej2.jpg
As you can see in the first red circle, before Globex shut down hour on Nov 7 , the discounted USDJPY futures was under USDJPY value. During this time, USDJPY moved down. Once the Globex started up, the discounted futures had to come towards USDJPY from its upward position, and it was stopped by the market's evaluation nearby USDJPY but in the upper side, since it came from up. It started to fluctuate around this value, this is why we see the DiscountedBasis average jump from negative to positive.
This second picture is to answer Juan's request to see how much basis modified since last month:
http://img210.imageshack.us/img210/1460/basisreductionya4.jpg
As you can see, the basis reduced from about 98 pips on Nov 9 to almost 43 pips now. Isn't that cool ?
I appeal again at my readers to help me with the parameters of T-notes, as I want to check about arbitrage windows forming between the three T-note classes (2 years, 5 years, 10 years).
- Citește mai mult...
- 5 comentarii
- 9.152 citiri
-
Well, a yield of 41% surely beats the hell of the Barclay's Hedge Fund Index
http://img222.imageshack.us/img222/4685/tradereportoct26ou2.jpg
This result was at a DiscountedBasis value of about 2 points. I have to mention that starting from morning of Oct 25, right after Globex respawn, the DiscountedBasis indicator, which was working at -5...-3 for about two weeks jumped around 0 and is averagely positive, meaning that the 6J future (direct quote) is slightly underpriced, compared with last week, when it was a bit overpriced (compared to the theoretical value). That means there is still room for average length arbitrages, shorter than a month.
The strategy risks are practically extinct. But the moral hazard risks?.... Don't ask!
- Citește mai mult...
- 5 comentarii
- 6.707 citiri
-
So far, so good...
http://img73.imageshack.us/img73/8026/mytradingoct102007dl8.jpg
- Citește mai mult...
- 1 comentariu
- 1.488 citiri
-
It seems when I inserted the MaxPasses parameter in ReliableOrderSend and ReliableOrderClose they became really broken. Last correction solves the issue, however there is still a bug:
Examining the corrected codes of the functions: copy from here and replace in BcLib.mq4!
int ReliableOrderSend(string symbol,int cmd,double volume,double price,int slippage,double stoploss,double takeprofit, string comment="",int magic=0,datetime expiration=0,color arrow_color=CLR_NONE,int MaxPasses=0) { int Gle=ERR_TRADE_CONTEXT_BUSY; string ErrType=""; string ErrText=""; string ErrExplanation=""; int passes=0; int res=-1; while (Gle==ERR_TRADE_CONTEXT_BUSY||Gle==ERR_REQUOTE||Gle==ERR_INVALID_PRICE||Gle==ERR_PRICE_CHANGED||Gle==ERR_OFF_QUOTES) { if (Gle==ERR_REQUOTE||Gle==ERR_INVALID_PRICE||Gle==ERR_PRICE_CHANGED||Gle==ERR_OFF_QUOTES||passes==0) { if (passes!=0) RefreshRates(); if (price==0.0) //if (passes!=0||price==0) price=MarketInfo(symbol,PriceOpenMode(cmd)); }//if (Gle==ERR_REQUOTE) res=OrderSend(symbol,cmd,volume,price,slippage,stoploss,takeprofit,comment,magic,expiration,arrow_color); Gle=GetLastError(); TranslateError(Gle,ErrType,ErrText,ErrExplanation); if (Gle!=ERR_NO_ERROR) Print("ReliableOrderSend error : ",Gle," : ",ErrText); passes=passes+1; if (MaxPasses!=0) { if (passes>=MaxPasses) break; } //ADD ONLY THIS LINE if (Gle==ERR_REQUOTE||Gle==ERR_INVALID_PRICE||Gle==ERR_PRICE_CHANGED||Gle==ERR_OFF_QUOTES) { price=0.0; } }//while (Gle==ERR_TRADE_CONTEXT_BUSY||Gle==ERR_REQUOTE) return(res); } bool ReliableOrderClose(int ticket, double lots, double price, int slippage, color Color=CLR_NONE,int MaxPasses=0) { int Gle=ERR_TRADE_CONTEXT_BUSY; string ErrType=""; string ErrText=""; string ErrExplanation=""; int passes=0; bool res; int otype; double olots; string osymbol; res=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES); osymbol=OrderSymbol(); otype=OrderType(); olots=OrderLots(); if (lots==0) lots=olots; if (res==True) { while (Gle==ERR_TRADE_CONTEXT_BUSY||Gle==ERR_REQUOTE||Gle==ERR_INVALID_PRICE||Gle==ERR_PRICE_CHANGED||Gle==ERR_OFF_QUOTES) { if (Gle==ERR_REQUOTE||Gle==ERR_INVALID_PRICE||Gle==ERR_PRICE_CHANGED||Gle==ERR_OFF_QUOTES||passes==0) { if (passes!=0) RefreshRates(); if (price==0.0) //if (passes!=0||price==0) price=MarketInfo(osymbol,PriceCloseMode(otype)); }//if (Gle==ERR_REQUOTE) res=OrderClose(ticket,lots,price,slippage,Color); Gle=GetLastError(); TranslateError(Gle,ErrType,ErrText,ErrExplanation); if (Gle!=ERR_NO_ERROR) Print("ReliableOrderClose error : ",Gle," : ",ErrText); passes=passes+1; if (MaxPasses!=0) { if (passes>=MaxPasses) break; } //ADD ONLY THIS LINE if (Gle==ERR_REQUOTE||Gle==ERR_INVALID_PRICE||Gle==ERR_PRICE_CHANGED||Gle==ERR_OFF_QUOTES) { price=0.0; } }//while (Gle==ERR_TRADE_CONTEXT_BUSY||Gle==ERR_REQUOTE) } return(res); }
As you can see, the 0 for entry price is correctly handled. As long as a bad error occurs (such as ERR_OFF_QUOTES occurs) and there is no price sent to OrderSend() the price is reread by MarketInfo. However, if a regular error comes (such as ERR_PRICE_CHANGED) then function enters a possible endless loop, as the MarketInfo price inquiry will not be executed. This is why, before while cycle ends, price will be reset in both ReliableOrderSend() and ReliableOrderClose(), making possible its read in the next cycle execution. This is the only modification to be done. In the same time, given the fact we reset the price before the while ends, the first execution is ok in both cases with a 0 price and a non-zero given price. (Don't look at the old closing while comments, they are really old, when functions didn't handle all these errors!)
Later edit: price must be reset only in some error conditions, not in all!
P.S.
I need some input folks! Can't see all the bugs lurking the shadows! At least for BcLib core modules...
P.S. no 2
My trading account floats around 3% ROE (started from late Aug. 27).
- Citește mai mult...
- 10 comentarii
- 14.701 citiri
-
I was looking over the oil arbitrage script making money on my friend Billy's server these days, and I thought to myself that the forum might benefit out of this. I am seeing that losses, that are a rule for forex traders, are accidents in arbitrage, and I said to myself "Enough with regular trading. People must know." We must never ever take abuse from regular trading again, and finally break down the old saying "You don't risk, you don't win". So I decided for the first time to release full code and documentation on the arbitrage strategies that I have on hand now (Intercross Arbitrage, Swap Arbitrage, Oil Arbitrage, and the following Cash/Futures Arbitrage), after the blog categories will be ready. Also decided to make it in english to increase website traffic.
- Citește mai mult...
- 4 comentarii
- 5.529 citiri
-
After two years of absence, I am announcing everyone that I have decided to move the blog on my own domain. Previous entries will remain here, some will be copied to the new address. However, the launch is highly dependant on how MT5 will be finally implemented - that is, how big will be the capacities of the new Strategy Tester, as well as options that supposedly will be introduced. The blog will focus on MT5 programming and multiasset strategies involving arbitrage, pair trading, and option trading strategies, from simple indicator ruled strategies to complex volatility scalping. The so-called lack of hedging accuse coming from forex traders to the MT5 platform is only partially true - it's based on a lack of knowledge of what hedging really is, which is the terrain of derivatives quants. Hedging with multiple orders on MT4 platform is the most rigid form of hedging. It has a lot of applications in easier trade planning as well as in psychological issues - some traders prefer to hedge against the choppiness of a trend instead of closing trades. But there is nothing to indicate that this hedging would really be beneficial - as it doesn't create any kind of white noise or arbitrage windows (remember that Michal Kreslik called it "futile hedge"). Now it's time for the rest of the world to know and use real hedging strategies, as option traders were almost prohibited to do it because of costs, regulatory issues and platform underdevelopment, that either prevented hedging options with underlying , option automation or backtest. Institutions however will always be a step ahead especially in option trading, because they have the opportunity to quote options and get filled, thereby making large economies, since the option spreads are pretty large. But the introduction of options along fx will be rather unique - for the first time, asymetric trading on the same asset, right from the expert advisor. Asymetric trading is full of opportunities, as portfolios will have double values - values at expiry vs market values - and this is where real hedging comes in place.
I don't promise anything. I really hope MetaQuotes will deliver the final MT5 in a state that will allow options and futures along fx trading. Or at least options along futures and equities (as in NFA regulations) all backtestable simultaneously with a new, renowned, Strategy Tester. In these new conditions, even the "forex trading" concept might vanish soon to be replaced by a radical "retail trading" concept - when traders trade across multiple asset classes without the current limitations.
The ball is still in MetaQuotes' yard, and we still play the waiting game...
- Citește mai mult...
- 0 comentarii
- 6.824 citiri
-
Updates list:
> Swap2Interest_Volume function now supports swap type 1 also;
> "Swap Functions" block renamed to "Financial Math";
> "Financial Math" block expanded to include functions for calculation or discount of currency futures;
> GetCurrency() now works when market is closed too;
> Added optimization types OPTIMIZE_SWAP_ONLY_VIRTUAL , OPTIMIZE_PRICE_ONLY_VIRTUAL to BcArb as possible parameter values for GetBestCross();
> Added variable bool SupportOneAtomCrosslists = false that can work as a switch to influence CreateCrosslist() and CreateCrosslistsTable() to discard or not one-atom crosslists;
...and perhaps others which I don't remember.
Check also the new and repaired SwapFinder_script that uses everywhere UnitsToLots().
- Citește mai mult...
- 0 comentarii
- 1.083 citiri
-
Have you ever considered that a large amount of brokers work as online casinos trading against their clients and getting not only the spreads, but also their money? What makes them "play the house" in this game? Newbie traders greed and confidence? They know that the traders that make money are only the 10%, why not taking the money of the rest...
Let's think for a moment: what kind of money management do you need to have in order to see the broker as a player, while you have the house?
How to make the a large number of losses not affect you and boost up equity during small gain series?
Let's consider the market as a binary stream of situations that are equal (as a huge stream of 0 and 1 digits). Let the 0's be the loss situations and 1's the win situations. How not to lose to much cash? Don't play too much on each situation. Suppose you divide your capital in 256 parts, and play each part to be won or lost. That means that after a huge number of say 20 consecutive losses, you lost 20 units from 256. The broker, on the other side, what did it win? Small gains "pip wise". Now pretty many times the randomness of market will put you in win situations. A played unit that is won remains and generates a unit of profit. So now on the next trade you have available 2 units from the previous trade + 1 unit (the one allocated for the trade). If the next trade is won, it will double the played units, which will be 6. You already have 6 units and play for the next one. That means 7 units available. You win this one, thus making 14 units. If you win the next one, it will be (14+1)*2 = 30 units. After a series of 4 wins you already recovered the 20 units and made 10 as profit. Did the broker lost 30 units in just 4 trades ? Yes. Did it play stupidly trading against you ? Yes. Was it "pound foolish" ? Yes again. Of course if you lose the last trade, you lose 4 units of the original 256 making the equity. Another version of this would be not adding an unit every won trade. Once the first wins another unit, play these 2 units and so on. On the loss moment, only the original unit is lost from equity.
It is up to you to decide how many consecutive wons will be doubled. After N predefined wons, you may consider breaking up the series and redefining the unit size, then start from the beginning.
However, wons will be from a lot smaller to slightly smaller that losses. Because of the spread. From 10 pips, 3 pips spread is 30%, but from 50 pips, 3 pips spread is just 6%, so you could consider a binary "fair" distribution of 53% losses to 47% wins, more similar to roulette distribution (remember they have the 0 and 00 numbers that reduce the win ratio).
Isn't this a form of statistically arbitraging the win chances by taking advantage in small series of wins and losing a little during larger series of consecutive losses?
- Citește mai mult...
- 0 comentarii
- 1.085 citiri
-
Place BcLib and BcArb in experts\include folder
Place BcTools.Dll and BcWin.exe in experts\libraries folder
First compile BcLib then BcArb.
- Citește mai mult...
- 0 comentarii
- 1.250 citiri