Dukascopy Support Board
http://www.dukascopy.com/swiss/english/forex/jforex/forum/

Position Size Calculator how to use into strategy
http://www.dukascopy.com/swiss/english/forex/jforex/forum/viewtopic.php?f=65&t=57188
Page 1 of 1

Author:  fxdiler [ Fri 01 Nov, 2019, 12:16 ]
Post subject:  Position Size Calculator how to use into strategy

Hello,

I need to use position size calculator into my strategy, I need to calculate position amount depends on risk % of equity. There is a calculator on Dukascopy web site https://www.dukascopy.com/swiss/english ... alculator/

Which formula can I use to calculate position size? I have the next code, it works with currencies but give wrong result for metals and CFDs.
private double getAmount(Instrument instrument, double price1, double price2) throws JFException {
     double pips = Math.abs(price1 - price2)/getPipValue(instrument);
     double amount = 0.0;
     double equity = context.getAccount().getEquity();
     double loss = equity * risk / 100.0;
     double price = (getAsk(instrument) + getBid(instrument)) / 2.0;
     if (loss > 0 && pips > 0) {
         double pipCost = getPipCost(instrument);
         amount = loss / (pips * pipCost * (price * pipCost / getPipValue(instrument)));
         if (amount < 1000.0) {
                amount = 1000.0;
         }
     }
     return amount / 1000000.0;
}


private double getPipCost(Instrument instrument) throws JFException {
    return utils.convertPipToCurrency(instrument, currency);
}
private double getPipValue(Instrument instrument) {
    return instrument.getPipValue();
}

private double getAsk(Instrument instrument) throws JFException {
    return history.getLastTick(instrument).getAsk();
}

private double getBid(Instrument instrument) throws JFException {
    return history.getLastTick(instrument).getBid();
}

Author:  goose_ [ Fri 01 Nov, 2019, 18:28 ]
Post subject:  Re: Position Size Calculator how to use into strategy

Maybe it will help a little bit... I use something like this to count position size per instrument. I count scale per instrument in function getScale and return this value in function getPosMinSize. And then I calc rate for currency to do this. Next I do count for limit in function calcLimit. Change the "int risk = 50;" in this function to 20, 25 or other value of risk. Subscribe 3 instruments like EURUSD, DEU.IDX, USA30TECH and watch result in console. This code is chaos, but i hope that will help you a little bit...

package jforex;

import java.util.*;

import com.dukascopy.api.*;

import com.dukascopy.api.IEngine.OrderCommand;

public class Strategy__demo__ implements IStrategy {
    private IEngine engine;
    private IConsole console;
    private IHistory history;
    private IContext context;
    private IIndicators indicators;
    private IUserInterface userInterface;
    private JFUtils utils;
   
    public void onStart(IContext context) throws JFException {
        this.engine = context.getEngine();
        this.console = context.getConsole();
        this.history = context.getHistory();
        this.context = context;
        this.indicators = context.getIndicators();
        this.userInterface = context.getUserInterface();
        this.utils = context.getUtils();
    }

    public void onAccount(IAccount account) throws JFException {
        print(account.getUseOfLeverage());
        print(account.getUsedMargin());
    }

    public void onMessage(IMessage message) throws JFException {
    }

    public void onStop() throws JFException {
    }

    public void onTick(Instrument instrument, ITick tick) throws JFException {
    }
   
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
       
        print(" equity : " + context.getAccount().getEquity() + "  | balance : " + context.getAccount().getBalance() );
        print(" scale : " + getScale(instrument));
        print(" posMinSize : " + getPosMinSize(instrument));
        print(" calcLimit : " + calcLimit(instrument));
       
        sendOrder(instrument, OrderCommand.BUY);
       
        for (IOrder order : engine.getOrders()) {
            print(order);
        }
       
        context.stop();
       
    }
   
    public void sendOrder(Instrument instrument, OrderCommand orderCommand) throws JFException {
        if (engine.getOrders(instrument).size() > 0) return;
        double min_trade_amount = instrument.getMinTradeAmount() / 1000000;
        print(" min_trade_amount --> " + min_trade_amount);
        engine.submitOrder(getLabel(instrument), instrument, orderCommand, min_trade_amount * calcLimit(instrument));
    }
   
    private int counter = 0;
   
    protected String getLabel(Instrument instrument) {
        String label = instrument.name();
        label = label + System.currentTimeMillis() + (counter++);
        label = label.toUpperCase();
        return label;
    }
   
    // to calc minimum position size
    public double getScale(Instrument instrument) {
        double scale = 0;
        if (instrument.getPipScale() == 4) { // eurusd, gbpusd
            scale = 10;
        }
        if (instrument.getPipScale() == 2) { // deu, usa30
            scale = 0.01;
        }
        if (instrument.equals(Instrument.USDJPY)) { // usdjpy
            scale = 10;
        }
        return scale;
    }
   
    // calc min position size
    public double getPosMinSize(Instrument instrument) throws JFException {
        double rate = utils.getRate(JFCurrency.getInstance(instrument.getSecondaryJFCurrency().toString()),
            JFCurrency.getInstance(context.getAccount().getAccountCurrency().toString()));
        return rate * getScale(instrument) * history.getLastTick(instrument).getBid();
    }
   
    // limit per instrument to open position
    public double calcLimit(Instrument instrument) throws JFException {
        int n = 0;
        //int limit = 500; // 500 is default
        Double balance = context.getAccount().getBalance();
        //int limit = balance.intValue() / 10; // 5 = 100% / 10 = 50% depo
        int risk = 50;
        //int limit = (risk * balance.intValue() / 100) / context.getSubscribedInstruments().size() - 1;
        int limit = (risk * balance.intValue()) / 100;
        while (getPosMinSize(instrument) * n < limit) {         
            n ++;
        }
        //return getPosMinSize(instrument) * n;
        return n;
    }
   
    public void print(Object o) {
        console.getOut().println(o);
    }
   
}

  Page 1 of 1