How do you make the renko charts immune to this problem? Any takers?
Algorithmic Quant Trading (Machine Learning + Stat-Arb) 25 replies
Forex with Machine Learning Software Project 1 reply
Machine Learning + Retail Forex = Profitable? (Quant) 1 reply
Potential new machine learning style software. 79 replies
My most recent advancements into machine learning 16 replies
DislikedHow do you make the renko charts immune to this problem? Any takers?Ignored
DislikedHow do you make the renko charts immune to this problem? Any takers?Ignored
Disliked{quote} As far as I can see my Renko charts do look the same regardless on when they start. I think the point is that Renko charts build their bricks on levels measured from the zero level rather than from the starting tick (if this was your objection). The objection about testing I did not get. IMHO there is no difference in fidelity comparing to the standard charts (if both constructed from ticks).Ignored
AsirikuyReturnCode EasyTrade::addNewRenkoRatesFromZero(int originalRatesIndex, int ratesIndex, double renkoSize) { int arraySize, i, newCandle; double cumulativeVolume; double currentOpen, lowest, highest, lastOpen; double upperLimit, lowerLimit; double originalLow, originalHigh; time_t currentTime; arraySize = pParams->ratesBuffers->rates[originalRatesIndex].info.arraySize; pParams->ratesBuffers->rates[ratesIndex].info.arraySize = 0 ; newCandle = TRUE; cumulativeVolume = 0; for(i=0;i<(arraySize-1);i++) { if (newCandle == TRUE) { if (pParams->ratesBuffers->rates[ratesIndex].info.arraySize == 0){ currentOpen = pParams->ratesBuffers->rates[originalRatesIndex].open[i] ; } else { currentOpen = lastOpen; } upperLimit = renkoSize*ceil(currentOpen/renkoSize)+renkoSize ; lowerLimit = renkoSize*floor(currentOpen/renkoSize)-renkoSize ; currentTime = pParams->ratesBuffers->rates[originalRatesIndex].time[i]; lowest = currentOpen; highest = currentOpen; cumulativeVolume = 0; newCandle = FALSE; } cumulativeVolume += pParams->ratesBuffers->rates[originalRatesIndex].volume[i]; originalLow = pParams->ratesBuffers->rates[originalRatesIndex].low[i]; originalHigh = pParams->ratesBuffers->rates[originalRatesIndex].high[i]; if (originalLow < lowest) lowest = originalLow; if (originalHigh > highest) highest = originalHigh; if ((originalLow <= lowerLimit) || (originalHigh >= upperLimit) || (i == arraySize-2)) { pParams->ratesBuffers->rates[ratesIndex].info.arraySize += 1 ; if (pParams->ratesBuffers->rates[ratesIndex].info.arraySize > 1) { pParams->ratesBuffers->rates[ratesIndex].time = (time_t*)realloc(pParams->ratesBuffers->rates[ratesIndex].time, pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(time_t)); pParams->ratesBuffers->rates[ratesIndex].open = (double*)realloc(pParams->ratesBuffers->rates[ratesIndex].open, pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); pParams->ratesBuffers->rates[ratesIndex].high = (double*)realloc(pParams->ratesBuffers->rates[ratesIndex].high, pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); pParams->ratesBuffers->rates[ratesIndex].low = (double*)realloc(pParams->ratesBuffers->rates[ratesIndex].low, pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); pParams->ratesBuffers->rates[ratesIndex].close = (double*)realloc(pParams->ratesBuffers->rates[ratesIndex].close, pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); pParams->ratesBuffers->rates[ratesIndex].volume = (double*)realloc(pParams->ratesBuffers->rates[ratesIndex].volume, pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); } else { pParams->ratesBuffers->rates[ratesIndex].time = (time_t*)malloc(pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(time_t)); pParams->ratesBuffers->rates[ratesIndex].open = (double*)malloc(pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); pParams->ratesBuffers->rates[ratesIndex].high = (double*)malloc(pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); pParams->ratesBuffers->rates[ratesIndex].low = (double*)malloc(pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); pParams->ratesBuffers->rates[ratesIndex].close = (double*)malloc(pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); pParams->ratesBuffers->rates[ratesIndex].volume = (double*)malloc(pParams->ratesBuffers->rates[ratesIndex].info.arraySize * sizeof(double)); } if (originalLow <= lowerLimit) { pParams->ratesBuffers->rates[ratesIndex].time[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = currentTime; pParams->ratesBuffers->rates[ratesIndex].open[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = currentOpen; pParams->ratesBuffers->rates[ratesIndex].high[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = highest; pParams->ratesBuffers->rates[ratesIndex].low[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = lowerLimit; pParams->ratesBuffers->rates[ratesIndex].close[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = lowerLimit; pParams->ratesBuffers->rates[ratesIndex].volume[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = cumulativeVolume; lastOpen = lowerLimit; } if (originalHigh >= upperLimit) { pParams->ratesBuffers->rates[ratesIndex].time[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = currentTime; pParams->ratesBuffers->rates[ratesIndex].open[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = currentOpen; pParams->ratesBuffers->rates[ratesIndex].high[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = upperLimit; pParams->ratesBuffers->rates[ratesIndex].low[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = lowest; pParams->ratesBuffers->rates[ratesIndex].close[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = upperLimit; pParams->ratesBuffers->rates[ratesIndex].volume[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = cumulativeVolume; lastOpen = upperLimit; } if ((i == arraySize-2) && (originalLow > lowerLimit) && (originalHigh < upperLimit)) { pParams->ratesBuffers->rates[ratesIndex].time[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = currentTime; pParams->ratesBuffers->rates[ratesIndex].open[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = currentOpen; pParams->ratesBuffers->rates[ratesIndex].high[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = highest; pParams->ratesBuffers->rates[ratesIndex].low[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = lowest; pParams->ratesBuffers->rates[ratesIndex].close[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = pParams->ratesBuffers->rates[originalRatesIndex].close[i]; pParams->ratesBuffers->rates[ratesIndex].volume[pParams->ratesBuffers->rates[ratesIndex].info.arraySize-1] = cumulativeVolume; } newCandle = TRUE; } } return SUCCESS; }
addNewRenkoRatesFromZero(PRIMARY_RATES,2,0.0050);
#include "Precompiled.h" #include <ta_libc.h> #include "AsirikuyStrategies.h" #include "InstanceStates.h" #include "AsirikuyTime.h" #include "Logging.h" #include "OrderManagement.h" #include "OrderSignals.h" #include "AsirikuyTechnicalAnalysis.h" #include "StrategyUserInterface.h" #include "EasyTradeCWrapper.hpp" #define USE_INTERNAL_SL FALSE #define USE_INTERNAL_TP FALSE // Careful, not thread safe!! static int lastRenkoDate = 0; void freeRenkoIndex2(StrategyParams* pParams){ free(pParams->ratesBuffers->rates[2].time); free(pParams->ratesBuffers->rates[2].open); free(pParams->ratesBuffers->rates[2].high); free(pParams->ratesBuffers->rates[2].low); free(pParams->ratesBuffers->rates[2].close); free(pParams->ratesBuffers->rates[2].volume); } typedef enum additionalSettings_t { BARS_IN_FRONTIER = ADDITIONAL_PARAM_1, BARS_PER_EXAMPLE = ADDITIONAL_PARAM_2, NUM_OF_EXAMPLES = ADDITIONAL_PARAM_3, RENKO_SIZE_PIPS = ADDITIONAL_PARAM_4 } AdditionalSettings; AsirikuyReturnCode runRenkoSample1(StrategyParams* pParams) { double stopLoss; double atr = iAtrWholeDaysSimple(PRIMARY_RATES, (int)pParams->settings[ATR_AVERAGING_PERIOD]); uint8_t ensemblePrediction = 0; double pipModifier = 10000; if (strstr(pParams->tradeSymbol, "JPY") != NULL){ pipModifier = 100; } stopLoss = atr * pParams->settings[SL_ATR_MULTIPLIER]; addNewRenkoRatesFromZero(PRIMARY_RATES,2,parameter(RENKO_SIZE_PIPS)/pipModifier); if (iOpenTime(2, 0) == lastRenkoDate){ freeRenkoIndex2(pParams); return SUCCESS; } else { lastRenkoDate = iOpenTime(2, 0); } ensemblePrediction = LR_Prediction_i_simpleReturn_o_mlemse((int)parameter(NUM_OF_EXAMPLES), (int)parameter(BARS_PER_EXAMPLE), (int)parameter(BARS_IN_FRONTIER)); if(ensemblePrediction == 1){ freeRenkoIndex2(pParams); return openOrUpdateLongEasy(0, stopLoss); } else if(ensemblePrediction == 2){ freeRenkoIndex2(pParams); return openOrUpdateShortEasy(0, stopLoss); } freeRenkoIndex2(pParams); return SUCCESS; }
SL_ATR_MULTIPLIER=1.3 BARS_IN_FRONTIER=60 BARS_PER_EXAMPLE=2.0 NUM_OF_EXAMPLES=50 RENKO_SIZE_PIPS=60
Data<RealVector> inputs(period,RealVector(barsUsed*2));
for(j=0;j<barsUsed;j++){ inputs.element(m)[j] = (iOpen(2,tl+j+i)-iOpen(2,1+tl+j+i))/iOpen(2,1+tl+j+i); } for(j=barsUsed;j<2*barsUsed;j++){ inputs.element(m)[j] = (iOpenTime(2,tl+j+i-barsUsed)-iOpenTime(2,1+tl+j+i-barsUsed)); }
DislikedUp front disclaimer I haven't used Renko bars. That said I do use range bars and volume bars (tick volume for spot FX actual volume for stocks). When translating tick data into the data store I use the open and close for the session. In the case of FX Inuse Monday's Sydney open and Friday's New York close. The rationale for this is that I'm capturing market behavior. My results aren't bad in live trading ... still this logic maybe floored? Thoughts.Ignored
SL_ATR_MULTIPLIER=1.2 BARS_IN_FRONTIER=60 BARS_PER_EXAMPLE=5.0 NUM_OF_EXAMPLES=50 RENKO_SIZE_PIPS=60
Disliked{quote} How long have you been trading? If you have traded for 4-5 years and it has been working well through all this time then don't change it. If it ain't broke don't fix it. If you haven't traded for this long then you'll have to wait to see enough variation in markets to see whether your assumptions will cost ya.Ignored
uint8_t LZ_Prediction_i_simpleReturn_o_mlemse(int learningPeriod, int barsUsed, int frontier) { double lambda = 1.0 ; RegressionDataset dataset = regression_i_simpleReturn_o_mlemse(learningPeriod, barsUsed, frontier); LinearModel<> model; LassoRegression<> trainer(lambda); trainer.train(model, dataset); uint8_t reply = 0; Data<RealVector> testOutput; RegressionDataset datasetInput = p_regression_i_simpleReturn(barsUsed); testOutput = model(datasetInput.inputs()); char filenameString[MAX_TIME_STRING_SIZE] = ""; if (testOutput.element(0)[0] > testOutput.element(0)[1] ) return(1); if (testOutput.element(0)[1] > testOutput.element(0)[0] ) return(2); return(0); }
uint8_t LZ_Prediction_i_simpleReturn_o_mlemse(int learningPeriod, int barsUsed, int frontier);
typedef enum mlalgoTypes_t { LINEAR_REGRESSION = 0, NEURAL_NETWORK = 1, K_NEAREST_NEIGHBOR = 2, RANDOM_FOREST = 3, SUPPORT_VECTOR_MACHINE = 4, LINEAR_MAPPING = 5, LASSO_REGRESSION = 6, // <--- ADDED MY LASSO ALGO ID HERE } mlalgoTypes;
if (mainKantuMLContainer->g_ml_algo_type[i] == LASSO_REGRESSION){ ensemblePrediction = LZ_Prediction_i_simpleReturn_o_mlemse(mainKantuMLContainer->g_learning_period[i], mainKantuMLContainer->g_bars_used[i], mainKantuMLContainer->g_frontier[i]); }.
if (ml_algo_type == LASSO_REGRESSION){ ensemblePrediction = LZ_Prediction_i_simpleReturn_o_mlemse((int)parameter(LEARNING_PERIOD_ML), (int)parameter(BARS_USED_ML), (int)parameter(FRONTIER_ML)); }
DislikedHi Algotraderjo, 1. From my tests when I use regularization on time series return all the weights become 0 (not relevant consider them noise) and all "EGDE" come from stop loss. 2. From my experiments in last few year the performance of ml mining systems is around +-0 in compare to past data 1987-2012? Regime change ? How you construct the portfolio from systems ? Do you give more weight to last performance in portfolio?Ignored