179 lines
9.3 KiB
JavaScript
179 lines
9.3 KiB
JavaScript
// Define Python generators for custom blocks
|
|
export function definePythonGenerators() {
|
|
// Python Generator for target_market
|
|
Blockly.Python['target_market'] = Blockly.Python.forBlock['target_market'] = function(block) {
|
|
var timeframe = block.getFieldValue('TF');
|
|
var exchange = block.getFieldValue('EXC');
|
|
var symbol = block.getFieldValue('SYM');
|
|
|
|
var code = `target_market(timeframe='${timeframe}', exchange='${exchange}', symbol='${symbol}')`;
|
|
return code;
|
|
};
|
|
// Generator for last_candle_value
|
|
Blockly.Python['last_candle_value'] = Blockly.Python.forBlock['last_candle_value'] = function(block) {
|
|
var candlePart = block.getFieldValue('CANDLE_PART');
|
|
var source = Blockly.Python.valueToCode(block, 'SOURCE', Blockly.Python.ORDER_ATOMIC) || 'None'; // Handle optional source
|
|
|
|
var code;
|
|
if (source !== 'None') {
|
|
// Use the provided source feed if available
|
|
code = `get_last_candle_value('${candlePart}', source=${source})`;
|
|
} else {
|
|
// Fallback to default source
|
|
code = `get_last_candle_value('${candlePart}')`;
|
|
}
|
|
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
|
|
|
|
// Comparison block to Python code
|
|
Blockly.Python['comparison'] = Blockly.Python.forBlock['comparison'] = function(block) {
|
|
const left = Blockly.Python.valueToCode(block, 'LEFT', Blockly.Python.ORDER_ATOMIC);
|
|
const right = Blockly.Python.valueToCode(block, 'RIGHT', Blockly.Python.ORDER_ATOMIC);
|
|
const operator = block.getFieldValue('OPERATOR');
|
|
return [left + ' ' + operator + ' ' + right, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
|
|
// Logical OR block to Python code
|
|
Blockly.Python['logical_or'] = Blockly.Python.forBlock['logical_or'] = function(block) {
|
|
var left = Blockly.Python.valueToCode(block, 'LEFT', Blockly.Python.ORDER_ATOMIC);
|
|
var right = Blockly.Python.valueToCode(block, 'RIGHT', Blockly.Python.ORDER_ATOMIC);
|
|
var code = `${left} or ${right}`;
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
|
|
// Logical AND block to Python code
|
|
Blockly.Python['logical_and'] = Blockly.Python.forBlock['logical_and'] = function(block) {
|
|
var left = Blockly.Python.valueToCode(block, 'LEFT', Blockly.Python.ORDER_ATOMIC);
|
|
var right = Blockly.Python.valueToCode(block, 'RIGHT', Blockly.Python.ORDER_ATOMIC);
|
|
var code = `${left} and ${right}`;
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
|
|
// Stop Loss block to Python code
|
|
Blockly.Python['stop_loss'] = Blockly.Python.forBlock['stop_loss'] = function(block) {
|
|
var stopLoss = Blockly.Python.valueToCode(block, 'STOP_LOSS', Blockly.Python.ORDER_ATOMIC);
|
|
return [stopLoss, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
|
|
// Take Profit block to Python code
|
|
Blockly.Python['take_profit'] = Blockly.Python.forBlock['take_profit'] = function(block) {
|
|
var takeProfit = Blockly.Python.valueToCode(block, 'TAKE_PROFIT', Blockly.Python.ORDER_ATOMIC);
|
|
return [takeProfit, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
|
|
// Python generator for is_false block
|
|
Blockly.Python['is_false'] =Blockly.Python.forBlock['is_false']= function(block) {
|
|
var condition = Blockly.Python.valueToCode(block, 'CONDITION', Blockly.Python.ORDER_ATOMIC);
|
|
var code = `not ${condition}`;
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
|
|
Blockly.Python['trade_action'] = Blockly.Python.forBlock['trade_action'] = function(block) {
|
|
const condition = Blockly.Python.valueToCode(block, 'CONDITION', Blockly.Python.ORDER_ATOMIC);
|
|
const tradeType = block.getFieldValue('TRADE_TYPE');
|
|
const size = Blockly.Python.valueToCode(block, 'SIZE', Blockly.Python.ORDER_ATOMIC) || 'None';
|
|
const stopLoss = Blockly.Python.valueToCode(block, 'STOP_LOSS', Blockly.Python.ORDER_ATOMIC) || 'None';
|
|
const takeProfit = Blockly.Python.valueToCode(block, 'TAKE_PROFIT', Blockly.Python.ORDER_ATOMIC) || 'None';
|
|
|
|
// Process trade options
|
|
let tradeOptionsCode = Blockly.Python.statementToCode(block, 'TRADE_OPTIONS').trim();
|
|
tradeOptionsCode = tradeOptionsCode.split('\n').filter(line => line.trim() !== '');
|
|
|
|
// Collect all arguments into an array
|
|
const argsList = [`size=${size}`, `stop_loss=${stopLoss}`, `take_profit=${takeProfit}`];
|
|
if (tradeOptionsCode.length > 0) {
|
|
argsList.push(...tradeOptionsCode);
|
|
}
|
|
const args = argsList.join(', ');
|
|
|
|
const code = `if ${condition}:\n self.${tradeType}(${args})\n`;
|
|
return code;
|
|
};
|
|
|
|
// Order Type block to Python code
|
|
Blockly.Python['order_type'] = Blockly.Python.forBlock['order_type'] = function(block) {
|
|
const orderType = block.getFieldValue('ORDER_TYPE');
|
|
const limitPrice = Blockly.Python.valueToCode(block, 'LIMIT_PRICE', Blockly.Python.ORDER_ATOMIC) || 'None';
|
|
|
|
let code = `order_type='${orderType}'`;
|
|
if (orderType === 'limit') {
|
|
code += `, limit_price=${limitPrice}`;
|
|
}
|
|
return code;
|
|
};
|
|
|
|
// Value Input block to Python code
|
|
Blockly.Python['value_input'] = Blockly.Python.forBlock['value_input'] = function(block) {
|
|
var value = block.getFieldValue('VALUE');
|
|
return [value.toString(), Blockly.Python.ORDER_ATOMIC]; // Returning both value and precedence
|
|
};
|
|
|
|
// Time in Force block to Python code
|
|
Blockly.Python['time_in_force'] = Blockly.Python.forBlock['time_in_force'] = function(block) {
|
|
const tif = block.getFieldValue('TIF');
|
|
const code = `tif='${tif}'`;
|
|
return code;
|
|
};
|
|
|
|
Blockly.Python['source'] = Blockly.Python.forBlock['source'] = function(block) {
|
|
var timeframe = block.getFieldValue('TF');
|
|
var exchange = block.getFieldValue('EXC');
|
|
var symbol = block.getFieldValue('SYM');
|
|
|
|
// Return the source information as an object or string
|
|
var code = `{'timeframe': '${timeframe}', 'exchange': '${exchange}', 'symbol': '${symbol}'}`;
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
// Generator code for strategy_profit_loss block
|
|
Blockly.Python['strategy_profit_loss'] = Blockly.Python.forBlock['strategy_profit_loss'] = function(block) {
|
|
var direction = block.getFieldValue('DIRECTION');
|
|
var code = `strategy_profit_loss('${direction}')`;
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
// Generator code for current_balance block
|
|
Blockly.Python['current_balance'] = Blockly.Python.forBlock['current_balance'] = function() {
|
|
var code = 'get_current_balance()';
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
|
|
// Generator code for starting_balance block
|
|
Blockly.Python['starting_balance'] = Blockly.Python.forBlock['starting_balance'] = function() {
|
|
var code = 'get_starting_balance()';
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
// Generator code for arithmetic_operator block
|
|
Blockly.Python['arithmetic_operator'] = Blockly.Python.forBlock['arithmetic_operator'] = function(block) {
|
|
var operator = block.getFieldValue('OPERATOR');
|
|
var left = Blockly.Python.valueToCode(block, 'LEFT', Blockly.Python.ORDER_ATOMIC);
|
|
var right = Blockly.Python.valueToCode(block, 'RIGHT', Blockly.Python.ORDER_ATOMIC);
|
|
|
|
var code = `${left} ${operator} ${right}`;
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
|
|
// Python generator for the active_trades block
|
|
Blockly.Python['active_trades'] = Blockly.Python.forBlock['active_trades'] = function(block) {
|
|
var code = `get_active_trades()`; // You would define this method in your Python backtesting engine
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
// Python generator for the flag_is_set block
|
|
Blockly.Python['flag_is_set'] = Blockly.Python.forBlock['flag_is_set'] = function(block) {
|
|
var flagName = block.getFieldValue('FLAG_NAME');
|
|
var code = `flag_is_set('${flagName}')`;
|
|
return [code, Blockly.Python.ORDER_ATOMIC];
|
|
};
|
|
// Python generator for set_flag block
|
|
Blockly.Python['set_flag'] = Blockly.Python.forBlock['set_flag'] = function(block) {
|
|
var condition = Blockly.Python.valueToCode(block, 'CONDITION', Blockly.Python.ORDER_ATOMIC);
|
|
var flagName = block.getFieldValue('FLAG_NAME');
|
|
var flagValue = block.getFieldValue('FLAG_VALUE') === 'True' ? 'True' : 'False';
|
|
|
|
var code = `if ${condition}:\n set_flag('${flagName}', ${flagValue})\n`;
|
|
return code;
|
|
};
|
|
|
|
console.log('Python generators defined');
|
|
}
|