Instructions to use misbah-dev/trade-parse-qlora with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use misbah-dev/trade-parse-qlora with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir trade-parse-qlora misbah-dev/trade-parse-qlora
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
| """ | |
| Synthetic data generator for TradeParse-LoRA / OrderIntent. | |
| Generates clean instruction -> JSON training pairs for fine-tuning a model to | |
| parse natural-language trade instructions into one consistent schema. | |
| The model may output either: | |
| - a successful trade parse | |
| - a structured error when the instruction is missing required information | |
| idempotency_key is intentionally excluded from model output. Generate it in | |
| Python after validation if needed. | |
| """ | |
| import argparse | |
| import json | |
| import random | |
| from pathlib import Path | |
| RNG = random.Random(42) | |
| SYSTEM_PROMPT = ( | |
| "Convert the user trade instruction into JSON only. " | |
| "If the instruction has enough information, use exactly this success schema: " | |
| '{"symbol": str, "action_conditions": [{"trigger": "price_below"|"price_above", ' | |
| '"value": number, "action": "buy"|"sell"}], "strategy_type": "intraday"|null}. ' | |
| "If required information is missing or ambiguous, use exactly this error schema: " | |
| '{"error": "missing_symbol"|"ambiguous_symbol"|"missing_price_condition"|"missing_action"|"unsupported_strategy", ' | |
| '"symbol": str|null, "message": str}. ' | |
| "Rules: if strategy type is not mentioned, set strategy_type to null. " | |
| "Only intraday is supported as a strategy_type; futures, delivery, and swing should not be copied into strategy_type. " | |
| "If no numeric price condition is present, return missing_price_condition. " | |
| "If no symbol/company is present, return missing_symbol. " | |
| "If no buy/sell style action is present, return missing_action. " | |
| "Do not include markdown, explanations, or extra keys." | |
| ) | |
| SYMBOL_ALIASES = { | |
| "INFY": ["INFY", "Infy", "Infosys", "INFY.NS"], | |
| "RELIANCE": ["RELIANCE", "Reliance"], | |
| "TCS": ["TCS", "Tcs", "Tata Consultancy Services"], | |
| "HDFC": ["HDFC", "Hdfc", "HDFC Bank"], | |
| "ICICIBANK": ["ICICIBANK", "Icicibank", "ICICI Bank"], | |
| "SBIN": ["SBIN", "Sbin", "SBI", "State Bank of India"], | |
| "WIPRO": ["WIPRO", "Wipro", "Wipro Ltd"], | |
| "TATASTEEL": ["TATASTEEL", "Tatasteel", "Tata Steel"], | |
| "BAJFINANCE": ["BAJFINANCE", "Bajfinance", "Bajaj Finance"], | |
| "ADANIENT": ["ADANIENT", "Adanient", "Adani Enterprises"], | |
| "MARUTI": ["MARUTI", "Maruti"], | |
| "SUNPHARMA": ["SUNPHARMA", "Sunpharma", "Sun Pharma"], | |
| "HCLTECH": ["HCLTECH", "Hcltech", "HCL Tech"], | |
| "AXISBANK": ["AXISBANK", "Axisbank", "Axis Bank"], | |
| "ONGC": ["ONGC", "Ongc"], | |
| } | |
| DOUBLE_TEMPLATES = [ | |
| "Buy {name} shares if it drops below {below} and sell if it goes above {above}{strategy_suffix}", | |
| "Buy {name} when price is below {below}, sell above {above}{strategy_suffix}", | |
| "Buy {name} if price falls under {below}, sell above {above}{strategy_suffix}", | |
| "If {name} goes below {below} buy it, and if it crosses {above} sell it{strategy_suffix}", | |
| "{name} - buy under {below}, book profit above {above}{strategy_suffix}", | |
| "Get me into {name} below {below}, exit above {above}{strategy_sentence}", | |
| "Place buy order for {name} below {below} and sell order above {above}{strategy_suffix}", | |
| ] | |
| BUY_ONLY_TEMPLATES = [ | |
| "Buy {name} if it drops below {below}{strategy_suffix}", | |
| "Buy {name} when price is below {below}{strategy_suffix}", | |
| "Get {name} below {below}{strategy_suffix}", | |
| "buy {name} under {below}{strategy_suffix}", | |
| "Accumulate {name} if it falls below {below}{strategy_suffix}", | |
| ] | |
| SELL_ONLY_TEMPLATES = [ | |
| "Sell {name} if it goes above {above}{strategy_suffix}", | |
| "Sell {name} above {above}{strategy_suffix}", | |
| "Exit {name} once it crosses {above}{strategy_suffix}", | |
| "Book profit in {name} above {above}{strategy_suffix}", | |
| ] | |
| MISSING_PRICE_TEMPLATES = [ | |
| "Buy {name} when it is cheap, sell when it is expensive", | |
| "Pick up {name} at a good level and exit higher", | |
| "Trade {name} based on support and resistance", | |
| "Buy {name} when it looks attractive", | |
| ] | |
| MISSING_SYMBOL_TEMPLATES = [ | |
| "buy this stock below {below}, sell above {above}{strategy_suffix}", | |
| "enter below {below} and exit above {above}", | |
| "buy it under {below}, sell it over {above}", | |
| ] | |
| MISSING_ACTION_TEMPLATES = [ | |
| "{name} at {price}{strategy_suffix}", | |
| "Watch {name} near {price}", | |
| "Alert me about {name} around {price}", | |
| ] | |
| AMBIGUOUS_SYMBOL_TEMPLATES = [ | |
| "Buy Tata below {below}", | |
| "Sell Tata above {above}", | |
| "Tata below {below} buy, above {above} sell", | |
| ] | |
| def choose_symbol(): | |
| symbol = RNG.choice(list(SYMBOL_ALIASES.keys())) | |
| name = RNG.choice(SYMBOL_ALIASES[symbol]) | |
| return symbol, name | |
| def choose_strategy_suffix(include_strategy: bool): | |
| if not include_strategy: | |
| return "", "" | |
| return ", intraday", ". intraday trade." | |
| def output(symbol, conditions, strategy_type): | |
| return { | |
| "symbol": symbol, | |
| "action_conditions": conditions, | |
| "strategy_type": strategy_type, | |
| } | |
| def error(error_type, symbol, message): | |
| return { | |
| "error": error_type, | |
| "symbol": symbol, | |
| "message": message, | |
| } | |
| def gen_double_condition_example(): | |
| symbol, name = choose_symbol() | |
| below = RNG.randint(100, 4000) | |
| above = below + RNG.randint(50, 500) | |
| include_strategy = RNG.random() < 0.6 | |
| strategy_suffix, strategy_sentence = choose_strategy_suffix(include_strategy) | |
| template = RNG.choice(DOUBLE_TEMPLATES) | |
| instruction = template.format( | |
| name=name, | |
| below=below, | |
| above=above, | |
| strategy_suffix=strategy_suffix, | |
| strategy_sentence=strategy_sentence, | |
| ).strip() | |
| return instruction, output( | |
| symbol, | |
| [ | |
| {"trigger": "price_below", "value": below, "action": "buy"}, | |
| {"trigger": "price_above", "value": above, "action": "sell"}, | |
| ], | |
| "intraday" if include_strategy else None, | |
| ) | |
| def gen_buy_only_example(): | |
| symbol, name = choose_symbol() | |
| below = RNG.randint(100, 4000) | |
| include_strategy = RNG.random() < 0.5 | |
| strategy_suffix, _ = choose_strategy_suffix(include_strategy) | |
| template = RNG.choice(BUY_ONLY_TEMPLATES) | |
| instruction = template.format(name=name, below=below, strategy_suffix=strategy_suffix).strip() | |
| return instruction, output( | |
| symbol, | |
| [{"trigger": "price_below", "value": below, "action": "buy"}], | |
| "intraday" if include_strategy else None, | |
| ) | |
| def gen_sell_only_example(): | |
| symbol, name = choose_symbol() | |
| above = RNG.randint(100, 4000) | |
| include_strategy = RNG.random() < 0.5 | |
| strategy_suffix, _ = choose_strategy_suffix(include_strategy) | |
| template = RNG.choice(SELL_ONLY_TEMPLATES) | |
| instruction = template.format(name=name, above=above, strategy_suffix=strategy_suffix).strip() | |
| return instruction, output( | |
| symbol, | |
| [{"trigger": "price_above", "value": above, "action": "sell"}], | |
| "intraday" if include_strategy else None, | |
| ) | |
| def gen_error_example(): | |
| kind = RNG.choice(["missing_price", "missing_symbol", "missing_action", "ambiguous_symbol"]) | |
| below = RNG.randint(100, 4000) | |
| above = below + RNG.randint(50, 500) | |
| strategy_suffix, _ = choose_strategy_suffix(RNG.random() < 0.3) | |
| if kind == "missing_price": | |
| symbol, name = choose_symbol() | |
| instruction = RNG.choice(MISSING_PRICE_TEMPLATES).format(name=name) | |
| return instruction, error("missing_price_condition", symbol, "No numeric price condition found.") | |
| if kind == "missing_symbol": | |
| instruction = RNG.choice(MISSING_SYMBOL_TEMPLATES).format( | |
| below=below, | |
| above=above, | |
| strategy_suffix=strategy_suffix, | |
| ) | |
| return instruction, error("missing_symbol", None, "No symbol or company name found.") | |
| if kind == "missing_action": | |
| symbol, name = choose_symbol() | |
| instruction = RNG.choice(MISSING_ACTION_TEMPLATES).format( | |
| name=name, | |
| price=below, | |
| strategy_suffix=strategy_suffix, | |
| ) | |
| return instruction, error("missing_action", symbol, "No buy or sell action found.") | |
| instruction = RNG.choice(AMBIGUOUS_SYMBOL_TEMPLATES).format(below=below, above=above) | |
| return instruction, error("ambiguous_symbol", "TATA", "Symbol is ambiguous. Specify the exact Tata company.") | |
| def fixed_examples(): | |
| """High-value examples that exactly match likely manual tests.""" | |
| return [ | |
| ( | |
| "Buy Infy when price below 1500 and sell above 1700, intraday", | |
| output("INFY", [ | |
| {"trigger": "price_below", "value": 1500, "action": "buy"}, | |
| {"trigger": "price_above", "value": 1700, "action": "sell"}, | |
| ], "intraday"), | |
| ), | |
| ( | |
| "Buy INFY if it drops below 1500, sell above 1700, intraday", | |
| output("INFY", [ | |
| {"trigger": "price_below", "value": 1500, "action": "buy"}, | |
| {"trigger": "price_above", "value": 1700, "action": "sell"}, | |
| ], "intraday"), | |
| ), | |
| ( | |
| "Buy Infosys if it drops below 1500, sell above 1700, intraday", | |
| output("INFY", [ | |
| {"trigger": "price_below", "value": 1500, "action": "buy"}, | |
| {"trigger": "price_above", "value": 1700, "action": "sell"}, | |
| ], "intraday"), | |
| ), | |
| ( | |
| "Buy Infy when price below 1500", | |
| output("INFY", [ | |
| {"trigger": "price_below", "value": 1500, "action": "buy"}, | |
| ], None), | |
| ), | |
| ( | |
| "Buy ONGC when it's cheap, sell when it's expensive", | |
| error("missing_price_condition", "ONGC", "No numeric price condition found."), | |
| ), | |
| ( | |
| "buy this stock below 500, sell above 600, futures", | |
| error("missing_symbol", None, "No symbol or company name found."), | |
| ), | |
| ( | |
| "Do something with Infosys at 1500", | |
| error("missing_action", "INFY", "No buy or sell action found."), | |
| ), | |
| ( | |
| "Buy Tata below 500", | |
| error("ambiguous_symbol", "TATA", "Symbol is ambiguous. Specify the exact Tata company."), | |
| ), | |
| ] | |
| def to_chat_format(instruction, output_json): | |
| return { | |
| "messages": [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": instruction}, | |
| {"role": "assistant", "content": json.dumps(output_json, ensure_ascii=False)}, | |
| ] | |
| } | |
| def generate_dataset(n_total=1600): | |
| examples = fixed_examples() | |
| while len(examples) < n_total: | |
| r = RNG.random() | |
| if r < 0.52: | |
| examples.append(gen_double_condition_example()) | |
| elif r < 0.68: | |
| examples.append(gen_buy_only_example()) | |
| elif r < 0.84: | |
| examples.append(gen_sell_only_example()) | |
| else: | |
| examples.append(gen_error_example()) | |
| RNG.shuffle(examples) | |
| return [to_chat_format(instruction, parsed) for instruction, parsed in examples] | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--n", type=int, default=1600, help="Total examples to generate") | |
| parser.add_argument("--train-split", type=float, default=0.85) | |
| parser.add_argument("--out-dir", type=str, default="data_v2") | |
| args = parser.parse_args() | |
| out_dir = Path(args.out_dir) | |
| out_dir.mkdir(parents=True, exist_ok=True) | |
| data = generate_dataset(args.n) | |
| split_idx = int(len(data) * args.train_split) | |
| train_data = data[:split_idx] | |
| valid_data = data[split_idx:] | |
| train_path = out_dir / "train.jsonl" | |
| valid_path = out_dir / "valid.jsonl" | |
| with train_path.open("w", encoding="utf-8") as f: | |
| for row in train_data: | |
| f.write(json.dumps(row, ensure_ascii=False) + "\n") | |
| with valid_path.open("w", encoding="utf-8") as f: | |
| for row in valid_data: | |
| f.write(json.dumps(row, ensure_ascii=False) + "\n") | |
| print(f"Generated {len(train_data)} training examples -> {train_path}") | |
| print(f"Generated {len(valid_data)} validation examples -> {valid_path}") | |
| print(json.dumps(train_data[0], indent=2)) | |
| if __name__ == "__main__": | |
| main() | |