PK 5I GetHistPricesCSV/PK
z5I L/ / GetHistPricesCSV/fxbuild.bat@echo off
set build_config=Release
set tgt_platform=x86
rem --------------------------------------------------------------------------------------------
rem Parse command line argument values.
rem Note: For ambiguous arguments the last one wins (ex: debug release)
rem --------------------------------------------------------------------------------------------
:Parse_Args
@IF /I "%~1"=="Debug" SET "build_config=Debug" & SHIFT & GOTO Parse_Args
@IF /I "%~1"=="Release" SET "build_config=Release" & SHIFT & GOTO Parse_Args
@IF /I "%~1"=="x86" SET "tgt_platform=x86" & SHIFT & GOTO Parse_Args
@IF /I "%~1"=="x64" SET "tgt_platform=x64" & SHIFT & GOTO Parse_Args
@IF /I "%~1"=="/?" GOTO Error_Usage
@IF "x%~1"=="x" GOTO Done_Args
ECHO Unknown command-line switch: %~1
GOTO Error_Usage
:Done_Args
@echo build_config=%build_config% %conf_suffix%
@if /i "%tgt_platform%"=="x86" (
set local_tgt_platform=Win32
) else (
set local_tgt_platform=x64
)
:VS80
@if /i "%VS80COMNTOOLS%" == "" (
@echo Variable VS80COMNTOOLS is not set or contains wrong path. Checking VS100COMNTOOLS...
goto VS100
)
call :unquoteStr ENV_SETUP "%VS80COMNTOOLS%vsvars32.bat"
@echo Using "%ENV_SETUP%" environment configuration script.
call "%ENV_SETUP%"
call vcbuild GetHistPricesCSV.vcproj "%build_config%|%local_tgt_platform%"
@goto :eof
:VS100
@if /i "%VS100COMNTOOLS%" == "" (
@echo Variable VS100COMNTOOLS is not set or contains wrong path. Checking VS110COMNTOOLS...
goto VS110
)
call :unquoteStr ENV_SETUP "%VS100COMNTOOLS%vsvars32.bat"
@echo Using "%ENV_SETUP%" environment configuration script.
call "%ENV_SETUP%"
if not exist GetHistPricesCSV.vcxproj (
@echo Converting vs2005 project to vs2010 format...
VCUpgrade.exe GetHistPricesCSV.vcproj -nologo -p
)
call msbuild GetHistPricesCSV.vcxproj /p:Configuration=%build_config% /p:platform=%local_tgt_platform%
@goto :eof
:VS110
@if /i "%VS110COMNTOOLS%" == "" (
@echo Variable VS110COMNTOOLS is not set or contains wrong path. Checking VS120COMNTOOLS...
goto VS120
)
call :unquoteStr ENV_SETUP "%VS110COMNTOOLS%vsvars32.bat"
@echo Using "%ENV_SETUP%" environment configuration script.
call "%ENV_SETUP%"
if not exist GetHistPricesCSV.vcxproj (
@echo Converting vs2005 project to vs2012 format...
VCUpgrade.exe GetHistPricesCSV.vcproj -nologo -p
)
call msbuild GetHistPricesCSV.vcxproj /p:Configuration=%build_config% /p:platform=%local_tgt_platform%
@goto :eof
:VS120
@if /i "%VS120COMNTOOLS%" == "" (
@echo Variable VS120COMNTOOLS is not set or contains wrong path.
goto ENV_ERR
)
call :unquoteStr ENV_SETUP "%VS120COMNTOOLS%vsvars32.bat"
@echo Using "%ENV_SETUP%" environment configuration script.
call "%ENV_SETUP%"
if not exist GetHistPricesCSV.vcxproj (
@echo Converting vs2005 project to vs2013 format...
VCUpgrade.exe GetHistPricesCSV.vcproj -nologo -p
)
call msbuild GetHistPricesCSV.vcxproj /p:Configuration=%build_config% /p:platform=%local_tgt_platform%
@goto :eof
:ENV_ERR
echo Can not setup visual studio environment.
set null
@goto :eof
:unquoteStr
set %1=%~2
@goto :eof
:Error_Usage
@rem --------------------------------------------------------------------------------------------
@rem Display command usage
@rem --------------------------------------------------------------------------------------------
echo Usage: "%~nx0 [debug|release] [x86|x64] [/?]"
echo.
echo debug - Debug build configuration
echo release - Release build configuration
echo x86 - Create 32-bit x86 applications
echo x64 - Create 64-bit x64 applications
echo. /? - Show usage
echo.
@goto :eof
PK
qvHO O GetHistPricesCSV/fxclean.bat@echo off
@if exist bin rd bin /q /s
@if exist obj rd obj /q /s
PK
y5IFc c GetHistPricesCSV/fxrun.bat@ECHO OFF
SET THIS_DIR="%~dp0"
PUSHD "%THIS_DIR%\..\bin\win32"
GetHistPricesCSV.exe %*
POPDPK
@b5InRi % GetHistPricesCSV/GetHistPricesCSV.sln
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GetHistPricesCSV", "GetHistPricesCSV.vcproj", "{747FD0FA-54B3-42CC-89CF-2CDF120523D6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{747FD0FA-54B3-42CC-89CF-2CDF120523D6}.Debug|Win32.ActiveCfg = Debug|Win32
{747FD0FA-54B3-42CC-89CF-2CDF120523D6}.Debug|Win32.Build.0 = Debug|Win32
{747FD0FA-54B3-42CC-89CF-2CDF120523D6}.Debug|x64.ActiveCfg = Debug|x64
{747FD0FA-54B3-42CC-89CF-2CDF120523D6}.Debug|x64.Build.0 = Debug|x64
{747FD0FA-54B3-42CC-89CF-2CDF120523D6}.Release|Win32.ActiveCfg = Release|Win32
{747FD0FA-54B3-42CC-89CF-2CDF120523D6}.Release|Win32.Build.0 = Release|Win32
{747FD0FA-54B3-42CC-89CF-2CDF120523D6}.Release|x64.ActiveCfg = Release|x64
{747FD0FA-54B3-42CC-89CF-2CDF120523D6}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
PK
d5IslE E ( GetHistPricesCSV/GetHistPricesCSV.vcproj
PK
y5I[; ; GetHistPricesCSV/readme.txtGetHistPricesCSV application
Brief
===============================================================================
This sample shows how to load instrument historical prices.
The sample does the following steps:
1. Log in.
2. Request historical prices with the specified timeframe for the specified period
using the PriceHistory API.
3. Write the gathered information to a CSV file.
4. Log out.
Building the application
===============================================================================
The following environment variables must be set to compile the application:
x64:
FOREXCONNECT_PATH_X64
HISTORICALPRICEAPI_PATH_X64
x86:
FOREXCONNECT_PATH_X86
HISTORICALPRICEAPI_PATH_X86
APIs installers for Windows set them automatically.
Windows:
To build this application, you will need MS Visual Studio 2005 or later.
To build the application, in MS Visual Studio, either run fxbuild.bat or select "build".
Linux/MacOS:
To build this application, you will need:
gcc-4.1 or later
g++-4.1 or later
CMake 2.6 or later (use 2.6 for MacOS)
To build the application, run fxbuild.sh.
Running the application
===============================================================================
You can run the application from the bin directory.
Also you can run this application by executing fxrun.bat or fxrun.sh on Windows
and Linux respectively.
All arguments must be passed from the command line -
this will run the application and display the output in your console.
You can run the application with no arguments, this will show the
application Help.
Arguments
===============================================================================
/login | --login | /l | -l
Your user name.
/password | --password | /p | -p
Your password.
/url | --url | /u | -u
The server URL. For example, http://www.fxcorporate.com/Hosts.jsp.
/connection | --connection | /c | -c
The connection name. For example, "Demo" or "Real".
/sessionid | --sessionid
The database name. This argument is optional.
Required only for users who have accounts in more than one database.
/pin | --pin
Your pin code. This argument is optional. Required only for users who have a pin.
/instrument | --instrument | /i | -i
The instrument that you want to use in the sample. For example, "EUR/USD".
/timeframe | --timeframe
The time period that forms a single candle. For example, m1 - for 1 minute, H1 - for 1 hour.
Custom timeframes (e.g. m2) are also supported.
/datefrom | --datefrom
The date and time starting from which you want to receive historical prices. This argument is optional.
If you leave this argument as is, a default value will be used. The format is "m.d.Y H:M:S".
The time is in UTC timezone.
/dateto | --dateto
The date and time until which you want to receive historical prices. This argument is optional.
If you leave this argument as is, the data will be received up to now. The format is "m.d.Y H:M:S".
The time is in UTC timezone.
/count | --count
The number of historical prices you want to receive. This argument is optional.
If you leave this argument as is, a default value will be used or the argument will be ignored if 'datefrom'
is specified.
/output | --output
The output file name.
Examples
===============================================================================
GetHistPricesCSV /login {LOGIN} /password {PASSWORD} /connection Demo /instrument EUR/USD /timeframe m1 /url http://www.fxcorporate.com/Hosts.jsp /datefrom "06.27.2014 20:50:00" /dateto "06.29.2014 22:05:00" /output result.csv
GetHistPricesCSV /login {LOGIN} /password {PASSWORD} /connection Demo /instrument EUR/USD /timeframe m2 /url http://www.fxcorporate.com/Hosts.jsp /count 10 /dateto "06.29.2014 22:05:00" /output result.csv
PK D{5I GetHistPricesCSV/source/PK
s5IuCm m ) GetHistPricesCSV/source/CommonSources.cpp/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
bool isNaN(double value)
{
return value != value;
}
std::string upperString(const std::string &str)
{
std::string upper;
std::transform(str.begin(), str.end(), std::back_inserter(upper), toupper);
return upper;
}PK
s5ISM ' GetHistPricesCSV/source/CommonSources.h/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
bool isNaN(double value);
std::string upperString(const std::string &str);
PK
qvHր 6 GetHistPricesCSV/source/CommunicatorStatusListener.cpp/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
#include "CommunicatorStatusListener.h"
CommunicatorStatusListener::CommunicatorStatusListener()
: mReady(false), mError(false)
{
mSyncCommunicatorEvent = CreateEvent(0, FALSE, FALSE, 0);
}
CommunicatorStatusListener::~CommunicatorStatusListener()
{
CloseHandle(mSyncCommunicatorEvent);
}
bool CommunicatorStatusListener::isReady()
{
return mReady;
}
void CommunicatorStatusListener::reset()
{
mReady = false;
mError = false;
}
bool CommunicatorStatusListener::waitEvents()
{
int res = WaitForSingleObject(mSyncCommunicatorEvent, _TIMEOUT);
if (res != 0)
std::cout << "Timeout occurred during waiting for communicator status is ready" << std::endl;
return res == 0;
}
void CommunicatorStatusListener::onCommunicatorStatusChanged(bool ready)
{
mReady = ready;
SetEvent(mSyncCommunicatorEvent);
}
void CommunicatorStatusListener::onCommunicatorInitFailed(pricehistorymgr::IError *error)
{
mError = true;
std::cout << "Communicator initialization error: " << error->getMessage() << std::endl;
SetEvent(mSyncCommunicatorEvent);
}
PK
qvHIi 4 GetHistPricesCSV/source/CommunicatorStatusListener.h/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
/** The Price History API communicator request status listener. */
class CommunicatorStatusListener :
public pricehistorymgr::TThreadSafeAddRefImpl
{
public:
CommunicatorStatusListener();
/** Returns true if the communicator is ready. */
bool isReady();
/** Reset error information. */
void reset();
/** Wait for the communicator's readiness or an error. */
bool waitEvents();
protected:
/** @name IPriceHistoryCommunicatorStatusListener interface implementation */
//@{
virtual void onCommunicatorStatusChanged(bool ready);
virtual void onCommunicatorInitFailed(pricehistorymgr::IError *error);
//@}
protected:
virtual ~CommunicatorStatusListener();
private:
bool mReady;
bool mError;
HANDLE mSyncCommunicatorEvent;
};
PK
t5I[ ' GetHistPricesCSV/source/LocalFormat.cpp/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
#include "LocalFormat.h"
LocalFormat::LocalFormat()
{
mListSeparator = "";
mDecimalSeparator = "";
}
const char *LocalFormat::getListSeparator()
{
if (mListSeparator.length() == 0)
{
char buff[32];
int rc;
rc = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLIST, buff, 32);
buff[rc] = 0;
mListSeparator = buff;
}
return mListSeparator.c_str();
}
const char *LocalFormat::getDecimalSeparator()
{
if (mDecimalSeparator.length() == 0)
{
char buff[32];
int rc;
rc = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, 32);
buff[rc] = 0;
mDecimalSeparator = buff;
}
return mDecimalSeparator.c_str();
}
std::string LocalFormat::formatDouble(double value, int precision)
{
char format[16];
char buffer[64];
sprintf_s(format, 16, "%%.%if", precision);
sprintf_s(buffer, 64, format, value);
char *point = strchr(buffer, '.');
if (point != 0)
*point = getDecimalSeparator()[0];
return std::string(buffer);
}
std::string LocalFormat::formatDate(double value)
{
SYSTEMTIME st;
memset(&st, 0, sizeof(st));
VariantTimeToSystemTime(value, &st);
char buffer[64];
std::string res = "";
int rc = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, 0, buffer, 64);
buffer[rc] = 0;
res += buffer;
res += " ";
rc = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, 0, buffer, 64);
buffer[rc] = 0;
res += buffer;
return res;
}
PK
s5IUЮt % GetHistPricesCSV/source/LocalFormat.h/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
/** The helper class that controls formatting and localization. */
class LocalFormat
{
std::string mListSeparator;
std::string mDecimalSeparator;
public:
LocalFormat();
const char *getListSeparator();
const char *getDecimalSeparator();
std::string formatDouble(double value, int precision);
std::string formatDate(double value);
};
PK
qvH5 ' GetHistPricesCSV/source/LoginParams.cpp/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
#include "LoginParams.h"
const char *LoginParams::Strings::loginNotSpecified = "'Login' is not specified (/l|-l|/login|--login)";
const char *LoginParams::Strings::passwordNotSpecified = "'Password' is not specified (/p|-p|/password|--password)";
const char *LoginParams::Strings::urlNotSpecified = "'URL' is not specified (/u|-u|/url|--url)";
const char *LoginParams::Strings::connectionNotSpecified = "'Connection' is not specified (/c|-c|/connection|--connection)";
LoginParams::LoginParams(int argc, char **argv)
{
/* Load parameters with short keys. */
mLogin = getArgument(argc, argv, "l");
mPassword = getArgument(argc, argv, "p");
mURL = getArgument(argc, argv, "u");
mConnection = getArgument(argc, argv, "c");
/* If parameters with short keys not loaded, load with long keys. */
if (mLogin.empty())
mLogin = getArgument(argc, argv, "login");
if (mPassword.empty())
mPassword = getArgument(argc, argv, "password");
if (mURL.empty())
mURL = getArgument(argc, argv, "url");
if (mConnection.empty())
mConnection = getArgument(argc, argv, "connection");
/* Load optional parameters. */
mSessionID = getArgument(argc, argv, "sessionid");
mPin = getArgument(argc, argv, "pin");
/* Append "Hosts.jsp" to URL if needed. */
if (mURL.length() != 0)
{
// case insensitive find.
if (upperString(mURL).find(upperString("Hosts.jsp")) == std::string::npos)
{
mURL += "/Hosts.jsp";
}
}
}
LoginParams::~LoginParams(void)
{
}
const char *LoginParams::getArgument(int argc, char **argv, const char *key)
{
for (int i = 1; i < argc; ++i)
{
if (argv[i][0] == '-' || argv[i][0] == '/')
{
int iDelimOffset = 0;
if (strncmp(argv[i], "--", 2) == 0)
iDelimOffset = 2;
else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "/", 1) == 0)
iDelimOffset = 1;
if (_stricmp(argv[i] + iDelimOffset, key) == 0 && argc > i+1)
return argv[i+1];
}
}
return "";
}
const char *LoginParams::getLogin()
{
return mLogin.c_str();
}
const char *LoginParams::getPassword()
{
return mPassword.c_str();
}
const char *LoginParams::getURL()
{
return mURL.c_str();
}
const char *LoginParams::getConnection()
{
return mConnection.c_str();
}
const char *LoginParams::getSessionID()
{
return mSessionID.c_str();
}
const char *LoginParams::getPin()
{
return mPin.c_str();
}
PK
qvH53 % GetHistPricesCSV/source/LoginParams.h/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
/** Class to work with login parameters. */
class LoginParams
{
public:
/** Class with static methods that return error messages. */
class Strings
{
public:
static const char *loginNotSpecified;
static const char *passwordNotSpecified;
static const char *urlNotSpecified;
static const char *connectionNotSpecified;
};
public:
LoginParams(int, char **);
~LoginParams(void);
const char *getLogin();
const char *getPassword();
const char *getURL();
const char *getConnection();
const char *getSessionID();
const char *getPin();
private:
const char *getArgument(int, char **, const char *);
std::string mLogin;
std::string mPassword;
std::string mURL;
std::string mConnection;
std::string mSessionID;
std::string mPin;
};
PK
D{5IeH H GetHistPricesCSV/source/main.cpp/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
#include "ResponseListener.h"
#include "SessionStatusListener.h"
#include "LoginParams.h"
#include "SampleParams.h"
#include "CommonSources.h"
#include "CommunicatorStatusListener.h"
#include "LocalFormat.h"
/** Forward declaration. */
void printHelp(std::string &);
bool checkObligatoryParams(LoginParams *, SampleParams *);
void printSampleParams(std::string &, LoginParams *, SampleParams *);
void writePrices(pricehistorymgr::IPriceHistoryCommunicator *communicator, pricehistorymgr::IPriceHistoryCommunicatorResponse *response,
const char *instrument, const char *outputFile);
bool getHistoryPrices(pricehistorymgr::IPriceHistoryCommunicator *communicator, const char *instrument,
const char *timeframe, DATE from, DATE to, int quotesCount, ResponseListener *responseListener, const char *outputFile);
int getInstrumentPrecision(pricehistorymgr::IPriceHistoryCommunicator *communicator, const char *instrument);
/** The sample's entry point.
How does it work:
- create ForexConnect session;
- create IPriceHistoryCommunicator using the session;
- login to ForexConnect;
- wait until IPriceHistoryCommunicator is ready;
- create and send a history request;
- wait and write results to a CSV file;
- cleanup and exit.
*/
int main(int argc, char *argv[])
{
std::string procName = "GetHistPricesCSV";
if (argc == 1)
{
printHelp(procName);
return -1;
}
bool bWasError = false;
LoginParams loginParams(argc, argv);
SampleParams sampleParams(argc, argv);
printSampleParams(procName, &loginParams, &sampleParams);
if (!checkObligatoryParams(&loginParams, &sampleParams))
return -1;
// create the ForexConnect trading session
O2G2Ptr session = CO2GTransport::createSession();
O2G2Ptr statusListener = new SessionStatusListener(session, true,
loginParams.getSessionID(),
loginParams.getPin());
// subscribe IO2GSessionStatus interface implementation for the status events
session->subscribeSessionStatus(statusListener);
statusListener->reset();
// create an instance of IPriceHistoryCommunicator
pricehistorymgr::IError *error = NULL;
O2G2Ptr communicator(
pricehistorymgr::PriceHistoryCommunicatorFactory::createCommunicator(session, "History", &error));
O2G2Ptr autoError(error);
if (!communicator)
{
std::cout << error->getMessage() << std::endl;
return -1;
}
// log in to ForexConnect
session->login(loginParams.getLogin(), loginParams.getPassword(),
loginParams.getURL(), loginParams.getConnection());
if (statusListener->waitEvents() && statusListener->isConnected())
{
O2G2Ptr communicatorStatusListener(new CommunicatorStatusListener());
communicator->addStatusListener(communicatorStatusListener);
// wait until the communicator signals that it is ready
if (communicator->isReady() ||
communicatorStatusListener->waitEvents() && communicatorStatusListener->isReady())
{
// attach the instance of the class that implements the IPriceHistoryCommunicatorListener
// interface to the communicator
O2G2Ptr responseListener(new ResponseListener());
communicator->addListener(responseListener);
if (!getHistoryPrices(communicator, sampleParams.getInstrument(),
sampleParams.getTimeframe(), sampleParams.getDateFrom(), sampleParams.getDateTo(),
sampleParams.getQuotesCount(), responseListener, sampleParams.getOutputFile()))
bWasError = true;
std::cout << "Done!" << std::endl;
communicator->removeListener(responseListener);
}
communicator->removeStatusListener(communicatorStatusListener);
statusListener->reset();
session->logout();
statusListener->waitEvents();
}
else
{
bWasError = true;
}
session->unsubscribeSessionStatus(statusListener);
if (bWasError)
return -1;
return 0;
}
/** Request historical prices for the specified timeframe of the specified period.
@param communicator
The price history communicator.
@param instrument
The instrument.
@param timeframe
The timeframe.
@param from
From-date.
@param to
To-date
@param quotesCount
The quotes count.
@param responseListener
The response listener.
@param outputFile
The output file name.
*/
bool getHistoryPrices(pricehistorymgr::IPriceHistoryCommunicator *communicator, const char *instrument,
const char *timeframe, DATE from, DATE to, int quotesCount,
ResponseListener *responseListener, const char *outputFile)
{
if (!communicator->isReady())
{
std::cout << "History communicator is not ready." << std::endl;
return false;
}
// create timeframe entity
O2G2Ptr timeframeFactory = communicator->getTimeframeFactory();
pricehistorymgr::IError *error = NULL;
O2G2Ptr timeframeObj = timeframeFactory->create(timeframe, &error);
O2G2Ptr autoError(error);
if (!timeframeObj)
{
std::cout << "Timeframe '" << timeframe << "' is incorrect! " << std::endl;
return false;
}
// create and send a history request
O2G2Ptr request =
communicator->createRequest(instrument, timeframeObj, from, to, quotesCount, &error);
if (!request)
{
std::cout << error->getMessage() << std::endl;
return false;
}
responseListener->setRequest(request);
if (!communicator->sendRequest(request, &error))
{
std::cout << error->getMessage() << std::endl;
return false;
}
// wait results
responseListener->wait();
// print results if any
O2G2Ptr response = responseListener->getResponse();
if (response)
writePrices(communicator, response, instrument, outputFile);
return true;
}
/** Gets precision of a specified instrument.
@param communicator
The price history communicator.
@param instrument
The instrument.
@return
The precision.
*/
int getInstrumentPrecision(pricehistorymgr::IPriceHistoryCommunicator *communicator, const char *instrument)
{
int precision = 6;
O2G2Ptr quotesManager = communicator->getQuotesManager();
quotesmgr::IError *error = NULL;
O2G2Ptr instruments = quotesManager->getInstruments(&error);
O2G2Ptr autoError(error);
if (instruments)
{
O2G2Ptr instr = instruments->find(instrument);
if (instr)
precision = instr->getPrecision();
}
return precision;
}
/** Writes history data from response.
@param communicator
The price history communicator.
@param response
The response. Cannot be null.
@param instrument
The instrument.
@param outputFile
The output file name.
*/
void writePrices(pricehistorymgr::IPriceHistoryCommunicator *communicator, pricehistorymgr::IPriceHistoryCommunicatorResponse *response,
const char *instrument, const char *outputFile)
{
std::fstream fs;
fs.open(outputFile, std::fstream::out | std::fstream::trunc);
if (!fs.is_open())
{
std::cout << "Could not open the output file." << std::endl;
return;
}
LocalFormat localFormat;
const char *separator = localFormat.getListSeparator();
int precision = getInstrumentPrecision(communicator, instrument);
// use IO2GMarketDataSnapshotResponseReader to extract price data from the response object
pricehistorymgr::IError *error = NULL;
O2G2Ptr reader = communicator->createResponseReader(response, &error);
O2G2Ptr autoError(error);
if (reader)
{
if (reader->isBar())
{
fs << "DateTime" << separator
<< "BidOpen" << separator << "BidHigh" << separator
<< "BidLow" << separator << "BidClose" << separator
<< "AskOpen" << separator << "AskHigh" << separator
<< "AskLow" << separator << "AskClose" << separator
<< "Volume" << separator << std::endl;
}
else
{
fs << "DateTime" << separator
<< "Bid" << separator << "Ask" << separator << std::endl;
}
for (int i = 0; i < reader->size(); ++i)
{
DATE dt = reader->getDate(i);
std::string time = localFormat.formatDate(dt);
if (reader->isBar())
{
fs << time << separator
<< localFormat.formatDouble(reader->getBidOpen(i), precision) << separator
<< localFormat.formatDouble(reader->getBidHigh(i), precision) << separator
<< localFormat.formatDouble(reader->getBidLow(i), precision) << separator
<< localFormat.formatDouble(reader->getBidClose(i), precision) << separator
<< localFormat.formatDouble(reader->getAskOpen(i), precision) << separator
<< localFormat.formatDouble(reader->getAskHigh(i), precision) << separator
<< localFormat.formatDouble(reader->getAskLow(i), precision) << separator
<< localFormat.formatDouble(reader->getAskClose(i), precision) << separator
<< localFormat.formatDouble(reader->getVolume(i), 0) << separator
<< std::endl;
}
else
{
fs << time << separator
<< localFormat.formatDouble(reader->getBid(i), precision) << separator
<< localFormat.formatDouble(reader->getAsk(i), precision) << separator
<< std::endl;
}
}
}
fs.close();
}
/** Print sample parameters data.
@param sProcName
The sample process name.
@param loginParams
The LoginParams instance pointer.
@param sampleParams
The LoginParams instance pointer.
*/
void printSampleParams(std::string &sProcName, LoginParams *loginParams, SampleParams *sampleParams)
{
std::cout << "Running " << sProcName << " with arguments:" << std::endl;
LocalFormat localFormat;
// login (common) information
if (loginParams)
{
std::cout << loginParams->getLogin() << " * "
<< loginParams->getURL() << " "
<< loginParams->getConnection() << " "
<< loginParams->getSessionID() << " "
<< loginParams->getPin() << std::endl;
}
// sample specific information
if (sampleParams)
{
std::cout << "Instrument='" << sampleParams->getInstrument() << "', "
<< "Timeframe='" << sampleParams->getTimeframe() << "', ";
if (isNaN(sampleParams->getDateFrom()))
std::cout << "DateFrom='', ";
else
std::cout << "DateFrom='" << localFormat.formatDate(sampleParams->getDateFrom()) << "', ";
if (isNaN(sampleParams->getDateTo()))
std::cout << "DateTo='', ";
else
std::cout << "DateTo='" << localFormat.formatDate(sampleParams->getDateTo()) << "', ";
std::cout << "QuotesCount='" << sampleParams->getQuotesCount() << "'";
std::cout << std::endl;
}
}
/** Print expected sample-login parameters and their description.
@param sProcName
The sample process name.
*/
void printHelp(std::string &sProcName)
{
std::cout << sProcName << " sample parameters:" << std::endl << std::endl;
std::cout << "/login | --login | /l | -l" << std::endl;
std::cout << "Your user name." << std::endl << std::endl;
std::cout << "/password | --password | /p | -p" << std::endl;
std::cout << "Your password." << std::endl << std::endl;
std::cout << "/url | --url | /u | -u" << std::endl;
std::cout << "The server URL. For example, http://www.fxcorporate.com/Hosts.jsp." << std::endl << std::endl;
std::cout << "/connection | --connection | /c | -c" << std::endl;
std::cout << "The connection name. For example, \"Demo\" or \"Real\"." << std::endl << std::endl;
std::cout << "/sessionid | --sessionid " << std::endl;
std::cout << "The database name. Required only for users who have accounts in more than one database. "
"Optional parameter." << std::endl << std::endl;
std::cout << "/pin | --pin " << std::endl;
std::cout << "Your pin code. Required only for users who have a pin. "
"Optional parameter." << std::endl << std::endl;
std::cout << "/instrument | --instrument | /i | -i" << std::endl;
std::cout << "An instrument which you want to use in sample. "
"For example, \"EUR/USD\"." << std::endl << std::endl;
std::cout << "/timeframe | --timeframe " << std::endl;
std::cout << "Time period which forms a single candle. "
"For example, m1 - for 1 minute, H1 - for 1 hour." << std::endl << std::endl;
std::cout << "/datefrom | --datefrom " << std::endl;
std::cout << "Date/time from which you want to receive historical prices. "
"If you leave this argument as it is, it will mean from last trading day. "
"Format is \"m.d.Y H:M:S\". Optional parameter." << std::endl << std::endl;
std::cout << "/dateto | --dateto " << std::endl;
std::cout << "Date/time until which you want to receive historical prices. "
"If you leave this argument as it is, it will mean to now. Format is \"m.d.Y H:M:S\". "
"Optional parameter." << std::endl << std::endl;
std::cout << "/count | --count " << std::endl;
std::cout << "Count of historical prices you want to receive. If you "
<< "leave this argument as it is, it will mean -1 (use some default "
<< "value or ignore if datefrom is specified)" << std::endl << std::endl;
std::cout << "/output | --output " << std::endl;
std::cout << "The output file name." << std::endl;
}
/** Check parameters for correct values.
@param loginParams
The LoginParams instance pointer.
@param sampleParams
The SampleParams instance pointer.
@return
true if parameters are correct.
*/
bool checkObligatoryParams(LoginParams *loginParams, SampleParams *sampleParams)
{
// check login parameters
if (strlen(loginParams->getLogin()) == 0)
{
std::cout << LoginParams::Strings::loginNotSpecified << std::endl;
return false;
}
if (strlen(loginParams->getPassword()) == 0)
{
std::cout << LoginParams::Strings::passwordNotSpecified << std::endl;
return false;
}
if (strlen(loginParams->getURL()) == 0)
{
std::cout << LoginParams::Strings::urlNotSpecified << std::endl;
return false;
}
if (strlen(loginParams->getConnection()) == 0)
{
std::cout << LoginParams::Strings::connectionNotSpecified << std::endl;
return false;
}
// check other parameters
if (strlen(sampleParams->getInstrument()) == 0)
{
std::cout << SampleParams::Strings::instrumentNotSpecified << std::endl;
return false;
}
if (strlen(sampleParams->getTimeframe()) == 0)
{
std::cout << SampleParams::Strings::timeframeNotSpecified << std::endl;
return false;
}
if (strlen(sampleParams->getOutputFile()) == 0)
{
std::cout << SampleParams::Strings::outputFileNotSpecified << std::endl;
return false;
}
bool bIsDateFromNotSpecified = false;
bool bIsDateToNotSpecified = false;
DATE dtFrom = sampleParams->getDateFrom();
DATE dtTo = sampleParams->getDateTo();
time_t tNow = time(NULL); // get time now
struct tm *tmNow = gmtime(&tNow);
DATE dtNow = 0;
CO2GDateUtils::CTimeToOleTime(tmNow, &dtNow);
LocalFormat localFormat;
if (isNaN(dtFrom))
{
bIsDateFromNotSpecified = true;
dtFrom = 0;
sampleParams->setDateFrom(dtFrom);
}
else
{
if (dtFrom - dtNow > 0.0001)
{
std::cout << "Sorry, 'DateFrom' value " << localFormat.formatDate(dtFrom) << " should be in the past" << std::endl;
return false;
}
}
if (isNaN(dtTo))
{
bIsDateToNotSpecified = true;
dtTo = 0;
sampleParams->setDateTo(dtTo);
}
else
{
if (!bIsDateFromNotSpecified && dtFrom - dtTo > 0.001)
{
std::cout << "Sorry, 'DateTo' value " << localFormat.formatDate(dtTo) << " should be later than 'DateFrom' value "
<< localFormat.formatDate(dtFrom) << std::endl;
return false;
}
}
return true;
}
PK
qvHiA , GetHistPricesCSV/source/ResponseListener.cpp/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
#include "ResponseListener.h"
ResponseListener::ResponseListener()
{
mSyncResponseEvent = CreateEvent(0, FALSE, FALSE, 0);
mResponse = NULL;
mRequest = NULL;
}
ResponseListener::~ResponseListener()
{
CloseHandle(mSyncResponseEvent);
}
bool ResponseListener::wait()
{
return WaitForSingleObject(mSyncResponseEvent, INFINITE) == WAIT_OBJECT_0;
}
/** Gets response.*/
pricehistorymgr::IPriceHistoryCommunicatorResponse* ResponseListener::getResponse()
{
if (mResponse)
mResponse->addRef();
return mResponse;
}
void ResponseListener::setRequest(pricehistorymgr::IPriceHistoryCommunicatorRequest *request)
{
mResponse = NULL;
mRequest = request;
request->addRef();
}
void ResponseListener::onRequestCompleted(pricehistorymgr::IPriceHistoryCommunicatorRequest *request,
pricehistorymgr::IPriceHistoryCommunicatorResponse *response)
{
if (mRequest == request)
{
mResponse = response;
mResponse->addRef();
SetEvent(mSyncResponseEvent);
}
}
void ResponseListener::onRequestFailed(pricehistorymgr::IPriceHistoryCommunicatorRequest *request,
pricehistorymgr::IError *error)
{
if (mRequest == request)
{
std::cout << "Request failed: " << error->getMessage() << std::endl;
mRequest = NULL;
mResponse = NULL;
SetEvent(mSyncResponseEvent);
}
}
void ResponseListener::onRequestCancelled(pricehistorymgr::IPriceHistoryCommunicatorRequest *request)
{
if (mRequest == request)
{
std::cout << "Request cancelled." << std::endl;
mRequest = NULL;
mResponse = NULL;
SetEvent(mSyncResponseEvent);
}
}
PK
qvH * GetHistPricesCSV/source/ResponseListener.h/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
/** The Price History API communicator request result listener. */
class ResponseListener
: public pricehistorymgr::TThreadSafeAddRefImpl
{
public:
ResponseListener();
/** Wait for request execution or an error. */
bool wait();
/** Get response.*/
pricehistorymgr::IPriceHistoryCommunicatorResponse* getResponse();
/** Set the request before waiting for execution response. */
void setRequest(pricehistorymgr::IPriceHistoryCommunicatorRequest *request);
public:
/** @name IPriceHistoryCommunicatorListener interface implementation */
//@{
virtual void onRequestCompleted(pricehistorymgr::IPriceHistoryCommunicatorRequest *request,
pricehistorymgr::IPriceHistoryCommunicatorResponse *response);
virtual void onRequestFailed(pricehistorymgr::IPriceHistoryCommunicatorRequest *request, pricehistorymgr::IError *error);
virtual void onRequestCancelled(pricehistorymgr::IPriceHistoryCommunicatorRequest *request);
//@}
protected:
virtual ~ResponseListener();
private:
O2G2Ptr mRequest;
O2G2Ptr mResponse;
HANDLE mSyncResponseEvent;
};
PK
{l5Il l ( GetHistPricesCSV/source/SampleParams.cpp/* Copyright 2013 Forex Capital Markets LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "stdafx.h"
#include "SampleParams.h"
const char *SampleParams::Strings::instrumentNotSpecified = "'Instrument' is not specified (/i|-i|/instrument|--instrument)";
const char *SampleParams::Strings::timeframeNotSpecified = "'Timeframe' is not specified (/timeframe|--timeframe)";
const char *SampleParams::Strings::outputFileNotSpecified = "'Output file' is not specified (/output|--output)";
SampleParams::SampleParams(int argc, char **argv)
{
/* Load parameters with short keys. */
mInstrument = getArgument(argc, argv, "i");
/* If parameters with short keys not loaded, load with long keys. */
if (mInstrument.empty())
mInstrument = getArgument(argc, argv, "instrument");
/* Load parameters with long keys. */
mTimeframe = getArgument(argc, argv, "timeframe");
std::string sDateFrom = getArgument(argc, argv, "datefrom");
std::string sDateTo = getArgument(argc, argv, "dateto");
std::string sQuotesCount = getArgument(argc, argv, "count");
mOutputFile = getArgument(argc, argv, "output");
/* Convert types. */
double const NaN = std::numeric_limits::quiet_NaN();
struct tm tmBuf = {0};
if (sDateFrom.empty())
mDateFrom = NaN;
else
{
strptime(sDateFrom.c_str(), "%m.%d.%Y %H:%M:%S", &tmBuf);
CO2GDateUtils::CTimeToOleTime(&tmBuf, &mDateFrom);
}
if (sDateTo.empty())
mDateTo = NaN;
else
{
strptime(sDateTo.c_str(), "%m.%d.%Y %H:%M:%S", &tmBuf);
CO2GDateUtils::CTimeToOleTime(&tmBuf, &mDateTo);
}
if (sQuotesCount.empty())
{
mQuotesCount = -1;
}
else
{
mQuotesCount = atoi(sQuotesCount.c_str());
if (mQuotesCount <= 0)
mQuotesCount = -1;
}
}
SampleParams::~SampleParams(void)
{
}
const char *SampleParams::getArgument(int argc, char **argv, const char *key)
{
for (int i = 1; i < argc; ++i)
{
if (argv[i][0] == '-' || argv[i][0] == '/')
{
int iDelimOffset = 0;
if (strncmp(argv[i], "--", 2) == 0)
iDelimOffset = 2;
else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "/", 1) == 0)
iDelimOffset = 1;
if (_stricmp(argv[i] + iDelimOffset, key) == 0 && argc > i+1)
return argv[i+1];
}
}
return "";
}
/** Getters. */
const char *SampleParams::getInstrument()
{
return mInstrument.c_str();
}
const char *SampleParams::getTimeframe()
{
return mTimeframe.c_str();
}
DATE SampleParams::getDateFrom()
{
return mDateFrom;
}
DATE SampleParams::getDateTo()
{
return mDateTo;
}
int SampleParams::getQuotesCount()
{
return mQuotesCount;
}
const char* SampleParams::getOutputFile()
{
return mOutputFile.c_str();
}
/** Setters. */
void SampleParams::setDateFrom(DATE value)
{
mDateFrom = value;
}
void SampleParams::setDateTo(DATE value)
{
mDateTo = value;
}
PK
r5IiLj &