I want to store strings in a char * array but I don't know how I can do that.
Each cell in the 2d array can contain letters or numbers with 2 digits.
|_|S|_|
|_|10|_|
|_|W|_|
|_|_|_|
|_|_|_|
I tried this, I used struct:
struct Etage {
char Idsalles[20];
int** etage;
int width;
int height;
};
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "etage.h"
#define COLS 15
#define ROWS 9
Etage *createMap()
{
Etage *e = malloc(sizeof(Etage));
e->width = COLS; // columns
e->height = ROWS; // rows
e->etage = malloc(sizeof(char *) * e->height);
for (int i = 0; i < e->height; i += 1)
{
e->etage[i] = malloc(sizeof(char) * e->width);
for (int j = 0; j < e->width; j += 1)
{
e->etage[i][j] = "0";
}
}
return e;
}
void randomId(Etage *e, int maxSalles)
{
srand(time(NULL));
int i = 0;
if (maxSalles < 10)
{
printf("Seulement %d disponibles, veuiller générer plus de salles.\n", maxSalles);
return;
}
while (i < 10)
{
int id = (rand() % maxSalles) + 1;
int existe = testId(e, id);
if (existe != 1)
{
e->Idsalles[i] = id;
i += 1;
}
}
return;
}
int testId(Etage *e, int id)
{
for (int i = 0; i < 10; i += 1)
{
if (id == e->Idsalles[i])
{
return 1;
}
}
return 0;
}
void printEtage(Etage *e)
{
for (int i = 0; i < e->height; i += 1)
{
for (int j = 0; j < e->width; j += 1)
{
if(e->etage[i][j] == 0){
printf(" ");
}else{
printf("%s", e->etage[i][j]);
printf(" ");
}
}
printf("\n");
}
printf("Id des salles de cette étage: ");
for(int i =0; i <10;i+=1){
printf("%d ",e->Idsalles[i]);
}
printf("\n");
}
void freeEtage(Etage *e)
{
//free(e->etage);
free(e);
}
void placerSalles(Etage* e){
int a=ROWS/2;
int b=COLS/2;
//0 = Haut; 1 = Droite; 2 = Bas; 3 = Gauche
e->etage[a][b] = e->Idsalles[0]+"\0"; // On place la premiere salle au centre de l'étage sa sera le spawner 'S'
srand(time(NULL));
int i = 1;
while(i<10){
int dir = randomDirections();
if(dir==0){ // On se déplace en haut
a = a-1; //On se déplace
if(e->etage[a][b] == 0 && a > 0){
e->etage[a][b] = e->Idsalles[i]+"\0";
i+=1;
}else{
a = a+1; // Sionon on revien a la derniere case connu
}
}else if(dir==1){ // On se déplace à droite
b=b+1;
if(e->etage[a][b] == 0 && b< e->width){
e->etage[a][b] = e->Idsalles[i]+"\0";
i+=1;
}else{
b = b-1;
}
}else if(dir==2){ // On se déplace en bas
a = a+1;
if(e->etage[a][b] == 0 && a>e->height){
e->etage[a][b] = e->Idsalles[i]+"\0";
i+=1;
}else{
a = a-1;
}
}else if(dir==3){ // On se déplace à gauche
b = b-1;
if(e->etage[a][b] == 0 && b>0){
e->etage[a][b] = e->Idsalles[i]+"\0";
i+=1;
}else{
b = b+1;
}
}
}
}
int randomDirections(){
int i = 0;
int id = rand() % 4; // Remplacé 10 par le nbrSalles
//printf("Position: %d\n",id);
return id;
}
I have a good understanding with 2d array but three...
I tried using malloc.
I don't even think this is possible...
If your string is a maximum of 2 characters long (your strings will be 3 chars long)
char array[rows][cols][3] = {{"2", "a", "34"}, ... };
or to use malloc
char (*array)[cols][3] = malloc(rows * sizeof(*array));
I was working in a University C project (first sem), in which our group wanted to make a simple pong game, we decided to use raylib, as it seemed easy. But here is the problem, in the following code:
void UpdatePad(Pad* pad)
{
int height = GetScreenHeight();
if (IsKeyDown(pad->Scheme.DownButton)) {
printf("Down = %d\n", pad->Scheme.DownButton);
pad->Position.y += GetFrameTime() * pad->Speed;
if ( pad->Position.y + pad->Size.y/2 > height ) {
pad->Position.y = height - pad->Size.y /2;
}
}
if (IsKeyDown(pad->Scheme.UpButton)) {
printf("Up = %d\n", pad->Scheme.UpButton);
pad->Position.y -= GetFrameTime() * pad -> Speed;
if (pad->Position.y - pad->Size.y/2 < 0 ) {
pad->Position.y = pad->Size.y /2;
}
}
}
The function IsKeyDown of raylib always returns true, whatever I do. Even if I replace pad->Scheme.DownButton to KEY_UP or something, it always returns true and executes the code block, Is there any solution for this?
Full script is:
#include <raylib.h>
#include <stdio.h>
#include "pad.h"
#include "main.h"
void DrawPad(Pad* pad);
void UpdatePad(Pad* pad);
void Update();
void DrawUpdate();
void Loop();
int main()
{
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "Table Tennis");
SetTargetFPS(12);
Loop();
return 0;
}
void Loop()
{
while (!WindowShouldClose()) {
DrawUpdate();
}
}
void UpdatePad(Pad* pad)
{
int height = GetScreenHeight();
if (IsKeyDown(pad->Scheme.DownButton)) {
printf("Down = %d\n", pad->Scheme.DownButton);
pad->Position.y += GetFrameTime() * pad->Speed;
if ( pad->Position.y + pad->Size.y/2 > height ) {
pad->Position.y = height - pad->Size.y /2;
}
}
if (IsKeyDown(pad->Scheme.UpButton)) {
printf("Up = %d\n", pad->Scheme.UpButton);
pad->Position.y -= GetFrameTime() * pad -> Speed;
if (pad->Position.y - pad->Size.y/2 < 0 ) {
pad->Position.y = pad->Size.y /2;
}
}
}
void DrawPad(Pad* pad)
{
DrawRectangle(pad->Position.x, pad->Position.y - (pad->Size.y /2), pad->Size.x, pad->Size.y, WHITE);
}
void DrawUpdate()
{
const char* scoreLeft = TextFormat("%d", 10);
int scoreSizeLeft = MeasureText(scoreLeft, 20);
InputScheme Input = { .DownButton = KEY_S, .UpButton = KEY_W };
Vector2 paddySize = { .x = 5, .y = 50 };
Vector2 paddyPos = { .x = GetScreenWidth() - paddySize.x , .y = GetScreenHeight() - paddySize.y };
Pad pad = { .Size = paddySize, .Speed = 50, .Scheme = Input , .Position = paddyPos };
Vector2 from = {.x = (GetScreenWidth() / (float) 2), .y = 5};
Vector2 to = { .x = (GetScreenWidth() / (float) 2), .y = ( GetScreenHeight() - (float) 5 ) };
UpdatePad(&pad);
BeginDrawing();
ClearBackground(BLACK);
DrawLineEx(from, to, 2, LIGHTGRAY);
DrawText(scoreLeft, (GetScreenWidth()/2) - 10 -scoreSizeLeft, 10, 20, LIGHTGRAY);
DrawPad(&pad);
EndDrawing();
}
The pad is:-
#include <raylib.h>
typedef struct {
int UpButton;
int DownButton;
} InputScheme;
typedef struct {
InputScheme Scheme;
int Score;
float Speed;
Vector2 Position;
Vector2 Size;
} Pad;
My program segfaults as soon as I press a key, but I am unable to come up with a minimal code. If I comment out pixels[y][pdpix] = col[sampleX][sampleY]; (line 110), key presses work as normal. Otherwise, it segfaults.
Full code and "bmp" files: https://drive.google.com/file/d/1663hiKbvodcNu0xG8FpbYACAUoGScfAn/view?usp=sharing
Code in main.c:
#include <SDL2/SDL.h>
#include <stdbool.h>
#include "read.h"
#define RESX 960
#define RESY 540
#define HRESX 480
#define DRAWDISTANCE 360
#define ROTSPEED 0.005
#define BGCOL 0
#define ARESY 539
void main() {
readCW();
bool running = true;
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
running = false;
}
window = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, RESX, RESY, SDL_WINDOW_SHOWN );
if( window==NULL) {
printf( "SDL_Error: %s\n", SDL_GetError() );
running = false;
}
renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);
if(renderer==NULL) {
printf("Renderer error: %s\n", SDL_GetError() );
running = false;
}
SDL_Texture * texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STREAMING, RESX,RESY);
readBW();
float playerX = 512;
float playerY = 512;
float dirX = 0.0;
float dirY = 1.0;
void rotatez(float rotspeed) {
float oldDirX = dirX;
dirX = dirX * cos(rotspeed) - dirY * sin(rotspeed);
dirY = oldDirX * sin(rotspeed) + dirY * cos(rotspeed);
}
const Uint8* keystate = SDL_GetKeyboardState( NULL );
while( running ) {
clock_t t1, t2;
t1 = SDL_GetTicks();
Uint32 pixels[RESY][RESX] = {[0 ... RESY-1][0 ...RESX-1] = 0x5555FF};
SDL_Event e;
running = !(SDL_PollEvent( &e ) && e.type == SDL_QUIT);
if(keystate[SDL_SCANCODE_ESCAPE]) running = false;
if(keystate[SDL_SCANCODE_LEFT]) rotatez(-ROTSPEED);
if(keystate[SDL_SCANCODE_RIGHT]) rotatez(ROTSPEED);
if(keystate[SDL_SCANCODE_W]) {
playerY += dirY;
playerX += dirX;
}
if(keystate[SDL_SCANCODE_S]) {
playerY -= dirY;
playerX -= dirX;
}
if(keystate[SDL_SCANCODE_A]) {
playerY -= dirX;
playerX += dirY;
}
if(keystate[SDL_SCANCODE_D]) {
playerY += dirX;
playerX -= dirY;
}
//rotatez(-ROTSPEED);
playerY -= dirY;//for testing
playerX -= dirX;//for testing
int heightBuffer[RESX] = {[0 ... 959] = RESY};
int playerHeight = 80;//disp[(int)playerX][(int)playerY] + 50;
int dpix = 0;
for( int dDist = 1; dDist < DRAWDISTANCE; dDist+=1) {
for( int pix = -dDist; pix < dDist; pix++) {
int pdpix = dpix;
dpix = (pix/(float)dDist+1) *HRESX;
int sampleX = (int)playerX + dDist*dirX + pix*-dirY;
int sampleY = (int)playerY + dDist*dirY + pix*dirX;
int height = disp[sampleX][sampleY];
int heightOnScreen = ( ((float)playerHeight - height) / dDist * 240 + 240); //alg for persp proj
if(heightOnScreen > 0 && heightOnScreen < RESY) {
for( pdpix; pdpix < dpix; pdpix++) {
if(heightOnScreen < heightBuffer[pdpix]) {
for(int y = heightBuffer[pdpix]; y > heightOnScreen; y-=1) {
pixels[y][pdpix] = col[sampleX][sampleY]; //if I comment out this line, segfault goes away.
}
heightBuffer[pdpix] = heightOnScreen;
}
}
}
}
}
SDL_UpdateTexture(texture, NULL, pixels, RESX * sizeof(Uint32));
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent( renderer );
t2 = SDL_GetTicks();
printf("%ld fps\n", 1000/(t2-t1));
}
SDL_DestroyWindow( window );
SDL_DestroyRenderer( renderer );
SDL_DestroyTexture( texture );
SDL_Quit();
}
I'm writing a EA for strategy tester purpose only, to evaluate portfolio. So I have hundreads/thousands of trades in an array, with open price and open time, and every 1 minute bar I check in a for loop if there's any trade to open in that minute. And it's taking forever.
How can I check (in a faster way) if in an array there's a open-time that coincides with current time?
Thanks!
if(NewBar)
{
CopyRates(_Symbol,PERIOD_M1,0,5,candle);
sizeAr=ArraySize(ar);
arColumns=ArrayRange(ar,1);
datetime candleNowTime = candle[0].time;
datetime nextCandleTime = candle[0].time+60;
for(int i=0;i<sizeAr/arColumns;i++)
{
if(ar[i][openTime]>candleNowTime && ar[i][openTime]<nextCandleTime)
{
//code to open trades
}
}
}
And the complete code is here:
//+------------------------------------------------------------------+
//| HedgeExperienceV001.mq5 |
//| Carlos Duna |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Carlos Duna"
#property link "https://www.mql5.com"
#property version "1.00"
#property tester_file "sinais.csv"
#include <Trade\Trade.mqh>
CTrade trade;
#include <Trade\SymbolInfo.mqh>
CSymbolInfo mysymbol;
#define columns 19
input double initialVolume = 0.01; // Volume inicial
input double slFixo = 0; // SL fixo (pips)(zero=SL do sinal)
input double tpFixo = 0; // TP fixo (pips)(zero=TP do sinal)
input ulong maxSlippage = 0; // Max Deviation/Slippage(0-não usa)
input double maxPricesVariation =10;// Max % variação Bid x TP x SL x OP
MqlRates candle[];
MqlDateTime TimeStruct;
MqlDateTime dealDay;
datetime dealDayStruct;
datetime now;
int secAnterior;
int previousDay;
bool NewBar;
datetime hj;
string orderComment;
bool orderOkToOpen;
datetime inicioHedge=0;
double profitPerMagic[][2];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
struct SLine
{
string field[];
};
SLine lines[];
string ar[][columns];
int sizeLine;
int sizeAr;
int arColumns;
double stopLossDelta;
double takeProfitDelta;
/*
lines[i].field[j]
** i= numero de cada trade, iniciando no zero (não há títulos de colunas), indo dinamicamente até a ultima linha
** j= valores dos campos
0 - tCanal
1 - str(msgId)
2 - dataHora HoraEntrada
3 - str(opType) CompraOuVenda
4 - ativo.upper()
5 - str(openPrice)
6 - str(stopLoss)
7 - str(takeProfit1)
8 - str(takeProfit2)
9 - str(takeProfit3)
10 - str(takeProfit4)
11 - str(takeProfit5)
12 - 'false' posição já foi aberta? true/false
13 - 'false' posição já foi fechada? true/false
14 - HalfCloseTime
15 - ManualCloseTime
16 - SLModify_Time
17 - SLModify_Price])
18 - magicCanal
*/
int xCanal = 0; // tCanal
int xOpCod = 1; // str(msgId)
int xDtEnt = 2; // dataHora HoraEntrada
int xBuySell=3; // str(opType) CompraOuVenda
int xAtv= 4; // ativo.upper()
int xOP = 5; // str(openPrice)
int xSL=6; // str(stopLoss)
int xTP1 = 7; // str(takeProfit1)
int xTP2 = 8; // str(takeProfit2)
int xTP3 = 9; // str(takeProfit3)
int xTP4 = 10; // str(takeProfit4)
int xTP5 = 11; // str(takeProfit5)
int xOpened = 12; // posição já foi aberta? true/false
int xClosed = 13; // posição já foi fechada? true/false
int xHalfC=14; // HalfCloseTime
int xManualC = 15; // ManualCloseTime
int xSLMTime = 16; // SLModify_Time
int xSLMPrice= 17; // SLModify_Price
int xMagic=18; // magicCanal
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
ArraySetAsSeries(candle,true);
if(!ReadFileToArrayCSV("sinais.csv",lines))
{
Alert("Error, see the \"Experts\" tab for details");
return(INIT_FAILED);
}
sizeLine=ArraySize(lines);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
ArrayFree(lines);
ArrayFree(ar);
double a = ProfitClosedPosition();
Print(a);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
now=TimeCurrent();
TimeToStruct(TimeCurrent(),TimeStruct);
if(previousDay!=TimeStruct.day_of_year) //Runs once a day
{
previousDay=TimeStruct.day_of_year;
// recria diariamente o array auxiliar ar
ArrayResize(ar,sizeLine);
for(int i=0;i<sizeLine;i++)
{
for(int j=0;j<columns;j++)
{
ar[i][j]=lines[i].field[j];
}
}
// após array ar recriado, elimina-se o que não for ser usado no dia
for(int i=sizeLine-1; i>=0; i--)
{
TimeToStruct((datetime)lines[i].field[xDtEnt],dealDay);
// if temporario; o deal close não será por data, e sim pelo fechamento do trade, a ser sinalizado no futuro
if(dealDay.day_of_year+2<TimeStruct.day_of_year && dealDay.year==TimeStruct.year)
{
ArrayRemove(ar,i,1);
}
// remove entradas cujas datas de entrada sejam superiores ao dia de hoje ou que possuam flag 'closed'
if((dealDay.day_of_year>TimeStruct.day_of_year && dealDay.year<=TimeStruct.year) || (lines[i].field[xClosed]==true))
{
ArrayRemove(ar,i,1);
}
}
}
NewBar=isNewBar();
if(NewBar)
{
CopyRates(_Symbol,PERIOD_M1,0,5,candle);
sizeAr=ArraySize(ar);
arColumns=ArrayRange(ar,1);
datetime candleNowTime = candle[0].time;
datetime nextCandleTime = candle[0].time+60;
for(int i=0;i<sizeAr/arColumns;i++)
{
if(ar[i][xDtEnt]>candleNowTime && ar[i][xDtEnt]<nextCandleTime)
{
fAbrirOp(i);
Print(ar[i][xCanal]," / ",ar[i][xOP]," / ",ar[i][xSL]," / ",ar[i][xTP1]);
}
}
}
}
//+------------------------------------------------------------------+
//| Função que transforma arquivo CSV em array |
//+------------------------------------------------------------------+
bool ReadFileToArrayCSV(string FileName,SLine &Lines[])
{
ResetLastError();
int h=FileOpen(FileName,FILE_READ|FILE_ANSI|FILE_CSV|FILE_COMMON,";");
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if(h==INVALID_HANDLE)
{
int ErrNum=GetLastError();
printf("Error opening file %s # %i",FileName,ErrNum);
return(false);
}
int lcnt=0; // variable for calculating lines
int fcnt=0; // variable for calculating line fields
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
while(!FileIsEnding(h))
{
string str=FileReadString(h);
// new line (new element of the structure array)
if(lcnt>=ArraySize(Lines))
{ // structure array completely filled
ArrayResize(Lines,ArraySize(Lines)+1024); // increase the array size by 1024 elements
}
ArrayResize(Lines[lcnt].field,64);// change the array size in the structure
Lines[lcnt].field[0]=str; // assign the first field value
// start reading other fields in the line
fcnt=1; // till one element in the line array is occupied
while(!FileIsLineEnding(h))
{ // read the rest of fields in the line
str=FileReadString(h);
if(fcnt>=ArraySize(Lines[lcnt].field))
{ // field array is completely filled
ArrayResize(Lines[lcnt].field,ArraySize(Lines[lcnt].field)+64); // increase the array size by 64 elements
}
Lines[lcnt].field[fcnt]=str; // assign the value of the next field
fcnt++; // increase the line counter
}
ArrayResize(Lines[lcnt].field,fcnt); // change the size of the field array according to the actual number of fields
lcnt++; // increase the line counter
}
ArrayResize(Lines,lcnt); // change the array of structures (lines) according to the actual number of lines
FileClose(h);
return(true);
}
//+------------------------------------------------------------------+
//| Função checar nova barra |
//+------------------------------------------------------------------+
bool isNewBar(void)
{
//--- memorize the time of opening of the last bar in the static variable
static datetime last_time=0;
//--- current time
datetime lastbar_time=(datetime)SeriesInfoInteger(Symbol(),PERIOD_M1,SERIES_LASTBAR_DATE);
//--- if it is the first call of the function
if(last_time==0)
{
//--- set the time and exit
last_time=lastbar_time;
return(false);
}
//--- if the time differs
if(last_time!=lastbar_time)
{
//--- memorize the time and return true
last_time=lastbar_time;
return(true);
}
//--- if we passed to this line, then the bar is not new; return false
return(false);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| entrada em operação |
//+------------------------------------------------------------------+
void fAbrirOp(int i)
{
if(inicioHedge==0)inicioHedge=datetime(ar[i][xDtEnt]);
double _TP;
double _SL;
orderOkToOpen=true;
Print("iniciando ativo: ",ar[i][xAtv]);
if(!mysymbol.Name(ar[i][xAtv]))
{
Print("Erro ao selecionar ativo ",ar[i][xAtv],"; operação não será aberta.");
orderOkToOpen=false;
}
mysymbol.RefreshRates();
double spread=mysymbol.Spread();
double bid = mysymbol.Bid();
double ask = mysymbol.Ask();
double maxPrice = ask * (100 + maxPricesVariation)/100;
double minPrice = bid * (100 - maxPricesVariation)/100;
//--- tuning for 3 or 5 digits
int digits_adjust=1;
if(mysymbol.Digits()==3 || mysymbol.Digits()==5)
digits_adjust=10;
stopLossDelta = slFixo*digits_adjust;
takeProfitDelta = tpFixo*digits_adjust;
if(maxSlippage!=0) trade.SetDeviationInPoints(maxSlippage);
if(double(ar[i][xOP])<minPrice || double(ar[i][xOP])>maxPrice || double(ar[i][xSL])<minPrice || double(ar[i][xSL])>maxPrice || double(ar[i][xTP1])<minPrice || double(ar[i][xTP1])>maxPrice)
{
Print("Erro nos níveis de preço do ativo ",ar[i][xAtv],". Bid = ",bid," / Open Price: ",ar[i][xOP]," / SL: ",ar[i][xSL]," / TP: ",ar[i][xTP1]," operação não será aberta.");
orderOkToOpen=false;
}
if(orderOkToOpen)
{
trade.SetExpertMagicNumber(ulong(ar[i][xMagic]));
if(ar[i][xBuySell]=="buy")
{
_TP = tpFixo == 0 ? double(ar[i][xTP1]) : double(ar[i][xOP]) + takeProfitDelta;
_SL = slFixo == 0 ? double(ar[i][xSL]) : double(ar[i][xOP]) - stopLossDelta;
if(trade.Buy(initialVolume,ar[i][xAtv],double(ar[i][xOP]),_SL,_TP,ar[i][xCanal]))
{
ar[i][xOpened]=true;
Print("Ordem colocada, ticket: ",trade.ResultDeal());
Print("preço: ",trade.ResultPrice()," , era pra ter sido por ",ar[i][xOP]);
trade.PrintResult();
}
else
{
Print(trade.ResultRetcodeDescription());
trade.PrintRequest();
}
}
else if(ar[i][xBuySell]=="sell")
{
_TP = tpFixo == 0 ? double(ar[i][xTP1]) : double(ar[i][xOP]) - takeProfitDelta;
_SL = slFixo == 0 ? double(ar[i][xSL]) : double(ar[i][xOP]) + stopLossDelta;
if(trade.Sell(initialVolume,ar[i][xAtv],double(ar[i][xOP]),_SL,_TP,ar[i][xCanal]))
{
ar[i][xOpened]=true;
Print("Ordem colocada, ticket: ",trade.ResultDeal());
Print("preço: ",trade.ResultPrice()," , era pra ter sido por ",ar[i][xOP]);
trade.PrintResult();
}
else
{
Print(trade.ResultRetcodeDescription());
trade.PrintRequest();
}
}
}
}
//+------------------------------------------------------------------+
//| Lucro acumulado do dia |
//+------------------------------------------------------------------+
double ProfitClosedPosition()
{
int lSize;
bool magicFound;
double profit=0;
int counter=1;
HistorySelect(inicioHedge,TimeCurrent());
int deals=HistoryDealsTotal();
int colunas = ArrayRange(profitPerMagic,1);
//---
for(int i=0;i<deals;i++)
{
ulong deal_ticket=HistoryDealGetTicket(i);
string symbol= HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
double _p_profit=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
int dealType = (int)HistoryDealGetInteger(deal_ticket,DEAL_TYPE);
int dealMagic = (int)HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
string dealComment =HistoryDealGetString(deal_ticket,DEAL_COMMENT);
if(dealType!=0 && dealType!=1) continue;
lSize = ArraySize(profitPerMagic);
magicFound=false;
if(lSize==0)ArrayResize(profitPerMagic,(lSize/colunas)+1);
for(int j=0;j<(ArraySize(profitPerMagic)/colunas);j++)
{
if(profitPerMagic[j][0]==double(dealMagic))
{
profitPerMagic[j][1]+=_p_profit;
magicFound=true;
break;
}
}
if(!magicFound)
{
ArrayResize(profitPerMagic,(lSize/colunas)+1);
for(int j=(ArraySize(profitPerMagic)/colunas)-1;j>=0;j--)
{
profitPerMagic[j][0]=dealMagic;
profitPerMagic[j][1]=profit;
break;
}
}
profit+=_p_profit;
Print(counter+": Ativo: "+symbol+" R$ "+_p_profit+" do tipo "+dealType+" , magic: "+dealMagic," / ",dealComment);
counter++;
}
for(int i=0;i<(ArraySize(profitPerMagic)/colunas);i++)
{
Print(profitPerMagic[i][0], " / " ,profitPerMagic[i][1]);
}
return(profit);
}
//+------------------------------------------------------------------+
The easiest way is to use classes, each class extends CObject and you must implement Compare function.
First, create a structure of entering (in=true) and exiting (in=false):
struct SEvent
{
datetime m_time;
double m_price;
bool m_in;
void Init(const datetime time,const double price,const bool in)
{
m_time=time;
m_price=price;
m_in=in;
}
int Compare(SEvent &another)const
{
return int(m_time-another.m_time);
}
};
Next, create the class CDeal : public CObject
class CDeal : public CObject
{
static int getDir(string cmd)
{
if(cmd=="Sell")
return(-1);
if(cmd=="Buy")
return(1);
if(cmd=="Type" || cmd=="Balance")
return(0);
printf("%i %s: unknown cmd=|%s|",__LINE__,__FILE__,cmd);
return(0);
}
static string getSymbol(string line)
{
return StringSubstr(line,0,StringLen(line)-StringLen(InpReportSuffix))+InpSymbolSuffix;
}
public:
intX m_id;
int m_dir;
SEvent m_in;
SEvent m_out;
double m_lot;
string m_symbol;
double m_osl;
double m_otp;
CDeal(string line)
{
//2019.05.13 18:27:56;Sell;0.10;EURCADm#;1.51270;;;2019.05.14 13:36:47;1.51142;;;0.10;
string array[];
const ushort separator=(ushort)';';
int size=StringSplit(line,separator,array);
if(size<11)
{
printf("%i %s: size=%d str=%s",__LINE__,__FILE__,size,line);
m_dir=0;
return;
}
m_dir=getDir(array[1]);
m_lot=StringToDouble(array[2]);
m_symbol=getSymbol(array[3]);
m_in.Init(StringToTime(array[0]),StringToDouble(array[4]),true);
m_osl=StringLen(array[5])>0 ? StringToDouble(array[5]) : 0;
m_otp=StringLen(array[6])>0 ? StringToDouble(array[6]) : 0;
m_out.Init(StringToTime(array[7]),StringToDouble(array[8]),false);
}
~CDeal(){}
virtual int Compare(const CObject *node,const int mode=0) const
{
CDeal *another=(CDeal*)node;
if(mode==1)
{
return m_in.Compare(another.m_in);
}
else
{
return m_out.Compare(another.m_out);
}
}
virtual string toString()const
{
return StringFormat("%s;%d;%.2f;%s;%.5f;%.5f;%.5f;%s;%.5f;%s",TimeToString(m_in.m_time),m_dir,m_lot,m_symbol,
m_in.m_price,m_osl,m_otp,TimeToString(m_out.m_time),m_out.m_price,m_pnl.toString());
}
};
Then, load all CDeals from string into CArrayObj and list.Sort(1) in order to sort them by time of entry. Then loop, either from some static int cursor=0; that increments if TimeCurrent()>((CDeal*) list.At(cursor)).m_in.m_time of course keeping in mind that you may reach end of your list, or detach the element if same condition is true, and attach to another CArrayObj listOfOpenDeals. Do not forget to sort the list of existing open deals each time you add an element. Same way check whether it is time to close some deal from the list of open deals, and delete element after closing.
Altogether 300 lines of code.
I am currently having a strange issue of dispay.
When I am running the program by doing that : t I have this result :
result of the execution of the t.exe
which is basicly the very begining of my program :
However, when I am using the gdb like that : gdb t.exe, everything works well like that : result of the execution in debug mode
Down below is my code (sorry it's not clean :/)
#include <stdio.h>
#include <stdlib.h>
typedef int typeElem;
typedef struct aa {
typeElem v ;
struct aa * fg , * fd ; // les fils gauche et droit
} abr;
#define arbre_vide NULL
typedef abr *arbre;
typedef int boolean;
arbre consa(typeElem x, arbre fils_gauche, arbre fils_droit) {
arbre N = malloc ( sizeof( arbre ) ) ;
N->fg = fils_gauche;
N->fd = fils_droit;
N->v = x;
return N;
}
void destruct(arbre ABR) {
free(ABR);
}
arbre gauche(arbre ABR) {
return ABR->fg;
}
arbre droit(arbre ABR) {
return ABR->fd;
}
int estVideArbre(arbre ABR) {
return (ABR == NULL);
}
typeElem racine(arbre ABR){
return (ABR->v);
}
/*
void destructAbr(arbre ABR){
if(!estVideArbre(ABR)){
destructAbr(gauche(ABR));
destructAbr(droit(ABR));
}
}
*/
void infixe(arbre ABR){
if(!(ABR == NULL)){
infixe(ABR->fg);
printf("%d ", ABR->v);
infixe(ABR->fd);
}
else {
//printf("est null \n");
}
}
void prefixe(arbre ABR){
if(!estVideArbre(ABR)){
printf("%d ", ABR->v);
infixe(ABR->fg);
infixe(ABR->fd);
}
}
void postfixe(arbre ABR){
if(!estVideArbre(ABR)){
infixe(gauche(ABR));
infixe(droit(ABR));
printf("%d ", racine(ABR));
}
}
int nbrTotalNoeuds(arbre ABR) {
if(estVideArbre(ABR))
return 0;
return 1 + nbrTotalNoeuds(gauche(ABR)) + nbrTotalNoeuds(droit(ABR));
}
int nbreNoeudsDe2Fils(arbre ABR) {
if( !estVideArbre(gauche(ABR)) && !estVideArbre(droit(ABR)) ){
return 1 + nbreNoeudsDe2Fils(gauche(ABR)) + nbreNoeudsDe2Fils(droit(ABR));
}
else if (!estVideArbre(gauche(ABR)) && estVideArbre(droit(ABR)) ) {
return nbreNoeudsDe2Fils(gauche(ABR));
}
else if (estVideArbre(gauche(ABR)) && !estVideArbre(droit(ABR)) ) {
return nbreNoeudsDe2Fils(droit(ABR));
}
else {
return 0;
}
}
int nbreNoeudsDe1Fils(arbre ABR) {
if( gauche(ABR) != NULL && droit(ABR) != NULL ) {
return 0 + nbreNoeudsDe1Fils(gauche(ABR)) + nbreNoeudsDe1Fils(droit(ABR));
}
else if( gauche(ABR) != NULL && droit(ABR) == NULL ) {
return 1 + nbreNoeudsDe1Fils(gauche(ABR));
}
else if( gauche(ABR) == NULL && droit(ABR) != NULL ) {
return 1 + nbreNoeudsDe1Fils(droit(ABR));
}
else {
return 0;
}
}
/*
5
/ \
3 6
/ \ \
2 4 7
\
9
*/
int main() { //test
printf("Lancement du programme \n");
arbre rac_g = consa(2,arbre_vide,arbre_vide);
arbre rac_d = consa(4,arbre_vide,arbre_vide);
arbre rac_d_d_d = consa(9,arbre_vide,arbre_vide);
arbre rac_d_d = consa(7,arbre_vide,rac_d_d_d);
arbre fg = consa(3,rac_g,rac_d);
arbre fd = consa(6,arbre_vide,rac_d_d);
arbre sommet = consa(5,fg,fd);
printf("\nEn ordre infixe : ");
infixe(sommet);
printf("\nEn ordre prefixe : ");
prefixe(sommet);
printf("\nEn ordre postfixe : ");
postfixe(sommet);
printf("\nNombre de noeuds dans cette arbre : %d\n", nbrTotalNoeuds(sommet));
printf("Nombre de noeuds a 2 fils : %d\n", nbreNoeudsDe2Fils(sommet));
printf("Nombre de noeuds a 1 fils : %d\n", nbreNoeudsDe1Fils(sommet));
// destructAbr(sommet);
return 0;
}
This
arbre N = malloc ( sizeof( arbre ) ) ;
does not do what you expect. It allocates memory for a pointer only, not for what a pointer pointed to.
Do
arbre N = malloc(sizeof *N);
instead.
I do not understand why you define three names for more or less the same thing. My advice is to drop abr and arbre, and only use struct aa and struct aa *.
Fewer names, less confusion, fewer errors.