Skip to content

New Updates #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 170 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
6a996af
Update README.md
JamesKBowler May 23, 2017
24d0c50
fxcmminerv1.1
JamesKBowler Jun 21, 2017
1a1ff20
Update README.md
JamesKBowler Jun 21, 2017
568d0f2
Removed fxcmminerv1.0
JamesKBowler Jun 21, 2017
5ded5cd
Merge branch 'master' of https://github.com/JamesKBowler/fxcmminer
JamesKBowler Jun 21, 2017
2ba66ee
Update README.md
JamesKBowler Jun 21, 2017
e8cdcdd
Update README.md
JamesKBowler Jun 21, 2017
382f844
Update dropdb.sql
JamesKBowler Jun 21, 2017
8a013bb
Update README.md
JamesKBowler Jun 21, 2017
d1bd72c
Update base.py
JamesKBowler Jun 23, 2017
54d8fea
Update base.py
JamesKBowler Jun 23, 2017
5f57889
Delete .log.py.swp
JamesKBowler Jun 23, 2017
e868d4d
Update laundry.py
JamesKBowler Jun 23, 2017
e716c1a
Update base.py
JamesKBowler Jun 23, 2017
7a0aef4
Update historical.py
JamesKBowler Jun 23, 2017
1fe6287
Update live.py
JamesKBowler Jun 23, 2017
d13aa38
Update engine.py
JamesKBowler Jun 23, 2017
936bd0d
added exception to get_data( )
JamesKBowler Jun 23, 2017
7274156
Update live.py
JamesKBowler Jul 11, 2017
78fc7f6
Update historical.py
JamesKBowler Jul 11, 2017
06277ea
Update laundry.py
JamesKBowler Jul 11, 2017
6d04f6d
Update catalogdict.py
JamesKBowler Jul 11, 2017
e30a699
Update log.py
JamesKBowler Jul 11, 2017
f4cb542
Update catalogparser.py
JamesKBowler Jul 11, 2017
6c3bca4
Update tradinghours.py
JamesKBowler Jul 11, 2017
a18613b
Update base.py
JamesKBowler Jul 11, 2017
0d186aa
fixed bug in DateTimeManagement
JamesKBowler Aug 16, 2017
824533d
Update base.py
JamesKBowler Aug 16, 2017
b45f7a1
Update base.py
JamesKBowler Aug 16, 2017
805e6ef
Update base.py
JamesKBowler Aug 16, 2017
14ebb10
Update base.py
JamesKBowler Aug 17, 2017
976f539
Update base.py
JamesKBowler Sep 6, 2017
b08bf98
new updates
JamesKBowler Jan 17, 2018
4325470
Merge https://github.com/JamesKBowler/fxcmminer
JamesKBowler Jan 17, 2018
17df27b
nuke and start again
JamesKBowler Jan 17, 2018
709fa24
full re-write of logic
JamesKBowler Jan 17, 2018
bc578f5
Merge https://github.com/JamesKBowler/fxcmminer
JamesKBowler Jan 17, 2018
29da328
full re-write of logic
JamesKBowler Jan 17, 2018
e63e361
Merge https://github.com/JamesKBowler/fxcmminer
JamesKBowler Jan 17, 2018
d891f80
Create LICENSE
JamesKBowler Jan 17, 2018
b4a59b6
Merge pull request #2 from JamesKBowler/add-license-1
JamesKBowler Jan 17, 2018
f1b64df
README
JamesKBowler Jan 17, 2018
e8c1a5e
adding new code
JamesKBowler Jan 17, 2018
6291847
adding __pycache__
JamesKBowler Jan 17, 2018
fa4a1ef
Rename _.py to _.txt
JamesKBowler Jan 17, 2018
e5a1815
Update README.md
JamesKBowler Jan 17, 2018
3c4de23
Update README.md
JamesKBowler Jan 17, 2018
8688e82
Update README.md
JamesKBowler Jan 17, 2018
74f53e0
Update README.md
JamesKBowler Jan 17, 2018
41104ca
tidy up of code
JamesKBowler Jan 17, 2018
c5ca691
Update broker.py
JamesKBowler Jan 17, 2018
df75a58
Update instrument.py
JamesKBowler Jan 17, 2018
7f927a6
PEP8
JamesKBowler Jan 17, 2018
aa21c93
PEP8
JamesKBowler Jan 17, 2018
a23e8e5
Update broker.py
JamesKBowler Jan 17, 2018
cc0c374
Update README.md
JamesKBowler Jan 18, 2018
39ab88f
fixed calculate_finished_bar()
JamesKBowler Jan 18, 2018
39c1895
Update collection.py
JamesKBowler Jan 18, 2018
096c2d0
Update README.md
JamesKBowler Jan 18, 2018
35e7a17
Update README.md
JamesKBowler Jan 18, 2018
b0001fe
Update README.md
JamesKBowler Jan 18, 2018
245f294
Update README.md
JamesKBowler Jan 18, 2018
ab9ae69
Update instrument.py
JamesKBowler Jan 18, 2018
a4520e6
Update database.py
JamesKBowler Jan 18, 2018
e57155d
Update database.py
JamesKBowler Jan 19, 2018
abae380
Update README.md
JamesKBowler Jan 19, 2018
9cbbf70
Update collection.py
JamesKBowler Jan 19, 2018
f37995e
Update collection.py
JamesKBowler Jan 19, 2018
f64a2db
Update collection.py
JamesKBowler Jan 19, 2018
efa2712
Update collection.py
JamesKBowler Jan 19, 2018
1d544bc
Update instrument.py
JamesKBowler Jan 19, 2018
e5b4b2f
Update instrument.py
JamesKBowler Jan 19, 2018
d593164
Update collection.py
JamesKBowler Jan 19, 2018
f07d8e1
Update collection.py
JamesKBowler Jan 20, 2018
7cc1a50
Update instrument.py
JamesKBowler Jan 20, 2018
ec4bbc6
Update instrument.py
JamesKBowler Jan 20, 2018
8feff72
Update collection.py
JamesKBowler Jan 20, 2018
817f13a
adding logger
JamesKBowler Jan 20, 2018
b6c3ee0
Update collection.py
JamesKBowler Jan 20, 2018
c3f412d
removed _
JamesKBowler Jan 20, 2018
d52d843
Update collection.py
JamesKBowler Jan 20, 2018
8aa579b
Update instrument.py
JamesKBowler Jan 20, 2018
adcc23d
Update broker.py
JamesKBowler Jan 20, 2018
ff58dc3
Update README.md
JamesKBowler Jan 20, 2018
e06eedb
Update README.md
JamesKBowler Jan 20, 2018
eb2de8b
Update collection.py
JamesKBowler Jan 21, 2018
5c298ad
Update instrument.py
JamesKBowler Jan 21, 2018
0513937
Update README.md
JamesKBowler Jan 21, 2018
001aef8
Update collection.py
JamesKBowler Jan 21, 2018
2051daa
Update collection.py
JamesKBowler Jan 21, 2018
92b4a85
Update collection.py
JamesKBowler Jan 21, 2018
91d919d
Update collection.py
JamesKBowler Jan 21, 2018
77af92a
Update collection.py
JamesKBowler Jan 21, 2018
56f59c0
Update collection.py
JamesKBowler Jan 21, 2018
ea24bec
Update settings.py
JamesKBowler Jan 21, 2018
798fc79
Update logger.py
JamesKBowler Jan 21, 2018
d7b374c
Update collection.py
JamesKBowler Jan 21, 2018
c2e1c24
Update collection.py
JamesKBowler Jan 21, 2018
e30bd41
Update collection.py
JamesKBowler Jan 21, 2018
842a021
Update collection.py
JamesKBowler Jan 22, 2018
f6c4ede
Update collection.py
JamesKBowler Jan 23, 2018
aa5dde4
Update broker.py
JamesKBowler Jan 23, 2018
d78e0fe
Update collection.py
JamesKBowler Jan 24, 2018
5bc0891
Update broker.py
JamesKBowler Jan 24, 2018
4650430
Update logger.py
JamesKBowler Jan 24, 2018
4bb5bb8
Update main.py
JamesKBowler Jan 24, 2018
c7d8459
Update broker.py
JamesKBowler Jan 24, 2018
9788225
Update broker.py
JamesKBowler Jan 24, 2018
62e0116
Update README.md
JamesKBowler Jan 24, 2018
ac78fb1
Update collection.py
JamesKBowler Jan 24, 2018
4f09514
Update broker.py
JamesKBowler Jan 24, 2018
e2a7632
Update collection.py
JamesKBowler Jan 24, 2018
8e47b9b
Update collection.py
JamesKBowler Jan 25, 2018
c624fe3
Update broker.py
JamesKBowler Jan 25, 2018
082fbe8
Update collection.py
JamesKBowler Jan 30, 2018
780df6e
Update instrument.py
JamesKBowler Jan 30, 2018
63726ab
Update logger.py
JamesKBowler Jan 30, 2018
26cb7ea
Create time_keeper.py
JamesKBowler Jan 30, 2018
fb66efb
Update collection.py
JamesKBowler Jan 30, 2018
294e645
Update collection.py
JamesKBowler Jan 30, 2018
4bc683d
Update collection.py
JamesKBowler Jan 30, 2018
759f4b2
Update broker.py
JamesKBowler Jan 30, 2018
aa6d387
Update main.py
JamesKBowler Jan 30, 2018
f064200
Update collection.py
JamesKBowler Jan 30, 2018
796f86b
Update main.py
JamesKBowler Jan 30, 2018
39c09d4
Update main.py
JamesKBowler Jan 30, 2018
d81ac29
Update main.py
JamesKBowler Jan 30, 2018
a0192de
Update main.py
JamesKBowler Jan 30, 2018
5b8705b
Update main.py
JamesKBowler Jan 31, 2018
7d9337e
Update database.py
JamesKBowler Jan 31, 2018
041a877
Update README.md
JamesKBowler Jan 31, 2018
c213643
Update database.py
JamesKBowler Jan 31, 2018
e93e3df
Update database.py
JamesKBowler Jan 31, 2018
5cdfecd
Update main.py
JamesKBowler Feb 2, 2018
8ad61f6
Update main.py
JamesKBowler Feb 2, 2018
daf5da0
starting again
JamesKBowler Feb 13, 2018
43c3fba
adding new version
JamesKBowler Feb 13, 2018
f9effe4
removed duplicate self.signals
JamesKBowler Feb 13, 2018
91f3fdd
Update README.md
JamesKBowler Feb 13, 2018
ee7b480
removed unused/non working function
JamesKBowler Feb 14, 2018
51e02f0
moved self.time_handler.generate_signals() from the bottom to the top…
JamesKBowler Feb 14, 2018
b3ee3f7
Update README.md
JamesKBowler Feb 15, 2018
af74316
Create drop_databases.sql
JamesKBowler Feb 15, 2018
bd3e0f6
Update fxcm.py
JamesKBowler Feb 16, 2018
eab5eaa
improved login
JamesKBowler Feb 16, 2018
058598f
improved login
JamesKBowler Feb 16, 2018
652d161
removed while loops as handling stuff on the C++ side
JamesKBowler Feb 16, 2018
0a5a389
removed unused code
JamesKBowler Feb 16, 2018
cb258e8
Updating with fatser improved code
JamesKBowler Feb 20, 2018
1423ed4
Rename GBPUSD to GBPUSD.json
JamesKBowler Feb 20, 2018
88d92cf
Update main.py
JamesKBowler Feb 20, 2018
7c90e8c
Update README.md
JamesKBowler Feb 20, 2018
ab7f02e
Joining some logic together
JamesKBowler Feb 21, 2018
01f8401
Merge branch 'master' of https://github.com/JamesKBowler/fxcollect
JamesKBowler Feb 21, 2018
a74fb9d
Update README.md
JamesKBowler Feb 21, 2018
dc7039d
Update time_signals.py
JamesKBowler Feb 22, 2018
5702ddf
removing 'boiler plate' code to utils
JamesKBowler Feb 22, 2018
3089538
adding month and new-york offset datetime func
JamesKBowler Feb 22, 2018
cb3b36e
Update README.md
JamesKBowler Feb 27, 2018
4cbf568
removing unused method
JamesKBowler Mar 1, 2018
8f1130d
Basic integer arithmetic bug... Prevents a crash.
Dec 30, 2018
ad75b20
Typo, mysql syntax
Dec 31, 2018
8e1cb5f
json_files cleanup: should not be in git, + added .gitignore
Dec 31, 2018
32e3cdb
Add setting to collect only a subset of available timeframes
Jan 1, 2019
e8262a0
Added flexible login information setting
Jan 1, 2019
08ea69a
Added Dockerfile configuration to be able to quickly assemble and sta…
Jan 1, 2019
9873216
Readme visual adjustments.
imperative Jan 1, 2019
89330fc
Merge pull request #5 from imperative/master
JamesKBowler Jan 4, 2019
895f822
Update README.md
JamesKBowler Feb 17, 2020
02d8a55
Update README.md
JamesKBowler May 22, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
FROM ubuntu:18.04
# Based on instructions in readme.md
# and https://github.com/JamesKBowler/python-forexconnect/tree/python3-forexconnect

RUN apt-get -y update && apt-get -y install python3 python3-pip \
python3-numpy python3-pymysql mariadb-server mariadb-client git \
build-essential python3-dev libboost-log-dev libboost-date-time-dev \
libboost-python-dev libtool m4 automake autogen checkinstall wget \
python3-termcolor sudo libcurl4-gnutls-dev libarchive-dev cmake gosu

RUN pip3 install cprint pytz ipython

RUN adduser --disabled-password --gecos "" nonroot



ARG WITH_PHPMYADMIN=0
ENV WITH_PHPMYADMIN=$WITH_PHPMYADMIN

RUN if [ "$WITH_PHPMYADMIN" -gt "0" ] ; then \
export DEBIAN_FRONTEND=noninteractive; \
echo "phpmyadmin phpmyadmin/dbconfig-install boolean false" | debconf-set-selections; \
echo "phpmyadmin phpmyadmin/reconfigure-webserver multiselect apache2" | debconf-set-selections; \
apt-get -q -y install phpmyadmin; \
fi


# --- Install libuv

RUN wget https://github.com/libuv/libuv/archive/v1.19.1/libuv-1.19.1.tar.gz && \
tar -xvzf libuv-1.19.1.tar.gz && \
cd libuv-1.19.1/ && \
sh autogen.sh && \
./configure --prefix=/usr --disable-static && \
make && \
sudo checkinstall

# --- Install libarchive

# -> Using distribution packages
#RUN wget http://www.libarchive.org/downloads/libarchive-3.3.2.tar.gz && \
# tar -xvzf libarchive-3.3.2.tar.gz && \
# cd libarchive-3.3.2/ && \
# ./configure --prefix=/usr --disable-static && \
# make && \
# sudo checkinstall

# --- Install curl

# -> Using distribution packages

# --- Installing boost

# -> Using distribution packages, Bionic is already at 1.65.
RUN apt-get -y install libboost-all-dev

# --- Install python3-forexconnect

RUN cd /home/nonroot; \
echo "export BOOST_ROOT=/usr" >> .profile; \
echo "export BOOST_INCLUDEDIR=/usr/include/" >> .profile; \
echo "export BOOST_LIBRARYDIR=/usr/lib/" >> .profile; \
echo "export INCLUDE=/usr/include/boost/:\$INCLUDE" >> .profile; \
echo "export LIBRARY_PATH=/usr/local/:\$LIBRARY_PATH" >> .profile; \
echo "export FOREXCONNECT_ROOT=\$(pwd)/ForexConnectAPI" >> .profile; \
echo "export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:\$(pwd)/ForexConnectAPI/lib" >> .profile; \
. ./.profile; \
ldconfig

RUN cd /home/nonroot; \
su - nonroot -c "wget http://fxcodebase.com/bin/forexconnect/1.4.1/ForexConnectAPI-1.4.1-Linux-x86_64.tar.gz && \
tar xvf ForexConnectAPI-1.4.1-Linux-x86_64.tar.gz && \
mv ForexConnectAPI-1.4.1-Linux-x86_64 ForexConnectAPI && \
git clone -b python3-forexconnect https://github.com/JamesKBowler/python-forexconnect.git && \
cd python-forexconnect && mkdir build && cd build && \
cmake .. -DDEFAULT_FOREX_URL='http://www.fxcorporate.com/Hosts.jsp' " && \
cd python-forexconnect/build && \
make install

# --- Database setup

RUN service mysql start && \
echo "CREATE USER 'sec_master'@'localhost' IDENTIFIED BY 'password'; \
GRANT ALL PRIVILEGES ON *.* TO 'sec_master'@'localhost'; \
FLUSH PRIVILEGES; \
set global max_connections = 1000; " | mysql -uroot

RUN echo "127.0.0.1:sec_master:password" > /home/nonroot/.database_sec_master_credentials; \
chown nonroot:nonroot /home/nonroot/.database_sec_master_credentials


COPY . /home/nonroot/fxcollect/

RUN chown -R nonroot:nonroot /home/nonroot; chmod +x /home/nonroot/fxcollect/runMainDocker.sh;

ENTRYPOINT ["/home/nonroot/fxcollect/runMainDocker.sh"]
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017 James K Bowler
Copyright (c) 2018 James Bowler

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
185 changes: 89 additions & 96 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,106 +1,100 @@
# fxcmminer v1.0
# fxcollect

The purpose of this software is to fully automate the simultaneous collection of historical and live financial data from FXCM, then store these data in a database ready for backtesting or live execution.
The purpose of 'fxcollect' is to automate the collection of historical and live financial
time series data from FXCM, then store these data in a MariaDB database ready for backtesting
or live execution.

### Setup
The development has been carried out on an ESXi server, however this will run on any hypervisor and most hardware.
### Quick Setup (using docker)
You can use the provided dockerfile to quickly and painlessly setup the application. It has been
tested on a debian-based x86_64 distribution, but will likely work on many others.

Specification:
2x CPUs
4GB RAM
100GB SSD/HDD (for testing hard drive is fine)

Total drive usage for the database (excluding OS etc) from 59 instruments, is 41GB as of 29/04/2017

Operating System:
Ubuntu Server 16.04 (without GUI) for testing, however this will run on most Linux OS with/without GUI.

1. First install all dependencies in the requiements.txt and Python 2.7

2. Install MariaDB 10.x
https://mariadb.org/download/

3. Setup MariaDB to allow the user 'sec_master' to access the database with read and write permissions.

`$ mysql -u root -p`
1. Modify `settings.py` to at least add your FXCM login credentials.
2. Modify `main.py` to adjust which symbols will be collected.
3. Browse into the top directory of the repository and build the docker container:

`mysql> CREATE USER 'sec_master'@'localhost' IDENTIFIED BY 'password';`
`mysql> GRANT ALL PRIVILEGES ON '*.*' TO 'sec_master'@'localhost';`
`mysql> FLUSH PRIVILEGES;`
`mysql> set global max_connections = 1000;`

(optional)
`$ sudo service mysql restart`

4. Download forexconnect and follow instructions.
https://github.com/JamesKBowler/python-forexconnect

5. Download this repository and place in a convenient location

6. Create a logs folder in the root directory
`$ mkdir ~/fxcmminer/fxcmminer_v1.0/logs`
```
$ cd fxcollect
$ docker build .
```
Or you can use the additional `WITH_PHPMYADMIN` argument to build container with phpmyadmin, to be able to easily
inspect the data right from the container:

$ docker build --build-arg WITH_PHPMYADMIN=1 .

4. Run the container, optionally forward ports to browse using phpmyadmin.
```
$ docker run -p 127.0.0.1:8080:80/tcp -it <built-image-id>
```


### Manual Setup
Specification:
- Ubuntu Server 16.04
- Python 3.x
- 2x CPUs
- 4GB RAM, but 2GB will work if tracking a few offers.
- 100GB SSD/HDD (for testing hard drive is fine)
59 instruments = 41GB as of 29/04/2017

7. Set the system time zone to America/New_York, this is important as all data on FXCM servers are stored in America/New_York time zone.
`$ sudo timedatectl set-timezone America/New_York`

8. To start the process just execute:
`$ python ~/fxcmminer/fxcmminer_v1.0/engine.py`

##### All FXCM data will take about 30 hours to download.

If you need assistance setting this up or find any bugs, please report using the Issue section.

### TODO:

1. Prioritize queue so that lower time frame data is written to database before higher time frame.

2. Improve logging

3. Add auto offer removal to the fxscout

4. Clean up code!

### Code Explanation

#### Scout

The process of collecting data is started by executing the engine.py script. This in turn will start the fxscout.py, who's primary job is to scout FXCM for currently tradable instruments (also know as 'offers'). Once the Scout has found 'offers' available, it will contact FXCM for the .xml catalogue and make a local copy to be accessed later by fxcmminer. If FXCM add another 'offer' the Scout will then make a new local copy of the catalogue.

The scout will continue checking FXCM for the entire duration whilst the program is running, and will only place an 'OFFER' event in the events queue on system startup or if a new 'offer' is added in the future.

#### DatabaseManager

If an 'OFFER' event is placed in the queue, the Engine class will pass the event over to the DatabaseManager located in db_manager.py. DatabaseManager will compare its local database with the offer. If the database already exists the creation is skipped, if not the corresponding database and tables for the following time frames will be created.

`{GBP/USD : ['M1','W1','D1','H8', 'H4', 'H2', 'H1','m30', 'm15', 'm5', 'm1']}`

The schema is one database per offer as this will provide plenty of space for future expansion.

#### HistoricalCollector

After a database check or creation has been carried out, a 'DBReady' event is placed into the queue, which is then passed over to the HistoricalCollector class located in historical.py .
The HistoricalCollector asks the DatabaseManager for the lastest date in the database, if this is a new offer or first time system startup, the DatabaseManager will return a date from the .xml catalogue. If the catalog does not have a corresponding date an artificial low date of 2007-01-01 00:00:00 is returned.
Now the HistoricalCollector has a starting point, it will begin to call FXCM's API and collect data. Once data is returned, a 'HISTDATA' event is created and placed in the queue, which in turn will be passed to the DatabaseManager and written to the database.
After all historical data has been collected for the offer, a 'LIVEREADY' event is placed into the queue and the HistoricalCollector process will exit.

#### TimeKeeper
The apscheduler will fire off at market invertals such as 1 minute, 5 minutes etc. On each fire a 'GETLIVE' event is placed into the queue.

#### LiveDataMiner

On receipt of the 'LIVEREADY' event, LiveDataMiner located in live.py, will update its current list of 'LIVEREADY' offers, and is now waiting for a 'GETLIVE' event from TimeKeeper. On receipt of an 'GETLIVE' event, LiveDataMiner will loop through the list of live ready offers for the corrsponding 'GETLIVE' event time_frame. Once data is collected a 'LIVEDATA' event is placed into the queue for the processing by the DatabaseManager and written to the database.

#### Other classes

TimeDelta will provide a range in minutes for each time frame, that will not exceed to 300 bars (data points). This is because the maximum bars return for any one API call to FXCM is 300.
Using the information from TimeDelta, DateRange will provide a date block which is used when calling the API. At the moment this is the only way I could exclude calling for data at the weekends whilst FXCM is closed, and due to the nature of the foreign exchange, holidays are not equal in all countries.

#### Queues
There are two queues one for historical data and one for live data.
1. Install dependencies
- numpy
- pymysql
- cprint
- pytz
- termcolor

2. Install MariaDB 10.x
https://mariadb.org/download/

3. Setup MariaDB to allow the user 'sec_master' to access the database with read and write permissions.

`$ mysql -u root -p`

`mysql> CREATE USER 'sec_master'@'localhost' IDENTIFIED BY 'password';`
`mysql> GRANT ALL PRIVILEGES ON *.* TO 'sec_master'@'localhost';`
`mysql> FLUSH PRIVILEGES;`
`mysql> set global max_connections = 1000;`

(optional)
`$ sudo service mysql restart`

4. Download forexconnect and follow instructions.
https://github.com/JamesKBowler/python-forexconnect/tree/python3-forexconnect

5. Download this repository
`$ git clone https://github.com/JamesKBowler/fxcollect ~/`

##### FXCM price data stored in UTC time zone.
6. Set the system time zone to UTC
`$ sudo timedatectl set-timezone UTC`

7. Execute:
`$ python3 ~/fxcollect/fx_collect/main.py`

##### Each instrument symbol data will take about 1 hour to download, then data will be collected at every time frame interval
+---------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+--------+
| date | bidopen | bidhigh | bidlow | bidclose | askopen | askhigh | asklow | askclose | volume |
+---------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+--------+
| 2017-04-27 10:01:00 | 17.294000 | 17.296000 | 17.289000 | 17.290000 | 17.340000 | 17.340000 | 17.334000 | 17.335000 | 113 |
| 2017-04-27 10:02:00 | 17.290000 | 17.298000 | 17.285000 | 17.295000 | 17.335000 | 17.342000 | 17.330000 | 17.340000 | 114 |
| 2017-04-27 10:03:00 | 17.295000 | 17.301000 | 17.289000 | 17.299000 | 17.340000 | 17.347000 | 17.340000 | 17.344000 | 98 |
| 2017-04-27 10:04:00 | 17.299000 | 17.300000 | 17.286000 | 17.295000 | 17.344000 | 17.345000 | 17.330000 | 17.340000 | 124 |
| 2017-04-27 10:05:00 | 17.295000 | 17.295000 | 17.285000 | 17.292000 | 17.340000 | 17.340000 | 17.330000 | 17.336000 | 130 |
| 2017-04-27 10:06:00 | 17.292000 | 17.292000 | 17.279000 | 17.292000 | 17.336000 | 17.336000 | 17.328000 | 17.332000 | 65 |
| 2017-04-27 10:07:00 | 17.292000 | 17.304000 | 17.287000 | 17.298000 | 17.332000 | 17.348000 | 17.332000 | 17.345000 | 144 |
| 2017-04-27 10:08:00 | 17.298000 | 17.306000 | 17.297000 | 17.302000 | 17.345000 | 17.350000 | 17.343000 | 17.346000 | 96 |
| 2017-04-27 10:09:00 | 17.302000 | 17.303000 | 17.294000 | 17.294000 | 17.346000 | 17.346000 | 17.338000 | 17.338000 | 50 |
| 2017-04-27 10:10:00 | 17.294000 | 17.296000 | 17.281000 | 17.291000 | 17.338000 | 17.338000 | 17.328000 | 17.333000 | 50 |

If you need assistance setting this up or find any bugs, please report using the Issue section.

### TODO:
1. Update C++ code
2. Update documentation

# License Terms

Copyright (c) 2017 James K Bowler
## Copyright (c) 2017 James K Bowler

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand All @@ -109,5 +103,4 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# Forex Trading Disclaimer

Trading foreign exchange on margin carries a high level of risk, and may not be suitable for all investors. Past performance is not indicative of future results. The high degree of leverage can work against you as well as for you. Before deciding to invest in foreign exchange you should carefully consider your investment objectives, level of experience, and risk appetite. The possibility exists that you could sustain a loss of some or all of your initial investment and therefore you should not invest money that you cannot afford to lose. You should be aware of all the risks associated with foreign exchange trading, and seek advice from an independent financial advisor if you have any doubts.
Empty file added __init__.py
Empty file.
Empty file added fx_collect/__init__.py
Empty file.
Empty file added fx_collect/broker/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions fx_collect/broker/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from abc import ABCMeta

class AbstractBroker(object):
"""
TODO doc string.....
"""
__metaclass__ = ABCMeta

pass
Empty file.
77 changes: 77 additions & 0 deletions fx_collect/broker/fxcm/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from ..base import AbstractBroker
from abc import ABCMeta
from forexconnect import (
ForexConnectHistoryClient,
ForexConnectOffersClient,
ForexConnectTradingClient,
set_log_level
)
from traceback import print_exc
from ...settings import FXCM_CREDENTIALS, FXCM_CREDENTIALS_FILE

set_log_level(9)



class AbstractFXCMBroker(AbstractBroker):
"""
The AbstractFXCMBroker object is designed to interact directly
with FXCM using the python-forexconnect API.
"""

__metaclass__ = ABCMeta

def url(self):
return 'http://www.fxcorporate.com/Hosts.jsp'

def whoami(self):
return 'fxcm'

def supported_timeframes(self):
return [
'm1', 'm5', 'm15', 'm30', 'H1',
'H2', 'H4', 'H8', 'D1', 'W1', 'M1'
]

def is_connected(self):
return self._session.is_connected()

def _offers_table(self):
return self._create_session(ForexConnectOffersClient)

def _market_data(self):
return self._create_session(ForexConnectHistoryClient)

def _trading(self):
return self._create_session(ForexConnectTradingClient)

def _create_session(self, session_type):
import time
rest = 0
if FXCM_CREDENTIALS:
credentials = FXCM_CREDENTIALS
else:
if FXCM_CREDENTIALS_FILE:
dir = FXCM_CREDENTIALS_FILE
with open(dir) as f:
credentials = f.readlines()
credentials = credentials[0]
else:
raise (Exception("No FXCM credentials found. Modify settings.py before running the application."))

fxcm_env, user, passwd = credentials.strip().split(':')
while True:
if rest<60: rest+=1
try:
session = session_type(
user.encode(), passwd.encode(),
fxcm_env.encode(), self.url().encode()
)
if session.is_connected():
return session
except RuntimeError as e:
print_exc()
time.sleep(rest)

def _logout_session(self):
self._session.logout()
Loading