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.
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.
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.
...and copy libta_lib.so to that new directory.
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.
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:
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!
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.
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:
Links to this post:
<< Home
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.
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.
Post a Comment
Links to this post:
<< Home
About me: I'm a software developer from Cordoba, Argentina.
I program in wide range of languages, specially Object Pascal (which i preffer),
also i work for 
