Wednesday, March 16, 2011

 

Technical analysis with FreePascal and TA-lib


As the home page explains, TA-Lib is a C++ library widely used by trading software developers requiring to perform technical analysis of financial market data. It Includes 200 indicators such as ADX, MACD, RSI, Stochastic, Bollinger Bands, and Candlestick pattern recognition.

The library was written in C++, but its developers made a very intelligent decision by creating a C wrapper, to allow other languages interact with it. Here I'll show an example of how you can calculate Bollinger Bands using this library and FreePascal.

Let's download and uncompress the library.

cd ~/
wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz
tar xvfz ta-lib-0.4.0-src.tar.gz


This will create a ta-lib directory in our home. For example in /home/leonardo/ta-lib.

Now, we need to create a shared library from its sources.

cd ~/ta-lib
./configure
make


That's all, the files "src/libta_lib.la" and "src/.libs/libta_lib.so" were created.

Now, let's create a new directory for our FreePascal program.

mkdir ~/fpc-talib
cd ~/fpc-talib


...and copy libta_lib.so to that new directory.

cp ~/ta-lib/src/.libs/libta_lib.so ~/fpc-talib
cd ~/fpc-talib


Before creating our first FPC/ta_lib program, I recommend reading the TA-Lib API Documentation, and also taking a look at the functions from the "src/ta_func" directory.

Now, let's take a look at the function TA_BBANDS. It allows us to calculate the Bollinger Bands for a serie of closing prices.


TA_RetCode TA_BBANDS( int startIdx,
int endIdx,
const double inReal[],
int optInTimePeriod,
double optInNbDevUp,
double optInNbDevDn,
TA_MAType optInMAType,
int *outBegIdx,
int *outNBElement,
double outRealUpperBand[],
double outRealMiddleBand[],
double outRealLowerBand[] )


The function's input is an array of double, containing for example the closing prices of XYZ stock for the last year. And its outputs are three arrays of double, of the same length as the input, containing the points that define the upper, middle and lower Bollinger bands.

To be able to work with this function, we must create a Pascal version of its interface:


TTA_BBANDS = function(
startIdx, endIdx: Integer;
const inReal: Array of Double;
optInTimePeriod: Integer;
optInNbDevUp, optInNbDevDn: Double;
optInMAType: TTA_MAType;
out outBegIdx: Integer;
out outNBElement: Integer;
outRealUpperBand: Array of Double;
outRealMiddleBand: Array of Double;
outRealLowerBand: Array of Double
): Integer; cdecl;


Well, I must admit it took me a whole afternoon to figure out that the function needed those "out" params, but after that, everything was pretty smooth.

Show me a complete example!


unit formulas;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils,
DynLibs;

type
TTA_MAType = (TA_MAType_SMA, TA_MAType_EMA, TA_MAType_WMA, TA_MAType_DEMA,
TA_MAType_TEMA, TA_MAType_TRIMA, TA_MAType_KAMA, TA_MAType_MAMA, TA_MAType_T3);

TTA_BBANDS = function(
startIdx, endIdx: Integer;
const inReal: Array of Double;
optInTimePeriod: Integer;
optInNbDevUp, optInNbDevDn: Double;
optInMAType: TTA_MAType;
out outBegIdx: Integer;
out outNBElement: Integer;
outRealUpperBand: Array of Double;
outRealMiddleBand: Array of Double;
outRealLowerBand: Array of Double
): Integer; cdecl;


implementation

var
lHandle: TLibHandle;
lBBands: TTA_BBANDS;
lInReal: Array of double;
lOutBegIdx: Integer;
lOutNBElement: Integer;
lOutRealUpper: Array of double;
lOutRealMiddle: Array of double;
lOutRealLower: Array of double;
lRes: Integer;
I: Integer;
lLowerVol: Double;
lSqueeze: Integer;

begin
lHandle := LoadLibrary('/home/leonardo/fpc-talib/libta_lib.so');
if lHandle <> 0 then
begin
Pointer(lBBands) := GetProcAddress(lHandle, 'TA_BBANDS');
if @lBBands <> nil then
begin
(* lInReal is the array of Closing prices containing
the last 100 days for XYZ stock *)
SetLength(lInReal, 100);
lInReal[0] := 10.50;
lInReal[1] := 10.75;
lInReal[2] := 11.25;
//..
//.. and so on to the 99nth element.
//..
lInReal[99] := 8.35;

SetLength(lOutRealUpper, Length(lInReal)); // the same length as lInReal
SetLength(lOutRealMiddle, Length(lInReal));// the same length as lInReal
SetLength(lOutRealLower, Length(lInReal));// the same length as lInReal

lRes := lBBands(
0, AQuotes.Count - 1, lInReal, APeriods, 2, 2, TA_MAType_SMA,
lOutBegIdx, lOutNBElement, lOutRealUpper, lOutRealMiddle, lOutRealLower);

lLowerVol := 0;
for I := 0 to Length(lInReal) - 1 do
begin
writeln(
Format('Close %f - Upper BBand %f - Middle BBand %f - Lower BBand %f',
[lInReal[I], lOutRealUpper[I], lOutRealMiddle[I], lOutRealLower[I]])
);
end;
end;
UnloadLibrary(lHandle);
end;
end;

end.

And that's it.

Following the same approach, I created a home-made trading system based on Bollinger Bands and Option Straddles that is performing pretty well!. I'm very seriously thinking of creating an investment fund, what about "The FreePascal Investment Fund" ? :). See you in my next post.
Comments:
Would like to see your trading program! Please send some screenshots or post a beta version.
 
Rick, well its not a "visual" program, so, no screenshots for now.

Basically the program is called by a cron once a minute, and fetches all s&p500 symbols, then append its data to an historical database containing a year of daily data for each symbol. Then the software applies the Bollinger Bands formula checking if the last price fetched is in the lowest volatility area of the past six months, in that case it checks for option straddle or strangle opportunities around the price of the stock, and with at least 30 days to expiration. If all those conditions are met, then the software does a "paper trade" buy order on that options.

Now, I'm trying to find the best method to let the software figure out when is the best moment to sell.
 
I am just getting in to FPC and searched for trading libraries wich lead me here. This example is just what I needed to get me off the ground. Thanks a lot Leonardo great job.
 
Would you share your translated library?
 
Mauricio, I don't have a library, I just use the functions in my programs as the examplo shows.
 
Hi Leonardo,

I'm currently putting together a pricing server in C++ using ta_lib and found your post interesting.

I'm have developed an FX trading strategy in MT4 but have encountered performance problems so am looking to distribute the calculation onto (serveral) linux servers.

I'm using 'zeromq' in order to distribute data and calculations to remote processes and was looking to use ta-lib for a number of pricing functions.

I'm struggling to find any decent api documentation and wondered if you had found any during your coding ?


Many thanks in advance

Paul
Fractal Forex Ltd.
 
Hi Leonardo,

I'm currently putting together a pricing server in C++ using ta_lib and found your post interesting.

I'm have developed an FX trading strategy in MT4 but have encountered performance problems so am looking to distribute the calculation onto (serveral) linux servers.

I'm using 'zeromq' in order to distribute data and calculations to remote processes and was looking to use ta-lib for a number of pricing functions.

I'm struggling to find any decent api documentation and wondered if you had found any during your coding ?


Many thanks in advance

Paul
Fractal Forex Ltd.
 
Hi Paul, the only source of information I used was the TA-Lib web site and its source code. In my case it wasn't too difficult because I was looking only for a bollinger bands function.

The interesting part of building a library of trading/financial functions is that you can encapsulate different libraries into your own "api", then easily call its functions from your app. This way, you can include TA-lib, Quantlib, etc.
 
I'll have to persevere by looking through the source code !

Seems like it might not be a good long term solution as I want to use more functions.

How is your options strategy progressing ?

P
 
> How is your options strategy progressing ?

First of all, I've created this project just for fun, trying to test a strategy based on bollinger bands, but as it didn't seem to be usefull I stopped using it, instead I bought a couple of books about options strategies and when I have some free time, I'll try to get back to this.

If I understand correctly your question, you are asking for how I'm handling automated order processing. I'm not doing that, the system just gives signals when some condition happens, then I evaluate and place orders by hand.
 
I wondered if the strategy was proving successful, sounds like it was not !

Good luck with your research.

Paul
 
Hello Leonardo, I might have to make the source code of your program to analyze it better?! Thank you very much. If you send it to me at the email francesco.sammarco@gmail.com

thanks
Francesco Sammarco
 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?