Skip to content
This repository has been archived by the owner on Dec 28, 2019. It is now read-only.

Commit

Permalink
исправлен баг чтения минут, изменен README
Browse files Browse the repository at this point in the history
  • Loading branch information
NewYaroslav committed Feb 3, 2018
1 parent 15ea15c commit dbab806
Show file tree
Hide file tree
Showing 15 changed files with 349 additions and 70 deletions.
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# trading_indicators
# trading indicators

Данная библиотека содержит различные функции и классы для проведения технического анализа.
Данная библиотека для С++ содержит различные функции и классы для проведения технического анализа. Можно считывать данные из CSV файлов, выводить графики, создавать свои стратегии и проверять их эффективность.

## классы индикаторов:
+ SMA
Expand All @@ -13,4 +13,35 @@
+ FATL
+ SATL
+ RBCI
+ MultiMa (шаблон класса для одновременной обработки нескольких любых скользящих средних)
+ Window (класс позволяет получить окно данных за определенный период)
+ SearchMinMax (класс позволяет получить минимум и максимум за n периодов, позволяет определить факт изменения min max)
+ LowPassFilter (фильтр низкой частоты)
+ LastExtrema (класс позволяет получить отфильтрованные последние n эксремумов, как всех сразу (min и max), так и по отдельности min и max)
+ PsychologicalLevel (класс позволяет определить принадлежность уровня к психологически важному значению (20, 50, 80, 100)
+ ShannonEntropy (класс позволяет получить энтропю Шеннона по факту изменения направления цены за n периодов. Энтропия возвращается в виде процента)

## определение эффективности стратегии в бинарных опционах:

+ StrategyEffectiveness класс позволяет получить эффективность стратегии в разное торговое время, процести оценку роста депозита, получить различные коэффициенты

## рисование графиков

+ Window (класс для получения данных свечей за n периодов в процессе торговли)
+ viewCandleGraph (функция для рисования графика со свечами и индикаторами, которые рисуются поверх графика)
+ drawOscilloscope4xBeam (функция рисует максимум 4 графика на одном окне)

## чтение данных

+ CurrencyQuote класс для чтения данных из CSV файлов, поддерживает два формата <TICKER>,<DTYYYYMMDD>,<TIME>,<OPEN>,<HIGH>,<LOW>,<CLOSE>,<VOL> и <DTYYYYMMDD>,<TIME>,<OPEN>,<HIGH>,<LOW>,<CLOSE>,<VOL>

## нормализация данных для нейросетей

+ calcMinMax получить нормирование по min max, от 0 до 1 или от - 1 до 1
+ calcZscore Z-Score нормализация данных
+ calcDifference создать массив разности элементов
+ calcMaxAmplitude максимизация амплитуды до 1
+ BollingerBandsNorm Класс для нормализации сигнала в пределах полос Боллинджера



Binary file modified programs/testWinrate/bin/Release/testWinrate.exe
Binary file not shown.
50 changes: 32 additions & 18 deletions programs/testWinrate/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,45 +46,59 @@ int main() {
int stopPos = TestData.close.size() * stop; // êîíåö äàííûõ
std::cout << "Source: " << vPairName[n] << " data size: " << TestData.close.size() << std::endl;

Indicators::BollingerBands iBB(20, 2.0); // èíäèêàòîð áîëëèíäæåð
Indicators::BollingerBands iBB(25, 2.1); // èíäèêàòîð áîëëèíäæåð
Indicators::RSI iRSI(14); // èíäèêàòîð RSI
Indicators::LastExtrema iLE(5, 10);
Indicators::SearchMinMax iMinMax(30);
StrategyEffectiveness iEffL;

for(int i = startPos; i < stopPos - expTime; i++) {
double& close = TestData.close[i];
double& closeFuture = TestData.close[i + expTime];
int hour = TestData.hour[i];

iLE.updata(close);
iMinMax.updata(close);
iBB.updata(close); // îáíîâëÿåì äàííûå áîëëèíäæåðà
double rsi = iRSI.updata(close); // îáíîâëÿåì äàííûå RSI

if(close > iBB.tl && rsi > 80) {
if(closeFuture < close) {
iEff.setWin(hour);
iEffL.setWin(hour);
} else
if(closeFuture > close) {
iEff.setLoss(hour);
iEffL.setLoss(hour);
}
} else
if(close < iBB.bl && rsi < 20) {
if(closeFuture > close) {
iEff.setWin(hour);
iEffL.setWin(hour);
if(iLE.vExtremaUp.size() > 2 && iLE.vExtremaDown.size() > 2) {
double upLevel = iLE.vExtremaUp.back();
double downLevel = iLE.vExtremaDown.back();
double ampl = iMinMax.maxData - iMinMax.minData;
double upDiff = std::abs(upLevel - close) / ampl;
double downDiff = std::abs(downLevel - close) / ampl;

if(close > iBB.tl && upDiff <= 0.02) {
if(closeFuture < close) {
iEff.setWin(hour);
iEffL.setWin(hour);
} else
if(closeFuture > close) {
iEff.setLoss(hour);
iEffL.setLoss(hour);
}
} else
if(closeFuture < close) {
iEff.setLoss(hour);
iEffL.setLoss(hour);
if(close < iBB.bl && downDiff <= 0.02) {
if(closeFuture > close) {
iEff.setWin(hour);
iEffL.setWin(hour);
} else
if(closeFuture < close) {
iEff.setLoss(hour);
iEffL.setLoss(hour);
}
}
}

} // for
std::cout << "Eff: " << iEffL.getEff() << " num win: " << iEffL.win << " num loss: " << iEffL.loss << std::endl;
for(int i = 0; i < 24; i++) {
double eff = (double)iEffL.hwin[i] / (double)(iEffL.hwin[i] + iEffL.hloss[i]);
std::cout << "hour: " << i << " eff: " << eff << std::endl;
}
} // for
std::cout << "Eff: " << iEff.getEff() << " num win: " << iEff.win << " num loss: " << iEff.loss << std::endl;
for(int i = 0; i < 24; i++) {
double eff = (double)iEff.hwin[i] / (double)(iEff.hwin[i] + iEff.hloss[i]);
std::cout << "hour: " << i << " eff: " << eff << std::endl;
Expand Down
Binary file modified programs/testWinrate/obj/Release/programs/testWinrate/main.o
Binary file not shown.
Binary file modified programs/testWinrate/obj/Release/src/TradingIndicators.o
Binary file not shown.
6 changes: 3 additions & 3 deletions programs/testWinrate/testWinrate.depend
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@
1517419972 d:\yar\_repoz\trading_indicators\src\strategyeffectiveness.hpp
<vector>

1517418478 source:d:\yar\_repoz\trading_indicators\src\tradingindicators.cpp
1517429995 source:d:\yar\_repoz\trading_indicators\src\tradingindicators.cpp
"TradingIndicators.hpp"
"NormalizationData.hpp"
<iostream>
"Drawing.hpp"

1517417615 d:\yar\_repoz\trading_indicators\src\tradingindicators.hpp
1517428883 d:\yar\_repoz\trading_indicators\src\tradingindicators.hpp
<vector>
<numeric>
<algorithm>
Expand All @@ -48,7 +48,7 @@
<algorithm>
"TradingIndicators.hpp"

1517421186 source:d:\yar\_repoz\trading_indicators\programs\testwinrate\main.cpp
1517431505 source:d:\yar\_repoz\trading_indicators\programs\testwinrate\main.cpp
<iostream>
"ReadingData.hpp"
"TradingIndicators.hpp"
Expand Down
4 changes: 2 additions & 2 deletions src/Drawing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,8 @@ namespace Drawing {
cv::putText(output, "4", cv::Point(width/4 + 30, 10), CV_FONT_HERSHEY_PLAIN, 1.0,cv::Scalar(0,255,255), 1, 8, 0);
cv::putText(output, text, cv::Point(8, 40), CV_FONT_HERSHEY_PLAIN, 1.0,cv::Scalar(125,255,0), 1, 8, 0);

if(mask == 1) {
std::string imageName = name + ".jpg";
if(mask & 0x10) {
std::string imageName = "img//" + name + ".jpg";
cv::imwrite(imageName, output);
}

Expand Down
29 changes: 29 additions & 0 deletions src/Drawing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,44 @@ namespace Drawing {
std::vector<CandlesType> getCandlesType();
};

/** @brief Ïîëó÷èòü ãðàôèê ñâå÷åé
@param[in] out èçîáðàæåíèå
@param[in] width øèðèíà èçîáðàæåíèÿ
@param[in] height âûñîòà èçîáðàæåíèÿ
@param[in] in ìàññèâ ñ äàííûìè ñâå÷åé
@param[in] backgroundColor öâåò ôîíà
@param[in] backgroundColor2 öâåò ôîíà
@param[in] lineColor öâåò ëèíèé èíäèêàòîðîâ
*/
void getCandleGraph(cv::Mat& out,
int width, int height,
std::vector<CandlesType>& in,
cv::Scalar backgroundColor, cv::Scalar backgroundColor2, std::vector<cv::Scalar>& lineColor);

/** @brief Ïîêàçàòü ãðàôèê ñâå÷åé
@param[in] name èìÿ îêíà èçîáðàæåíèÿ
@param[in] in ìàññèâ ñ äàííûìè ñâå÷åé
@param[in] flag ôëàã âêëþ÷åíèÿ çàäåðæêè êàäðîâ (äëÿ ïðîïóñêà êàäðà íàäî íàæàòü àíãëèéñêóþ P)
*/
void viewCandleGraph(std::string name, std::vector<CandlesType>& in, int flag);

/** @brief Ñîõðàíèòü ãðàôèê ñâå÷åé
@param[in] name èìÿ îêíà èçîáðàæåíèÿ
@param[in] in ìàññèâ ñ äàííûìè ñâå÷åé
*/
void saveCandleGraph(std::string name, std::vector<CandlesType>& in);

/** @brief Ïîêàçàòü ãðàôèê
@param[in] name èìÿ îêíà èçîáðàæåíèÿ
@param[in] text òåêñ íà èçîáðàæåíèè
@param[in] in1 ìàññèâ ñ äàííûìè
@param[in] in2 ìàññèâ ñ äàííûìè
@param[in] in3 ìàññèâ ñ äàííûìè
@param[in] in4 ìàññèâ ñ äàííûìè
@param[in] width øèðèíà èçîáðàæåíèÿ
@param[in] height âûñîòà èçîáðàæåíèÿ
@param[in] mask ôëàã, êîòîðûé åñëè ðàâåí 0x10 âêëþ÷åò ñîõðàíåíèå êàðòèíêè â ïàïêå img ñ èìåíåì name.jpg
*/
char drawOscilloscope4xBeam(
std::string name, std::string text,
std::vector<double> in1, std::vector<double> in2, std::vector<double> in3, std::vector<double> in4,
Expand Down
6 changes: 3 additions & 3 deletions src/ReadingData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,10 @@ int CurrencyQuote::openFile(std::string name) {

numberStr = strData2.substr(0, 2);
char _hour = atoi(numberStr.c_str());
numberStr = strData2.substr(2, 2);
numberStr = strData2.substr(3, 2);
char _minutes = atoi(numberStr.c_str());
numberStr = strData2.substr(4, 2);
char _seconds = atoi(numberStr.c_str());
//numberStr = strData2.substr(4, 2);
char _seconds = 0; //atoi(numberStr.c_str());

//std::cout << (int)_hour << ":" << (int)_minutes << ":" << (int)_seconds << std::endl;
// open
Expand Down
20 changes: 10 additions & 10 deletions src/ReadingData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ class CurrencyQuote {
DTYYYYMMDD_TIME_OPEN_HIGH_LOW_CLOSE_VOL ///< Äàííûå èäóò â ïîðÿäêå: <DTYYYYMMDD>,<TIME>,<OPEN>,<HIGH>,<LOW>,<CLOSE>,<VOL>
} dataType = TICKER_DTYYYYMMDD_TIME_OPEN_HIGH_LOW_CLOSE_VOL;
std::string nameCurrencyPair; ///< Èìÿ âàëþòíîé ïàðû
std::vector<short> year;
std::vector<char> month;
std::vector<char> day;
std::vector<char> hour;
std::vector<char> minutes;
std::vector<char> seconds;
std::vector<short> year; ///< Ãîä ñâå÷è
std::vector<char> month; ///< Ìåñÿö ñâå÷è
std::vector<char> day; ///< äåíü ñâå÷è
std::vector<char> hour; ///< ÷àñ ñâå÷è
std::vector<char> minutes; ///< ìèíóòà ñâå÷è
std::vector<char> seconds; ///< ñåêóíäà ñâå÷è

std::vector<double> open;
std::vector<double> high;
std::vector<double> low;
std::vector<double> close;
std::vector<double> open; ///< öåíà îòêðûòèÿ ñâå÷è
std::vector<double> high; ///< íàèâûñøàÿ öåíà ñâå÷è
std::vector<double> low; ///< íàèíèçøàÿ öåíà ñâå÷è
std::vector<double> close; ///< öåíà çàêðûòèÿ ñâå÷è
//std::vector<int> vol;

CurrencyQuote(std::string name);
Expand Down
70 changes: 64 additions & 6 deletions src/StrategyEffectiveness.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/*
* trading_indicators - Indicators for technical analysis.
*
* Copyright (c) 2018 Yaroslav Barabanov. Email: elektroyar@yandex.ru
*
* 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:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*/

#include "StrategyEffectiveness.hpp"
#include <cmath>

Expand All @@ -13,11 +37,18 @@ StrategyEffectiveness::StrategyEffectiveness() {
hwin[i] = 0;
hloss[i] = 0;
}
for(int i = 0; i < 1440; i++) {
mwin[i] = 0;
mloss[i] = 0;
}
};


void StrategyEffectiveness::setWin() {
win++;
if(lossState > maxLoss) {
maxLoss = lossState; lossState = 0;
}
money += profit*rate*money;
grossprofit += profit*rate*money;
vMoney.push_back(money);
Expand All @@ -26,6 +57,7 @@ void StrategyEffectiveness::setWin() {

void StrategyEffectiveness::setLoss() {
loss++;
lossState++;
money -= rate*money;
grossloss += rate*money;
vMoney.push_back(money);
Expand All @@ -34,6 +66,9 @@ void StrategyEffectiveness::setLoss() {
void StrategyEffectiveness::setWin(int hour) {
hwin[hour]++;
win++;
if(lossState > maxLoss) {
maxLoss = lossState; lossState = 0;
}
money += profit*rate*money;
grossprofit += profit*rate*money;
vMoney.push_back(money);
Expand All @@ -42,6 +77,29 @@ void StrategyEffectiveness::setWin(int hour) {
void StrategyEffectiveness::setLoss(int hour) {
hloss[hour]++;
loss++;
lossState++;
money -= rate*money;
grossloss += rate*money;
vMoney.push_back(money);
}

void StrategyEffectiveness::setWin(int hour, int minutes) {
mwin[hour*60 + minutes]++;
hwin[hour]++;
win++;
if(lossState > maxLoss) {
maxLoss = lossState; lossState = 0;
}
money += profit*rate*money;
grossprofit += profit*rate*money;
vMoney.push_back(money);
}

void StrategyEffectiveness::setLoss(int hour, int minutes) {
mloss[hour*60 + minutes]++;
hloss[hour]++;
loss++;
lossState++;
money -= rate*money;
grossloss += rate*money;
vMoney.push_back(money);
Expand All @@ -54,7 +112,7 @@ double StrategyEffectiveness::getConsistency() {
//double delta = ((double)(vMoney.back() - vMoney.front()) / (double)(vMoney.size()));
double delta = ((double)(log(vMoney.back()) - log(vMoney.front())) / (double)(vMoney.size()));
double y0 = log(vMoney.front());
for(int i = 1; i < vMoney.size() - 1; i++) {
for(int i = 1; i < (int)vMoney.size() - 1; i++) {
double y = y0 + delta * (double)i;
double diff = log(vMoney[i]) - y;
sum += diff * diff;
Expand All @@ -71,7 +129,7 @@ double StrategyEffectiveness::getProfitStability() {
double& trendProfit = delta;
double y0 = log(vMoney.front());
double totalVolume = 0;
for(int i = 0; i < vMoney.size(); i++) {
for(int i = 0; i < (int)vMoney.size(); i++) {
double logMoney = log(vMoney[i]);
double y = y0 + delta * (double)i;
double diff = logMoney - y;
Expand All @@ -97,7 +155,7 @@ double StrategyEffectiveness::getProfitLoss() {
double StrategyEffectiveness::getAverageGeometricYield() {
if(vMoney.size() < 2) return 0;
double mx = 1.0;
for(int i = 1; i < vMoney.size(); i++) {
for(int i = 1; i < (int)vMoney.size(); i++) {
double ri = vMoney[i - 1] > 0 ? 1.0 + ((double)(vMoney[i] - vMoney[i - 1]) / (double)vMoney[i - 1]) : 0;
//double ri = vMoney[i - 1] > 0 ? ((double)vMoney[i] / (double)vMoney[i - 1]) : 0;
mx *= ri;
Expand All @@ -109,7 +167,7 @@ double StrategyEffectiveness::getAverageGeometricYield() {
double StrategyEffectiveness::getAverageGeometricYieldMx() {
if(vMoney.size() < 2) return 0;
double mx = 1.0;
for(int i = 1; i < vMoney.size(); i++) {
for(int i = 1; i < (int)vMoney.size(); i++) {
double ri = vMoney[i - 1] > 0 ? 1.0 + ((double)(vMoney[i] - vMoney[i - 1]) / (double)vMoney[i - 1]) : 0;
//double ri = vMoney[i - 1] > 0 ? ((double)vMoney[i] / (double)vMoney[i - 1]) : 0;
mx *= ri;
Expand All @@ -124,7 +182,7 @@ double StrategyEffectiveness::getCoeffSharpe() {
double re = getAverageGeometricYield();
if(re == 0) return 0;
double sum = 0;
for(int i = 1; i < vMoney.size(); i++) {
for(int i = 1; i < (int)vMoney.size(); i++) {
double ri = vMoney[i - 1] > 0 ? 1.0 + ((double)(vMoney[i] - vMoney[i - 1]) / (double)vMoney[i - 1]) : 0;
//double ri = vMoney[i - 1] > 0 ? ((double)vMoney[i] / (double)vMoney[i - 1]) : 0;
double diff = ri - re;
Expand All @@ -141,7 +199,7 @@ double StrategyEffectiveness::getBalanceMaxCoeffSharpe() {
double re = getAverageGeometricYield();
if(re == 0) return 0;
double sum = 0;
for(int i = 1; i < vMoney.size(); i++) {
for(int i = 1; i < (int)vMoney.size(); i++) {
double ri = vMoney[i - 1] > 0 ? 1.0 + ((double)(vMoney[i] - vMoney[i - 1]) / (double)vMoney[i - 1]) : 0;
//double ri = vMoney[i - 1] > 0 ? ((double)vMoney[i] / (double)vMoney[i - 1]) : 0;
double diff = ri - re;
Expand Down
Loading

0 comments on commit dbab806

Please sign in to comment.