Gamestudio Links
Zorro Links
Newest Posts
Respect History setting for Z systems
by AndrewAMD. 10/02/26 15:43
Purchase A8 full licence version
by ukgamer. 10/02/26 01:31
A3 projects
by Yopachi. 09/28/26 17:04
Parent/child object
by rayp. 09/27/26 14:43
AUM Magazine
Latest Screens
Dorifto samurai
Shadow 2
Rocker`s Revenge
Stug 3 Stormartillery
Who's Online Now
3 registered members (TipmyPip, AndrewAMD, gbe), 8,027 guests, and 2 spiders.
Key: Admin, Global Mod, Mod
Newest Members
julienp, julienper, KelleyAbbey, Yopachi, Knull
19245 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Has anyone developed a turtle trading script? #424960
06/24/13 18:36
06/24/13 18:36
Joined: Jun 2013
Posts: 3
W
wastinglight Offline OP
Guest
wastinglight  Offline OP
Guest
W

Joined: Jun 2013
Posts: 3
I am new to Zorro and fairly new to trading(2 years), one of the strategies I found interesting was the trend trading method used by Richard Dennis and the turtle traders.
In the Help notes you guys mention and discard it briefly, I was wondering if I should spend time developing a script for this strategy, or if it is available for download and testing.

Re: Has anyone developed a turtle trading script? [Re: wastinglight] #424991
06/25/13 09:48
06/25/13 09:48
Joined: Jul 2000
Posts: 28,136
Frankfurt
jcl Offline

Chief Engineer
jcl  Offline

Chief Engineer

Joined: Jul 2000
Posts: 28,136
Frankfurt
The basic turtle system is simple, so you can get a description from the Internet and relatively easily code it. But there are two problems. First, it's for stocks. Second, while the original trade idea is simple, it got a lot of complicated extra conditions that have possibly been added over time whenever the original system failed. So it is not 100% clear which system was originally traded and if it was profitable at all.

Re: Has anyone developed a turtle trading script? [Re: jcl] #425009
06/25/13 13:27
06/25/13 13:27
Joined: Jun 2013
Posts: 3
W
wastinglight Offline OP
Guest
wastinglight  Offline OP
Guest
W

Joined: Jun 2013
Posts: 3
I agree that the idea is simple.
Trade any breakout above/below a 20 or 55 day High/Low.
Yet the adding of entry positions as the trade moves in a positive direction, together with the money management suggested in the books I read by Michael Covel make the whole of the strategy a bit more complicated.
I believe it is not only for stocks but any market showing regular trends, as the forex market does.
Also commodities were among that traded by the turtles.
I plan on writing the script myself since I originally only downloaded Zorro to backtest the strategy, what I would like to know is if I will be able to tell Zorro for instance to start on a certain account balance, or must that be programmed via a seperate variable that is then monitored by the script?

Last edited by wastinglight; 06/25/13 13:29.
Re: Has anyone developed a turtle trading script? [Re: wastinglight] #425031
06/25/13 17:32
06/25/13 17:32
Joined: Jul 2000
Posts: 28,136
Frankfurt
jcl Offline

Chief Engineer
jcl  Offline

Chief Engineer

Joined: Jul 2000
Posts: 28,136
Frankfurt
Starting with a certain balance is rarely necessary, but I've put a script example under "Tips&Tricks" as some other people also asked for it.

Re: Has anyone developed a turtle trading script? [Re: jcl] #425046
06/25/13 20:01
06/25/13 20:01
Joined: May 2013
Posts: 245
S
swingtraderkk Offline
Member
swingtraderkk  Offline
Member
S

Joined: May 2013
Posts: 245
wastinglight,

I've been looking at other implementations of the donchian channel system, all are profitable (so long as you select the correct assets) but not very and have high drawdowns, because trades can last months - this means losing years!!

Courtney Smith has some amendments in his book on how to make the Donchian system more profitable and others on here have posted a sample script to get you started.

I'm still intending to get back to working on them, but I'm still learning zorro so my skills are not yet up to trying the things I want to improve them, particularly adding on to profitable trades like the turtles.

I'm also not really clear on the turtle's selection of 20 day vs 55 day breakout depending on whether the last trade was a winner or loser. That sounds like it might be difficult to code.

I'm also in a rather confused situation, everything I thought I knew about trading is not really very profitable when I backtest with optimisation and WFO with zorro and accurately describes my manual trading, low long term profitability and large drawdowns.

I like jcl's logic in the tutorial and nothing I've been doing prior to zorro has backtested as well as even the simple workshop scripts!!

So where do I invest my efforts? testing and tweaking a few % out of my old methods or taking the plunge and trying to follow Ehlers, the statisticians and signal processing engineers. I'm a long way from understanding what even a Lowpass filer or Dominant cycle really is. I don't really get how wave frequencies are applied to price curves...

Back to the turtles, if you post the rules in english I'll have a stab at coding them.





Last edited by swingtraderkk; 06/25/13 20:03.
Re: Has anyone developed a turtle trading script? [Re: swingtraderkk] #425100
06/26/13 19:36
06/26/13 19:36
Joined: Jun 2013
Posts: 3
W
wastinglight Offline OP
Guest
wastinglight  Offline OP
Guest
W

Joined: Jun 2013
Posts: 3
Hi swingtraderkk.
Thank you for the reply.
I also would like to trade my own version of the turtle system at some point(when I have tested some theories and backtested them).
I do believe however that it is important to stick to the fundamentals of the original system.
I think it is very important to stick with a system once you have decided on it, to give it a fair chance of working.

Here is a link to the system : http://www.metastocktools.com/downloads/turtlerules.pdf

This is my interpretation of it:

Money management:
Risk between 2-4% of your notional account value.
Notional account value is the same as your equity if you are on 0% drawdown for the calendar year.
A 10% drawdown of your account will result in a 20% drop in your notional account value(the value from which you work
out what the 2% risk is in dollar terms).

So the idea with this system is that during big drawdowns you trade less and less risky, waiting for those trends to start coming,
and then you go back to risking a bit more.

1. Firstly you use daily candlestick charts.
2. With Donchian channels on 20 and 55 day high and lows.
3. N is the variable used to represent volatility. ( It is the ATR of the past 20 days)
4. A stop loss is place at 2 times the ATR (2N) from entry.(This is a trailing stop-loss)
5. And the lot size is obviously then worked out from the 2% risk amount divided by the value in dolars of your 2N stop-loss.
6. Once your first order is entered, three additional orders in that same direction are placed 1/2N from the first.
7. So if the market does trend, you will have 4 entries that are 1/2N apart.
8. If you made profit from a 20-day breakout trade, you will skip the next 20-day breakout.
9. BUT, you will always trade a 55-day breakout.
10. If a loss is made from a 20-day breakout trade, you trade the next 20-day breakout again.

11. There are some additional rules regarding total trades in play, and correlated markets, but they might be really hard to program.

I am still learning the programming of scripts, but if you could write up something in the meantime it will definetely help me,
and I could even check if the logic follows the rules.
One thing I wanted to test after reading what I think is a clue dropped in one of Covels books is to play around with the "20" and "55",
the way I understand it there is a range in there that is more profittable. (Maybe 44 or whatever)

Let me know if you have any questions.
Thanks.

Re: Has anyone developed a turtle trading script? [Re: wastinglight] #489687
1 hour ago
1 hour ago
Joined: Oct 2025
Posts: 4
gbe Online
Guest
gbe  Online
Guest

Joined: Oct 2025
Posts: 4
// ---- Real-trade scan buffers: rebuilt every bar, nothing carried ---- [R-33]
#define SCAN_NA 16 // [R-33] max assets in the list
#define SCAN_W 4 // [R-33] events kept per asset and bar
int ScanFillN[SCAN_NA], ScanClsN[SCAN_NA];
var ScanFillID[64], ScanFillDir[64], ScanFillPx[64]; // [R-33] 64 = SCAN_NA * SCAN_W
var ScanClsID[64], ScanClsPx[64];
int FltBars = 0, FltGreen = 0; // [R-22] filter census, trace only

// [R-33] Index of an asset in the list, -1 if absent.
int scanIdx(string Name)
{
int i;
for(i = 0; i < NumAssetsListed; i++)
if(strcmp(Name, Assets[i]) == 0) return i;
return -1;
}

// [R-33] Slot of this bar's fill on asset k in direction Dir, -1 if none.
int scanFill(int k, int Dir)
{
int j;
for(j = 0; j < ScanFillN[k]; j++)
if(j < SCAN_W && ScanFillDir[k*SCAN_W + j] == Dir) return j;
return -1;
}

// [R-33] Slot of this bar's close of trade ID on asset k, -1 if none.
int scanCls(int k, var ID)
{
int j;
for(j = 0; j < ScanClsN[k]; j++)
if(j < SCAN_W && ScanClsID[k*SCAN_W + j] == ID) return j;
return -1;
}

// [R-28] Classify a closed signal by its move before costs, signed by direction.
// [R-28] A move of exactly zero changes nothing.
void classify(vars PrevLoss, vars HaveHist, int Dir, int How, var Move)
{
printf("\n@SIG,%s,%i,%i,%i,%.8f", Asset, (int)Bar, Dir, How, (var)Move); // [R-28] trace
if(Move < 0) { PrevLoss[0] = 1; HaveHist[0] = 1; }
else if(Move > 0) { PrevLoss[0] = 0; HaveHist[0] = 1; }
}

function run()
{
// ---- Engine / mode setup ---------------------------------- [R-01..R-05]
BarPeriod = 1440; // [R-01] daily bars
BarOffset = 940; // [R-01] bar starts 15:40 in the bar time zone
set(LOGFILE); // [R-03] export logs and statistics files
set(TICKS); // [R-02] tick-precise intrabar simulation (D021)
Verbose = 3; // [R-03] skipped trades + parameter errors
// !! [R-03] Warning 047 verbosity is OBSERVED, not documented -- see 3.1.

// ---- Data source ------------------------------------------------ [R-04]
// !! [R-04] '*' reads the year files but keeps Zorro's silent bare-file
// !! fallback; the AssetFirstBar preflight below is the only control on it.
History = "put your \\Zorro\\History\\*.t6"; // [R-04]
NumYears = 20; // [R-05] simulation window
EndDate = 20261001; // [R-05] window end pinned (D029 Add. 3)

// ---- Parameter block -------------- [R-07, R-08, R-24, R-26, R-27, R-31]
int EntryDays = 20; // [R-07] System 1 entry channel, trading days
int ExitDays = 10; // [R-07] System 1 exit channel, trading days
int FailDays = 55; // [R-07] failsafe entry channel, trading days
int NPeriod = 20; // [R-26] N = average true range over 20 days
var StopMult = 2.0; // [R-27] hard stop at 2N from the fill price
int BreakTicks = 1; // [R-08] strict break: price increments beyond the level

// ---- Warm-up ---------------------------------------------- [R-09, R-26]
LookBack = 70; // [R-09] covers 55-day channel and 20-day N
UnstablePeriod = 40; // [R-26] recursive TA-Lib indicators re-run over 40 bars

// ---- Order handling ------------------------------------- [R-10..R-13]
EntryTime = 2; // [R-11] pending order lifetime, bars. INERT (see R-18)
Fill = 2; // [R-12] alternative order filling (D023)
Hedge = 0; // [R-13] netting by ASSET, not by algo

// ---- Universe --------------------------------------------------- [R-06]
if(is(INITRUN))
assetList("AssetsDryRunP7"); // [R-06] frozen P7 (D019)

MaxLong = 1; // [R-10] one position per side per asset
MaxShort = 1; // [R-10] magnitude live, sign inert (see R-18)

// ---- Real-trade scan: this bar's fills and closes ------------- [R-33]
// [R-33] Above the asset loop: enumeration loops cannot be nested.
int si, sk, ss;
for(si = 0; si < SCAN_NA; si++) { ScanFillN[si] = 0; ScanClsN[si] = 0; }
for(past_trades) {
if(TradeID != 0) {
sk = scanIdx(TradeAsset);
if(sk >= 0) {
// !! [R-33] TradeInt is 0 on a new trade: OBSERVED, not documented.
if(TradeInt[15] == 0) { // [R-33] fill not seen yet
TradeInt[15] = 1;
if(ScanFillN[sk] < SCAN_W) {
ss = sk*SCAN_W + ScanFillN[sk];
ScanFillID[ss] = TradeID; ScanFillDir[ss] = ifelse(TradeIsLong, 1, -1);
ScanFillPx[ss] = TradePriceOpen;
}
ScanFillN[sk] += 1;
}
if(TradeIsClosed && TradeInt[14] == 0) { // [R-33] close not seen yet
TradeInt[14] = 1;
if(ScanClsN[sk] < SCAN_W) {
ss = sk*SCAN_W + ScanClsN[sk];
ScanClsID[ss] = TradeID; ScanClsPx[ss] = TradePriceClose;
}
ScanClsN[sk] += 1;
}
}
}
}
if(is(EXITRUN))
printf("\n@FGR,%i,%i", FltGreen, FltBars); // [R-22] filter census, trace only

for(listed_assets)
{
// [R-25] for(listed_assets) only assigns Asset; it does not select.
if(!asset(Asset)) continue;

// [R-04] Reject any asset whose history does not cover the window.
if(AssetFirstBar > 0) {
printf("\n SKIP %s -- history starts at bar %i/%i",
Asset, (int)AssetFirstBar, (int)NumBars);
continue;
}

// [R-08] Read PIP inside the loop: it is an asset-specific parameter.
var BreakOffset = BreakTicks * PIP;

// ---- Price series ------------------------------------------------
vars H = series(priceHigh());
vars L = series(priceLow());

// ---- Rolling trading-day channels ------------------ [R-15, R-25]
// [R-25] Per-asset state lives in series(), NEVER in a bare static.
// [R-15] Carried as series so the code can read the level that was
// actually RESTING during a given bar -- see R-16.
vars ChEntryHigh = series(0), ChEntryLow = series(0);
vars ChExitLow = series(0), ChExitHigh = series(0);
vars ChFailHigh = series(0), ChFailLow = series(0);

ChEntryHigh[0] = MaxVal(H, EntryDays); // 20-day high
ChEntryLow[0] = MinVal(L, EntryDays); // 20-day low
ChExitLow[0] = MinVal(L, ExitDays); // 10-day low
ChExitHigh[0] = MaxVal(H, ExitDays); // 10-day high
ChFailHigh[0] = MaxVal(H, FailDays); // 55-day high
ChFailLow[0] = MinVal(L, FailDays); // 55-day low

// ---- Volatility primitive N -------------------------------- [R-26]
vars N = series(ATR(NPeriod));

// ---- Warm-up counter ---------------------------------------- [R-09]
vars BarsSeen = series(0);
BarsSeen[0] = BarsSeen[1] + 1;

// ---- Shadow-tracker series -------------------- [R-22, R-25, R-28]
// [R-25] Created ABOVE the warm-up gate: series() calls must never be
// skipped by a bar-varying condition. Only their [0] elements are set
// conditionally, further down.
vars ShDir = series(0); // shadow signal: 0 none, +1 long, -1 short
vars ShEntry = series(0); // shadow entry price (level + break offset)
vars ShAdv = series(0); // [R-28] the 2N adverse level, fixed at signal
vars PrevLoss = series(0); // 1 = last CLOSED shadow signal was a loser
vars HaveHist = series(0); // 1 = at least one shadow signal has closed

ShDir[0] = ShDir[1];
ShEntry[0] = ShEntry[1];
ShAdv[0] = ShAdv[1];
PrevLoss[0] = PrevLoss[1];
HaveHist[0] = HaveHist[1];

// ---- Real-trade link series ---------------------------- [R-33, R-25]
vars TrkID = series(0); // [R-33] real trade tied to the open signal, 0 none
vars PlL = series(0); // [R-33] 1 = a 20-day long entry rested this bar
vars PlS = series(0); // [R-33] 1 = a 20-day short entry rested this bar
TrkID[0] = TrkID[1];

// [R-09] Warm-up gate. Every series() call for this asset is ABOVE it.
if(BarsSeen[0] < 70) continue;

// ---- Level-or-distance preflight -------------------- [R-17, R-32]
var HalfPrice = 0.5 * priceClose();
bool badEntryHigh = (ChEntryHigh[0] < HalfPrice);
bool badEntryLow = (ChEntryLow[0] < HalfPrice);
bool badExitLow = (ChExitLow[0] < HalfPrice);
bool badExitHigh = (ChExitHigh[0] < HalfPrice);
bool badFailHigh = (ChFailHigh[0] < HalfPrice);
bool badFailLow = (ChFailLow[0] < HalfPrice);
bool badStopDist = (StopMult * N[0] >= HalfPrice);

if(badEntryHigh || badEntryLow || badExitLow || badExitHigh || badFailHigh || badFailLow)
printf("\n!!! %s bar %i: channel level below half the asset price %.5f (EntryHigh %.5f, EntryLow %.5f, ExitLow %.5f, ExitHigh %.5f, FailHigh %.5f, FailLow %.5f) -- Zorro reads such a value as a DISTANCE, not a level (stop.htm).",
Asset, (int)Bar, (var)HalfPrice, (var)ChEntryHigh[0], (var)ChEntryLow[0],
(var)ChExitLow[0], (var)ChExitHigh[0], (var)ChFailHigh[0], (var)ChFailLow[0]);
if(badStopDist)
printf("\n!!! %s bar %i: 2N stop distance %.5f is at or above half the asset price %.5f -- Zorro would read it as a LEVEL, not a distance (stop.htm).",
Asset, (int)Bar, (var)(StopMult * N[0]), (var)HalfPrice);
// [R-32] Exit levels are NOT gated -- suppressing an exit removes protection.
if(badExitLow || badExitHigh)
printf("\n@XLV,%s,%i,%.8f,%.8f,%.8f", Asset, (int)Bar,
(var)ChExitLow[0], (var)ChExitHigh[0], (var)HalfPrice);

// ---- One-bar order-placement lag -------------------------- [R-16]
// [R-16] Convention: every TEST reads [1], every ORDER is placed with [0].
var RestEntryHigh = ChEntryHigh[1];
var RestEntryLow = ChEntryLow[1];
var RestExitLow = ChExitLow[1];
var RestExitHigh = ChExitHigh[1];
var RestFailHigh = ChFailHigh[1];
var RestFailLow = ChFailLow[1];
var RestN = N[1];

// [R-08] Entry breaks are STRICT: the offset is in the test and in the
// order, so shadow and real fill on the same bar at the same price.
bool hitEntryHigh = (H[0] >= RestEntryHigh + BreakOffset);
bool hitEntryLow = (L[0] <= RestEntryLow - BreakOffset);
// [R-20] Exit stops are taken AT the level -- the break rule is on entries.
bool hitExitLow = (L[0] <= RestExitLow);
bool hitExitHigh = (H[0] >= RestExitHigh);

// ---- Shadow signal bookkeeping ---------- [R-22, R-28, R-21, R-33]
int ScanK = scanIdx(Asset); // [R-33]
int RealClosed = 0, Slot = -1, FillSlot = -1, OpenDir = 0;
var RealExit = 0, Rested20 = 0;
if(TrkID[0] != 0) {
Slot = scanCls(ScanK, TrkID[0]);
if(Slot >= 0) { RealClosed = 1; RealExit = ScanClsPx[ScanK*SCAN_W + Slot]; }
}
int ShStart = ShDir[0]; // [R-22] shadow state at bar start
if(ShStart != 0 && TrkID[0] != 0)
{
// [R-33] A taken breakout closes with its real trade, never on the shadow tests.
if(RealClosed) {
classify(PrevLoss, HaveHist, ShStart, 3, (RealExit - ShEntry[0]) * ShStart);
ShDir[0] = 0;
}
}
else if(ShStart > 0)
{
// [R-28] 2N adverse excursion tested BEFORE the 10-day exit.
if(L[0] <= ShAdv[0]) {
classify(PrevLoss, HaveHist, 1, 1, ShAdv[0] - ShEntry[0]);
ShDir[0] = 0;
} else if(hitExitLow) {
classify(PrevLoss, HaveHist, 1, 2, RestExitLow - ShEntry[0]);
ShDir[0] = 0;
}
}
else if(ShStart < 0)
{
if(H[0] >= ShAdv[0]) {
classify(PrevLoss, HaveHist, -1, 1, ShEntry[0] - ShAdv[0]);
ShDir[0] = 0;
} else if(hitExitHigh) {
classify(PrevLoss, HaveHist, -1, 2, ShEntry[0] - RestExitHigh);
ShDir[0] = 0;
}
}
if(RealClosed) TrkID[0] = 0;
if(ShStart == 0)
{
// [R-21] Outside-bar tie-break: long tested first, deterministically.
if(hitEntryHigh) OpenDir = 1;
else if(hitEntryLow) OpenDir = -1;
// [R-22] No same-bar close: a shadow opened here is tested from
// the NEXT bar.
}
else if(ShDir[0] == 0) // [R-22] closed on this bar
{
// [R-22] An OPPOSITE break on the closing bar opens a new signal.
if(ShStart > 0 && hitEntryLow) OpenDir = -1;
else if(ShStart < 0 && hitEntryHigh) OpenDir = 1;
}
if(OpenDir != 0)
{
ShDir[0] = OpenDir;
if(OpenDir > 0) ShEntry[0] = RestEntryHigh + BreakOffset;
else ShEntry[0] = RestEntryLow - BreakOffset;
ShAdv[0] = ShEntry[0] - OpenDir * StopMult * RestN; // [R-28]
// [R-33] Taken: a same-direction fill this bar, from a 20-day order rested last bar.
FillSlot = scanFill(ScanK, OpenDir);
Rested20 = PlS[1];
if(OpenDir > 0) Rested20 = PlL[1];
if(FillSlot >= 0 && Rested20 == 1) {
TrkID[0] = ScanFillID[ScanK*SCAN_W + FillSlot];
ShEntry[0] = ScanFillPx[ScanK*SCAN_W + FillSlot]; // [R-33] the real fill
Slot = scanCls(ScanK, TrkID[0]);
if(Slot >= 0) {
// [R-33] The real trade also closed on its fill bar.
classify(PrevLoss, HaveHist, OpenDir, 3, (ScanClsPx[ScanK*SCAN_W + Slot] - ShEntry[0]) * OpenDir);
ShDir[0] = 0;
TrkID[0] = 0;
}
}
}

// ---- Previous-signal filter ------------------------ [R-22, R-23]
// [R-22] Read AFTER this bar's shadow update.
// [R-23] First signal on each asset is taken: there is no previous one.
bool filterOK = (HaveHist[0] == 0) || (PrevLoss[0] > 0);
FltBars += 1; if(filterOK) FltGreen += 1; // [R-22] census, trace only

// ---- Real orders ---- [R-14, R-18..R-21, R-27, R-29..R-32]
if(NumOpenLong > 0)
{
// [R-19] Cancel the opposite pending order left alive by the fill.
exitShort(0);
// [R-20, R-30] Ratcheted 10-day channel exit, re-issued each bar at
// the current level; it can only tighten. [R-27] the 2N stop stays
// attached and the nearer of the two closes the trade.
exitLong(0, ChExitLow[0]);
}
else if(NumOpenShort > 0)
{
exitLong(0);
exitShort(0, ChExitHigh[0]);
}
else
{
// [R-18] Cancel yesterday's unfilled orders, then re-place fresh.
// Reached ONLY when flat -- the branch structure IS the guard.
exitLong(0);
exitShort(0);

Stop = StopMult * N[0]; // [R-27] 2N hard stop, a DISTANCE to the fill price

// [R-29] Filter green: the 20-day levels. Filter red: the 55-day failsafe.
var LongLevel = ChEntryHigh[0];
var ShortLevel = ChEntryLow[0];
bool badLong = badEntryHigh;
bool badShort = badEntryLow;
if(!filterOK) {
LongLevel = ChFailHigh[0]; badLong = badFailHigh;
ShortLevel = ChFailLow[0]; badShort = badFailLow;
}

// [R-14] Family B: resting stop orders AT the level, not close tests.
// [R-08] Entry carries the break offset.
// [R-32] An order the engine would misread is suppressed, per side.
if(badLong || badStopDist)
printf("\n@SUP,%s,%i,L,%.8f,%.8f,%.8f", Asset, (int)Bar,
(var)LongLevel, (var)HalfPrice, (var)(StopMult * N[0]));
else {
enterLong(1, LongLevel + BreakOffset);
PlL[0] = filterOK; // [R-33] 1 = rested at the 20-day level
}

if(badShort || badStopDist)
printf("\n@SUP,%s,%i,S,%.8f,%.8f,%.8f", Asset, (int)Bar,
(var)ShortLevel, (var)HalfPrice, (var)(StopMult * N[0]));
else {
enterShort(1, ShortLevel - BreakOffset);
PlS[0] = filterOK; // [R-33] 1 = rested at the 20-day level
}
}
}
}


Moderated by  Petra 

Gamestudio download | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1