int main(int argc, char *argv[]) { FILE *fin; checkExit(argc != 2, "Wrong parameters.\nUsage: ssim file", NULL); fin = fopen(argv[1], "rb"); checkExit(fin == NULL, "Failed to load file", argv[1]); init(); load(fin); atexit(clean); run(); return 0; }
int main(int argc, char *argv[]) { int exit = 0; char *line; /* string to be read from input */ FILE *input; /* file input stream */ dogeFullColor(); newProcessList(); prepareSignals(); input = handleArguments(argc, argv); while(!exit) { showcwd("$"); line = readline(input); if(checkExit(line)) { exit = 1; } else { execute(line); } free(line); } destroyProcessList(); return EXIT_SUCCESS; }
void printGlobalStats(struct config* config) { pthread_mutex_lock(&stats_lock); struct timeval currentTime; gettimeofday(¤tTime, NULL); double timeDiff = currentTime.tv_sec - global_stats.last_time.tv_sec + 1e-6*(currentTime.tv_sec - global_stats.last_time.tv_sec); double rps = global_stats.requests/timeDiff; double std = getStdDev(&global_stats.response_time); double q90 = findQuantile(&global_stats.response_time, .90); double q95 = findQuantile(&global_stats.response_time, .95); double q99 = findQuantile(&global_stats.response_time, .99); //printf("%10s,%8s,%16s, %8s,%11s,%10s,%13s,%10s,%10s,%10s,%12s,%10s,%10s,%11s,%14s\n", "timeDiff", "rps", "requests", "gets", "sets", "hits", "misses", "avg_lat", "90th", "95th", "99th", "std", "min", "max", "avgGetSize"); printf("%10f, %9.1f, %10d, %10d, %10d, %10d, %10d, %10f, %10f, %10f, %10f, %10f, %10f, %10f, %10f\n", timeDiff, rps, global_stats.requests, global_stats.gets, global_stats.sets, global_stats.hits, global_stats.misses, 1000*getAvg(&global_stats.response_time), 1000*q90, 1000*q95, 1000*q99, 1000*std, 1000*global_stats.response_time.min, 1000*global_stats.response_time.max, getAvg(&global_stats.get_size)); /* printf("Outstanding requests per worker:\n"); for(i=0; i<config->n_workers; i++){ printf("%d ", config->workers[i]->n_requests); } printf("\n"); */ //Reset stats memset(&global_stats, 0, sizeof(struct memcached_stats)); global_stats.response_time.min = 1000000; global_stats.last_time = currentTime; checkExit(config); pthread_mutex_unlock(&stats_lock); }//End printGlobalStats()
int main( int argc, char* argv[] ) { //Create the game framework Initialise(SCREEN_X, SCREEN_Y, false); initGame(); do { g_iFrameCounter++; if(g_iFrameCounter > 5000) { g_iFrameCounter = 0; } ClearScreen(); updateGame(); drawGame(); if( checkExit() ) { break; } } while( FrameworkUpdate() == false ); destroyGame(); Shutdown(); return 0; }
static ssize_t DoMessageReceive ( Channel_t chid, uintptr_t * msgid, void * msgbuf, size_t msgbuf_len ) { RefPtr<Message> m; RefPtr<Channel> c = THREAD_CURRENT()->process->LookupChannel(chid); if (!c) { return -ERROR_INVALID; } int ret = c->ReceiveMessage(m, msgbuf, msgbuf_len); if (ret < 0) { *msgid = -1; } else { if (!m) { *msgid = 0; } else { *msgid = THREAD_CURRENT()->process->RegisterMessage(m); } } checkExit(ret); return ret; }
void mainWindow::makeConnections() { QObject::connect(actionAbout, SIGNAL( triggered() ), this, SLOT( show_aboutDialog() ) ); QObject::connect(actionPreferences, SIGNAL( triggered() ), this, SLOT( show_preferences() ) ); QObject::connect(actionStart, SIGNAL( triggered() ), this, SLOT( startFolding() ) ); QObject::connect(actionStop, SIGNAL( triggered() ), this, SLOT( stopFolding() ) ); QObject::connect(actionHomepage, SIGNAL( triggered() ), this, SLOT( loadHomepage() ) ); QObject::connect(actionSourceForge, SIGNAL( triggered() ), this, SLOT( loadSourceForge() ) ); QObject::connect(actionFoldingWebsite, SIGNAL( triggered() ), this, SLOT( loadFoldingWebsite() ) ); QObject::connect(actionFoldingForum, SIGNAL( triggered() ), this, SLOT( loadFoldingForum() ) ); QObject::connect(actionContact, SIGNAL( triggered() ), this, SLOT( contactAuthor() ) ); QObject::connect(actionAddClient, SIGNAL( triggered() ), this, SLOT( addClient() ) ); QObject::connect(actionRemoveClient, SIGNAL( triggered() ), this, SLOT( removeClient() ) ); QObject::connect(actionSaveConfig, SIGNAL( triggered() ), this, SLOT( saveConfig() ) ); QObject::connect(actionPersonalStats, SIGNAL( triggered() ), this, SLOT( reloadPersonalStats() ) ); QObject::connect(actionTeamStats, SIGNAL( triggered() ), this, SLOT( reloadTeamStats() ) ); QObject::connect(actionMoleculeViewer, SIGNAL( triggered() ), this, SLOT( showMolecule() ) ); QObject::connect(actionExit, SIGNAL(triggered()), this, SLOT(checkExit())); QObject::connect(clients->table, SIGNAL( cellClicked( int, int) ), this, SLOT( showInfo())); Reloader = new QTimer(this); connect(Reloader, SIGNAL(timeout()), this, SLOT(reloadClients())); Reloader->start(60000); }
static ssize_t DoMessageReceiveV ( Channel_t chid, uintptr_t * msgid, struct iovec const * user_msgv, size_t msgv_count ) { int ret; RefPtr<Message> m; RefPtr<Channel> c = THREAD_CURRENT()->process->LookupChannel(chid); TranslationTable * user_tt = TranslationTable::GetUser(); TranslationTable * kernel_tt = TranslationTable::GetKernel(); if (!c) { return -ERROR_INVALID; } size_t k_msgv_sz = sizeof(IoBuffer) * msgv_count; IoBuffer * k_msgv = (IoBuffer *)kmalloc(k_msgv_sz); if (msgv_count > 0 && !k_msgv) { ret = -ERROR_NO_MEM; goto free_buffers; } for (size_t i = 0; i < msgv_count; ++i) { if (!CopyIoVecToIoBuffer(user_tt, &user_msgv[i], kernel_tt, &k_msgv[i])) { ret = -ERROR_INVALID; goto free_buffers; } } ret = c->ReceiveMessage(m, k_msgv, msgv_count); if (ret < 0) { *msgid = -1; } else { if (!m) { *msgid = 0; } else { *msgid = THREAD_CURRENT()->process->RegisterMessage(m); } } free_buffers: if (k_msgv) { kfree(k_msgv, k_msgv_sz); } checkExit(ret); return ret; }
static ssize_t DoMessageReplyV ( uintptr_t msgid, unsigned int status, struct iovec const * user_replyv, size_t replyv_count ) { int ret; RefPtr<Message> m; IoBuffer * k_replyv = NULL; size_t k_replyv_sz; TranslationTable * user_tt; TranslationTable * kernel_tt; m = THREAD_CURRENT()->process->LookupMessage(msgid); if (!m) { ret = -ERROR_INVALID; goto free_buffers; } k_replyv_sz = sizeof(IoBuffer) * replyv_count; k_replyv = (IoBuffer *)kmalloc(k_replyv_sz); if (replyv_count > 0 && !k_replyv) { ret = -ERROR_NO_MEM; goto free_buffers; } user_tt = TranslationTable::GetUser(); kernel_tt = TranslationTable::GetKernel(); for (size_t i = 0; i < replyv_count; ++i) { if (!CopyIoVecToIoBuffer (user_tt, &user_replyv[i], kernel_tt, &k_replyv[i])) { ret = -ERROR_INVALID; goto free_buffers; } } THREAD_CURRENT()->process->UnregisterMessage(msgid); ret = m->Reply(status, k_replyv, replyv_count); free_buffers: if (k_replyv) { kfree(k_replyv, k_replyv_sz); } checkExit(ret); return ret; }
static ssize_t DoMessageSend ( Connection_t coid, void * msgbuf, size_t msgbuf_len, void * replybuf, size_t replybuf_len ) { RefPtr<Connection> c = THREAD_CURRENT()->process->LookupConnection(coid); if (!c) { return -ERROR_INVALID; } int ret = c->SendMessage(IoBuffer(msgbuf, msgbuf_len), IoBuffer(replybuf, replybuf_len)); checkExit(ret); return ret; }
static ssize_t DoMessageReply ( uintptr_t msgid, unsigned int status, void * replybuf, size_t replybuf_len ) { RefPtr<Message> m = THREAD_CURRENT()->process->LookupMessage(msgid); if (!m) { return -ERROR_INVALID; } THREAD_CURRENT()->process->UnregisterMessage(msgid); int ret = m->Reply(status, replybuf, replybuf_len); checkExit(ret); return ret; }
bool BootAnimation::movie() { ZipEntryRO desc = mZip->findEntryByName("desc.txt"); ALOGE_IF(!desc, "couldn't find desc.txt"); if (!desc) { return false; } FileMap* descMap = mZip->createEntryFileMap(desc); mZip->releaseEntry(desc); ALOGE_IF(!descMap, "descMap is null"); if (!descMap) { return false; } String8 desString((char const*)descMap->getDataPtr(), descMap->getDataLength()); descMap->release(); char const* s = desString.string(); Animation animation; // Parse the description file for (;;) { const char* endl = strstr(s, "\n"); if (!endl) break; String8 line(s, endl - s); const char* l = line.string(); int fps, width, height, count, pause; char path[ANIM_ENTRY_NAME_MAX]; char pathType; if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) { //LOGD("> w=%d, h=%d, fps=%d", width, height, fps); animation.width = width; animation.height = height; animation.fps = fps; } else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) { //LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path); Animation::Part part; part.playUntilComplete = pathType == 'c'; part.count = count; part.pause = pause; part.path = path; animation.parts.add(part); } s = ++endl; } // read all the data structures const size_t pcount = animation.parts.size(); void *cookie = NULL; if (!mZip->startIteration(&cookie)) { return false; } ZipEntryRO entry; char name[ANIM_ENTRY_NAME_MAX]; while ((entry = mZip->nextEntry(cookie)) != NULL) { const int foundEntryName = mZip->getEntryFileName(entry, name, ANIM_ENTRY_NAME_MAX); if (foundEntryName > ANIM_ENTRY_NAME_MAX || foundEntryName == -1) { ALOGE("Error fetching entry file name"); continue; } const String8 entryName(name); const String8 path(entryName.getPathDir()); const String8 leaf(entryName.getPathLeaf()); if (leaf.size() > 0) { for (size_t j=0 ; j<pcount ; j++) { if (path == animation.parts[j].path) { int method; // supports only stored png files if (mZip->getEntryInfo(entry, &method, NULL, NULL, NULL, NULL, NULL)) { if (method == ZipFileRO::kCompressStored) { FileMap* map = mZip->createEntryFileMap(entry); if (map) { Animation::Frame frame; frame.name = leaf; frame.map = map; Animation::Part& part(animation.parts.editItemAt(j)); part.frames.add(frame); } } } } } } } mZip->endIteration(cookie); // clear screen glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(mDisplay, mSurface); glBindTexture(GL_TEXTURE_2D, 0); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); const int xc = (mWidth - animation.width) / 2; const int yc = ((mHeight - animation.height) / 2); nsecs_t lastFrame = systemTime(); nsecs_t frameDuration = s2ns(1) / animation.fps; Region clearReg(Rect(mWidth, mHeight)); clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height)); for (size_t i=0 ; i<pcount ; i++) { const Animation::Part& part(animation.parts[i]); const size_t fcount = part.frames.size(); glBindTexture(GL_TEXTURE_2D, 0); for (int r=0 ; !part.count || r<part.count ; r++) { // Exit any non playuntil complete parts immediately if(exitPending() && !part.playUntilComplete) break; for (size_t j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) { const Animation::Frame& frame(part.frames[j]); nsecs_t lastFrame = systemTime(); if (r > 0) { glBindTexture(GL_TEXTURE_2D, frame.tid); } else { if (part.count != 1) { glGenTextures(1, &frame.tid); glBindTexture(GL_TEXTURE_2D, frame.tid); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } initTexture(frame); } if (!clearReg.isEmpty()) { Region::const_iterator head(clearReg.begin()); Region::const_iterator tail(clearReg.end()); glEnable(GL_SCISSOR_TEST); while (head != tail) { const Rect& r(*head++); glScissor(r.left, mHeight - r.bottom, r.width(), r.height()); glClear(GL_COLOR_BUFFER_BIT); } glDisable(GL_SCISSOR_TEST); } glDrawTexiOES(xc, yc, 0, animation.width, animation.height); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime(); nsecs_t delay = frameDuration - (now - lastFrame); //ALOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay)); lastFrame = now; if (delay > 0) { struct timespec spec; spec.tv_sec = (now + delay) / 1000000000; spec.tv_nsec = (now + delay) % 1000000000; int err; do { err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); } while (err<0 && errno == EINTR); } checkExit(); } usleep(part.pause * ns2us(frameDuration)); // For infinite parts, we've now played them at least once, so perhaps exit if(exitPending() && !part.count) break; } // free the textures for this part if (part.count != 1) { for (size_t j=0 ; j<fcount ; j++) { const Animation::Frame& frame(part.frames[j]); glDeleteTextures(1, &frame.tid); } } } return false; }
bool BootAnimation::android() { initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png"); initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png"); // clear screen glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(mDisplay, mSurface); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLint xc = (mWidth - mAndroid[0].w) / 2; const GLint yc = (mHeight - mAndroid[0].h) / 2; const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h); glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(), updateRect.height()); // Blend state glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const nsecs_t startTime = systemTime(); do { nsecs_t now = systemTime(); double time = now - startTime; float t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w; GLint offset = (1 - (t - floorf(t))) * mAndroid[1].w; GLint x = xc - offset; glDisable(GL_SCISSOR_TEST); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, mAndroid[1].name); glDrawTexiOES(x, yc, 0, mAndroid[1].w, mAndroid[1].h); glDrawTexiOES(x + mAndroid[1].w, yc, 0, mAndroid[1].w, mAndroid[1].h); glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, mAndroid[0].name); glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h); EGLBoolean res = eglSwapBuffers(mDisplay, mSurface); if (res == EGL_FALSE) break; // 12fps: don't animate too fast to preserve CPU const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now); if (sleepTime > 0) usleep(sleepTime); checkExit(); } while (!exitPending()); glDeleteTextures(1, &mAndroid[0].name); glDeleteTextures(1, &mAndroid[1].name); return false; }
FILE *handleArguments(int argc, char *argv[]) { int showVersion = 0; /* --version */ int readArgCommand = 0; /* --command or -c */ int readScript = 0; /* argc > 1 with no option */ int i; /* no arguments, only program name */ if(argc <= 1) { return stdin; } /* check for version */ for(i = 1; i < argc; i++) { if(strcmp(argv[i], "--version") == 0) { showVersion = 1; break; } } /* check for command */ for(i = 1; i < argc; i++) { if(strcmp(argv[i], "--command") == 0 || strcmp(argv[i], "-c") == 0) { readArgCommand = 1; break; } } if(showVersion) { printf("Shelldoge version %s\n", VERSION); } /* check for script */ if(!readArgCommand) { for(i = 1; i < argc; i++) { if(argv[i][0] != '-') { readScript = 1; break; } } } /* give a script file to be the input */ if(readScript) { FILE *input = fopen(argv[i], "r"); if(input != NULL) { return input; } else { fprintf(stderr, "Script ignored: Can't open file \"%s\", stdin is the input\n", argv[i]); } } /* execute arguments as commands */ if(readArgCommand) { for(i = 1; i < argc; i++) { if(argv[i][0] != '-') { if(checkExit(argv[i])) { exit(EXIT_SUCCESS); } else { execute(argv[i]); } } } } return stdin; }
int main(int argc, char **argv) { // header information std::cout << "Blackbird Bitcoin Arbitrage\nVersion 0.0.2" << std::endl; std::cout << "DISCLAIMER: USE THE SOFTWARE AT YOUR OWN RISK.\n" << std::endl; // read the config file (config.json) json_error_t error; json_t *root = json_load_file("config.json", 0, &error); if (!root) { std::cout << "ERROR: config.json incorrect (" << error.text << ")\n" << std::endl; return 1; } // get config variables int gapSec = json_integer_value(json_object_get(root, "GapSec")); unsigned debugMaxIteration = json_integer_value(json_object_get(root, "DebugMaxIteration")); bool useFullCash = json_boolean_value(json_object_get(root, "UseFullCash")); double untouchedCash = json_real_value(json_object_get(root, "UntouchedCash")); double cashForTesting = json_real_value(json_object_get(root, "CashForTesting")); if (!useFullCash && cashForTesting < 15.0) { std::cout << "ERROR: Minimum test cash is $15.00.\n" << std::endl; return 1; } // function arrays getQuoteType getQuote[] = {Bitfinex::getQuote, OkCoin::getQuote, Bitstamp::getQuote, Kraken::getQuote}; getAvailType getAvail[] = {Bitfinex::getAvail, OkCoin::getAvail, Bitstamp::getAvail, Kraken::getAvail}; sendOrderType sendOrder[] = {Bitfinex::sendOrder, OkCoin::sendOrder, Bitstamp::sendOrder}; isOrderCompleteType isOrderComplete[] = {Bitfinex::isOrderComplete, OkCoin::isOrderComplete, Bitstamp::isOrderComplete}; getActivePosType getActivePos[] = {Bitfinex::getActivePos, OkCoin::getActivePos, Bitstamp::getActivePos, Kraken::getActivePos}; getLimitPriceType getLimitPrice[] = {Bitfinex::getLimitPrice, OkCoin::getLimitPrice, Bitstamp::getLimitPrice, Kraken::getLimitPrice}; // thousand separator std::locale mylocale(""); std::cout.imbue(mylocale); // print precision of two digits std::cout.precision(2); std::cout << std::fixed; // create a parameters structure Parameters params(root); params.addExchange("Bitfinex", 0.0020, true); params.addExchange("OKCoin", 0.0020, false); params.addExchange("Bitstamp", 0.0025, false); params.addExchange("Kraken", 0.0025, true); // CSV file std::string csvFileName; csvFileName = "result_" + printDateTimeFileName() + ".csv"; std::ofstream csvFile; csvFile.open(csvFileName.c_str(), std::ofstream::trunc); // CSV header csvFile << "TRADE_ID,EXCHANGE_LONG,EXHANGE_SHORT,ENTRY_TIME,EXIT_TIME,DURATION,TOTAL_EXPOSURE,BALANCE_BEFORE,BALANCE_AFTER,RETURN\n"; csvFile.flush(); // time structure time_t rawtime; rawtime = time(NULL); struct tm * timeinfo; timeinfo = localtime(&rawtime); bool inMarket = false; int resultId = 0; Result res; res.clear(); // Vector of Bitcoin std::vector<Bitcoin*> btcVec; // create Bitcoin objects for (unsigned i = 0; i < params.nbExch(); ++i) { btcVec.push_back(new Bitcoin(i, params.exchName[i], params.fees[i], params.hasShort[i])); } // cURL CURL* curl; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); std::cout << "[ Targets ]" << std::endl; std::cout << " Spread to enter: " << params.spreadEntry * 100.0 << "%" << std::endl; std::cout << " Spread to exit: " << params.spreadExit * 100.0 << "%" << std::endl; std::cout << std::endl; // store current balances std::cout << "[ Current balances ]" << std::endl; std::vector<double> balanceUsd; std::vector<double> balanceBtc; for (unsigned i = 0; i < params.nbExch(); ++i) { balanceUsd.push_back(getAvail[i](curl, params, "usd")); balanceBtc.push_back(getAvail[i](curl, params, "btc")); } // vectors that contains balances after a completed trade std::vector<double> newBalUsd(params.nbExch(), 0.0); std::vector<double> newBalBtc(params.nbExch(), 0.0); for (unsigned i = 0; i < params.nbExch(); ++i) { std::cout << " " << params.exchName[i] << ":\t"; std::cout << balanceUsd[i] << " USD\t" << std::setprecision(6) << balanceBtc[i] << std::setprecision(2) << " BTC" << std::endl; } std::cout << std::endl; std::cout << "[ Cash exposure ]" << std::endl; if (useFullCash) { std::cout << " FULL cash used!" << std::endl; } else { std::cout << " TEST cash used\n Value: $" << cashForTesting << std::endl; } std::cout << std::endl; // wait the next gapSec seconds before starting time(&rawtime); timeinfo = localtime(&rawtime); while ((int)timeinfo->tm_sec % gapSec != 0) { sleep(0.01); time(&rawtime); timeinfo = localtime(&rawtime); } // main loop if (!params.verbose) { std::cout << "Running..." << std::endl; } unsigned currIteration = 0; bool stillRunning = true; while (stillRunning) { time_t currTime = mktime(timeinfo); time(&rawtime); // check if we are already too late if (difftime(rawtime, currTime) > 0) { std::cout << "WARNING: " << difftime(rawtime, currTime) << " second(s) too late at " << printDateTime(currTime) << std::endl; unsigned skip = (unsigned)ceil(difftime(rawtime, currTime) / gapSec); for (unsigned i = 0; i < skip; ++i) { // std::cout << " Skipped iteration " << printDateTime(currTime) << std::endl; for (unsigned e = 0; e < params.nbExch(); ++e) { btcVec[e]->addData(currTime, btcVec[e]->getLastBid(), btcVec[e]->getLastAsk(), 0.0); } // go to next iteration timeinfo->tm_sec = timeinfo->tm_sec + gapSec; currTime = mktime(timeinfo); } std::cout << std::endl; } // wait for the next iteration while (difftime(rawtime, currTime) != 0) { sleep(0.01); time(&rawtime); } if (params.verbose) { if (!inMarket) { std::cout << "[ " << printDateTime(currTime) << " ]" << std::endl; } else { std::cout << "[ " << printDateTime(currTime) << " IN MARKET: Long " << res.exchNameLong << " / Short " << res.exchNameShort << " ]" << std::endl; } } // download the exchanges prices for (unsigned e = 0; e < params.nbExch(); ++e) { double bid = getQuote[e](curl, true); double ask = getQuote[e](curl, false); // add previous price if bid or ask is 0.0 if (bid == 0.0) { bid = btcVec[e]->getLastBid(); std::cout << " WARNING: " << params.exchName[e] << " bid is null, use previous one" << std::endl; } if (ask == 0.0) { ask = btcVec[e]->getLastAsk(); std::cout << " WARNING: " << params.exchName[e] << " ask is null, use previous one" << std::endl; } if (params.verbose) { std::cout << " " << params.exchName[e] << ": \t" << bid << " / " << ask << std::endl; } btcVec[e]->addData(currTime, bid, ask, 0.0); curl_easy_reset(curl); } // load data terminated if (params.verbose) { std::cout << " ----------------------------" << std::endl; } // compute entry point if (!inMarket) { for (unsigned i = 0; i < params.nbExch(); ++i) { for (unsigned j = 0; j < params.nbExch(); ++j) { if (i != j) { if (checkEntry(btcVec[i], btcVec[j], res, params)) { // entry opportunity found // compute exposure res.exposure = std::min(balanceUsd[res.idExchLong], balanceUsd[res.idExchShort]); if (res.exposure == 0.0) { std::cout << " WARNING: Opportunity found but no cash available. Trade canceled." << std::endl; break; } if (useFullCash == false && res.exposure <= cashForTesting) { std::cout << " WARNING: Opportunity found but no enough cash. Need more than TEST cash (min. $" << cashForTesting << "). Trade canceled." << std::endl; break; } if (useFullCash) { // leave untouchedCash res.exposure -= untouchedCash * res.exposure; } else { // use test money res.exposure = cashForTesting; } // check volumes double volumeLong = res.exposure / btcVec[res.idExchLong]->getLastAsk(); double volumeShort = res.exposure / btcVec[res.idExchShort]->getLastBid(); double limPriceLong = getLimitPrice[res.idExchLong](curl, volumeLong, false); double limPriceShort = getLimitPrice[res.idExchShort](curl, volumeShort, true); if (limPriceLong - res.priceLongIn > 0.30 || res.priceShortIn - limPriceShort > 0.30) { std::cout << " WARNING: Opportunity found but not enough volume. Trade canceled." << std::endl; break; } inMarket = true; resultId++; // update result res.id = resultId; res.entryTime = currTime; res.printEntry(); res.maxSpread[res.idExchLong][res.idExchShort] = -1.0; res.minSpread[res.idExchLong][res.idExchShort] = 1.0; int longOrderId = 0; int shortOrderId = 0; // send Long order longOrderId = sendOrder[res.idExchLong](curl, params, "buy", volumeLong, btcVec[res.idExchLong]->getLastAsk()); // send Short order shortOrderId = sendOrder[res.idExchShort](curl, params, "sell", volumeShort, btcVec[res.idExchShort]->getLastBid()); // wait for the orders to be filled sleep(3.0); std::cout << "Waiting for the two orders to be filled..." << std::endl; while (!isOrderComplete[res.idExchLong](curl, params, longOrderId) || !isOrderComplete[res.idExchShort](curl, params, shortOrderId)) { sleep(3.0); } std::cout << "Done" << std::endl; longOrderId = 0; shortOrderId = 0; break; } } } if (inMarket) { break; } } if (params.verbose) { std::cout << std::endl; } } // in market, looking to exit else if (inMarket) { if (checkExit(btcVec[res.idExchLong], btcVec[res.idExchShort], res, params, currTime)) { // exit opportunity found // check current exposure std::vector<double> btcUsed; for (unsigned i = 0; i < params.nbExch(); ++i) { btcUsed.push_back(getActivePos[i](curl, params)); } // check volumes double volumeLong = btcUsed[res.idExchLong]; double volumeShort = btcUsed[res.idExchShort]; double limPriceLong = getLimitPrice[res.idExchLong](curl, volumeLong, true); double limPriceShort = getLimitPrice[res.idExchShort](curl, volumeShort, false); if (res.priceLongOut - limPriceLong > 0.30 || limPriceShort - res.priceShortOut > 0.30) { std::cout << " WARNING: Opportunity found but not enough volume. Trade canceled." << std::endl; } else { res.exitTime = currTime; res.printExit(); // send orders int longOrderId = 0; int shortOrderId = 0; std::cout << std::setprecision(6) << "BTC exposure on " << params.exchName[res.idExchLong] << ": " << volumeLong << std::setprecision(2) << std::endl; std::cout << std::setprecision(6) << "BTC exposure on " << params.exchName[res.idExchShort] << ": " << volumeShort << std::setprecision(2) << std::endl; std::cout << std::endl; // Close Long longOrderId = sendOrder[res.idExchLong](curl, params, "sell", fabs(btcUsed[res.idExchLong]), btcVec[res.idExchLong]->getLastBid()); // Close Short shortOrderId = sendOrder[res.idExchShort](curl, params, "buy", fabs(btcUsed[res.idExchShort]), btcVec[res.idExchShort]->getLastAsk()); // wait for the orders to be filled sleep(3.0); std::cout << "Waiting for the two orders to be filled..." << std::endl; while (!isOrderComplete[res.idExchLong](curl, params, longOrderId) || !isOrderComplete[res.idExchShort](curl, params, shortOrderId)) { sleep(3.0); } std::cout << "Done\n" << std::endl; longOrderId = 0; shortOrderId = 0; // market exited inMarket = false; // new balances for (unsigned i = 0; i < params.nbExch(); ++i) { newBalUsd[i] = getAvail[i](curl, params, "usd"); newBalBtc[i] = getAvail[i](curl, params, "btc"); } for (unsigned i = 0; i < params.nbExch(); ++i) { std::cout << "New balance on " << params.exchName[i] << ": \t"; std::cout << newBalUsd[i] << " USD (perf $" << newBalUsd[i] - balanceUsd[i] << "), "; std::cout << std::setprecision(6) << newBalBtc[i] << std::setprecision(2) << " BTC" << std::endl; } std::cout << std::endl; // update res with total balance res.befBalUsd = std::accumulate(balanceUsd.begin(), balanceUsd.end(), 0.0); res.aftBalUsd = std::accumulate(newBalUsd.begin(), newBalUsd.end(), 0.0); // update current balances with new values for (unsigned i = 0; i < params.nbExch(); ++i) { balanceUsd[i] = newBalUsd[i]; balanceBtc[i] = newBalBtc[i]; } // display performance std::cout << "ACTUAL PERFORMANCE: " << "$" << res.aftBalUsd - res.befBalUsd << " (" << res.totPerf() * 100.0 << "%)\n" << std::endl; // new csv line with result csvFile << res.id << "," << res.exchNameLong << "," << res.exchNameShort << "," << printDateTimeCsv(res.entryTime) << "," << printDateTimeCsv(res.exitTime); csvFile << "," << res.getLength() << "," << res.exposure * 2.0 << "," << res.befBalUsd << "," << res.aftBalUsd << "," << res.totPerf() << "\n"; csvFile.flush(); // send email if (params.sendEmail) { sendEmail(res, params); std::cout << "Email sent" << std::endl; } // delete result information res.clear(); // if "stop_after_exit" file exists then return std::ifstream infile("stop_after_exit"); if (infile.good()) { std::cout << "Exit after last trade (file stop_after_exit found)" << std::endl; stillRunning = false; } } } if (params.verbose) { std::cout << std::endl; } } // activities for this iteration terminated timeinfo->tm_sec = timeinfo->tm_sec + gapSec; currIteration++; if (currIteration >= debugMaxIteration) { std::cout << "Max iteration reached (" << debugMaxIteration << ")" <<std::endl; stillRunning = false; } } // delete Bitcoin objects for (unsigned i = 0; i < params.nbExch(); ++i) { delete(btcVec[i]); } json_decref(root); // close cURL curl_easy_cleanup(curl); curl_global_cleanup(); // close csv file csvFile.close(); return 0; }
int main(int argc, char** argv) { std::cout << "Blackbird Bitcoin Arbitrage" << std::endl; std::cout << "DISCLAIMER: USE THE SOFTWARE AT YOUR OWN RISK\n" << std::endl; std::locale mylocale(""); Parameters params("blackbird.conf"); if (!params.demoMode) { if (!params.useFullCash) { if (params.cashForTesting < 10.0) { std::cout << "WARNING: Minimum test cash recommended: $10.00\n" << std::endl; } if (params.cashForTesting > params.maxExposure) { std::cout << "ERROR: Test cash ($" << params.cashForTesting << ") is above max exposure ($" << params.maxExposure << ")\n" << std::endl; return -1; } } } getQuoteType getQuote[10]; getAvailType getAvail[10]; sendOrderType sendOrder[10]; isOrderCompleteType isOrderComplete[10]; getActivePosType getActivePos[10]; getLimitPriceType getLimitPrice[10]; int index = 0; if (params.bitfinexApi.empty() == false || params.demoMode == true) { params.addExchange("Bitfinex", params.bitfinexFees, params.bitfinexCanShort, true); getQuote[index] = Bitfinex::getQuote; getAvail[index] = Bitfinex::getAvail; sendOrder[index] = Bitfinex::sendOrder; isOrderComplete[index] = Bitfinex::isOrderComplete; getActivePos[index] = Bitfinex::getActivePos; getLimitPrice[index] = Bitfinex::getLimitPrice; index++; } if (params.okcoinApi.empty() == false || params.demoMode == true) { params.addExchange("OKCoin", params.okcoinFees, params.okcoinCanShort, true); getQuote[index] = OkCoin::getQuote; getAvail[index] = OkCoin::getAvail; sendOrder[index] = OkCoin::sendOrder; isOrderComplete[index] = OkCoin::isOrderComplete; getActivePos[index] = OkCoin::getActivePos; getLimitPrice[index] = OkCoin::getLimitPrice; index++; } if (params.bitstampClientId.empty() == false || params.demoMode == true) { params.addExchange("Bitstamp", params.bitstampFees, params.bitstampCanShort, true); getQuote[index] = Bitstamp::getQuote; getAvail[index] = Bitstamp::getAvail; sendOrder[index] = Bitstamp::sendOrder; isOrderComplete[index] = Bitstamp::isOrderComplete; getActivePos[index] = Bitstamp::getActivePos; getLimitPrice[index] = Bitstamp::getLimitPrice; index++; } if (params.geminiApi.empty() == false || params.demoMode == true) { params.addExchange("Gemini", params.geminiFees, params.geminiCanShort, true); getQuote[index] = Gemini::getQuote; getAvail[index] = Gemini::getAvail; sendOrder[index] = Gemini::sendOrder; isOrderComplete[index] = Gemini::isOrderComplete; getActivePos[index] = Gemini::getActivePos; getLimitPrice[index] = Gemini::getLimitPrice; index++; } if (params.krakenApi.empty() == false || params.demoMode == true) { params.addExchange("Kraken", params.krakenFees, params.krakenCanShort, true); getQuote[index] = Kraken::getQuote; getAvail[index] = Kraken::getAvail; sendOrder[index] = Kraken::sendOrder; isOrderComplete[index] = Kraken::isOrderComplete; getActivePos[index] = Kraken::getActivePos; getLimitPrice[index] = Kraken::getLimitPrice; index++; } if (params.itbitApi.empty() == false || params.demoMode == true) { params.addExchange("ItBit", params.itbitFees, params.itbitCanShort, false); getQuote[index] = ItBit::getQuote; getAvail[index] = ItBit::getAvail; // sendOrder[index] = ItBit::sendOrder; // isOrderComplete[index] = ItBit::isOrderComplete; getActivePos[index] = ItBit::getActivePos; getLimitPrice[index] = ItBit::getLimitPrice; index++; } if (params.btceApi.empty() == false || params.demoMode == true) { params.addExchange("BTC-e", params.btceFees, params.btceCanShort, false); getQuote[index] = BTCe::getQuote; getAvail[index] = BTCe::getAvail; // sendOrder[index] = BTCe::sendOrder; // isOrderComplete[index] = BTCe::isOrderComplete; getActivePos[index] = BTCe::getActivePos; getLimitPrice[index] = BTCe::getLimitPrice; index++; } if (params.sevennintysixApi.empty() == false || params.demoMode == true) { params.addExchange("796.com", params.sevennintysixFees, params.sevennintysixCanShort, true); getQuote[index] = SevenNintySix::getQuote; getAvail[index] = SevenNintySix::getAvail; sendOrder[index] = SevenNintySix::sendOrder; isOrderComplete[index] = SevenNintySix::isOrderComplete; getActivePos[index] = SevenNintySix::getActivePos; getLimitPrice[index] = SevenNintySix::getLimitPrice; index++; } if (index < 2) { std::cout << "ERROR: Blackbird needs at least two Bitcoin exchanges. Please edit the config.json file to add new exchanges\n" << std::endl; return -1; } std::string currDateTime = printDateTimeFileName(); std::string csvFileName = "blackbird_result_" + currDateTime + ".csv"; std::ofstream csvFile; csvFile.open(csvFileName.c_str(), std::ofstream::trunc); csvFile << "TRADE_ID,EXCHANGE_LONG,EXHANGE_SHORT,ENTRY_TIME,EXIT_TIME,DURATION,TOTAL_EXPOSURE,BALANCE_BEFORE,BALANCE_AFTER,RETURN\n"; csvFile.flush(); std::string logFileName = "blackbird_log_" + currDateTime + ".log"; std::ofstream logFile; logFile.open(logFileName.c_str(), std::ofstream::trunc); logFile.imbue(mylocale); logFile.precision(2); logFile << std::fixed; params.logFile = &logFile; logFile << "--------------------------------------------" << std::endl; logFile << "| Blackbird Bitcoin Arbitrage Log File |" << std::endl; logFile << "--------------------------------------------\n" << std::endl; logFile << "Blackbird started on " << printDateTime() << "\n" << std::endl; if (params.demoMode) { logFile << "Demo mode: trades won't be generated\n" << std::endl; } std::cout << "Log file generated: " << logFileName << "\nBlackbird is running... (pid " << getpid() << ")\n" << std::endl; // Vector of Bitcoin objects std::vector<Bitcoin*> btcVec; int num_exchange = params.nbExch(); // create Bitcoin objects for (int i = 0; i < num_exchange; ++i) { btcVec.push_back(new Bitcoin(i, params.exchName[i], params.fees[i], params.canShort[i], params.isImplemented[i])); } curl_global_init(CURL_GLOBAL_ALL); params.curl = curl_easy_init(); logFile << "[ Targets ]" << std::endl; logFile << " Spread Entry: " << params.spreadEntry * 100.0 << "%" << std::endl; logFile << " Spread Target: " << params.spreadTarget * 100.0 << "%" << std::endl; if (params.spreadEntry <= 0.0) { logFile << " WARNING: Spread Entry should be positive" << std::endl; } if (params.spreadTarget <= 0.0) { logFile << " WARNING: Spread Target should be positive" << std::endl; } logFile << std::endl; // store current balances logFile << "[ Current balances ]" << std::endl; double* balanceUsd = (double*)malloc(sizeof(double) * num_exchange); double* balanceBtc = (double*)malloc(sizeof(double) * num_exchange); for (int i = 0; i < num_exchange; ++i) { if (params.demoMode) { balanceUsd[i] = 0.0; balanceBtc[i] = 0.0; } else { balanceUsd[i] = getAvail[i](params, "usd"); balanceBtc[i] = getAvail[i](params, "btc"); } } // contains balances after a completed trade double* newBalUsd = (double*)malloc(sizeof(double) * num_exchange); double* newBalBtc = (double*)malloc(sizeof(double) * num_exchange); memset(newBalUsd, 0.0, sizeof(double) * num_exchange); memset(newBalBtc, 0.0, sizeof(double) * num_exchange); for (int i = 0; i < num_exchange; ++i) { logFile << " " << params.exchName[i] << ":\t"; logFile << balanceUsd[i] << " USD\t" << std::setprecision(6) << balanceBtc[i] << std::setprecision(2) << " BTC" << std::endl; if (balanceBtc[i] > 0.0300) { logFile << "ERROR: All BTC accounts must be empty before starting Blackbird" << std::endl; return -1; } } logFile << std::endl; logFile << "[ Cash exposure ]" << std::endl; if (params.demoMode) { logFile << " No cash - Demo mode" << std::endl; } else { if (params.useFullCash) { logFile << " FULL cash used!" << std::endl; } else { logFile << " TEST cash used\n Value: $" << params.cashForTesting << std::endl; } } logFile << std::endl; time_t rawtime; rawtime = time(NULL); struct tm* timeinfo; timeinfo = localtime(&rawtime); // wait the next gapSec seconds before starting time(&rawtime); timeinfo = localtime(&rawtime); while ((int)timeinfo->tm_sec % params.gapSec != 0) { sleep(0.01); time(&rawtime); timeinfo = localtime(&rawtime); } // main loop if (!params.verbose) { logFile << "Running..." << std::endl; } bool inMarket = false; int resultId = 0; Result res; res.clear(); unsigned currIteration = 0; bool stillRunning = true; time_t currTime; time_t diffTime; while (stillRunning) { currTime = mktime(timeinfo); time(&rawtime); diffTime = difftime(rawtime, currTime); // check if we are already too late if (diffTime > 0) { logFile << "WARNING: " << diffTime << " second(s) too late at " << printDateTime(currTime) << std::endl; // unsigned skip = (unsigned)ceil(diffTime / gapSec); // go to next iteration timeinfo->tm_sec = timeinfo->tm_sec + (ceil(diffTime / params.gapSec) + 1) * params.gapSec; currTime = mktime(timeinfo); sleep(params.gapSec - (diffTime % params.gapSec)); logFile << std::endl; } else if (diffTime < 0) { sleep(-difftime(rawtime, currTime)); // sleep until the next iteration } if (params.verbose) { if (!inMarket) { logFile << "[ " << printDateTime(currTime) << " ]" << std::endl; } else { logFile << "[ " << printDateTime(currTime) << " IN MARKET: Long " << res.exchNameLong << " / Short " << res.exchNameShort << " ]" << std::endl; } } for (int e = 0; e < num_exchange; ++e) { double bid = getQuote[e](params, true); double ask = getQuote[e](params, false); if (bid == 0.0) { logFile << " WARNING: " << params.exchName[e] << " bid is null, use previous one" << std::endl; } if (ask == 0.0) { logFile << " WARNING: " << params.exchName[e] << " ask is null, use previous one" << std::endl; } if (params.verbose) { logFile << " " << params.exchName[e] << ": \t" << bid << " / " << ask << std::endl; } btcVec[e]->updateData(bid, ask, 0.0); curl_easy_reset(params.curl); } if (params.verbose) { logFile << " ----------------------------" << std::endl; } // compute entry point if (!inMarket) { for (int i = 0; i < num_exchange; ++i) { for (int j = 0; j < num_exchange; ++j) { if (i != j) { if (checkEntry(btcVec[i], btcVec[j], res, params)) { // entry opportunity found res.exposure = std::min(balanceUsd[res.idExchLong], balanceUsd[res.idExchShort]); if (params.demoMode) { logFile << "INFO: Opportunity found but no trade will be generated (Demo mode)" << std::endl; break; } if (res.exposure == 0.0) { logFile << "WARNING: Opportunity found but no cash available. Trade canceled" << std::endl; break; } if (params.useFullCash == false && res.exposure <= params.cashForTesting) { logFile << "WARNING: Opportunity found but no enough cash. Need more than TEST cash (min. $" << params.cashForTesting << "). Trade canceled" << std::endl; break; } if (params.useFullCash) { res.exposure -= params.untouchedCash * res.exposure; // leave untouchedCash if (res.exposure > params.maxExposure) { logFile << "WARNING: Opportunity found but exposure ($" << res.exposure << ") above the limit" << std::endl; logFile << " Max exposure will be used instead ($" << params.maxExposure << ")" << std::endl; res.exposure = params.maxExposure; } } else { res.exposure = params.cashForTesting; // use test money } double volumeLong = res.exposure / btcVec[res.idExchLong]->getAsk(); double volumeShort = res.exposure / btcVec[res.idExchShort]->getBid(); double limPriceLong = getLimitPrice[res.idExchLong](params, volumeLong, false); double limPriceShort = getLimitPrice[res.idExchShort](params, volumeShort, true); if (limPriceLong - res.priceLongIn > params.priceDeltaLim || res.priceShortIn - limPriceShort > params.priceDeltaLim) { logFile << "WARNING: Opportunity found but not enough liquidity. Trade canceled" << std::endl; logFile << " Target long price: " << res.priceLongIn << ", Real long price: " << limPriceLong << std::endl; logFile << " Target short price: " << res.priceShortIn << ", Real short price: " << limPriceShort << std::endl; res.trailing[res.idExchLong][res.idExchShort] = -1.0; break; } inMarket = true; resultId++; // update result res.id = resultId; res.entryTime = currTime; res.printEntry(*params.logFile); res.maxSpread[res.idExchLong][res.idExchShort] = -1.0; res.minSpread[res.idExchLong][res.idExchShort] = 1.0; res.trailing[res.idExchLong][res.idExchShort] = 1.0; int longOrderId = 0; int shortOrderId = 0; // send orders longOrderId = sendOrder[res.idExchLong](params, "buy", volumeLong, btcVec[res.idExchLong]->getAsk()); shortOrderId = sendOrder[res.idExchShort](params, "sell", volumeShort, btcVec[res.idExchShort]->getBid()); // wait for the orders to be filled logFile << "Waiting for the two orders to be filled..." << std::endl; sleep(3.0); while (!isOrderComplete[res.idExchLong](params, longOrderId) || !isOrderComplete[res.idExchShort](params, shortOrderId)) { sleep(3.0); } logFile << "Done" << std::endl; longOrderId = 0; shortOrderId = 0; break; } } } if (inMarket) { break; } } if (params.verbose) { logFile << std::endl; } } // in market, looking to exit else if (inMarket) { if (checkExit(btcVec[res.idExchLong], btcVec[res.idExchShort], res, params, currTime)) { // exit opportunity found // check current exposure double* btcUsed = (double*)malloc(sizeof(double) * num_exchange); for (int i = 0; i < num_exchange; ++i) { btcUsed[i] = getActivePos[i](params); } double volumeLong = btcUsed[res.idExchLong]; double volumeShort = btcUsed[res.idExchShort]; double limPriceLong = getLimitPrice[res.idExchLong](params, volumeLong, true); double limPriceShort = getLimitPrice[res.idExchShort](params, volumeShort, false); if (res.priceLongOut - limPriceLong > params.priceDeltaLim || limPriceShort - res.priceShortOut > params.priceDeltaLim) { logFile << "WARNING: Opportunity found but not enough liquidity. Trade canceled" << std::endl; logFile << " Target long price: " << res.priceLongOut << ", Real long price: " << limPriceLong << std::endl; logFile << " Target short price: " << res.priceShortOut << ", Real short price: " << limPriceShort << std::endl; res.trailing[res.idExchLong][res.idExchShort] = 1.0; } else { res.exitTime = currTime; res.printExit(*params.logFile); int longOrderId = 0; int shortOrderId = 0; logFile << std::setprecision(6) << "BTC exposure on " << params.exchName[res.idExchLong] << ": " << volumeLong << std::setprecision(2) << std::endl; logFile << std::setprecision(6) << "BTC exposure on " << params.exchName[res.idExchShort] << ": " << volumeShort << std::setprecision(2) << std::endl; logFile << std::endl; // send orders longOrderId = sendOrder[res.idExchLong](params, "sell", fabs(btcUsed[res.idExchLong]), btcVec[res.idExchLong]->getBid()); shortOrderId = sendOrder[res.idExchShort](params, "buy", fabs(btcUsed[res.idExchShort]), btcVec[res.idExchShort]->getAsk()); // wait for the orders to be filled logFile << "Waiting for the two orders to be filled..." << std::endl; sleep(3.0); while (!isOrderComplete[res.idExchLong](params, longOrderId) || !isOrderComplete[res.idExchShort](params, shortOrderId)) { sleep(3.0); } logFile << "Done\n" << std::endl; longOrderId = 0; shortOrderId = 0; inMarket = false; // new balances for (int i = 0; i < num_exchange; ++i) { newBalUsd[i] = getAvail[i](params, "usd"); newBalBtc[i] = getAvail[i](params, "btc"); } for (int i = 0; i < num_exchange; ++i) { logFile << "New balance on " << params.exchName[i] << ": \t"; logFile << newBalUsd[i] << " USD (perf $" << newBalUsd[i] - balanceUsd[i] << "), "; logFile << std::setprecision(6) << newBalBtc[i] << std::setprecision(2) << " BTC" << std::endl; } logFile << std::endl; // update res with total balance for (int i = 0; i < num_exchange; ++i) { res.befBalUsd += balanceUsd[i]; res.aftBalUsd += newBalUsd[i]; } // update current balances with new values for (int i = 0; i < num_exchange; ++i) { balanceUsd[i] = newBalUsd[i]; balanceBtc[i] = newBalBtc[i]; } logFile << "ACTUAL PERFORMANCE: " << "$" << res.aftBalUsd - res.befBalUsd << " (" << res.totPerf() * 100.0 << "%)\n" << std::endl; csvFile << res.id << "," << res.exchNameLong << "," << res.exchNameShort << "," << printDateTimeCsv(res.entryTime) << "," << printDateTimeCsv(res.exitTime); csvFile << "," << res.getLength() << "," << res.exposure * 2.0 << "," << res.befBalUsd << "," << res.aftBalUsd << "," << res.totPerf() << "\n"; csvFile.flush(); if (params.sendEmail) { sendEmail(res, params); logFile << "Email sent" << std::endl; } res.clear(); std::ifstream infile("stop_after_exit"); if (infile.good()) { logFile << "Exit after last trade (file stop_after_exit found)" << std::endl; stillRunning = false; } } } if (params.verbose) { logFile << std::endl; } } timeinfo->tm_sec = timeinfo->tm_sec + params.gapSec; currIteration++; if (currIteration >= params.debugMaxIteration) { logFile << "Max iteration reached (" << params.debugMaxIteration << ")" <<std::endl; stillRunning = false; } } for (int i = 0; i < num_exchange; ++i) { delete(btcVec[i]); } curl_easy_cleanup(params.curl); curl_global_cleanup(); csvFile.close(); logFile.close(); return 0; }
static ssize_t DoMessageSendV ( Connection_t coid, struct iovec const * user_msgv, size_t msgv_count, struct iovec const * user_replyv, size_t replyv_count ) { int ret; TranslationTable * user_tt; TranslationTable * kernel_tt; RefPtr<Connection> c = THREAD_CURRENT()->process->LookupConnection(coid); if (!c) { return -ERROR_INVALID; } size_t k_msgv_sz = sizeof(IoBuffer) * msgv_count; size_t k_replyv_sz = sizeof(IoBuffer) * replyv_count; IoBuffer * k_msgv = (IoBuffer *)kmalloc(k_msgv_sz); IoBuffer * k_replyv = (IoBuffer *)kmalloc(k_replyv_sz); if ((msgv_count > 0 && !k_msgv) || (replyv_count > 0 && !k_replyv)) { ret = -ERROR_NO_MEM; goto free_bufs; } user_tt = TranslationTable::GetUser(); kernel_tt = TranslationTable::GetKernel(); for (size_t i = 0; i < msgv_count; ++i) { if (!CopyIoVecToIoBuffer(user_tt, &user_msgv[i], kernel_tt, &k_msgv[i])) { ret = -ERROR_INVALID; goto free_bufs; } } for (size_t i = 0; i < replyv_count; ++i) { if (!CopyIoVecToIoBuffer(user_tt, &user_replyv[i], kernel_tt, &k_replyv[i])) { ret = -ERROR_INVALID; goto free_bufs; } } ret = c->SendMessage(k_msgv, msgv_count, k_replyv, replyv_count); free_bufs: if (k_msgv) kfree(k_msgv, k_msgv_sz); if (k_replyv) kfree(k_replyv, k_replyv_sz); checkExit(ret); return ret; }
double tradeSystem(char* szName, int iYear, int iEntryWindow, int iTrailStopWindow, int iStopLossWindow, char* szEntryDate, char* szNoEntryDate, char* szExitDate) { double* adOpen; double* adClose; double* adLow; double* adHigh; char** aszDates; int iSize; double* adEntryChannel; double* adTrailStopChannel; double* adStopLossChannel; commod comCommodity; int iError; int iExit; int t; int i; int fStartDayOn = 0; //we aren't on at the start of the day yet double dEntryPoints = 0; double dExitPoints = 0; double dStopLoss; double dProfit; //set commodity values comCommodity.szName = szName; comCommodity.iYear = iYear; iError = lookupTypeTick(&comCommodity); if(iError == ERRVAL) { FPRINTE(stderr, "lookupTypeTick failed\n"); return iError; } //get trade data iError = generateTradeData(comCommodity, &adLow, &adHigh, &adOpen, &adClose, &aszDates, &iSize); if(iError == ERRVAL) { FPRINTE(stderr, "generateTradeData failed\n"); return iError; } //get channels iError = generateChannels(comCommodity, adLow, adHigh, iEntryWindow, iTrailStopWindow, iStopLossWindow, iSize, &adEntryChannel, &adTrailStopChannel, &adStopLossChannel); if(iError == ERRVAL) { FPRINTE(stderr, "generatechannels failed\n"); goto exit2; } //calculate the start day t = computeStartDay(iEntryWindow, iTrailStopWindow, iStopLossWindow); while(t < iSize) { //check for NA values iError = checkForNAValues(t, adEntryChannel, adTrailStopChannel, adStopLossChannel); if(iError == ERRVAL) { FPRINTE(stderr, "checkForNAValues failed\n"); goto exit; } //if we haven't entered if(!fStartDayOn) { //check if we should enter if(checkEnter(comCommodity.iType, adEntryChannel[t-1], adLow[t], adHigh[t], szEntryDate, szNoEntryDate, aszDates[t])) { //set flag to on, compute entry price and stop loss fStartDayOn = 1; dEntryPoints += computeEntryPoints(comCommodity.iType, comCommodity.dTickSize, adEntryChannel[t-1], adOpen[t]); dStopLoss = adStopLossChannel[t-1]; } //if we didn't enter else { //set done flag, if past entry window if(inEntryWindow(szEntryDate, szNoEntryDate, aszDates[t]) > 0) { break; } } } //if we have entered else { iExit = checkExit(comCommodity.iType, dStopLoss, adTrailStopChannel[t-1], adLow[t], adHigh[t], szExitDate, aszDates[t], dEntryPoints); //check if we should exit if(iExit) { //set flag to off, compute exit price fStartDayOn = 0; dExitPoints += computeExitPoints(comCommodity.iType, comCommodity.dTickSize, dStopLoss, adTrailStopChannel[t-1], adOpen[t], adClose[t], iExit); //set done flag, if past entry window if(inEntryWindow(szEntryDate, szNoEntryDate, aszDates[t]) > 0) { break; } } } t++; } //compute profit! dProfit = computeProfit(comCommodity.iType, dEntryPoints, dExitPoints, comCommodity.dTickVal, comCommodity.dTickSize); exit: free(adEntryChannel); free(adTrailStopChannel); free(adStopLossChannel); exit2: for (i = 0; i < iSize; i++) { if(aszDates[i] != NULL) free(aszDates[i]); } free(adOpen); free(adClose); free(adLow); free(adHigh); free(aszDates); return iError == ERRVAL ? -1.0 : dProfit; }
bool BootAnimation::movie() { char bootenabled[PROPERTY_VALUE_MAX]; char bootsound[PROPERTY_VALUE_MAX]; char bootvolume[PROPERTY_VALUE_MAX]; property_get("persist.sys.boot_enabled", bootenabled, "1"); property_get("persist.sys.boot_sound", bootsound, "1"); property_get("persist.sys.boot_volume", bootvolume, "0.2"); bool bootEnabled = atoi(bootenabled) != 0; bool enableSound = atoi(bootsound) != 0; float bootVolume = strtof(bootvolume, NULL); if(!bootEnabled) { return false; } if(enableSound){ sp<MediaPlayer> mediaplay = new MediaPlayer(); mediaplay->setDataSource ("/system/media/audio.mp3", NULL); mediaplay->setVolume (bootVolume, bootVolume); mediaplay->prepare(); mediaplay->start(); } ZipFileRO& zip(mZip); size_t numEntries = zip.getNumEntries(); ZipEntryRO desc = zip.findEntryByName("desc.txt"); FileMap* descMap = zip.createEntryFileMap(desc); ALOGE_IF(!descMap, "descMap is null"); if (!descMap) { return false; } String8 desString((char const*)descMap->getDataPtr(), descMap->getDataLength()); char const* s = desString.string(); Animation animation; float r = 0.0f; float g = 0.0f; float b = 0.0f; // Parse the description file for (;;) { const char* endl = strstr(s, "\n"); if (!endl) break; String8 line(s, endl - s); const char* l = line.string(); int fps, width, height, count, pause, red, green, blue; char path[256]; char pathType; if (sscanf(l, "%d %d %d %d %d %d", &width, &height, &fps, &red, &green, &blue) == 6) { //ALOGD("> w=%d, h=%d, fps=%d, rgb=(%d, %d, %d)", width, height, fps, red, green, blue); animation.width = width; animation.height = height; animation.fps = fps; r = (float) red / 255.0f; g = (float) green / 255.0f; b = (float) blue / 255.0f; } else if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) { //LOGD("> w=%d, h=%d, fps=%d", width, height, fps); animation.width = width; animation.height = height; animation.fps = fps; } else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) { //LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path); Animation::Part part; part.playUntilComplete = pathType == 'c'; part.count = count; part.pause = pause; part.path = path; animation.parts.add(part); } s = ++endl; } // read all the data structures const size_t pcount = animation.parts.size(); for (size_t i=0 ; i<numEntries ; i++) { char name[256]; ZipEntryRO entry = zip.findEntryByIndex(i); if (zip.getEntryFileName(entry, name, 256) == 0) { const String8 entryName(name); const String8 path(entryName.getPathDir()); const String8 leaf(entryName.getPathLeaf()); if (leaf.size() > 0) { for (size_t j=0 ; j<pcount ; j++) { if (path == animation.parts[j].path) { int method; // supports only stored png files if (zip.getEntryInfo(entry, &method, 0, 0, 0, 0, 0)) { if (method == ZipFileRO::kCompressStored) { FileMap* map = zip.createEntryFileMap(entry); if (map) { Animation::Frame frame; frame.name = leaf; frame.map = map; Animation::Part& part(animation.parts.editItemAt(j)); part.frames.add(frame); } } } } } } } } #ifndef CONTINUOUS_SPLASH // clear screen glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glClearColor(r,g,b,1); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(mDisplay, mSurface); #endif glBindTexture(GL_TEXTURE_2D, 0); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); const int xc = (mWidth - animation.width) / 2; const int yc = ((mHeight - animation.height) / 2); nsecs_t lastFrame = systemTime(); nsecs_t frameDuration = s2ns(1) / animation.fps; Region clearReg(Rect(mWidth, mHeight)); clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height)); for (int i=0 ; i<pcount ; i++) { const Animation::Part& part(animation.parts[i]); const size_t fcount = part.frames.size(); // can be 1, 0, or not set #ifdef NO_TEXTURE_CACHE const int noTextureCache = NO_TEXTURE_CACHE; #else const int noTextureCache = ((animation.width * animation.height * fcount) > 48 * 1024 * 1024) ? 1 : 0; #endif glBindTexture(GL_TEXTURE_2D, 0); for (int r=0 ; !part.count || r<part.count ; r++) { // Exit any non playuntil complete parts immediately if(exitPending() && !part.playUntilComplete) break; for (int j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) { const Animation::Frame& frame(part.frames[j]); nsecs_t lastFrame = systemTime(); if (r > 0 && !noTextureCache) { glBindTexture(GL_TEXTURE_2D, frame.tid); } else { if (part.count != 1) { glGenTextures(1, &frame.tid); glBindTexture(GL_TEXTURE_2D, frame.tid); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } initTexture( frame.map->getDataPtr(), frame.map->getDataLength()); } if (!clearReg.isEmpty()) { Region::const_iterator head(clearReg.begin()); Region::const_iterator tail(clearReg.end()); glEnable(GL_SCISSOR_TEST); while (head != tail) { const Rect& r(*head++); glScissor(r.left, mHeight - r.bottom, r.width(), r.height()); glClear(GL_COLOR_BUFFER_BIT); } glDisable(GL_SCISSOR_TEST); } glDrawTexiOES(xc, yc, 0, animation.width, animation.height); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime(); nsecs_t delay = frameDuration - (now - lastFrame); //ALOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay)); lastFrame = now; if (delay > 0) { struct timespec spec; spec.tv_sec = (now + delay) / 1000000000; spec.tv_nsec = (now + delay) % 1000000000; int err; do { err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); } while (err<0 && errno == EINTR); } checkExit(); if (noTextureCache) glDeleteTextures(1, &frame.tid); } usleep(part.pause * ns2us(frameDuration)); // For infinite parts, we've now played them at least once, so perhaps exit if(exitPending() && !part.count) break; } // free the textures for this part if (part.count != 1 && !noTextureCache) { for (size_t j=0 ; j<fcount ; j++) { const Animation::Frame& frame(part.frames[j]); glDeleteTextures(1, &frame.tid); } } } return false; }