Connecting multiple stages of parallel synths, with array of buses, in superCollider - supercollider

When I have 2 stages of multiple parallel synths, I am able to connect it with an array of buses. (Thanks to Dan S for the answer to a previous question). When there is a 3 stage, this doesn't seem to work.
(
SynthDef(\siny, { arg freq, outBus=0; Out.ar( outBus, SinOsc.ar(freq!2,0,0.2) ) } ).send(s);
SynthDef(\filter, { arg cFreq,q=0.8, inBus, outBus=0; Out.ar( outBus, BPF.ar(In.ar(inBus), cFreq!2, 1/q ) ) } ).send(s);
)
(
var z = [100,500,1000,1500,200];
~sourceOut = z.collect{ Bus.audio(s) };
~sineOut = z.collect{ Bus.audio(s) };
~sine_Group = ParGroup.new;
~myGroup = ParGroup.new;
{
z.do({ arg val, index; Synth( \siny, [\freq: val, \outBus: ~sourceOut[index]], ~sine_Group ) });
z.do({ arg val, index; Synth.after(~sine_Group, \filter, [\inBus: ~sourceOut[index], \outBus: ~sineOut[index],\cFreq: 200, \q: 20 ], ~myGroup) });
z.do({ arg val, index; Synth.after(~myGroup, \filter, [\inBus: ~sineOut[index], \cFreq: 200, \q: 20]) });
}.play;
)
Another harm that I am doing here is, everytime I stop and run the synth, new instances of busses are created and eventually run out of audio buses. How can I solve this?

There are a number of issues with your code (some irrelevant with your question):
a. send(s) is a reminiscent of the past, these days simply add is preferable - you may consult the documentation for their differences.
b. it's not a good practice to mix local variables var with environmental ones (such as ~sourceOut) unless there is some good reason.
c. .collect(func) (or directly collect{/*function body here*/}) when send to an array results to another array where each element is the result of the func with the respective element of the original array passed as an argument. So here:
var z = [100,500,1000,1500,200];
~sourceOut = z.collect{ Bus.audio(s) };
~sineOut = z.collect{ Bus.audio(s) };
you don't use the original numbers anywhere, you just create two arrays containing 5 Audio buses each. Directly doing so would be less confusing and more explicit:
~sourceOut = Array.fill(5,{Bus.audio(s)});
~sineOut = Array.fill(5,{Bus.audio(s)});
d. there's no point in calling z.do three times.. you can call it just once and put the rest in the same function.
e. check you routings... You have two parallel groups and you're merely saying that I want these synths on that group and these others after that other group.. What you really want to say is that I want these Synths after those Synths on that group.
f. you don't free your Buses or your Synths when done... this is a memory leak :)
g. you call play on a function that want to evaluate really... you should call value instead.
This code does produces sound and cleans up everything when don, note however that the result is pretty boring because you've filtered all the higher-end.
s.waitForBoot({ // this is a routine
var frequencies = [100,500,1000,1500,200];
var sources = Array.fill(frequencies.size,{Bus.audio(s)});
var filters = Array.fill(frequencies.size,{Bus.audio(s)});
var parGroups = Array.fill(2,{ParGroup.new});
var sineSynths;
var firstOrderFilters;
var secondOrderFilters;
SynthDef(\siny, {
arg freq, outBus=0;
Out.ar( outBus, SinOsc.ar(freq!2,0,0.2));
}).add;
SynthDef(\filter, {
arg cFreq,q=0.8, inBus, outBus=0;
Out.ar( outBus, BPF.ar(In.ar(inBus), cFreq!2, 1/q ) )
}).add;
s.sync; // wait for the synthdefs to load
frequencies.do{ arg freq, index;
sineSynths = sineSynths.add( Synth(\siny, [\freq: freq.postln, \outBus: sources[index]],
parGroups[0])); // create synths and add them in the sineSynths Array
firstOrderFilters = firstOrderFilters.add(
Synth.after(sineSynths[index], \filter, [\inBus: sources[index],
\outBus: filters[index], \cFreq: 200, \q: 20 ], parGroups[1]));
secondOrderFilters = secondOrderFilters.add(
Synth.after(firstOrderFilters[index], \filter, [\inBus: filters[index],
\outBus: 0, \cFreq: 200, \q: 20 ], parGroups[1]));
};
10.wait; // wait 10 seconds;
// clean up everything
sineSynths.do{arg i; i.free};
firstOrderFilters.do{arg i; i.free};
secondOrderFilters.do{arg i; i.free};
sources.do{arg i; i.free};
filters.do{arg i; i.free};
});

Related

Algorithm / data structure for resolving nested interpolated values in this example?

I am working on a compiler and one aspect currently is how to wait for interpolated variable names to be resolved. So I am wondering how to take a nested interpolated variable string and build some sort of simple data model/schema for unwrapping the evaluated string so to speak. Let me demonstrate.
Say we have a string like this:
foo{a{x}-{y}}-{baz{one}-{two}}-foo{c}
That has 1, 2, and 3 levels of nested interpolations in it. So essentially it should resolve something like this:
wait for x, y, one, two, and c to resolve.
when both x and y resolve, then resolve a{x}-{y} immediately.
when both one and two resolve, resolve baz{one}-{two}.
when a{x}-{y}, baz{one}-{two}, and c all resolve, then finally resolve the whole expression.
I am shaky on my understanding of the logic flow for handling something like this, wondering if you could help solidify/clarify the general algorithm (high level pseudocode or something like that). Mainly just looking for how I would structure the data model and algorithm so as to progressively evaluate when the pieces are ready.
I'm starting out trying and it's not clear what to do next:
{
dependencies: [
{
path: [x]
},
{
path: [y]
}
],
parent: {
dependency: a{x}-{y} // interpolated term
parent: {
dependencies: [
{
}
]
}
}
}
Some sort of tree is probably necessary, but I am having trouble figuring out what it might look like, wondering if you could shed some light on that with some pseudocode (or JavaScript even).
watch the leaf nodes at first
then, when the children of a node are completed, propagate upward to resolving the next parent node. This would mean once x and y are done, it could resolve a{x}-{y}, but then wait until the other nodes are ready before doing the final top-level evaluation.
You can just simulate it by sending "events" to the system theoretically, like:
ready('y')
ready('c')
ready('x')
ready('a{x}-{y}')
function ready(variable) {
if ()
}
...actually that may not work, not sure how to handle the interpolated nodes in a hacky way like that. But even a high level description of how to solve this would be helpful.
export type SiteDependencyObserverParentType = {
observer: SiteDependencyObserverType
remaining: number
}
export type SiteDependencyObserverType = {
children: Array<SiteDependencyObserverType>
node: LinkNodeType
parent?: SiteDependencyObserverParentType
path: Array<string>
}
(What I'm currently thinking, some TypeScript)
Here is an approach in JavaScript:
Parse the input string to create a Node instance for each {} term, and create parent-child dependencies between the nodes.
Collect the leaf Nodes of this tree as the tree is being constructed: group these leaf nodes by their identifier. Note that the same identifier could occur multiple times in the input string, leading to multiple Nodes. If a variable x is resolved, then all Nodes with that name (the group) will be resolved.
Each node has a resolve method to set its final value
Each node has a notify method that any of its child nodes can call in order to notify it that the child has been resolved with a value. This may (or may not yet) lead to a cascading call of resolve.
In a demo, a timer is set up that at every tick will resolve a randomly picked variable to some number
I think that in your example, foo, and a might be functions that need to be called, but I didn't elaborate on that, and just considered them as literal text that does not need further treatment. It should not be difficult to extend the algorithm with such function-calling features.
class Node {
constructor(parent) {
this.source = ""; // The slice of the input string that maps to this node
this.texts = []; // Literal text that's not part of interpolation
this.children = []; // Node instances corresponding to interpolation
this.parent = parent; // Link to parent that should get notified when this node resolves
this.value = undefined; // Not yet resolved
}
isResolved() {
return this.value !== undefined;
}
resolve(value) {
if (this.isResolved()) return; // A node is not allowed to resolve twice: ignore
console.log(`Resolving "${this.source}" to "${value}"`);
this.value = value;
if (this.parent) this.parent.notify();
}
notify() {
// Check if all dependencies have been resolved
let value = "";
for (let i = 0; i < this.children.length; i++) {
const child = this.children[i];
if (!child.isResolved()) { // Not ready yet
console.log(`"${this.source}" is getting notified, but not all dependecies are ready yet`);
return;
}
value += this.texts[i] + child.value;
}
console.log(`"${this.source}" is getting notified, and all dependecies are ready:`);
this.resolve(value + this.texts.at(-1));
}
}
function makeTree(s) {
const leaves = {}; // nodes keyed by atomic names (like "x" "y" in the example)
const tokens = s.split(/([{}])/);
let i = 0; // Index in s
function dfs(parent=null) {
const node = new Node(parent);
const start = i;
while (tokens.length) {
const token = tokens.shift();
i += token.length;
if (token == "}") break;
if (token == "{") {
node.children.push(dfs(node));
} else {
node.texts.push(token);
}
}
node.source = s.slice(start, i - (tokens.length ? 1 : 0));
if (node.children.length == 0) { // It's a leaf
const label = node.texts[0];
leaves[label] ??= []; // Define as empty array if not yet defined
leaves[label].push(node);
}
return node;
}
dfs();
return leaves;
}
// ------------------- DEMO --------------------
let s = "foo{a{x}-{y}}-{baz{one}-{two}}-foo{c}";
const leaves = makeTree(s);
// Create a random order in which to resolve the atomic variables:
function shuffle(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
[array[j], array[i]] = [array[i], array[j]];
}
return array;
}
const names = shuffle(Object.keys(leaves));
// Use a timer to resolve the variables one by one in the given random order
let index = 0;
function resolveRandomVariable() {
if (index >= names.length) return; // all done
console.log("\n---------------- timer tick --------------");
const name = names[index++];
console.log(`Variable ${name} gets a value: "${index}". Calling resolve() on the connected node instance(s):`);
for (const node of leaves[name]) node.resolve(index);
setTimeout(resolveRandomVariable, 1000);
}
setTimeout(resolveRandomVariable, 1000);
your idea of building a dependency tree it's really likeable.
Anyway I tryed to find a solution as simplest possible.
Even if it already works, there are many optimizations possible, take this just as proof of concept.
The background idea it's produce a List of Strings which you can read in order where each element it's what you need to solve progressively. Each element might be mandatory to solve something that come next in the List, hence for the overall expression. Once you solved all the chunks you have all pieces to solve your original expression.
It's written in Java, I hope it's understandable.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class StackOverflow {
public static void main(String[] args) {
String exp = "foo{a{x}-{y}}-{baz{one}-{two}}-foo{c}";
List<String> chunks = expToChunks(exp);
//it just reverse the order of the list
Collections.reverse(chunks);
System.out.println(chunks);
//output -> [c, two, one, baz{one}-{two}, y, x, a{x}-{y}]
}
public static List<String> expToChunks(String exp) {
List<String> chunks = new ArrayList<>();
//this first piece just find the first inner open parenthesys and its relative close parenthesys
int begin = exp.indexOf("{") + 1;
int numberOfParenthesys = 1;
int end = -1;
for(int i = begin; i < exp.length(); i++) {
char c = exp.charAt(i);
if (c == '{') numberOfParenthesys ++;
if (c == '}') numberOfParenthesys --;
if (numberOfParenthesys == 0) {
end = i;
break;
}
}
//this if put an end to recursive calls
if(begin > 0 && begin < exp.length() && end > 0) {
//add the chunk to the final list
String substring = exp.substring(begin, end);
chunks.add(substring);
//remove from the starting expression the already considered chunk
String newExp = exp.replace("{" + substring + "}", "");
//recursive call for inner element on the chunk found
chunks.addAll(Objects.requireNonNull(expToChunks(substring)));
//calculate other chunks on the remained expression
chunks.addAll(Objects.requireNonNull(expToChunks(newExp)));
}
return chunks;
}
}
Some details on the code:
The following piece find the begin and the end index of the first outer chunk of expression. The background idea is: in a valid expression the number of open parenthesys must be equal to the number of closing parenthesys. The count of open(+1) and close(-1) parenthesys can't ever be negative.
So using that simple loop once I find the count of parenthesys to be 0, I also found the first chunk of the expression.
int begin = exp.indexOf("{") + 1;
int numberOfParenthesys = 1;
int end = -1;
for(int i = begin; i < exp.length(); i++) {
char c = exp.charAt(i);
if (c == '{') numberOfParenthesys ++;
if (c == '}') numberOfParenthesys --;
if (numberOfParenthesys == 0) {
end = i;
break;
}
}
The if condition provide validation on the begin and end indexes and stop the recursive call when no more chunks can be found on the remained expression.
if(begin > 0 && begin < exp.length() && end > 0) {
...
}

Solving problem using Zoho Deluge script in custom function

I need an output as follows for 1200+ accounts:
accounts_count = {
"a": 120,
"b": 45,
"z": 220
}
So it will take the first Letter of an account name and make count for all account with their initial letter.
How can I solve it using Zoho Deluge script in a custom function?
The hard part is getting all the contacts due to the 200 record limit in zoho
I'm not going to provide the full solution here, just the harder parts.
// this is the maximum number of records that you can query at once
max = 200;
// set to a value slightly higher than you need
max_contacts = 1500;
// round up one
n = max_contacts / max + 1;
// This is how many times you will loop (convert to int)
iterations = n.toNumber();
// this is a zoho hack to create a range of the length we want
counter = leftpad("1",iterations).replaceAll(" ","1,").toList();
// set paging
page = 1;
// TODO: initialize an alphabet map
//result = Map( {a: 0, b:0....});
// set to true when done so you're not wasting API Calls
done = false;
for each i in counter
{
// prevent extra crm calls
if(!done)
{
response = zoho.crm.getRecords("Contacts",page,max);
if(!isEmpty(response))
{
if(isNull(response.get(0)) && !isNull(response.get("code")))
{
info "Error:";
info response;
}
else
{
for each user in response
{
// this is the easy part: get the first letter (lowercase)
// get the current value and add one
// set the value again
// set in result map
}
}
}
else
{
done = true;
}
}
// increment the page
page = page + 1;
}

How to repeat the values until next non-empty row and then repeat next row's data and so on with Google Apps Script?

The challenge here is to capture the customer ID and its name and repeat it down below until the script reaches the next non-empty row. Then, the next ID and customer name are the ones that will be repeated.
This is just how far I've gotten on my own, but I can't build the core of the logic mylself (yes).
function repeatValues() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Sheet1");
const originData = sheet.getRange(6, 1, sheet.getLastRow(), 3).getValues();
const targetSheet = ss.getSheetByName("Sheet2");
for (var a = 0; a < originData.length; a++) {
if (originData[a][0] != ''){
var customerID = originData[a][0];
var customer = originData[a][1];
}
if (originData == ''){
targetSheet.getRange(2,1,originData.length, originData.length).setValue(customerID);
}
}
}
Here's a link to the sample spreadsheet: https://docs.google.com/spreadsheets/d/1wU3dql6dnh_JBC6yMkrFzEYxdyzyNdkBmve2pfyxG0g/edit?usp=sharing
Expected Result includes these values in blue repeated:
Any help is appreciated!
I believe your goal as follows.
You want to achieve the following situation. (The following image is from your question.) You want to add the texts of blue font color.
You want to put the values to "Sheet2".
Modification points:
In your script, at const originData = sheet.getRange(6, 1, sheet.getLastRow(), 3).getValues();, the start row is 6. In this case, please modify sheet.getLastRow() to sheet.getLastRow() - 5
In order to create an array for putting to "Sheet2", it is required to check the columns "A" and "B" of "Sheet1". For this, in this modification, I used temp as follows.
When above points are reflected to your script, it becomes as follows.
Modified script:
function repeatValues() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Sheet1");
const originData = sheet.getRange(6, 1, sheet.getLastRow() - 5, 3).getValues(); // Modified
const targetSheet = ss.getSheetByName("Sheet2");
// I added below script.
let temp = ["", ""];
const putValues = originData.map(([a, b, c]) => {
if (a.toString() && b.toString() && temp[0] != a && temp[1] != b) {
temp = [a, b];
}
return temp.concat(c);
});
targetSheet.getRange(2, 1, putValues.length, putValues[0].length).setValues(putValues);
}
Note:
This modified script is for your sample Spreadsheet. So when the structure of Spreadsheet is changed, the script might not be able to be used. Please be careful this.
Reference:
map()

Why MQL4 OrderModify() will not modify the order when backtesting?

I'm trying to ADD a stop loss to my open market orders in MetaTrader 4 when a position gets 100 pips "to the good" which is to be equal to the Order Open Price;
OrderStopLoss() == OrderOpenPrice()
But this isn't happening.
I've added Print() & GetLastError() functions and nothing is coming up in the journal, so it must be something in my coding - but cannot see what would be wrong.
OK this is what I have so far, one for loop for the buy, one for the sell. I've also Normalized the "doubles" as I have been advised to do & have also declared the BuyMod & SellMod to "true" at the very top. This should ensure that the default won't resort to false. I also thought it might be helpful if I told you I have the MetaEditor version 5 build 1241:)
The following code I have is the following;
/*Breakeven Order Modification*/
bool BuyMod = true;
bool SellMod = true;
for(int b = OrdersTotal()-1;b>=0;b--)
{
if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
{
double aBidPrice = MarketInfo(Symbol(),MODE_BID);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = (aBidPrice - anOpenPrice)/_Point;
double stopPoints = (aBidPrice - aNewSLPrice)/_Point;
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL));
int aTicket = OrderTicket();
if(OrderType() == OP_BUY)
if(stopPoints >= stopLevel)
if(aTicket > 0)
if(pnlPoints >= breakeven)
if(aNewSLPrice != aCurrentSL)
{
BuyMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,buycolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
}
}
}
for(int s = OrdersTotal()-1; s>=0; s--)
{
if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES))
{
double anAskPrice = MarketInfo(Symbol(),MODE_ASK);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = (anOpenPrice - anAskPrice)/_Point;
double stopPoints = (aNewSLPrice - anAskPrice)/_Point;
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL));
int aTicket = OrderTicket();
if(OrderType()== OP_SELL)
if(stopPoints >= stopLevel)
if(pnlPoints >= breakeven)
if(aNewSLPrice != aCurrentSL)
if(aTicket > 0)
{
SellMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,sellcolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
}
}
}
trading algorithmic-trading mql4 metatrader4
shareeditdeleteflag
edited just now
asked 2 days ago
Todd Gilbey
264
You might want to know, StackOverflow does not promote duplicate questions. ( see the
Besides meeting an MQL4 syntax-rules,there are more conditions:
A first hidden trouble is in number rounding issues.
MetaQuotes, Inc., recommends wherever possible, to normalise float values into a proper price-representation.
Thus,wherever a price goes into a server-side instruction { OrderSend(), OrderModify(), ... } one shall always prepare such aPriceDOMAIN valueby a call to NormalizeDouble( ... , _Digits ), before a normalised price hits any server-side instruction call.
May sound rather naive, but this saves you issues with server-side rejections.
Add NormalizeDouble() calls into your code on a regular base as your life-saving vest.
A second, even a better hidden trouble is in STOP_ZONE-s and FREEZE_ZONE-s
While not visible directly, any Broker set's in their respective Terms & Conditions these parameters.
In practice,this means, if you instruct { OrderSend() | OrderModify() } to set / move aPriceDOMAIN level to be setup too close to current actual Ask/Bid ( violating a Broker-forbidden STOP_ZONE )orto delete / modify aPriceDOMAIN level of TP or SL, that are already set and is right now, within a Broker-forbidden FREEZE_ZONE distance from actual Ask/Bid,such instruction will not be successfully accepted and executed.
So besides calls to the NormalizeDouble(), always wait a bit longer as the price moves "far" enough and regularly check for not violating forbidden STOP_ + FREEZE_ zones before ordering any modifications in your order-management part of your algotrading projects.
Anyway, Welcome to Wild Worlds of MQL4
Update: while StackOverflow is not a Do-a-Homework site, let me propose a few directions for the solution:
for ( int b = OrdersTotal() - 1; b >= 0; b-- ) // ________________________ // I AM NOT A FAN OF db.Pool-looping, but will keep original approach for context purposes
{ if ( ( OrderSelect( b, SELECT_BY_POS, MODE_TRADES ) ) == true )
{ // YES, HAVE TO OPEN A CODE-BLOCK FOR if()-POSITIVE CASE:
// ------------------------------------------------------
double aBidPRICE = MarketInfo( Symbol(), MODE_BID ); // .UPD
double anOpenPRICE = OrderOpenPrice(); // .SET FROM a db.Pool Current Record
double aNewTpPRICE = OrderTakeProfit(); // .SET FROM a db.Pool Current Record
double aCurrentSlPRICE = OrderStopLoss(); // .SET FROM a db.Pool Current Record
double aNewSlPRICE = anOpenPRICE; // .SET
double pnlPOINTs = ( aBidPRICE - anOpenPRICE )/_Point; // .SET
double stopPOINTs = ( aBidPRICE - aNewSlPRICE )/_Point; // .SET
// ------------------------------------------------------------ // .TEST
if ( OP_BUY == OrderType() )
if ( Period() == OrderMagicNumber() )
if ( stopPOINTa > stopLevel )
if ( pnlPOINTs >= breakeven )
if ( aNewSlPRICE != aCurrentSlPRICE )
{ // YES, HAVE TO OPEN A BLOCK {...}-CODE-BLOCK FOR THE if()if()if()if()-chain's-POSITIVE CASE:
// -------------------------------------------------------------------------------------------
int aBuyMOD = OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( aNewSlPRICE, Digits ),
NormalizeDouble( aNewTpPRICE, Digits ),
0,
buycolor
);
switch( aBuyMOD )
{ case ( NULL ): { ...; break; } // FAIL ( ANALYSE ERROR )
default: { ...; break; } // PASS OrderModify()
}
}
}
The problem is in your call to a built-in OrderModify() function.
OrderStopLoss() == OrderModify() will evaluate as false which in turn will evaluate as 0 since == is a comparison operator.
An OrderStopLoss() is a call to another built-in function (not a variable), you can't save anything to it so OrderStopLoss() = 4 wouldn't work either.
From the MQL4 documentation:
bool OrderModify( int ticket, // ticket
double price, // price
double stoploss, // stop loss
double takeprofit, // take profit
datetime expiration, // expiration
color arrow_color // color
);
In your case that would be the following, assuming ModBuy is already defined somewhere in the code:
ModBuy = OrderModify( OrderTicket(), // <-ticket from record OrderSelect()'d
OrderOpenPrice(), // <-price from current record
OrderOpenPrice(), // <-price from current record
OrderTakeProfit(), // <-TP from current record
0, // ( cannot set P/O expiration for M/O )
buycolor // ( set a color for a GUI marker )
);
Or you could just use any other valid value instead of the second OrderOpenPrice() to set a new stoploss.
I'm really sorry, I'm new to Stackoverflow, this is the revised code I now have based on everyone's comments & recommendation's below
**Local Declarations**
pnlPoints = 0;
point = MarketInfo(Symbol(),MODE_POINT);
stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL)+MarketInfo (Symbol(),MODE_SPREAD));
sl = NormalizeDouble(OrderStopLoss(),Digits);
tp = OrderTakeProfit();
cmd = OrderType();
breakeven = 100;
**Global Variables**
double pnlPoints;
double price,sl,tp;
double point;
int stopLevel;
int cmd;
int breakeven;
double newSL;
for(int b = OrdersTotal()-1; b>=0; b--)
{
if((OrderSelect(b,SELECT_BY_POS,MODE_TRADES))==true)
price = MarketInfo(Symbol(),MODE_BID);
newSL = NormalizeDouble(OrderOpenPrice(),Digits);
pnlPoints = (price - OrderOpenPrice())/point;
{
if(OrderType()==OP_BUY)
if(OrderMagicNumber() == Period())
if((price-newSL)/point>=stopLevel)
if(pnlPoints>=breakeven)
if(sl!=newSL)
ModBuy = OrderModify(OrderTicket(),OrderOpenPrice(),newSL,tp,buycolor);
else if(ModBuy == false)
{
Print("OrderModify failed with error #",GetLastError());
}
}
}

Array of buses in superCollider

I have a Synth generated with a do:
(
SynthDef(\siny, { arg freq, outBus=0; Out.ar( outBus, SinOsc.ar(freq!2,0,0.2) ) } ).send(s);
SynthDef(\filter, { arg cFreq,q=0.8, inBus; Out.ar( 0, BPF.ar(In.ar(inBus), cFreq!2, 1/q ) ) } ).send(s);
)
(
~sourceOut = Bus.audio(s);
~sine_Group = ParGroup.new;
z = [100,500,1000,1500,250];
{
z.do({ arg val; Synth.head(~sine_Group, \siny, [\freq: val, \outBus: ~sourceOut]) });
z.do({ arg val; Synth.after(~sine_Group, \filter, [\inBus: ~sourceOut, \cFreq: 200] ) });
}.play;
)
Right now, my understanding is that, output of multiple instances of Synth \siny get mixed in the bus ~sourceOut, and goes as an input into synth \filter
What i actually want to do is to have a one-to-one connection between the multiple instances of \siny and \filter.. Could I use an array of busses to connect them? If so, how do I do that?
Yes you can. Here I've modified your code minimally. First I made ~sourceOut an array of Busses rather than a single Bus. Second, inside the do loops I made use of the fact that the main iteration functions in SuperCollider can provide a second index argument as well as each item itself. Thirdly I use that index argument to select the desired Bus:
(
z = [100,500,1000,1500,250];
~sourceOut = z.collect{ Bus.audio(s) };
~sine_Group = ParGroup.new;
{
z.do({ arg val, index; Synth.head(~sine_Group, \siny, [\freq: val, \outBus: ~sourceOut[index]]) });
z.do({ arg val, index; Synth.after(~sine_Group, \filter, [\inBus: ~sourceOut[index], \cFreq: 200] ) });
}.play;
)
Depending on your needs, you might also like to look at NodeProxy which is useful for prototyping and live coding, and provides some tricks for plugging synths' output into each other.

Resources