У меня была интересная идея прошлой ночью. Я не говорю, что это хорошая идея — мой мозг испытывает какую-то серьезную странность из-за семичасовой смены времени. Но хорошая идея или нет, я построил это и решил, что поделюсь этим.
Знаете ли вы, что вы можете создавать функции в JavaScript, передавая строку? Я не вижу много людей, использующих эту технику (хорошо, я никогда не видел, чтобы кто-нибудь использовал это), но суть в том, что вы можете создать новый объект Function , перечислив любое количество аргументов, за которыми следует строка кода. Вот пример:
x = new Function("a","b", "return a+b");
x(1,2);
Это заставило меня задуматься о том, какой код будет использовать эту форму определения функций. Около четырех лет назад я попросил своих читателей принять участие в конкурсе по программированию, который потребовал от вас написать логику для работы с лимонадным стендом. В конкурсе вы написали UDF, который отвечал на ежедневные сводки погоды. Он передал вам информацию о ваших активах, и вы просто ответили действием. Идея заключалась в том, что вы строите «интеллектуального агента» для управления бизнесом.
Имея это в виду, я решил создать нечто подобное в JavaScript. В моем моделировании вы пишете агента, который отслеживает акции и решает, когда покупать или продавать акции. Ваш код будет функцией, которой передаются основные данные, такие как цена акций, изменение и т. Д. Затем вы обрабатываете возврат действия: покупка акций, продажа акций, ничего не делать.
Вам дана простая функция для начала:
Когда вы нажимаете кнопку Start Simulation, я беру этот код и генерирую из него функцию:
$("#startSim").on("click", function(e) {
code = $("#functiontext").val();
if(code === "") return;
$(this).attr("disabled","disabled");
//build the func
try {
userFunc = new Function("value,change,cash,shares,storage", code);
beginSim();
} catch(e) {
handleError(e);
}
});
Там try / catch обрабатывает некоторые ошибки, но не все. Поскольку код запускает симуляцию, мне нужно больше обрабатывать ошибки на стороне обработки. Вот эта логика:
function runFunc() {
count++;
if(count > maxCount) { endSim(); return; }
console.log("runFunc");
//Is the stock going up or down?
var x = Math.random();
var change = Math.floor(Math.random() * 10);
if(x > 0.5) {
if((stockvalue - change) < 1) { change = stockvalue-1; }
change = -1 * change;
}
stockvalue += change;
try {
console.log("Calling userfunc",stockvalue,change,usercash,sharesowned);
var result = userFunc(stockvalue,change,usercash,sharesowned,storage);
if(!result) {
throw new Error("Your function did not return a result.");
}
if(!result.hasOwnProperty("action")) {
throw new Error("Your result did not include the action key.");
}
if(!validAction(result.action)) {
throw new Error("Your result did not contain a valid action value.");
}
if(result.action === "sell") {
if(!result.hasOwnProperty("quantity")) {
throw new Error("Your result tried to sell without returning a quantity value.");
} else {
console.log("doing a sale");
if(result.quantity > sharesowned) throw new Error("You tried to sell "+result.quantity+" shares but only owned "+sharesowned);
sharesowned -= result.quantity;
usercash += result.quantity*stockvalue;
}
}
if(result.action === "buy") {
if(!result.hasOwnProperty("quantity")) {
throw new Error("Your result tried to buy without returning a quantity value.");
} else {
if(result.quantity * stockvalue > usercash) throw new Error("You tried to spend "+(result.quantity*stockvalue)+" on shares but only have "+usercash);
sharesowned += result.quantity;
usercash -= result.quantity*stockvalue;
}
}
displayStats();
} catch(e) {
console.log("Error", e);
handleError(e);
}
}function runFunc() {
count++;
if(count > maxCount) { endSim(); return; }
console.log("runFunc");
//Is the stock going up or down?
var x = Math.random();
var change = Math.floor(Math.random() * 10);
if(x > 0.5) {
if((stockvalue - change) < 1) { change = stockvalue-1; }
change = -1 * change;
}
stockvalue += change;
try {
console.log("Calling userfunc",stockvalue,change,usercash,sharesowned);
var result = userFunc(stockvalue,change,usercash,sharesowned,storage);
if(!result) {
throw new Error("Your function did not return a result.");
}
if(!result.hasOwnProperty("action")) {
throw new Error("Your result did not include the action key.");
}
if(!validAction(result.action)) {
throw new Error("Your result did not contain a valid action value.");
}
if(result.action === "sell") {
if(!result.hasOwnProperty("quantity")) {
throw new Error("Your result tried to sell without returning a quantity value.");
} else {
console.log("doing a sale");
if(result.quantity > sharesowned) throw new Error("You tried to sell "+result.quantity+" shares but only owned "+sharesowned);
sharesowned -= result.quantity;
usercash += result.quantity*stockvalue;
}
}
if(result.action === "buy") {
if(!result.hasOwnProperty("quantity")) {
throw new Error("Your result tried to buy without returning a quantity value.");
} else {
if(result.quantity * stockvalue > usercash) throw new Error("You tried to spend "+(result.quantity*stockvalue)+" on shares but only have "+usercash);
sharesowned += result.quantity;
usercash -= result.quantity*stockvalue;
}
}
displayStats();
} catch(e) {
console.log("Error", e);
handleError(e);
}
}
Это может быть немного более жестким, но вы можете увидеть основы того, что я делаю здесь. Во время симуляции вы видите отчет о вашей статистике.
Итак — хотите дать ему шанс? Фондовый рынок AI Simulator
Если вам интересно — вы можете абсолютно обмануть это. Я не ищу подлых вещей, таких как продажа отрицательного количества акций. Также я не блокирую вас от выхода на глобальный уровень и манипулирования вашими ценностями. Мне бы очень хотелось посмотреть, что люди попробуют в демоверсии. Разместите свои примеры в виде комментариев ниже.