Está perdiendo oportunidades comerciales:
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Registro
Entrada
Usted acepta la política del sitio web y las condiciones de uso
Si no tiene cuenta de usuario, regístrese
¡Esto NO está en la documentación! En consecuencia, se trata de un ensayo sobre un tema libre. Igual que mi afirmación sobre la inicialización automática, aún más genial. Al menos el mío tenía un descargo de responsabilidad...
Es imposible describir absolutamente todo en la documentación.
Si "prev_calculate==0" - significa que tenemos que recorrer todo el buffer del indicador. Si "prev_calculate!=0", sólo se calculará la barra más a la derecha o varias nuevas (utilizamos el límite):
{
//---
if(prev_calculated==0)
{
Print("prev_calculated==0");
for(int i=0;i<rates_total;i++)
{
//--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
}
return(rates_total);
}
//--- экономный пересчёт только самого правого бара или новых баров
int limit=rates_total-prev_calculated+1;
//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
for(int i=0;i<limit;i++)
{
ExtBuffer[i]=чевой-то там;
}
Es imposible describir absolutamente todo en la documentación.
Si se obtiene "prev_calculate==0", significa que hay que recorrer todo el buffer del indicador. Si "prev_calculate!=0", sólo se calculará la barra más a la derecha o varias nuevas (utilizamos el límite):
{
//---
if(prev_calculated==0)
{
Print("prev_calculated==0");
for(int i=0;i<rates_total;i++)
{
//--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
}
return(rates_total);
}
//--- экономный пересчёт только самого правого бара или новых баров
int limit=rates_total-prev_calculated+1;
//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
for(int i=0;i<limit;i++)
{
ExtBuffer[i]=чевой-то там;
}
¿Cuál es el valor? No necesito ningún valor excepto la barra de la derecha. ¡¡¡ PERO!!! Entonces, cuando esta derecha se desplaza a la izquierda estos datos deben ser guardados...
No tienes que escribir todos los topes, pero podrías escribir uno con mis deseos en mente. Si es la primera ejecución, todo el historial debería estar vacío. Si prev_calculated se reinició como resultado del intercambio de la historia, TODO lo que se puso en el buffer debe permanecer sin cambios. Aunque haya agujeros.
Conclusiones preliminares:
¿Por qué dices tonterías? Si esta inicialización se pone en OnCalculate, se pone a cero sin ningún ciclo. Pero si ponemos a cero prev_calculado, se borran todos los datos que se han acumulado durante la operación...
¿Cuál es el valor? No necesito ningún otro valor que no sea la barra de la derecha. ¡¡¡ PERO!!! Entonces, cuando esta derecha se desplaza a la izquierda, hay que guardar esos datos...
...
Ya he sugerido una manera:
Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias de comercio
prev_calculado
Karputov Vladimir, 2016.10.18 15:11
Disculpe el retraso en la respuesta. La única forma de guardar los valores calculados para un determinado periodo de tiempo es guardarlos en un archivo. Hay que ocuparse de la sincronización, para que al leer del archivo los datos se coloquen en sus barras. Lo más lógico es sincronizarlo con la hora de apertura de la barra, pero puede haber algunos matices: por ejemplo, la hora de apertura de la barra (guardada en un archivo) era 2016.09.05. 25:02, pero ahora el gráfico tiene una barra con hora igual a 2016.09.05. 25:01.Un indicador no es una base de datos ni un depósito.
Por lo tanto, si el indicador muestra datos que luego no pueden ser calculados en el historial, entonces sólo es necesario guardar el buffer del indicador en un archivo, y luego (en caso de intercambio de historial) leer y sincronizar el archivo y las barras.Ya he sugerido una manera:
Un indicador no es una base de datos ni un depósito.
Por lo tanto, si el indicador muestra los datos, que luego no se pueden calcular en el historial, entonces sólo tenemos que guardar el buffer del indicador en un archivo, y luego (en el caso de la paginación del historial) realizar la lectura y sincronizar el archivo y las barras.... y preferiblemente sin escribir en un archivo o incluso más en GV.
Vladimir, ya que has dedicado este tema específicamente a prev_calculated, hazlo útil en este tema. En primer lugar, hay que especificar el problema que se suele producir con esta variable. Si no está familiarizado con estos problemas, formularé
---
a... aunque dice en la ayuda
La razón es (está escrito en la ayuda + dicho por los desarrolladores) que la variable se pone a cero cuando la suma de comprobación cambia, por lo general debido al intercambio de la historia.
---
b - tampoco se puede utilizar prev_calculado == 0 como bandera de la primera ejecución de onCalculate. Por la misma razón
---
c - y tampoco se puede utilizar prev_calculated == 0 como bandera de paginación del historial
---
Para reducir el desgaste de los usuarios, la redacción debe ser breve y sin ambigüedades: si la paginación de la historia no ha ocurrido en la llamada actual de OnCalculate, prev_calculated contiene el número de barras procesadas en la llamada anterior. Si ha pasado - se pone a cero
---
Los 3 problemas mencionados se pueden resolver con muletas. Sin embargo, dado que MT5 no puede tener muletas por definición, Vladimir, ¿podría crear una solución atractiva para estos tres problemas? Una fea es algo así:
#property indicator_buffers 0
#property indicator_plots 0
struct BROWNIE {
int i_Prew_Calculated; // кол-во посчитанных баров
bool b_First_Run; // флаг первого запуска
bool b_History_Updated; // флаг обновления истории
BROWNIE() {
i_Prew_Calculated = WRONG_VALUE;
b_First_Run = true;
b_History_Updated = false;
}
void f_Reset(bool b_Reset_First_Run = true) {
i_Prew_Calculated = WRONG_VALUE;
if(b_Reset_First_Run) b_First_Run = true;
b_History_Updated = false;
}
void f_Update(int i_New_Prew_Calculated = WRONG_VALUE) {
if(i_New_Prew_Calculated > -1) {
b_History_Updated = i_New_Prew_Calculated == 0 && i_Prew_Calculated > WRONG_VALUE;
if(b_First_Run) b_First_Run = false;
if(i_Prew_Calculated == WRONG_VALUE) i_Prew_Calculated = i_New_Prew_Calculated;
else if(i_New_Prew_Calculated > 0) i_Prew_Calculated = i_New_Prew_Calculated;
}
}
};
BROWNIE go_Brownie;
int OnInit(void) {return(INIT_SUCCEEDED);}
void OnDeinit(const int reason) {
go_Brownie.f_Reset(reason != REASON_CHARTCHANGE);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &Time[],
const double &Open[],
const double &High[],
const double &Low[],
const double &Close[],
const long &TickVolume[],
const long &Volume[],
const int &Spread[]
) {
if(go_Brownie.b_First_Run) {/* обработка 1го запуска */}
if(go_Brownie.b_History_Updated) {/* обработка обновления истории */}
go_Brownie.f_Update(prev_calculated);
return(rates_total);
}
Descargo de responsabilidad: Código - sólo una idea, no lo he probado en un gráfico.
En OnDeinit hay un ejemplo - procesamiento para el indicador que no usa buffers, no le importa el TF y el símbolo, en cada cambio de TF/símbolo no hay necesidad de empezar de cero. Por ejemplo, trabaja con los elementos gráficos existentes, emite información sobre el estado de las cuentas, los pedidos, etc.
---
Por cierto
Si el buffer del indicador se guardara en un archivo, y luego (en caso de carga del historial) habría que leer y sincronizar el archivo y las barras.
... y preferiblemente sin escribir en un archivo o más aún en un GV.
¿Quizás esto te sirva?
No he entrado en detalles, pero esto se soluciona con esta línea de código. Copiar un array en sí mismo con un desplazamiento de índice.
ArrayCopy(arr, arr, 0, 1, 4);
// и дальнейшее заполнение 4го индекса массива.