Beispiel #1
0
bool isOrderComplete(CURL *curl, Parameters params, int orderId) {
 
  bool isComplete;
  if (orderId == 0) {
    return true;
  }
  std::ostringstream oss;
  oss << "\"order_id\":" << orderId;
  std::string options = oss.str();

  json_t *root = authRequest(curl, params, "https://api.bitfinex.com/v1/order/status", "order/status", options);

  isComplete = !json_boolean_value(json_object_get(root, "is_live"));
  json_decref(root);
  return isComplete;
}
int read_cfg_bool(json_t *root, const char *key, bool *val, bool required, bool default_val)
{
    json_t *node = json_object_get(root, key);
    if (!node) {
        if (required) {
            return -__LINE__;
        } else {
            *val = default_val;
            return 0;
        }
    }
    if (!json_is_boolean(node))
        return -__LINE__;
    *val = json_boolean_value(node);

    return 0;
}
Beispiel #3
0
int borrowBtc(Parameters& params, double amount) {
  int borrowId = 0;
  bool isBorrowAccepted = false;
  std::ostringstream oss;
  oss << "api_key=" << params.okcoinApi << "&symbol=btc_usd&days=fifteen&amount=" << 1 << "&rate=0.0001&secret_key=" << params.okcoinSecret;
  std::string signature = oss.str();
  oss.clear();
  oss.str("");
  oss << "api_key=" << params.okcoinApi << "&symbol=btc_usd&days=fifteen&amount=" << 1 << "&rate=0.0001";
  std::string content = oss.str();
  json_t* root = authRequest(params, "https://www.okcoin.com/api/v1/borrow_money.do", signature, content);
  std::cout << "<OKCoin> Borrow " << amount << " BTC:\n" << json_dumps(root, 0) << std::endl;
  isBorrowAccepted = json_boolean_value(json_object_get(root, "result"));
  if (isBorrowAccepted) {
    borrowId = json_integer_value(json_object_get(root, "borrow_id"));
  }
  json_decref(root);
  return borrowId;
}
Beispiel #4
0
static inline int device_set_boolean(setter_boolean fn, struct Device *device,
                                     json_t *value, const char *context,
                                     struct MbDeviceJsonError *error)
{
    int ret;

    if (!json_is_boolean(value)) {
        json_error_set_mismatched_type(
                error, context, value->type, JSON_BOOLEAN);
        return -1;
    }

    ret = fn(device, json_boolean_value(value));
    if (ret < 0) {
        json_error_set_standard_error(error, ret);
        return -1;
    }

    return 0;
}
Beispiel #5
0
// gets a json value from a key
int json_object_get_bool(json_t *object, char *key, int **value)
{
  int *value_return = NULL;

  int exit_code = 0;

  check_not_null(object);
  check_not_null(key);
  check_not_null(value);

  json_t *json_boolean_peek = json_object_get(object, key);
  if (json_boolean_peek == NULL)
  {
    *value = NULL;
    goto cleanup;
  }

  int json_typeof_result = json_typeof(json_boolean_peek);
  if (json_typeof_result != JSON_TRUE && json_typeof_result != JSON_FALSE)
  {
    *value = NULL;
    goto cleanup;
  }

  int value_peek = json_boolean_value(json_boolean_peek);
  check_result(malloc_memcpy_int(&value_return, &value_peek), 0);

  *value = value_return;

  goto cleanup;

error:

  if (value_return != NULL) { free(value_return); }

  exit_code = -1;

cleanup:

  return exit_code;
}
Beispiel #6
0
static void buf_appendjson(struct buf *buf, json_t *jvalue)
{
    switch (json_typeof(jvalue)) {
    case JSON_ARRAY: {
        size_t i, n = json_array_size(jvalue);
        const char *sep = "";

        for (i = 0; i < n; i++, sep = ",") {
            buf_appendcstr(buf, sep);
            buf_appendjson(buf, json_array_get(jvalue, i));
        }
        break;
    }

    case JSON_STRING:
        buf_appendcstr(buf, json_string_value(jvalue));
        break;

    case JSON_INTEGER:
        buf_printf(buf, "%" JSON_INTEGER_FORMAT, json_integer_value(jvalue));
        break;

    case JSON_REAL:
        buf_printf(buf, "%f", json_real_value(jvalue));
        break;

    case JSON_TRUE:
    case JSON_FALSE:
        buf_printf(buf, "%d", json_boolean_value(jvalue));
        break;

    default:
        /* Shouldn't get here - ignore object */
        break;
    }
}
Beispiel #7
0
int broker_start_server(json_t *config) {
    json_incref(config);

    const char *httpHost = NULL;
    char httpPort[8];
    memset(httpPort, 0, sizeof(httpPort));
    {
        json_t *http = json_object_get(config, "http");
        if (http) {
            json_t *enabled = json_object_get(http, "enabled");
            if (!(enabled && json_boolean_value(enabled))) {
                json_decref(config);
                return 0;
            }
            httpHost = json_string_value(json_object_get(http, "host"));

            json_t *jsonPort = json_object_get(http, "port");
            if (jsonPort) {
                json_int_t p = json_integer_value(jsonPort);
                int len = snprintf(httpPort, sizeof(httpPort) - 1,
                                   "%" JSON_INTEGER_FORMAT, p);
                httpPort[len] = '\0';
            }
        }
    }

    int httpActive = 0;
    Server httpServer;
    uv_poll_t httpPoll;
    if (httpHost && httpPort[0] != '\0') {
        mbedtls_net_init(&httpServer.srv);
        httpServer.data_ready = broker_on_data_callback;

        httpActive = start_http_server(&httpServer, httpHost, httpPort,
                                       mainLoop, &httpPoll);
    }

    uv_signal_t sigInt;
    uv_signal_init(mainLoop, &sigInt);
    uv_signal_start(&sigInt, stop_server_handler, SIGINT);

    uv_signal_t sigTerm;
    uv_signal_init(mainLoop, &sigTerm);
    uv_signal_start(&sigTerm, stop_server_handler, SIGTERM);

//    upstream_connect_conn(&loop, "http://10.0.1.158:8080/conn", "dartbroker", "cbroker");

    if (httpActive) {
        uv_run(mainLoop, UV_RUN_DEFAULT);
    }

    uv_signal_stop(&sigInt);
    uv_signal_stop(&sigTerm);

    if (httpActive) {
        uv_poll_stop(&httpPoll);
    }
    uv_loop_close(mainLoop);
#if defined(__unix__) || defined(__APPLE__)
    if (mainLoop && mainLoop->watchers) {
        uv__free(mainLoop->watchers);
    }
#endif

    json_decref(config);
    return 0;
}
Beispiel #8
0
/* Call the simple functions not covered by other tests of the public API */
static void run_tests()
{
    json_t *value;

    value = json_boolean(1);
    if(!json_is_true(value))
        fail("json_boolean(1) failed");
    json_decref(value);

    value = json_boolean(-123);
    if(!json_is_true(value))
        fail("json_boolean(-123) failed");
    json_decref(value);

    value = json_boolean(0);
    if(!json_is_false(value))
        fail("json_boolean(0) failed");
    if(json_boolean_value(value) != 0)
        fail("json_boolean_value failed");
    json_decref(value);


    value = json_integer(1);
    if(json_typeof(value) != JSON_INTEGER)
        fail("json_typeof failed");

    if(json_is_object(value))
        fail("json_is_object failed");

    if(json_is_array(value))
        fail("json_is_array failed");

    if(json_is_string(value))
        fail("json_is_string failed");

    if(!json_is_integer(value))
        fail("json_is_integer failed");

    if(json_is_real(value))
        fail("json_is_real failed");

    if(!json_is_number(value))
        fail("json_is_number failed");

    if(json_is_true(value))
        fail("json_is_true failed");

    if(json_is_false(value))
        fail("json_is_false failed");

    if(json_is_boolean(value))
        fail("json_is_boolean failed");

    if(json_is_null(value))
        fail("json_is_null failed");

    json_decref(value);


    value = json_string("foo");
    if(!value)
        fail("json_string failed");
    if(strcmp(json_string_value(value), "foo"))
        fail("invalid string value");
    if (json_string_length(value) != 3)
        fail("invalid string length");

    if(json_string_set(value, "barr"))
        fail("json_string_set failed");
    if(strcmp(json_string_value(value), "barr"))
        fail("invalid string value");
    if (json_string_length(value) != 4)
        fail("invalid string length");

    if(json_string_setn(value, "hi\0ho", 5))
        fail("json_string_set failed");
    if(memcmp(json_string_value(value), "hi\0ho\0", 6))
        fail("invalid string value");
    if (json_string_length(value) != 5)
        fail("invalid string length");

    json_decref(value);

    value = json_string(NULL);
    if(value)
        fail("json_string(NULL) failed");

    /* invalid UTF-8  */
    value = json_string("a\xefz");
    if(value)
        fail("json_string(<invalid utf-8>) failed");

    value = json_string_nocheck("foo");
    if(!value)
        fail("json_string_nocheck failed");
    if(strcmp(json_string_value(value), "foo"))
        fail("invalid string value");
    if (json_string_length(value) != 3)
        fail("invalid string length");

    if(json_string_set_nocheck(value, "barr"))
        fail("json_string_set_nocheck failed");
    if(strcmp(json_string_value(value), "barr"))
        fail("invalid string value");
    if (json_string_length(value) != 4)
        fail("invalid string length");

    if(json_string_setn_nocheck(value, "hi\0ho", 5))
        fail("json_string_set failed");
    if(memcmp(json_string_value(value), "hi\0ho\0", 6))
        fail("invalid string value");
    if (json_string_length(value) != 5)
        fail("invalid string length");

    json_decref(value);

    /* invalid UTF-8 */
    value = json_string_nocheck("qu\xff");
    if(!value)
        fail("json_string_nocheck failed");
    if(strcmp(json_string_value(value), "qu\xff"))
        fail("invalid string value");
    if (json_string_length(value) != 3)
        fail("invalid string length");

    if(json_string_set_nocheck(value, "\xfd\xfe\xff"))
        fail("json_string_set_nocheck failed");
    if(strcmp(json_string_value(value), "\xfd\xfe\xff"))
        fail("invalid string value");
    if (json_string_length(value) != 3)
        fail("invalid string length");

    json_decref(value);


    value = json_integer(123);
    if(!value)
        fail("json_integer failed");
    if(json_integer_value(value) != 123)
        fail("invalid integer value");
    if(json_number_value(value) != 123.0)
        fail("invalid number value");

    if(json_integer_set(value, 321))
        fail("json_integer_set failed");
    if(json_integer_value(value) != 321)
        fail("invalid integer value");
    if(json_number_value(value) != 321.0)
        fail("invalid number value");

    json_decref(value);

    value = json_real(123.123);
    if(!value)
        fail("json_real failed");
    if(json_real_value(value) != 123.123)
        fail("invalid integer value");
    if(json_number_value(value) != 123.123)
        fail("invalid number value");

    if(json_real_set(value, 321.321))
        fail("json_real_set failed");
    if(json_real_value(value) != 321.321)
        fail("invalid real value");
    if(json_number_value(value) != 321.321)
        fail("invalid number value");

    json_decref(value);

    value = json_true();
    if(!value)
        fail("json_true failed");
    json_decref(value);

    value = json_false();
    if(!value)
        fail("json_false failed");
    json_decref(value);

    value = json_null();
    if(!value)
        fail("json_null failed");
    json_decref(value);

    /* Test reference counting on singletons (true, false, null) */
    value = json_true();
    if(value->refcount != (size_t)-1)
      fail("refcounting true works incorrectly");
    json_decref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting true works incorrectly");
    json_incref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting true works incorrectly");

    value = json_false();
    if(value->refcount != (size_t)-1)
      fail("refcounting false works incorrectly");
    json_decref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting false works incorrectly");
    json_incref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting false works incorrectly");

    value = json_null();
    if(value->refcount != (size_t)-1)
      fail("refcounting null works incorrectly");
    json_decref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting null works incorrectly");
    json_incref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting null works incorrectly");
}
Beispiel #9
0
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;
}
Beispiel #10
0
static void twitch_parse_followers()
{
	struct AudienceMember {
		const char *name;
		bool isFollower;
		bool isInChat;
		bool isMod;
		bool exists;
		bool shouldTrack;
	};

	std::vector<AudienceMember> members;

	http_json_response *jsonResponse = _twitchJsonResponse;
	if (json_is_array(jsonResponse->root)) {
		int audienceCount = json_array_size(jsonResponse->root);
		for (int i = 0; i < audienceCount; i++) {
			json_t *audienceMember = json_array_get(jsonResponse->root, i);
			if (!json_is_object(audienceMember))
				continue;

			json_t *name = json_object_get(audienceMember, "name");
			json_t *isFollower = json_object_get(audienceMember, "isFollower");
			json_t *isInChat = json_object_get(audienceMember, "inChat");
			json_t *isMod = json_object_get(audienceMember, "isMod");

			AudienceMember member;
			member.name = json_string_value(name);
			member.isFollower = json_boolean_value(isFollower);
			member.isInChat = json_boolean_value(isInChat);
			member.isMod = json_boolean_value(isMod);
			member.exists = false;
			member.shouldTrack = false;

			if (member.name == NULL || member.name[0] == 0)
				continue;

			if (member.isInChat && gConfigTwitch.enable_chat_peep_tracking)
				member.shouldTrack = true;
			else if (member.isFollower && gConfigTwitch.enable_follower_peep_tracking)
				member.shouldTrack = true;

			if (gConfigTwitch.enable_chat_peep_names && member.isInChat)
				members.push_back(member);
			else if (gConfigTwitch.enable_follower_peep_names && member.isFollower)
				members.push_back(member);
		}

		uint16 spriteIndex;
		rct_peep *peep;
		char buffer[256];

		// Check what followers are already in the park
		FOR_ALL_GUESTS(spriteIndex, peep) {
			if (is_user_string_id(peep->name_string_idx)) {
				format_string(buffer, peep->name_string_idx, NULL);

				AudienceMember *member = NULL;
				for (size_t i = 0; i < members.size(); i++) {
					if (_strcmpi(buffer, members[i].name) == 0) {
						member = &members[i];
						members[i].exists = true;
						break;
					}
				}

				if (peep->peep_flags & PEEP_FLAGS_TWITCH) {
					if (member == NULL) {
						// Member no longer peep name worthy
						peep->peep_flags &= ~(PEEP_FLAGS_TRACKING | PEEP_FLAGS_TWITCH);

						// TODO set peep name back to number / real name
					} else {
						if (member->shouldTrack)
							peep->peep_flags |= (PEEP_FLAGS_TRACKING);
						else if (!member->shouldTrack)
							peep->peep_flags &= ~(PEEP_FLAGS_TRACKING);
					}
				} else if (member != NULL && !(peep->peep_flags & PEEP_FLAGS_LEAVING_PARK)) {
					// Peep with same name already exists but not twitch
					peep->peep_flags |= PEEP_FLAGS_TWITCH;
					if (member->shouldTrack)
						peep->peep_flags |= PEEP_FLAGS_TRACKING;
				}
			}
		}

		// Rename non-named peeps to followers that aren't currently in the park.
		if (members.size() > 0) {
			int memberIndex = -1;
			FOR_ALL_GUESTS(spriteIndex, peep) {
				int originalMemberIndex = memberIndex;
				for (size_t i = memberIndex + 1; i < members.size(); i++) {
					if (!members[i].exists) {
						memberIndex = i;
						break;
					}
				}
				if (originalMemberIndex == memberIndex)
					break;

				AudienceMember *member = &members[memberIndex];
				if (!is_user_string_id(peep->name_string_idx) && !(peep->peep_flags & PEEP_FLAGS_LEAVING_PARK)) {
					// Rename peep and add flags
					rct_string_id newStringId = user_string_allocate(4, member->name);
					if (newStringId != 0) {
						peep->name_string_idx = newStringId;
						peep->peep_flags |= PEEP_FLAGS_TWITCH;
						if (member->shouldTrack)
							peep->peep_flags |= PEEP_FLAGS_TRACKING;
					}
				} else {
					// Peep still yet to be found for member
					memberIndex--;
				}
			}
Beispiel #11
0
json_t *broker_handshake_handle_conn(Broker *broker,
                                     const char *dsId,
                                     const char *token,
                                     json_t *handshake) {
    if (dslink_map_contains(&broker->client_connecting, (void *) dsId)) {
        ref_t *ref = dslink_map_remove_get(&broker->client_connecting,
                                           (void *) dsId);
        RemoteDSLink *link = ref->data;
        dslink_map_remove(&broker->client_connecting,
                          (void *) link->name);
        broker_remote_dslink_free(link);
        dslink_free(link);
        dslink_decref(ref);
    }

    RemoteDSLink *link = dslink_calloc(1, sizeof(RemoteDSLink));
    json_t *resp = json_object();
    if (!(link && resp)) {
        goto fail;
    }

    if (broker_remote_dslink_init(link) != 0) {
        goto fail;
    }

    link->broker = broker;
    link->auth = dslink_calloc(1, sizeof(RemoteAuth));
    if (!link->auth) {
        goto fail;
    }

    if (dslink_handshake_generate_key_pair(&link->auth->tempKey) != 0) {
        log_err("Failed to create temporary key for DSLink\n");
        goto fail;
    }

    {
        json_t *jsonPubKey = json_object_get(handshake, "publicKey");
        if (!jsonPubKey) {
            goto fail;
        }

        const char *tmp = json_string_value(jsonPubKey);
        if (!tmp) {
            goto fail;
        }
        tmp = dslink_strdup(tmp);
        if (!tmp) {
            goto fail;
        }
        link->auth->pubKey = tmp;
    }

    char tempKey[90];
    size_t tempKeyLen = 0;
    if (dslink_handshake_encode_pub_key(&link->auth->tempKey, tempKey,
                                        sizeof(tempKey), &tempKeyLen) != 0) {
        goto fail;
    }

    if (generate_salt((unsigned char *) link->auth->salt,
                      sizeof(link->auth->salt)) != 0) {
        goto fail;
    }

    json_object_set_new_nocheck(resp, "wsUri", json_string_nocheck("/ws"));
    json_object_set_new_nocheck(resp, "tempKey", json_string_nocheck(tempKey));
    json_object_set_new_nocheck(resp, "salt", json_string_nocheck(link->auth->salt));
    if (json_boolean_value(json_object_get(handshake, "isResponder"))) {
        link->isResponder = 1;
    }

    if (json_boolean_value(json_object_get(handshake, "isRequester"))) {
        link->isRequester = 1;
    }

    json_t *linkData = json_object_get(handshake, "linkData");
    if (json_is_object(linkData)) {
        json_incref(linkData);
        link->linkData = linkData;
    }

    {
        char buf[512] = {0};
        snprintf(buf, sizeof(buf), "/downstream/");
        char *name = buf + sizeof("/downstream/")-1;

        size_t dsIdLen = strlen(dsId);
        if (dsIdLen < 44) {
            goto fail;
        }
        size_t nameLen = dsIdLen - 43;
        if (dsId[nameLen - 1] == '-') {
            nameLen--;
        }
        int nodeExists = 0;
        // find a valid name from broker->client_names
        memcpy(name, dsId, nameLen);
        while (1) {
            ref_t *ref = dslink_map_get(&broker->client_connecting, name);
            if (ref) {
                RemoteDSLink *l = ref->data;
                if (l && l->dsId && strcmp(l->dsId->data, dsId) == 0) {
                    dslink_map_remove(&broker->client_connecting, name);
                    broker_remote_dslink_free(l);
                    break;
                } else {
                    name[nameLen] = dsId[nameLen];
                    nameLen++;
                }
            }
            ref = dslink_map_get(broker->downstream->children,
                                 (void *) name);
            if (ref == NULL) {
                break;
            }
            if (!((DownstreamNode *) ref->data)->dsId || strcmp(dsId, ((DownstreamNode *) ref->data)->dsId->data) == 0) {
                nodeExists = 1;
                break;
            }

            name[nameLen] = dsId[nameLen];
            nameLen++;
        }
        if (!nodeExists && broker_enable_token) {
            if (!token) {
                log_err("Failed to connet, need token\n");
                goto fail;
            }
            BrokerNode* tokenNode = get_token_node(token, dsId);
            if (tokenNode) {
                DownstreamNode *node = broker_init_downstream_node(broker->downstream, name);

                if (json_is_true(json_object_get(node->meta, "$$managed"))) {
                    json_object_set_new_nocheck(node->meta, "$$token", json_string_nocheck(tokenNode->name));
                }

                node->dsId = dslink_str_ref(dsId);
                if (broker->downstream->list_stream) {
                    update_list_child(broker->downstream,
                                      broker->downstream->list_stream,
                                      link->name);
                }

                json_t *group = json_object_get(tokenNode->meta, "$$group");
                if (json_is_string(group)) {
                    json_object_set_nocheck(node->meta, "$$group", group);
                }

                token_used(tokenNode);

                broker_downstream_nodes_changed(broker);
            } else {
                log_err("Invalid token: %s\n", token);
                goto fail;
            }
        }
        json_object_set_new_nocheck(resp, "path", json_string_nocheck(buf));

        link->path = dslink_strdup(buf);
        if (!link->path) {
            goto fail;
        }
        link->name = link->path + sizeof("/downstream/") - 1;

        // add to connecting map with the name
        if (dslink_map_set(&broker->client_connecting,
                           dslink_ref((void *) link->name, NULL),
                           dslink_ref(link, NULL)) != 0) {
            dslink_free((void *) link->path);
            goto fail;
        }
    }

    {
        ref_t *tmp = dslink_ref(dslink_strdup(dsId), dslink_free);
        if (!tmp) {
            goto fail;
        }
        // add to connecting map with dsId
        if (dslink_map_set(&broker->client_connecting, tmp,
                           dslink_ref(link, NULL)) != 0) {
            dslink_free(tmp);
            goto fail;
        }
    }

    return resp;
fail:
    if (link) {
        broker_remote_dslink_free(link);
        dslink_free((void *) link->path);
        dslink_free(link);
    }
    DSLINK_CHECKED_EXEC(json_decref, resp);
    return NULL;
}
vita_imports_t *vita_imports_loads(FILE *text, int verbose)
{
	json_t *libs, *lib_data;
	json_error_t error;
	const char *lib_name, *mod_name, *target_name;

	libs = json_loadf(text, 0, &error);
	if (libs == NULL) {
		fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
		return NULL;
	}

	if (!json_is_object(libs)) {
		fprintf(stderr, "error: modules is not an object\n");
		json_decref(libs);
		return NULL;
	}

	vita_imports_t *imports = vita_imports_new(json_object_size(libs));
	int i, j, k;

	i = -1;
	json_object_foreach(libs, lib_name, lib_data) {
		json_t *nid, *modules, *mod_data;

		i++;

		if (!json_is_object(lib_data)) {
			fprintf(stderr, "error: library %s is not an object\n", lib_name);
			json_decref(libs);
			return NULL;
		}

		nid = json_object_get(lib_data, "nid");
		if (!json_is_integer(nid)) {
			fprintf(stderr, "error: library %s: nid is not an integer\n", lib_name);
			json_decref(libs);
			return NULL;
		}

		modules = json_object_get(lib_data, "modules");
		if (!json_is_object(modules)) {
			fprintf(stderr, "error: library %s: module is not an object\n", lib_name);
			json_decref(libs);
			return NULL;
		}

		imports->libs[i] = vita_imports_lib_new(
				lib_name,
				json_integer_value(nid),
				json_object_size(modules));

		if (verbose)
			printf("Lib: %s\n", lib_name);

		j = -1;
		json_object_foreach(modules, mod_name, mod_data) {
			json_t *nid, *kernel, *functions, *variables, *target_nid;
			int has_variables = 1;

			j++;

			if (!json_is_object(mod_data)) {
				fprintf(stderr, "error: module %s is not an object\n", mod_name);
				json_decref(libs);
				return NULL;
			}

			nid = json_object_get(mod_data, "nid");
			if (!json_is_integer(nid)) {
				fprintf(stderr, "error: module %s: nid is not an integer\n", mod_name);
				json_decref(libs);
				return NULL;
			}

			kernel = json_object_get(mod_data, "kernel");
			if (!json_is_boolean(kernel)) {
				fprintf(stderr, "error: module %s: kernel is not a boolean\n", mod_name);
				json_decref(libs);
				return NULL;
			}

			functions = json_object_get(mod_data, "functions");
			if (!json_is_object(functions)) {
				fprintf(stderr, "error: module %s: functions is not an array\n", mod_name);
				json_decref(libs);
				return NULL;
			}

			variables = json_object_get(mod_data, "variables");
			if (variables == NULL) {
				has_variables = 0;
			}

			if (has_variables && !json_is_object(variables)) {
				fprintf(stderr, "error: module %s: variables is not an array\n", mod_name);
				json_decref(libs);
				return NULL;
			}

			if (verbose)
				printf("\tModule: %s\n", mod_name);

			imports->libs[i]->modules[j] = vita_imports_module_new(
					mod_name,
					json_boolean_value(kernel),
					json_integer_value(nid),
					json_object_size(functions),
					json_object_size(variables));

			k = -1;
			json_object_foreach(functions, target_name, target_nid) {
				k++;

				if (!json_is_integer(target_nid)) {
					fprintf(stderr, "error: function %s: nid is not an integer\n", target_name);
					json_decref(libs);
					return NULL;
				}

				if (verbose)
					printf("\t\tFunction: %s\n", target_name);

				imports->libs[i]->modules[j]->functions[k] = vita_imports_stub_new(
						target_name,
						json_integer_value(target_nid));

			}