<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>the genetic trader . com</title>
	<atom:link href="http://www.thegenetictrader.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thegenetictrader.com</link>
	<description>Freelance quantitative analyst specialising in evolutionary computing techniques.</description>
	<lastBuildDate>Wed, 23 Jun 2010 12:51:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Particle Swarm Optimisation</title>
		<link>http://www.thegenetictrader.com/2010/01/14/particle-swarm-optimisation/</link>
		<comments>http://www.thegenetictrader.com/2010/01/14/particle-swarm-optimisation/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 23:26:40 +0000</pubDate>
		<dc:creator>andrew</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Optimisation]]></category>

		<guid isPermaLink="false">http://www.thegenetictrader.com/?p=85</guid>
		<description><![CDATA[Several commentators have mentioned Particle Swarm Optimisation so I have researched it and coded an example below in Haskell. PSO is a search algorithm that mimics the swarming tendencies seen in nature e.g. flocks of birds, shoals of fish, etc. To visualize how it works it&#8217;s best to think of a natural example. Imagine a [...]]]></description>
			<content:encoded><![CDATA[<!-- AdSense Now! V1.90 -->
<!-- Post[count: 2] -->
<div class="adsense adsense-leadin" style="float:right;margin: 12px;"><script type="text/javascript"><!--
google_ad_client = "pub-1213643583738263";
/* 234x60, AdSenseNow created 3/1/09 */
google_ad_slot = "5294177075";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><p>Several commentators have mentioned <a href="http://www.swarmintelligence.org/">Particle Swarm Optimisation</a> so I have researched it and coded an example below in Haskell. PSO is a search algorithm that mimics the swarming tendencies seen in nature e.g. flocks of birds, shoals of fish, etc. To visualize how it works it&#8217;s best to think of a natural example.</p>
<p>Imagine a single bird in search of food, as it moves about over a landscape its nose will pick up the scent of food &#8211; the closer the food the stronger the scent. It knows where it registered the strongest scent so it will concentrate it&#8217;s search around that location i.e. slowing down and moving around more closely until it finds it. One bird on it&#8217;s own will take a long time to search a large area so now let&#8217;s imagine that two birds are searching and they can communicate with each other to notify where they have a strong scent &#8211; this will induce swarming as the other bird travels towards the stronger scent.</p>
<p>This is how the algorithm works, so the x and y coordinates in the landscape are the parameters to be optimised i.e. find the value that gives the strongest scent &#8211; the location of the food ! The birds change their velocities i.e. how quickly they move over those parameters to home in on stronger values so the birds will swarm around likely solutions. The &#8216;scent&#8217; is provided by a fitness function that basically takes the parameters (x, y) and returns a score.</p>
<pre style="border: 1px dashed #999999; padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: #000000; background-color: #eeeeee; font-size: 12px; line-height: 14px; width: 100%;"><code>module Main where

import System.Random
import Data.List (find, maximum)
import Data.Maybe

c1 = 2.0
c2 = 2.0
vMax = 5.0

-- infinite list of infinite random lists (TODO: Remove fixed seed 42)
rl :: [[Double]]
rl = [randomRs ((0.0), 1.0) g | g &lt;- gl (mkStdGen 42)]
   where gl gen = gen:(gl (fst $ split gen)) 

-- Particle data type representing one particle
data Particle = Particle {
                  pbest :: [Double],           -- particle's best solution
                  pbestFitness :: Double,
                  velocities :: [Double],      -- particle's velocities
                  present :: [Double],         -- particle's present solution
                  fitness :: Double            -- current fitness
                  } deriving (Show)

cap :: Double -&gt; Double
cap x | x &lt; 0.0   = max x (-vMax)
      | otherwise = min x vMax    

-- Calculate the new velocities for a particle
calcVelocities :: Particle -&gt; [Double] -&gt; [Double] -&gt; [Double]
calcVelocities p gbest rand = [ cap (v + c1 * r1 * (pb - pr) + c2 * r2 * (gb - pr))
                                    | v &lt;- velocities p
                                    | pr &lt;- present p
                                    | pb &lt;- pbest p
                                    | gb &lt;- gbest
                                    | r1 &lt;- rand
                                    | r2 &lt;- drop (length $ velocities p) rand]

-- Update a particle's present solution and velocities
updateParticle :: Particle -&gt; [Double] -&gt; [Double] -&gt; Particle
updateParticle p gbest rands = p { present = [pr + v | pr &lt;- present p
                                                     | v &lt;- newVelocities ],
                                   velocities = newVelocities }
    where newVelocities = calcVelocities p gbest rands                                                                                                            

-- Find the best global solution in the population
getBest :: [Particle] -&gt; [Double]
getBest p = if (isJust b) then pbest (fromJust b) else []
    where  b = find (\x -&gt; pbestFitness x == m) p
           m = maximum [pbestFitness f | f &lt;- p]

-- Return the next generation
psoEvolve :: [[Double]] -&gt; [Particle] -&gt; [Particle]
psoEvolve rands population = [updateParticle p gbest r | p &lt;- pbests | r &lt;- rands]
    where fitnesses = [p { fitness = fitnessFunction (present p) } | p &lt;- population]
          pbests    = [if (fitness p &gt; pbestFitness p) then
                          p { pbest = (present p), pbestFitness = fitness p }
                       else
                          p  | p &lt;- fitnesses ]
          gbest     = getBest pbests         

-- Solve the problem using the ranges and fitness function
psoSolve :: [(Double, Double)] -&gt; Int -&gt; Int -&gt; [Double]
psoSolve ranges numParticles numGenerations = getBest $ foldl (\a x -&gt; psoEvolve (drop (2 + x) rl) a) pop [1..numGenerations]
    where pop = [Particle [] 0.0
                     (take l (head rl))
                     [(fst r) + x * ((snd r) - (fst r)) |r &lt;- ranges |x &lt;- (take l (rl !! 1))]
                     0.0 | n &lt;- [1..numParticles]]
          l   = length ranges

-- Fitness function takes the particles 'present' solution and returns a score
fitnessFunction :: [Double] -&gt; Double
fitnessFunction xs = (100.0 / sqrt (dx1 * dx1 + dy1 * dy1 + dz1 * dz1)) +
                     (50.0 / sqrt (dx2 * dx2 + dy2 * dy2 + dz2 * dz2))
    where dx1 = 53.4 - (xs !! 0)
          dy1 = 67.8 - (xs !! 1)
          dz1 = 32.6 - (xs !! 2)
          dx2 = 23.8 - (xs !! 0)
          dy2 = 18.0 - (xs !! 1)
          dz2 = 4.6 - (xs !! 2)

main = do
       print $ psoSolve [(0.0, 100.0), (0.0, 100.0), (0.0, 100.0)] 100 100 

</code></pre>
<p>The fitness function evaluates how close the particle (bird) is to two food sources in 3d space and returns the value. There is a large food source at (53.4, 67.8, 32.6) and a small food source at (23.8, 18.0, 4.6) so the optimum solution is the position of the large food source.</p>
<p>Here&#8217;s the result :-</p>
<pre style="border: 1px dashed #999999; padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: #000000; background-color: #eeeeee; font-size: 12px; line-height: 14px; width: 100%;"><code>[1 of 1] Compiling Main             ( /home/andrew/workspace/pso/src/Main.hs, interpreted )
Ok, modules loaded: Main.
*Main&gt; main
[53.422443402059535,67.83854324652401,32.637809690239244]
*Main&gt;
</code></pre>
<p>Notice that it has found the large food source with an error rate of only around 0.03 on each axis i.e. 0.03 % this is with 100 particles and 100 generations so 10,000 evaluations of the fitness function. An exhaustive search would have had to to 1000 evaluations in each axis i.e. 0.1 increments = 1,000,000,000 evaluations ! Depending on the granularity of the exhaustive search, it could have easily misidentified the smaller food source as the optimum solution which PSO avoided.</p>
<p>As you can see PSO is a very efficient search algorithm that can be several orders of magnitude faster than an exhaustive search and, as can be seen, is relatively simple to implement and use over a very wide range of problem domains.</p>
<p>So how is it going to help me in my quest to produce profitable trading strategies ? Well there are several possibilities :-</p>
<ul>
<li>Use to optimise GP solutions, i.e. use GP to create the structure of the solutions but PSO to optimise the constants used in the structure,</li>
<li>Use PSO to optimise the parameters used in the GP evolutions,</li>
<li>Use PSO to optimise the parameters to hand coded strategies.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.thegenetictrader.com/2010/01/14/particle-swarm-optimisation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Extracting historic data from MetaTrader</title>
		<link>http://www.thegenetictrader.com/2009/09/16/extracting-historic-data-from-metatrader/</link>
		<comments>http://www.thegenetictrader.com/2009/09/16/extracting-historic-data-from-metatrader/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 21:18:22 +0000</pubDate>
		<dc:creator>andrew</dc:creator>
				<category><![CDATA[MetaTrader]]></category>

		<guid isPermaLink="false">http://www.thegenetictrader.com/?p=33</guid>
		<description><![CDATA[If you&#8217;ve looked at my plan for forex, you&#8217;ll know that my first step is to create an EA that dumps the historic data out of MetaTrader into a CSV file so that I can load this into my Scheme programs creating the genetic programs. Here&#8217;s the code for DataDumper.mq4 that does just that :- [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve looked at my <a href="/2009/09/14/the-plan-for-forex/">plan for forex</a>, you&#8217;ll know that my first step is to create an EA that dumps the historic data out of MetaTrader into a CSV file so that I can load this into my Scheme programs creating the genetic programs.</p>
<p>Here&#8217;s the code for DataDumper.mq4 that does just that :-</p>
<pre style="border: 1px dashed #999999; padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: #000000; background-color: #eeeeee; font-size: 12px; line-height: 14px; width: 100%;"><code>//+---------------------------+

//| Historic Data Dumping EA  |

//+---------------------------+

#property copyright "Andrew Whaley"

extern int min_year = 2008;
extern int max_year = 2009;

// Global scope

int handle;

int init()

{

   int p = Period();

   string pd;

   if (p == 1) pd = "M1";

   else if (p == 5) pd = "M5";

   else if (p == 15) pd = "M15";

   else if (p == 30) pd = "M30";

   else if (p == 60) pd = "H1";

   else if (p == 240) pd = "H4";

   else pd = "D1";

   string filename = StringConcatenate(Symbol(), "_", pd, ".csv");

   handle = FileOpen(filename, FILE_CSV|FILE_WRITE, ',');

   FileWrite(handle, "Date", "Time", "Volume", "Low", "Open", "Close", "High", "Bid", "Ask");

   return(0);

}

int deinit()

{

   FileClose(handle);

   return(0);

}

int start()

{
   string d,m,y,h,mi;
   double open,close,high,low;
   double vol;

   if ((Year() &gt;= min_year) &amp;&amp; (Year() &lt;= max_year))
   {
     if (Day() &lt; 10) d = StringConcatenate("0", DoubleToStr(Day(),0));
     else d = DoubleToStr(Day(),0);

     if (Month() &lt; 10) m = StringConcatenate("0", DoubleToStr(Month(),0));
     else m = DoubleToStr(Month(),0);

     y = DoubleToStr(Year(),0);

     if (TimeHour(TimeCurrent()) &lt; 10) h = StringConcatenate("0", DoubleToStr(TimeHour(TimeCurrent()),0));
     else h = DoubleToStr(TimeHour(TimeCurrent()),0);

     if (TimeMinute(TimeCurrent()) &lt; 10) mi = StringConcatenate("0", DoubleToStr(TimeMinute(TimeCurrent()),0));
     else mi = DoubleToStr(TimeMinute(TimeCurrent()),0);

     string ds = StringConcatenate(""", d, "-", m, "-", y, """);

     string ts = StringConcatenate(""", h, ":", mi, """);

     open = iOpen(NULL, 0, 1);
     close = iClose(NULL, 0, 1);
     high = iHigh(NULL, 0, 1);
     low = iLow(NULL, 0, 1);
     vol = iVolume(NULL, 0, 1);

     FileWrite(handle, ds, ts, vol, low, open, close, high, Bid, Ask);
   }

   return(0);

}

</code></pre>
<p>Here&#8217;s how to use it :-</p>
<ol>
<li>Open the chart that you want use it on and attach the DataDumper EA,</li>
<li>Press F6 for the Tester</li>
<li>Select the symbol and period</li>
<li>Select the &#8216;Open prices only&#8217; model</li>
<li>Configure the EA properties for start and end year</li>
<li>Run the backtest</li>
</ol>
<p>When the test has finished, check your &lt;METATRADER&gt;/tester/files directory for the resultant CSV file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thegenetictrader.com/2009/09/16/extracting-historic-data-from-metatrader/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Running MetaTrader on Linux</title>
		<link>http://www.thegenetictrader.com/2009/09/10/running-metatrader-on-linux/</link>
		<comments>http://www.thegenetictrader.com/2009/09/10/running-metatrader-on-linux/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 11:39:43 +0000</pubDate>
		<dc:creator>andrew</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MetaTrader]]></category>

		<guid isPermaLink="false">http://www.thegenetictrader.com/?p=5</guid>
		<description><![CDATA[Many of the Forex brokers e.g. FXCM and Alpari UK are now offering direct trading through MetaTrader which offers great opportunities to program &#8216;Expert Advisors&#8217; to automate your trading. This means that you can be day trading full time whilst you&#8217;re at work and asleep. Unfortunately MetaTrader is a purely Windows application but the great [...]]]></description>
			<content:encoded><![CDATA[<p>Many of the Forex brokers e.g. <a href="http://www.fxcm.co.uk/">FXCM</a> and <a href="http://www.alpari.co.uk/">Alpari UK</a> are now offering direct trading through MetaTrader which offers great opportunities to program &#8216;Expert Advisors&#8217; to automate your trading. This means that you can be day trading full time whilst you&#8217;re at work and asleep.</p>
<p>Unfortunately MetaTrader is a purely Windows application but the great news is that it installs and runs fine under Wine on Ubuntu 9.04. It will install under vanilla Wine from the Ubuntu repository but unfortunately it won&#8217;t run because it requires MFC libraries that aren&#8217;t included in the default Wine installation.</p>
<p>This is easily remedied by copying the following files from a Windows XP box :-</p>
<p><code>-rwxrwxrwx 1 andrew andrew  924432 2003-07-16 17:28 mfc40.dll<br />
-rwxrwxrwx 1 andrew andrew  927504 2008-04-14 01:11 mfc40u.dll<br />
-rwxrwxrwx 1 andrew andrew 1028096 2008-04-14 01:11 mfc42.dll<br />
-rwxrwxrwx 1 andrew andrew  981760 2007-04-03 04:14 mfc42u.dll<br />
-rwxrwxrwx 1 andrew andrew 1060864 2003-03-18 20:20 mfc71.dll<br />
-rwxrwxrwx 1 andrew andrew 1047552 2003-03-18 20:12 mfc71u.dll<br />
-rwxrwxrwx 1 andrew andrew   22528 2008-04-14 01:11 mfcsubs.dll</code></p>
<p>to your .wine/dosdevices/c:/windows/system32 directory.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thegenetictrader.com/2009/09/10/running-metatrader-on-linux/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
